From patchwork Fri Dec 14 11:03:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Lunn X-Patchwork-Id: 1878361 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 C5B1A40079 for ; Fri, 14 Dec 2012 11:03:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756363Ab2LNLD3 (ORCPT ); Fri, 14 Dec 2012 06:03:29 -0500 Received: from londo.lunn.ch ([80.238.139.98]:46156 "EHLO londo.lunn.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756355Ab2LNLD2 (ORCPT ); Fri, 14 Dec 2012 06:03:28 -0500 Received: from lunn by londo.lunn.ch with local (Exim 3.36 #1 (Debian)) id 1TjT2s-0000Ez-00; Fri, 14 Dec 2012 12:03:10 +0100 From: Andrew Lunn To: linux ARM , iwamatsu@nigauri.org, linux-pm@vger.kernel.org Cc: Jason Cooper , Sebastian Hesselbarth , Thomas Petazzoni , jgunthorpe@obsidianresearch.com, Andrew Lunn Subject: [PATCH 1/2] thermal: Add support for thermal sensor for Orion SoC Date: Fri, 14 Dec 2012 12:03:05 +0100 Message-Id: <1355482986-885-2-git-send-email-andrew@lunn.ch> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1355482986-885-1-git-send-email-andrew@lunn.ch> References: <1355482986-885-1-git-send-email-andrew@lunn.ch> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org From: Nobuhiro Iwamatsu Some Orion SoC has thermal sensor. This patch adds support for 88F6282 and 88F6283. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Andrew Lunn Tested-by: Jason Gunthorpe Tested-by: Nobuhiro Iwamatsu --- .../devicetree/bindings/thermal/orion-thermal.txt | 16 +++ drivers/thermal/Kconfig | 7 ++ drivers/thermal/Makefile | 1 + drivers/thermal/orion_thermal.c | 133 ++++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/orion-thermal.txt create mode 100644 drivers/thermal/orion_thermal.c diff --git a/Documentation/devicetree/bindings/thermal/orion-thermal.txt b/Documentation/devicetree/bindings/thermal/orion-thermal.txt new file mode 100644 index 0000000..5ce925d --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/orion-thermal.txt @@ -0,0 +1,16 @@ +* Orion Thermal + +This initial version is for Kirkwood 88F8262 & 88F6283 SoCs, however +it is expected the driver will sometime in the future be expanded to +also support Dove, using a different compatibility string. + +Required properties: +- compatible : "marvell,kirkwood-thermal" +- reg : Address range of the thermal registers + +Example: + + thermal@10078 { + compatible = "marvell,kirkwood"; + reg = <0x10078 0x4>; + }; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index e1cb6bd..3bba13f 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 ORION_THERMAL + tristate "Temperature sensor on Marvel Orion SoCs" + depends on PLAT_ORION && THERMAL + help + Support for the Orion thermal sensor driver into the Linux thermal + framework. This currently supports only 88F6282 and 88F6283. diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 885550d..2fc64aa 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_ORION_THERMAL) += orion_thermal.o obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o diff --git a/drivers/thermal/orion_thermal.c b/drivers/thermal/orion_thermal.c new file mode 100644 index 0000000..e8a2a68 --- /dev/null +++ b/drivers/thermal/orion_thermal.c @@ -0,0 +1,133 @@ +/* + * Orion 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 + +/* Orion Thermal Sensor Dev Structure */ +struct orion_thermal_dev { + void __iomem *base_addr; +}; + +static int orion_get_temp(struct thermal_zone_device *thermal, + unsigned long *temp) +{ + unsigned long reg; + struct orion_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, + "Temperature sensor reading not valid\n"); + return -EIO; + } + + reg = (reg >> THERMAL_TEMP_OFFSET) & THERMAL_TEMP_MASK; + /* Calculate temperature. See Table 814 in 8262 hardware manual. */ + *temp = ((322UL - reg) * 10000UL * 1000UL) / 13625UL; + + return 0; +} + +static struct thermal_zone_device_ops ops = { + .get_temp = orion_get_temp, +}; + +static int orion_thermal_probe(struct platform_device *pdev) +{ + struct thermal_zone_device *thermal = NULL; + struct orion_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("orion_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 orion_thermal_exit(struct platform_device *pdev) +{ + struct thermal_zone_device *orion_thermal = platform_get_drvdata(pdev); + + thermal_zone_device_unregister(orion_thermal); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id orion_thermal_id_table[] = { + { .compatible = "marvell,kirkwood-thermal" }, + {} +}; +MODULE_DEVICE_TABLE(of, orion_thermal_id_table); + +static struct platform_driver orion_thermal_driver = { + .probe = orion_thermal_probe, + .remove = orion_thermal_exit, + .driver = { + .name = "orion_thermal", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(orion_thermal_id_table), + }, +}; + +module_platform_driver(orion_thermal_driver); + +MODULE_AUTHOR("Nobuhiro Iwamatsu "); +MODULE_DESCRIPTION("orion thermal driver"); +MODULE_LICENSE("GPL");