[PATCH 13/16] thermal: mvebu: Add support for Marvell Dove SoC family
Ezequiel Garcia
ezequiel.garcia at free-electrons.com
Wed Mar 20 18:36:34 EDT 2013
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 <ezequiel.garcia at free-electrons.com>
---
.../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 at 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 at 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 <andrew at lunn.ch>
- *
- * 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 <linux/device.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/thermal.h>
-
-#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 <andrew at lunn.ch>");
-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 <andrew at lunn.ch>
* Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
*
* 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 <andrew at lunn.ch>");
MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu at nigauri.org>");
MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia at free-electrons.com>");
MODULE_DESCRIPTION("mvebu thermal driver");
--
1.7.8.6
More information about the linux-arm-kernel
mailing list