Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nobuhiro Iwamatsu and committed by
Zhang Rui
7060aa36 76cc1887

+158
+15
Documentation/devicetree/bindings/thermal/kirkwood-thermal.txt
··· 1 + * Kirkwood Thermal 2 + 3 + This version is for Kirkwood 88F8262 & 88F6283 SoCs. Other kirkwoods 4 + don't contain a thermal sensor. 5 + 6 + Required properties: 7 + - compatible : "marvell,kirkwood-thermal" 8 + - reg : Address range of the thermal registers 9 + 10 + Example: 11 + 12 + thermal@10078 { 13 + compatible = "marvell,kirkwood-thermal"; 14 + reg = <0x10078 0x4>; 15 + };
+8
drivers/thermal/Kconfig
··· 101 101 Enable this to plug the R-Car thermal sensor driver into the Linux 102 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 112 config EXYNOS_THERMAL 105 113 tristate "Temperature sensor on Samsung EXYNOS" 106 114 depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
+1
drivers/thermal/Makefile
··· 15 15 # platform thermal drivers 16 16 obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o 17 17 obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o 18 + obj-$(CONFIG_KIRKWOOD_THERMAL) += kirkwood_thermal.o 18 19 obj-$(CONFIG_EXYNOS_THERMAL) += exynos_thermal.o 19 20 obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o 20 21 obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
+134
drivers/thermal/kirkwood_thermal.c
··· 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");