From patchwork Fri Dec 7 23:15:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nobuhiro Iwamatsu X-Patchwork-Id: 1852031 X-Patchwork-Delegate: rui.zhang@intel.com Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id E6B79400ED for ; Fri, 7 Dec 2012 23:03:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1031011Ab2LGXD1 (ORCPT ); Fri, 7 Dec 2012 18:03:27 -0500 Received: from mail-pa0-f46.google.com ([209.85.220.46]:49833 "EHLO mail-pa0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031009Ab2LGXD0 (ORCPT ); Fri, 7 Dec 2012 18:03:26 -0500 Received: by mail-pa0-f46.google.com with SMTP id bh2so780216pad.19 for ; Fri, 07 Dec 2012 15:03:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=fP7F9o5Ed4U2QDkMSyREGoeD/92i/v63mPeeasd5hR8=; b=j3XeLd6SGwbAJ79VQOwFFTEhSfG2NtMU1kcOe8Mece8JLMWZ50ftRxNc5kdSJoCd0i ELNIgi28gkz6Znw2By7bfLOno9NWfWcrC0iX6sNwpYJk2dMSsa+h+cseko3aVFEG8tfh HYWHGrVlHFQwqxtDxZ8DK+YUd7UuiyDvSpi8v93IeJfINcWonmsSUiH+lOy7mdYCmbp9 e0rktDkqd2R4FKlkUXPET8UnfZwRYZhvYyRn8iRIen7q+lUdD8ymF1Z8ZgmNha76oiiF WPLpRocvncHlkLvXzHIsat5Kkuft7WbAgdYmR5If5gac/JMtyDo5bXj47iAFyBuqC4o0 n8YQ== Received: by 10.66.88.196 with SMTP id bi4mr17401244pab.16.1354921405608; Fri, 07 Dec 2012 15:03:25 -0800 (PST) Received: from chimagu (y104036.dynamic.ppp.asahi-net.or.jp. [118.243.104.36]) by mx.google.com with ESMTPS id na4sm7380853pbc.18.2012.12.07.15.03.23 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 07 Dec 2012 15:03:24 -0800 (PST) Received: from iwamatsu by chimagu with local (Exim 4.80) (envelope-from ) id 1Th796-0000qx-OW; Sat, 08 Dec 2012 08:15:52 +0900 From: Nobuhiro Iwamatsu To: linux-pm@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, rui.zhang@intel.com, jason@lakedaemon.net, Nobuhiro Iwamatsu Subject: [PATCH 1/2] thermal: Add support for thermal sensor for Kirkwood SoC Date: Sat, 8 Dec 2012 08:15:50 +0900 Message-Id: <1354922151-3250-1-git-send-email-iwamatsu@nigauri.org> X-Mailer: git-send-email 1.7.10.4 X-Gm-Message-State: ALoCoQlcw+gZVRm0p2m981sVGwR3ee7DGLU6Hrm805jhimvrFrBTzkxrvYxyOFOoUS0JpccBNKU2 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Some kirkwood SoC has thermal sensor. This patch adds support for 88F6282 and 88F6283. Signed-off-by: Nobuhiro Iwamatsu Tested-by: Jason Gunthorpe --- drivers/thermal/Kconfig | 7 ++ drivers/thermal/Makefile | 1 + drivers/thermal/kirkwood_thermal.c | 131 ++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 drivers/thermal/kirkwood_thermal.c diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index e1cb6bd..8710ac2 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -55,3 +55,10 @@ config EXYNOS_THERMAL help If you say yes here you get support for TMU (Thermal Managment Unit) on SAMSUNG EXYNOS series of SoC. + +config KIRKWOOD_THERMAL + tristate "Temperature sensor on Marvel Kirkwood" + depends on ARCH_KIRKWOOD && THERMAL + help + Support for the Kirkwood thermal sensor driver into the Linux thermal + framework. This supports only 88F6282 and 88F6283. diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 885550d..4dbe5e1 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_THERMAL) += thermal_sys.o obj-$(CONFIG_CPU_THERMAL) += cpu_cooling.o obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o +obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c new file mode 100644 index 0000000..bddcf49 --- /dev/null +++ b/drivers/thermal/kirkwood_thermal.c @@ -0,0 +1,131 @@ +/* + * kirkwood thermal sensor driver + * + * Copyright (C) 2012 Nobuhiro Iwamatsu + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define THERMAL_VALID_OFFSET 9 +#define THERMAL_VALID_MASK 0x1 +#define THERMAL_TEMP_OFFSET 10 +#define THERMAL_TEMP_MASK 0x1FF + +/* Kirkwood Thermal Sensor Dev Structure */ +struct kirkwood_thermal_dev { + void __iomem *base_addr; +}; + +static inline int kirkwood_get_temp(struct thermal_zone_device *thermal, + unsigned long *temp) +{ + unsigned long reg; + struct kirkwood_thermal_dev *thermal_dev = thermal->devdata; + + reg = readl_relaxed(thermal_dev->base_addr); + + /* Valid check */ + if (!(reg >> THERMAL_VALID_OFFSET) & THERMAL_VALID_MASK) { + dev_info(&thermal->device, "Reading temperature is not valid\n"); + return -EIO; + } + + reg = (reg >> THERMAL_TEMP_OFFSET) & THERMAL_TEMP_MASK; + /* Calculate temperature. See Table 814 in hardware manual. */ + *temp = ((322 - reg) * 10000) / 13625; + + return 0; +} + +static struct thermal_zone_device_ops ops = { + .get_temp = kirkwood_get_temp, +}; + +static int kirkwood_thermal_probe(struct platform_device *pdev) +{ + struct thermal_zone_device *thermal = NULL; + struct kirkwood_thermal_dev *thermal_dev; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Failed to get platform resource\n"); + return -ENODEV; + } + + thermal_dev + = devm_kzalloc(&pdev->dev, sizeof(*thermal_dev), GFP_KERNEL); + if (!thermal_dev) { + dev_err(&pdev->dev, "kzalloc fail\n"); + return -ENOMEM; + } + + thermal_dev->base_addr = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!thermal_dev->base_addr) { + dev_err(&pdev->dev, "Failed to ioremap memory\n"); + return -ENOMEM; + } + + thermal = thermal_zone_device_register("kirkwood_thermal", 0, 0, + thermal_dev, &ops, 0, 0); + if (IS_ERR(thermal)) { + dev_err(&pdev->dev, "Failed to register thermal zone device\n"); + return PTR_ERR(thermal); + } + + platform_set_drvdata(pdev, thermal); + + dev_info(&thermal->device, KBUILD_MODNAME ": Thermal sensor registered\n"); + + return 0; +} + +static int kirkwood_thermal_exit(struct platform_device *pdev) +{ + struct thermal_zone_device *kirkwood_thermal + = platform_get_drvdata(pdev); + + thermal_zone_device_unregister(kirkwood_thermal); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id kirkwood_thermal_id_table[] = { + { .compatible = "marvel,thermal-kirkwood" }, + {} +}; +MODULE_DEVICE_TABLE(of, kirkwood_thermal_id_table); + +static struct platform_driver kirkwood_thermal_driver = { + .probe = kirkwood_thermal_probe, + .remove = kirkwood_thermal_exit, + .driver = { + .name = "kirkwood_thermal", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(kirkwood_thermal_id_table), + }, +}; + +module_platform_driver(kirkwood_thermal_driver); + +MODULE_AUTHOR("Nobuhiro Iwamatsu "); +MODULE_DESCRIPTION("kirkwood thermal driver"); +MODULE_LICENSE("GPL");