diff options
author | Nobuhiro Iwamatsu <iwamatsu@nigauri.org> | 2013-02-06 01:35:24 -0500 |
---|---|---|
committer | Zhang Rui <rui.zhang@intel.com> | 2013-02-08 07:25:56 -0500 |
commit | 7060aa36645c51d1205ef0e0cbf7b564f1f52f36 (patch) | |
tree | 068862ada1e03eaa9dbd564d3ca60325cb3d50c4 /drivers/thermal | |
parent | 76cc1887496fe80138c6b07c37d7f81e4cf27cde (diff) |
thermal: Add support for the thermal sensor on Kirkwood SoCs
This patch adds support for Kirkwood 88F6282 and 88F6283 thermal sensor.
Signed-off-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r-- | drivers/thermal/Kconfig | 8 | ||||
-rw-r--r-- | drivers/thermal/Makefile | 1 | ||||
-rw-r--r-- | drivers/thermal/kirkwood_thermal.c | 134 |
3 files changed, 143 insertions, 0 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index e4cf7fbc3a59..5070fbee24ef 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -101,6 +101,14 @@ config RCAR_THERMAL | |||
101 | Enable this to plug the R-Car thermal sensor driver into the Linux | 101 | Enable this to plug the R-Car thermal sensor driver into the Linux |
102 | thermal framework | 102 | thermal framework |
103 | 103 | ||
104 | config KIRKWOOD_THERMAL | ||
105 | tristate "Temperature sensor on Marvell Kirkwood SoCs" | ||
106 | depends on ARCH_KIRKWOOD | ||
107 | depends on OF | ||
108 | help | ||
109 | Support for the Kirkwood thermal sensor driver into the Linux thermal | ||
110 | framework. Only kirkwood 88F6282 and 88F6283 have this sensor. | ||
111 | |||
104 | config EXYNOS_THERMAL | 112 | config EXYNOS_THERMAL |
105 | tristate "Temperature sensor on Samsung EXYNOS" | 113 | tristate "Temperature sensor on Samsung EXYNOS" |
106 | depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) | 114 | depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) |
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 574f5f505b9f..b32c35de67e7 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_THERMAL) += cpu_cooling.o | |||
15 | # platform thermal drivers | 15 | # platform thermal drivers |
16 | obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o | 16 | obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o |
17 | obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o | 17 | obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o |
18 | obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o | ||
18 | obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o | 19 | obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o |
19 | obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o | 20 | obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o |
20 | obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o | 21 | obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o |
diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c new file mode 100644 index 000000000000..65cb4f09e8f6 --- /dev/null +++ b/drivers/thermal/kirkwood_thermal.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Kirkwood thermal sensor driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/thermal.h> | ||
24 | |||
25 | #define KIRKWOOD_THERMAL_VALID_OFFSET 9 | ||
26 | #define KIRKWOOD_THERMAL_VALID_MASK 0x1 | ||
27 | #define KIRKWOOD_THERMAL_TEMP_OFFSET 10 | ||
28 | #define KIRKWOOD_THERMAL_TEMP_MASK 0x1FF | ||
29 | |||
30 | /* Kirkwood Thermal Sensor Dev Structure */ | ||
31 | struct kirkwood_thermal_priv { | ||
32 | void __iomem *sensor; | ||
33 | }; | ||
34 | |||
35 | static int kirkwood_get_temp(struct thermal_zone_device *thermal, | ||
36 | unsigned long *temp) | ||
37 | { | ||
38 | unsigned long reg; | ||
39 | struct kirkwood_thermal_priv *priv = thermal->devdata; | ||
40 | |||
41 | reg = readl_relaxed(priv->sensor); | ||
42 | |||
43 | /* Valid check */ | ||
44 | if (!(reg >> KIRKWOOD_THERMAL_VALID_OFFSET) & | ||
45 | KIRKWOOD_THERMAL_VALID_MASK) { | ||
46 | dev_err(&thermal->device, | ||
47 | "Temperature sensor reading not valid\n"); | ||
48 | return -EIO; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Calculate temperature. See Section 8.10.1 of the 88AP510, | ||
53 | * datasheet, which has the same sensor. | ||
54 | * Documentation/arm/Marvell/README | ||
55 | */ | ||
56 | reg = (reg >> KIRKWOOD_THERMAL_TEMP_OFFSET) & | ||
57 | KIRKWOOD_THERMAL_TEMP_MASK; | ||
58 | *temp = ((2281638UL - (7298*reg)) / 10); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static struct thermal_zone_device_ops ops = { | ||
64 | .get_temp = kirkwood_get_temp, | ||
65 | }; | ||
66 | |||
67 | static const struct of_device_id kirkwood_thermal_id_table[] = { | ||
68 | { .compatible = "marvell,kirkwood-thermal" }, | ||
69 | {} | ||
70 | }; | ||
71 | |||
72 | static int kirkwood_thermal_probe(struct platform_device *pdev) | ||
73 | { | ||
74 | struct thermal_zone_device *thermal = NULL; | ||
75 | struct kirkwood_thermal_priv *priv; | ||
76 | struct resource *res; | ||
77 | |||
78 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
79 | if (!res) { | ||
80 | dev_err(&pdev->dev, "Failed to get platform resource\n"); | ||
81 | return -ENODEV; | ||
82 | } | ||
83 | |||
84 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||
85 | if (!priv) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | priv->sensor = devm_request_and_ioremap(&pdev->dev, res); | ||
89 | if (!priv->sensor) { | ||
90 | dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); | ||
91 | return -EADDRNOTAVAIL; | ||
92 | } | ||
93 | |||
94 | thermal = thermal_zone_device_register("kirkwood_thermal", 0, 0, | ||
95 | priv, &ops, NULL, 0, 0); | ||
96 | if (IS_ERR(thermal)) { | ||
97 | dev_err(&pdev->dev, | ||
98 | "Failed to register thermal zone device\n"); | ||
99 | return PTR_ERR(thermal); | ||
100 | } | ||
101 | |||
102 | platform_set_drvdata(pdev, thermal); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int kirkwood_thermal_exit(struct platform_device *pdev) | ||
108 | { | ||
109 | struct thermal_zone_device *kirkwood_thermal = | ||
110 | platform_get_drvdata(pdev); | ||
111 | |||
112 | thermal_zone_device_unregister(kirkwood_thermal); | ||
113 | platform_set_drvdata(pdev, NULL); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | MODULE_DEVICE_TABLE(of, kirkwood_thermal_id_table); | ||
119 | |||
120 | static struct platform_driver kirkwood_thermal_driver = { | ||
121 | .probe = kirkwood_thermal_probe, | ||
122 | .remove = kirkwood_thermal_exit, | ||
123 | .driver = { | ||
124 | .name = "kirkwood_thermal", | ||
125 | .owner = THIS_MODULE, | ||
126 | .of_match_table = of_match_ptr(kirkwood_thermal_id_table), | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | module_platform_driver(kirkwood_thermal_driver); | ||
131 | |||
132 | MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu@nigauri.org>"); | ||
133 | MODULE_DESCRIPTION("kirkwood thermal driver"); | ||
134 | MODULE_LICENSE("GPL"); | ||