From patchwork Wed Mar 20 22:36:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ezequiel Garcia X-Patchwork-Id: 2309891 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 0CDDDDF24C for ; Wed, 20 Mar 2013 22:37:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753441Ab3CTWhn (ORCPT ); Wed, 20 Mar 2013 18:37:43 -0400 Received: from mail.free-electrons.com ([94.23.35.102]:50657 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751782Ab3CTWhn (ORCPT ); Wed, 20 Mar 2013 18:37:43 -0400 Received: by mail.free-electrons.com (Postfix, from userid 106) id DA044143C; Wed, 20 Mar 2013 23:37:41 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.3.2 Received: from localhost.localdomain (20.222.3.200.ros.express.com.ar [200.3.222.20]) by mail.free-electrons.com (Postfix) with ESMTPA id 4E37C905; Wed, 20 Mar 2013 23:37:37 +0100 (CET) From: Ezequiel Garcia To: Cc: Zhang Rui , , Thomas Petazzoni , Gregory Clement , Nobuhiro Iwamatsu , Andrew Lunn , Jason Cooper , Florian Fainelli , Sebastian Hesselbarth , Lior Amsalem , Ezequiel Garcia Subject: [PATCH 13/16] thermal: mvebu: Add support for Marvell Dove SoC family Date: Wed, 20 Mar 2013 19:36:34 -0300 Message-Id: <1363818997-23137-14-git-send-email-ezequiel.garcia@free-electrons.com> X-Mailer: git-send-email 1.7.8.6 In-Reply-To: <1363818997-23137-1-git-send-email-ezequiel.garcia@free-electrons.com> References: <1363818997-23137-1-git-send-email-ezequiel.garcia@free-electrons.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org With the infrastructure added in mvebu-thermal to support multiple SoC families, it is now possible to add support for Dove SoC. This patch adds such support taking the implementation from the dove-thermal driver, and then removing it. Signed-off-by: Ezequiel Garcia --- .../devicetree/bindings/thermal/dove-thermal.txt | 18 -- .../devicetree/bindings/thermal/mvebu-thermal.txt | 8 + drivers/thermal/Kconfig | 8 - drivers/thermal/Makefile | 1 - drivers/thermal/dove_thermal.c | 209 -------------------- drivers/thermal/mvebu_thermal.c | 75 +++++++ 6 files changed, 83 insertions(+), 236 deletions(-) delete mode 100644 Documentation/devicetree/bindings/thermal/dove-thermal.txt delete mode 100644 drivers/thermal/dove_thermal.c diff --git a/Documentation/devicetree/bindings/thermal/dove-thermal.txt b/Documentation/devicetree/bindings/thermal/dove-thermal.txt deleted file mode 100644 index 6f47467..0000000 --- a/Documentation/devicetree/bindings/thermal/dove-thermal.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Dove Thermal - -This driver is for Dove SoCs which contain a thermal sensor. - -Required properties: -- compatible : "marvell,dove-thermal" -- reg : Address range of the thermal registers - -The reg properties should contain two ranges. The first is for the -three Thermal Manager registers, while the second range contains the -Thermal Diode Control Registers. - -Example: - - thermal@10078 { - compatible = "marvell,dove-thermal"; - reg = <0xd001c 0x0c>, <0xd005c 0x08>; - }; diff --git a/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt b/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt index 49d55a9..2c5297a 100644 --- a/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt @@ -6,6 +6,7 @@ Required properties: marvell,kirkwood-thermal marvell,armadaxp-thermal marvell,armada370-thermal + marvell,dove-thermal - reg: Device's register space. One or two entries are expected, see the examples below. @@ -21,3 +22,10 @@ Kirkwood example: compatible = "marvell,kirkwood-thermal"; reg = <0x10078 0x4>; }; + +Dove example: + + thermal: thermal@d001c { + compatible = "marvell,dove-thermal"; + reg = <0xd001c 0x0c>, <0xd005c 0x08>; + }; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 74f6b97..237c3e6 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -126,14 +126,6 @@ config EXYNOS_THERMAL_EMUL device directory to support emulation mode. With emulation mode sysfs node, you can manually input temperature to TMU for simulation purpose. -config DOVE_THERMAL - tristate "Temperature sensor on Marvell Dove SoCs" - depends on ARCH_DOVE - depends on OF - help - Support for the Dove thermal sensor driver in the Linux thermal - framework. - config DB8500_THERMAL bool "DB8500 thermal management" depends on ARCH_U8500 diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 40293a1..ddd77f4 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o obj-$(CONFIG_MVEBU_THERMAL) += mvebu_thermal.o obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o -obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c deleted file mode 100644 index 7b0bfa0..0000000 --- a/drivers/thermal/dove_thermal.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Dove thermal sensor driver - * - * Copyright (C) 2013 Andrew Lunn - * - * 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 DOVE_THERMAL_TEMP_OFFSET 1 -#define DOVE_THERMAL_TEMP_MASK 0x1FF - -/* Dove Thermal Manager Control and Status Register */ -#define PMU_TM_DISABLE_OFFS 0 -#define PMU_TM_DISABLE_MASK (0x1 << PMU_TM_DISABLE_OFFS) - -/* Dove Theraml Diode Control 0 Register */ -#define PMU_TDC0_SW_RST_MASK (0x1 << 1) -#define PMU_TDC0_SEL_VCAL_OFFS 5 -#define PMU_TDC0_SEL_VCAL_MASK (0x3 << PMU_TDC0_SEL_VCAL_OFFS) -#define PMU_TDC0_REF_CAL_CNT_OFFS 11 -#define PMU_TDC0_REF_CAL_CNT_MASK (0x1FF << PMU_TDC0_REF_CAL_CNT_OFFS) -#define PMU_TDC0_AVG_NUM_OFFS 25 -#define PMU_TDC0_AVG_NUM_MASK (0x7 << PMU_TDC0_AVG_NUM_OFFS) - -/* Dove Thermal Diode Control 1 Register */ -#define PMU_TEMP_DIOD_CTRL1_REG 0x04 -#define PMU_TDC1_TEMP_VALID_MASK (0x1 << 10) - -/* Dove Thermal Sensor Dev Structure */ -struct dove_thermal_priv { - void __iomem *sensor; - void __iomem *control; -}; - -static int dove_init_sensor(const struct dove_thermal_priv *priv) -{ - u32 reg; - u32 i; - - /* Configure the Diode Control Register #0 */ - reg = readl_relaxed(priv->control); - - /* Use average of 2 */ - reg &= ~PMU_TDC0_AVG_NUM_MASK; - reg |= (0x1 << PMU_TDC0_AVG_NUM_OFFS); - - /* Reference calibration value */ - reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; - reg |= (0x0F1 << PMU_TDC0_REF_CAL_CNT_OFFS); - - /* Set the high level reference for calibration */ - reg &= ~PMU_TDC0_SEL_VCAL_MASK; - reg |= (0x2 << PMU_TDC0_SEL_VCAL_OFFS); - writel(reg, priv->control); - - /* Reset the sensor */ - reg = readl_relaxed(priv->control); - writel((reg | PMU_TDC0_SW_RST_MASK), priv->control); - writel(reg, priv->control); - - /* Enable the sensor */ - reg = readl_relaxed(priv->sensor); - reg &= ~PMU_TM_DISABLE_MASK; - writel(reg, priv->sensor); - - /* Poll the sensor for the first reading */ - for (i = 0; i < 1000000; i++) { - reg = readl_relaxed(priv->sensor); - if (reg & DOVE_THERMAL_TEMP_MASK) - break; - } - - if (i == 1000000) - return -EIO; - - return 0; -} - -static int dove_get_temp(struct thermal_zone_device *thermal, - unsigned long *temp) -{ - unsigned long reg; - struct dove_thermal_priv *priv = thermal->devdata; - - /* Valid check */ - reg = readl_relaxed(priv->control + PMU_TEMP_DIOD_CTRL1_REG); - if ((reg & PMU_TDC1_TEMP_VALID_MASK) == 0x0) { - dev_err(&thermal->device, - "Temperature sensor reading not valid\n"); - return -EIO; - } - - /* - * Calculate temperature. See Section 8.10.1 of 88AP510, - * Documentation/arm/Marvell/README - */ - reg = readl_relaxed(priv->sensor); - reg = (reg >> DOVE_THERMAL_TEMP_OFFSET) & DOVE_THERMAL_TEMP_MASK; - *temp = ((2281638UL - (7298*reg)) / 10); - - return 0; -} - -static struct thermal_zone_device_ops ops = { - .get_temp = dove_get_temp, -}; - -static const struct of_device_id dove_thermal_id_table[] = { - { .compatible = "marvell,dove-thermal" }, - {} -}; - -static int dove_thermal_probe(struct platform_device *pdev) -{ - struct thermal_zone_device *thermal = NULL; - struct dove_thermal_priv *priv; - struct resource *res; - int ret; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Failed to get platform resource\n"); - return -ENODEV; - } - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->sensor = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->sensor) { - dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); - return -EADDRNOTAVAIL; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res) { - dev_err(&pdev->dev, "Failed to get platform resource\n"); - return -ENODEV; - } - priv->control = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->control) { - dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); - return -EADDRNOTAVAIL; - } - - ret = dove_init_sensor(priv); - if (ret) { - dev_err(&pdev->dev, "Failed to initialize sensor\n"); - return ret; - } - - thermal = thermal_zone_device_register("dove_thermal", 0, 0, - priv, &ops, NULL, 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); - - return 0; -} - -static int dove_thermal_exit(struct platform_device *pdev) -{ - struct thermal_zone_device *dove_thermal = - platform_get_drvdata(pdev); - - thermal_zone_device_unregister(dove_thermal); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -MODULE_DEVICE_TABLE(of, dove_thermal_id_table); - -static struct platform_driver dove_thermal_driver = { - .probe = dove_thermal_probe, - .remove = dove_thermal_exit, - .driver = { - .name = "dove_thermal", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(dove_thermal_id_table), - }, -}; - -module_platform_driver(dove_thermal_driver); - -MODULE_AUTHOR("Andrew Lunn "); -MODULE_DESCRIPTION("Dove thermal driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/thermal/mvebu_thermal.c b/drivers/thermal/mvebu_thermal.c index 0b1e7a8..fbb0612 100644 --- a/drivers/thermal/mvebu_thermal.c +++ b/drivers/thermal/mvebu_thermal.c @@ -2,6 +2,7 @@ * Marvell EBU thermal sensor driver * * Copyright (C) 2013 Marvell + * Copyright (C) 2013 Andrew Lunn * Copyright (C) 2012 Nobuhiro Iwamatsu * * This software is licensed under the terms of the GNU General Public @@ -28,6 +29,7 @@ #define MVEBU_THERMAL_SOC_VARIANT_KIRKWOOD 0x1 #define MVEBU_THERMAL_SOC_VARIANT_ARMADA_XP 0x2 #define MVEBU_THERMAL_SOC_VARIANT_ARMADA_370 0x3 +#define MVEBU_THERMAL_SOC_VARIANT_DOVE 0x4 #define MVEBU_THERMAL_VALID_OFFSET 9 #define MVEBU_THERMAL_VALID_MASK 0x1 @@ -42,6 +44,14 @@ #define PMU_TDC0_REF_CAL_CNT_MASK (0x1ff << PMU_TDC0_REF_CAL_CNT_OFFS) #define PMU_TDC0_OTF_CAL_MASK (0x1 << 30) #define PMU_TDC0_START_CAL_MASK (0x1 << 25) +#define PMU_TDC0_AVG_NUM_OFFS 25 +#define PMU_TDC0_AVG_NUM_MASK (0x7 << PMU_TDC0_AVG_NUM_OFFS) +#define PMU_TDC0_SEL_VCAL_OFFS 5 +#define PMU_TDC0_SEL_VCAL_MASK (0x3 << PMU_TDC0_SEL_VCAL_OFFS) + +/* Dove Thermal Diode Control 1 Register */ +#define PMU_TEMP_DIOD_CTRL1_REG 0x04 +#define PMU_TDC1_TEMP_VALID_MASK (0x1 << 10) /* Marvell EBU Thermal Sensor Dev Structure */ struct mvebu_thermal_priv { @@ -110,6 +120,53 @@ static void armada370_init_sensor(struct mvebu_thermal_priv *priv) mdelay(10); } +static void dove_init_sensor(struct mvebu_thermal_priv *priv) +{ + unsigned long reg; + int i; + + if (!priv->control) + return; + + /* Configure the Diode Control Register #0 */ + reg = readl_relaxed(priv->control); + + /* Use average of 2 */ + reg &= ~PMU_TDC0_AVG_NUM_MASK; + reg |= (0x1 << PMU_TDC0_AVG_NUM_OFFS); + + /* Reference calibration value */ + reg &= ~PMU_TDC0_REF_CAL_CNT_MASK; + reg |= (0x0F1 << PMU_TDC0_REF_CAL_CNT_OFFS); + + /* Set the high level reference for calibration */ + reg &= ~PMU_TDC0_SEL_VCAL_MASK; + reg |= (0x2 << PMU_TDC0_SEL_VCAL_OFFS); + writel(reg, priv->control); + + /* Reset the sensor */ + reg = readl_relaxed(priv->control); + writel((reg | PMU_TDC0_SW_RST_MASK), priv->control); + writel(reg, priv->control); + + /* Enable the sensor */ + reg = readl_relaxed(priv->sensor); + reg &= ~PMU_TM_DISABLE_MASK; + writel(reg, priv->sensor); + + /* + * FIXME: This looks really ugly. Can't we just remove it? + * Poll the sensor for the first reading + */ + for (i = 0; i < 1000000; i++) { + reg = (readl_relaxed(priv->sensor) >> MVEBU_THERMAL_TEMP_OFFSET) + & MVEBU_THERMAL_TEMP_MASK; + if (reg) + break; + } + return; +} + static bool mvebu_is_valid(struct mvebu_thermal_priv *priv) { unsigned long reg = readl_relaxed(priv->sensor); @@ -118,6 +175,13 @@ static bool mvebu_is_valid(struct mvebu_thermal_priv *priv) MVEBU_THERMAL_VALID_MASK; } +static bool dove_is_valid(struct mvebu_thermal_priv *priv) +{ + unsigned long reg = + readl_relaxed(priv->control + PMU_TEMP_DIOD_CTRL1_REG); + return reg & PMU_TDC1_TEMP_VALID_MASK; +} + static int mvebu_get_temp(struct thermal_zone_device *thermal, unsigned long *temp) { @@ -144,6 +208,9 @@ static int mvebu_get_temp(struct thermal_zone_device *thermal, case MVEBU_THERMAL_SOC_VARIANT_ARMADA_370: *temp = (228000UL - 723*reg); break; + case MVEBU_THERMAL_SOC_VARIANT_DOVE: + *temp = ((2281638UL - (7298*reg)) / 10); + break; default: *temp = 0; break; @@ -169,6 +236,10 @@ static const struct of_device_id mvebu_thermal_id_table[] = { .data = (void *) MVEBU_THERMAL_SOC_VARIANT_ARMADA_370, }, { + .compatible = "marvell,dove-thermal", + .data = (void *) MVEBU_THERMAL_SOC_VARIANT_DOVE, + }, + { /* sentinel */ }, }; @@ -218,6 +289,9 @@ static int mvebu_thermal_probe(struct platform_device *pdev) priv->is_valid = mvebu_is_valid; priv->init_sensor = armada370_init_sensor; break; + case MVEBU_THERMAL_SOC_VARIANT_DOVE: + priv->is_valid = dove_is_valid; + priv->init_sensor = dove_init_sensor; default: break; } @@ -261,6 +335,7 @@ static struct platform_driver mvebu_thermal_driver = { module_platform_driver(mvebu_thermal_driver); +MODULE_AUTHOR("Andrew Lunn "); MODULE_AUTHOR("Nobuhiro Iwamatsu "); MODULE_AUTHOR("Ezequiel Garcia "); MODULE_DESCRIPTION("mvebu thermal driver");