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

Merge branches 'thermal-core', 'thermal-intel' and 'thermal-soc' into next

Zhang Rui b82ddd48 d0b45880

+1041 -122
+15 -3
Documentation/devicetree/bindings/thermal/exynos-thermal.txt
··· 11 11 "samsung,exynos5420-tmu" for TMU channel 0, 1 on Exynos5420 12 12 "samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4 13 13 Exynos5420 (Must pass triminfo base and triminfo clock) 14 + "samsung,exynos5433-tmu" 14 15 "samsung,exynos5440-tmu" 15 16 "samsung,exynos7-tmu" 16 17 - interrupt-parent : The phandle for the interrupt controller ··· 41 40 for current TMU channel 42 41 -- "tmu_sclk" clock for functional operation of the current TMU 43 42 channel 44 - - vtmu-supply: This entry is optional and provides the regulator node supplying 45 - voltage to TMU. If needed this entry can be placed inside 46 - board/platform specific dts file. 43 + 44 + The Exynos TMU supports generating interrupts when reaching given 45 + temperature thresholds. Number of supported thermal trip points depends 46 + on the SoC (only first trip points defined in DT will be configured): 47 + - most of SoC: 4 48 + - samsung,exynos5433-tmu: 8 49 + - samsung,exynos7-tmu: 8 50 + 47 51 Following properties are mandatory (depending on SoC): 48 52 - samsung,tmu_gain: Gain value for internal TMU operation. 49 53 - samsung,tmu_reference_voltage: Value of TMU IP block's reference voltage ··· 61 55 - samsung,tmu_second_point_trim: Second point trimming value 62 56 - samsung,tmu_default_temp_offset: Default temperature offset 63 57 - samsung,tmu_cal_type: Callibration type 58 + 59 + ** Optional properties: 60 + 61 + - vtmu-supply: This entry is optional and provides the regulator node supplying 62 + voltage to TMU. If needed this entry can be placed inside 63 + board/platform specific dts file. 64 64 65 65 Example 1): 66 66
+43
Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
··· 1 + * Mediatek Thermal 2 + 3 + This describes the device tree binding for the Mediatek thermal controller 4 + which measures the on-SoC temperatures. This device does not have its own ADC, 5 + instead it directly controls the AUXADC via AHB bus accesses. For this reason 6 + this device needs phandles to the AUXADC. Also it controls a mux in the 7 + apmixedsys register space via AHB bus accesses, so a phandle to the APMIXEDSYS 8 + is also needed. 9 + 10 + Required properties: 11 + - compatible: "mediatek,mt8173-thermal" 12 + - reg: Address range of the thermal controller 13 + - interrupts: IRQ for the thermal controller 14 + - clocks, clock-names: Clocks needed for the thermal controller. required 15 + clocks are: 16 + "therm": Main clock needed for register access 17 + "auxadc": The AUXADC clock 18 + - resets: Reference to the reset controller controlling the thermal controller. 19 + - mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses 20 + - mediatek,apmixedsys: A phandle to the APMIXEDSYS controller. 21 + - #thermal-sensor-cells : Should be 0. See ./thermal.txt for a description. 22 + 23 + Optional properties: 24 + - nvmem-cells: A phandle to the calibration data provided by a nvmem device. If 25 + unspecified default values shall be used. 26 + - nvmem-cell-names: Should be "calibration-data" 27 + 28 + Example: 29 + 30 + thermal: thermal@1100b000 { 31 + #thermal-sensor-cells = <1>; 32 + compatible = "mediatek,mt8173-thermal"; 33 + reg = <0 0x1100b000 0 0x1000>; 34 + interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; 35 + clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; 36 + clock-names = "therm", "auxadc"; 37 + resets = <&pericfg MT8173_PERI_THERM_SW_RST>; 38 + reset-names = "therm"; 39 + mediatek,auxadc = <&auxadc>; 40 + mediatek,apmixedsys = <&apmixedsys>; 41 + nvmem-cells = <&thermal_calibration_data>; 42 + nvmem-cell-names = "calibration-data"; 43 + };
+68
Documentation/thermal/sysfs-api.txt
··· 72 72 It deletes the corresponding entry form /sys/class/thermal folder and 73 73 unbind all the thermal cooling devices it uses. 74 74 75 + 1.1.3 struct thermal_zone_device *thermal_zone_of_sensor_register( 76 + struct device *dev, int sensor_id, void *data, 77 + const struct thermal_zone_of_device_ops *ops) 78 + 79 + This interface adds a new sensor to a DT thermal zone. 80 + This function will search the list of thermal zones described in 81 + device tree and look for the zone that refer to the sensor device 82 + pointed by dev->of_node as temperature providers. For the zone 83 + pointing to the sensor node, the sensor will be added to the DT 84 + thermal zone device. 85 + 86 + The parameters for this interface are: 87 + dev: Device node of sensor containing valid node pointer in 88 + dev->of_node. 89 + sensor_id: a sensor identifier, in case the sensor IP has more 90 + than one sensors 91 + data: a private pointer (owned by the caller) that will be 92 + passed back, when a temperature reading is needed. 93 + ops: struct thermal_zone_of_device_ops *. 94 + 95 + get_temp: a pointer to a function that reads the 96 + sensor temperature. This is mandatory 97 + callback provided by sensor driver. 98 + get_trend: a pointer to a function that reads the 99 + sensor temperature trend. 100 + set_emul_temp: a pointer to a function that sets 101 + sensor emulated temperature. 102 + The thermal zone temperature is provided by the get_temp() function 103 + pointer of thermal_zone_of_device_ops. When called, it will 104 + have the private pointer @data back. 105 + 106 + It returns error pointer if fails otherwise valid thermal zone device 107 + handle. Caller should check the return handle with IS_ERR() for finding 108 + whether success or not. 109 + 110 + 1.1.4 void thermal_zone_of_sensor_unregister(struct device *dev, 111 + struct thermal_zone_device *tzd) 112 + 113 + This interface unregisters a sensor from a DT thermal zone which was 114 + successfully added by interface thermal_zone_of_sensor_register(). 115 + This function removes the sensor callbacks and private data from the 116 + thermal zone device registered with thermal_zone_of_sensor_register() 117 + interface. It will also silent the zone by remove the .get_temp() and 118 + get_trend() thermal zone device callbacks. 119 + 120 + 1.1.5 struct thermal_zone_device *devm_thermal_zone_of_sensor_register( 121 + struct device *dev, int sensor_id, 122 + void *data, const struct thermal_zone_of_device_ops *ops) 123 + 124 + This interface is resource managed version of 125 + thermal_zone_of_sensor_register(). 126 + All details of thermal_zone_of_sensor_register() described in 127 + section 1.1.3 is applicable here. 128 + The benefit of using this interface to register sensor is that it 129 + is not require to explicitly call thermal_zone_of_sensor_unregister() 130 + in error path or during driver unbinding as this is done by driver 131 + resource manager. 132 + 133 + 1.1.6 void devm_thermal_zone_of_sensor_unregister(struct device *dev, 134 + struct thermal_zone_device *tzd) 135 + 136 + This interface is resource managed version of 137 + thermal_zone_of_sensor_unregister(). 138 + All details of thermal_zone_of_sensor_unregister() described in 139 + section 1.1.4 is applicable here. 140 + Normally this function will not need to be called and the resource 141 + management code will ensure that the resource is freed. 142 + 75 143 1.2 thermal cooling device interface 76 144 1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name, 77 145 void *devdata, struct thermal_cooling_device_ops *)
+19 -2
drivers/thermal/Kconfig
··· 178 178 config HISI_THERMAL 179 179 tristate "Hisilicon thermal driver" 180 180 depends on (ARCH_HISI && CPU_THERMAL && OF) || COMPILE_TEST 181 + depends on HAS_IOMEM 181 182 help 182 183 Enable this to plug hisilicon's thermal sensor driver into the Linux 183 184 thermal framework. cpufreq is used as the cooling device to throttle ··· 198 197 config SPEAR_THERMAL 199 198 tristate "SPEAr thermal sensor driver" 200 199 depends on PLAT_SPEAR || COMPILE_TEST 200 + depends on HAS_IOMEM 201 201 depends on OF 202 202 help 203 203 Enable this to plug the SPEAr thermal sensor driver into the Linux ··· 208 206 tristate "Rockchip thermal driver" 209 207 depends on ARCH_ROCKCHIP || COMPILE_TEST 210 208 depends on RESET_CONTROLLER 209 + depends on HAS_IOMEM 211 210 help 212 211 Rockchip thermal driver provides support for Temperature sensor 213 212 ADC (TS-ADC) found on Rockchip SoCs. It supports one critical ··· 217 214 218 215 config RCAR_THERMAL 219 216 tristate "Renesas R-Car thermal driver" 220 - depends on ARCH_SHMOBILE || COMPILE_TEST 217 + depends on ARCH_RENESAS || COMPILE_TEST 221 218 depends on HAS_IOMEM 222 219 help 223 220 Enable this to plug the R-Car thermal sensor driver into the Linux ··· 226 223 config KIRKWOOD_THERMAL 227 224 tristate "Temperature sensor on Marvell Kirkwood SoCs" 228 225 depends on MACH_KIRKWOOD || COMPILE_TEST 226 + depends on HAS_IOMEM 229 227 depends on OF 230 228 help 231 229 Support for the Kirkwood thermal sensor driver into the Linux thermal ··· 235 231 config DOVE_THERMAL 236 232 tristate "Temperature sensor on Marvell Dove SoCs" 237 233 depends on ARCH_DOVE || MACH_DOVE || COMPILE_TEST 234 + depends on HAS_IOMEM 238 235 depends on OF 239 236 help 240 237 Support for the Dove thermal sensor driver in the Linux thermal ··· 254 249 config ARMADA_THERMAL 255 250 tristate "Armada 370/XP thermal management" 256 251 depends on ARCH_MVEBU || COMPILE_TEST 252 + depends on HAS_IOMEM 257 253 depends on OF 258 254 help 259 255 Enable this option if you want to have support for thermal management ··· 272 266 273 267 config DB8500_CPUFREQ_COOLING 274 268 tristate "DB8500 cpufreq cooling" 275 - depends on ARCH_U8500 269 + depends on ARCH_U8500 || COMPILE_TEST 270 + depends on HAS_IOMEM 276 271 depends on CPU_THERMAL 277 272 default y 278 273 help ··· 372 365 Thermal reporting device will provide temperature reading, 373 366 programmable trip points and other information. 374 367 368 + config MTK_THERMAL 369 + tristate "Temperature sensor driver for mediatek SoCs" 370 + depends on ARCH_MEDIATEK || COMPILE_TEST 371 + depends on HAS_IOMEM 372 + default y 373 + help 374 + Enable this option if you want to have support for thermal management 375 + controller present in Mediatek SoCs 376 + 375 377 menu "Texas Instruments thermal drivers" 376 378 depends on ARCH_HAS_BANDGAP || COMPILE_TEST 379 + depends on HAS_IOMEM 377 380 source "drivers/thermal/ti-soc-thermal/Kconfig" 378 381 endmenu 379 382
+1
drivers/thermal/Makefile
··· 48 48 obj-$(CONFIG_ST_THERMAL) += st/ 49 49 obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o 50 50 obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o 51 + obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
+6
drivers/thermal/intel_pch_thermal.c
··· 24 24 25 25 /* Intel PCH thermal Device IDs */ 26 26 #define PCH_THERMAL_DID_WPT 0x9CA4 /* Wildcat Point */ 27 + #define PCH_THERMAL_DID_SKL 0x9D31 /* Skylake PCH */ 27 28 28 29 /* Wildcat Point-LP PCH Thermal registers */ 29 30 #define WPT_TEMP 0x0000 /* Temperature */ ··· 202 201 ptd->ops = &pch_dev_ops_wpt; 203 202 dev_name = "pch_wildcat_point"; 204 203 break; 204 + case PCH_THERMAL_DID_SKL: 205 + ptd->ops = &pch_dev_ops_wpt; 206 + dev_name = "pch_skylake"; 207 + break; 205 208 default: 206 209 dev_err(&pdev->dev, "unknown pch thermal device\n"); 207 210 return -ENODEV; ··· 271 266 272 267 static struct pci_device_id intel_pch_thermal_id[] = { 273 268 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_WPT) }, 269 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL) }, 274 270 { 0, }, 275 271 }; 276 272 MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id);
+625
drivers/thermal/mtk_thermal.c
··· 1 + /* 2 + * Copyright (c) 2015 MediaTek Inc. 3 + * Author: Hanyi Wu <hanyi.wu@mediatek.com> 4 + * Sascha Hauer <s.hauer@pengutronix.de> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 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/clk.h> 17 + #include <linux/delay.h> 18 + #include <linux/interrupt.h> 19 + #include <linux/kernel.h> 20 + #include <linux/module.h> 21 + #include <linux/nvmem-consumer.h> 22 + #include <linux/of.h> 23 + #include <linux/of_address.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/slab.h> 26 + #include <linux/io.h> 27 + #include <linux/thermal.h> 28 + #include <linux/reset.h> 29 + #include <linux/types.h> 30 + #include <linux/nvmem-consumer.h> 31 + 32 + /* AUXADC Registers */ 33 + #define AUXADC_CON0_V 0x000 34 + #define AUXADC_CON1_V 0x004 35 + #define AUXADC_CON1_SET_V 0x008 36 + #define AUXADC_CON1_CLR_V 0x00c 37 + #define AUXADC_CON2_V 0x010 38 + #define AUXADC_DATA(channel) (0x14 + (channel) * 4) 39 + #define AUXADC_MISC_V 0x094 40 + 41 + #define AUXADC_CON1_CHANNEL(x) BIT(x) 42 + 43 + #define APMIXED_SYS_TS_CON1 0x604 44 + 45 + /* Thermal Controller Registers */ 46 + #define TEMP_MONCTL0 0x000 47 + #define TEMP_MONCTL1 0x004 48 + #define TEMP_MONCTL2 0x008 49 + #define TEMP_MONIDET0 0x014 50 + #define TEMP_MONIDET1 0x018 51 + #define TEMP_MSRCTL0 0x038 52 + #define TEMP_AHBPOLL 0x040 53 + #define TEMP_AHBTO 0x044 54 + #define TEMP_ADCPNP0 0x048 55 + #define TEMP_ADCPNP1 0x04c 56 + #define TEMP_ADCPNP2 0x050 57 + #define TEMP_ADCPNP3 0x0b4 58 + 59 + #define TEMP_ADCMUX 0x054 60 + #define TEMP_ADCEN 0x060 61 + #define TEMP_PNPMUXADDR 0x064 62 + #define TEMP_ADCMUXADDR 0x068 63 + #define TEMP_ADCENADDR 0x074 64 + #define TEMP_ADCVALIDADDR 0x078 65 + #define TEMP_ADCVOLTADDR 0x07c 66 + #define TEMP_RDCTRL 0x080 67 + #define TEMP_ADCVALIDMASK 0x084 68 + #define TEMP_ADCVOLTAGESHIFT 0x088 69 + #define TEMP_ADCWRITECTRL 0x08c 70 + #define TEMP_MSR0 0x090 71 + #define TEMP_MSR1 0x094 72 + #define TEMP_MSR2 0x098 73 + #define TEMP_MSR3 0x0B8 74 + 75 + #define TEMP_SPARE0 0x0f0 76 + 77 + #define PTPCORESEL 0x400 78 + 79 + #define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff) 80 + 81 + #define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff) << 16) 82 + #define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff) 83 + 84 + #define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x) (x) 85 + 86 + #define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0) 87 + #define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1) 88 + 89 + #define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5) 90 + #define TEMP_ADCVALIDMASK_VALID_POS(bit) (bit) 91 + 92 + #define MT8173_TS1 0 93 + #define MT8173_TS2 1 94 + #define MT8173_TS3 2 95 + #define MT8173_TS4 3 96 + #define MT8173_TSABB 4 97 + 98 + /* AUXADC channel 11 is used for the temperature sensors */ 99 + #define MT8173_TEMP_AUXADC_CHANNEL 11 100 + 101 + /* The total number of temperature sensors in the MT8173 */ 102 + #define MT8173_NUM_SENSORS 5 103 + 104 + /* The number of banks in the MT8173 */ 105 + #define MT8173_NUM_ZONES 4 106 + 107 + /* The number of sensing points per bank */ 108 + #define MT8173_NUM_SENSORS_PER_ZONE 4 109 + 110 + /* Layout of the fuses providing the calibration data */ 111 + #define MT8173_CALIB_BUF0_VALID BIT(0) 112 + #define MT8173_CALIB_BUF1_ADC_GE(x) (((x) >> 22) & 0x3ff) 113 + #define MT8173_CALIB_BUF0_VTS_TS1(x) (((x) >> 17) & 0x1ff) 114 + #define MT8173_CALIB_BUF0_VTS_TS2(x) (((x) >> 8) & 0x1ff) 115 + #define MT8173_CALIB_BUF1_VTS_TS3(x) (((x) >> 0) & 0x1ff) 116 + #define MT8173_CALIB_BUF2_VTS_TS4(x) (((x) >> 23) & 0x1ff) 117 + #define MT8173_CALIB_BUF2_VTS_TSABB(x) (((x) >> 14) & 0x1ff) 118 + #define MT8173_CALIB_BUF0_DEGC_CALI(x) (((x) >> 1) & 0x3f) 119 + #define MT8173_CALIB_BUF0_O_SLOPE(x) (((x) >> 26) & 0x3f) 120 + 121 + #define THERMAL_NAME "mtk-thermal" 122 + 123 + struct mtk_thermal; 124 + 125 + struct mtk_thermal_bank { 126 + struct mtk_thermal *mt; 127 + int id; 128 + }; 129 + 130 + struct mtk_thermal { 131 + struct device *dev; 132 + void __iomem *thermal_base; 133 + 134 + struct clk *clk_peri_therm; 135 + struct clk *clk_auxadc; 136 + 137 + struct mtk_thermal_bank banks[MT8173_NUM_ZONES]; 138 + 139 + /* lock: for getting and putting banks */ 140 + struct mutex lock; 141 + 142 + /* Calibration values */ 143 + s32 adc_ge; 144 + s32 degc_cali; 145 + s32 o_slope; 146 + s32 vts[MT8173_NUM_SENSORS]; 147 + 148 + struct thermal_zone_device *tzd; 149 + }; 150 + 151 + struct mtk_thermal_bank_cfg { 152 + unsigned int num_sensors; 153 + unsigned int sensors[MT8173_NUM_SENSORS_PER_ZONE]; 154 + }; 155 + 156 + static const int sensor_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 }; 157 + 158 + /* 159 + * The MT8173 thermal controller has four banks. Each bank can read up to 160 + * four temperature sensors simultaneously. The MT8173 has a total of 5 161 + * temperature sensors. We use each bank to measure a certain area of the 162 + * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple 163 + * areas, hence is used in different banks. 164 + * 165 + * The thermal core only gets the maximum temperature of all banks, so 166 + * the bank concept wouldn't be necessary here. However, the SVS (Smart 167 + * Voltage Scaling) unit makes its decisions based on the same bank 168 + * data, and this indeed needs the temperatures of the individual banks 169 + * for making better decisions. 170 + */ 171 + static const struct mtk_thermal_bank_cfg bank_data[] = { 172 + { 173 + .num_sensors = 2, 174 + .sensors = { MT8173_TS2, MT8173_TS3 }, 175 + }, { 176 + .num_sensors = 2, 177 + .sensors = { MT8173_TS2, MT8173_TS4 }, 178 + }, { 179 + .num_sensors = 3, 180 + .sensors = { MT8173_TS1, MT8173_TS2, MT8173_TSABB }, 181 + }, { 182 + .num_sensors = 1, 183 + .sensors = { MT8173_TS2 }, 184 + }, 185 + }; 186 + 187 + struct mtk_thermal_sense_point { 188 + int msr; 189 + int adcpnp; 190 + }; 191 + 192 + static const struct mtk_thermal_sense_point 193 + sensing_points[MT8173_NUM_SENSORS_PER_ZONE] = { 194 + { 195 + .msr = TEMP_MSR0, 196 + .adcpnp = TEMP_ADCPNP0, 197 + }, { 198 + .msr = TEMP_MSR1, 199 + .adcpnp = TEMP_ADCPNP1, 200 + }, { 201 + .msr = TEMP_MSR2, 202 + .adcpnp = TEMP_ADCPNP2, 203 + }, { 204 + .msr = TEMP_MSR3, 205 + .adcpnp = TEMP_ADCPNP3, 206 + }, 207 + }; 208 + 209 + /** 210 + * raw_to_mcelsius - convert a raw ADC value to mcelsius 211 + * @mt: The thermal controller 212 + * @raw: raw ADC value 213 + * 214 + * This converts the raw ADC value to mcelsius using the SoC specific 215 + * calibration constants 216 + */ 217 + static int raw_to_mcelsius(struct mtk_thermal *mt, int sensno, s32 raw) 218 + { 219 + s32 tmp; 220 + 221 + raw &= 0xfff; 222 + 223 + tmp = 203450520 << 3; 224 + tmp /= 165 + mt->o_slope; 225 + tmp /= 10000 + mt->adc_ge; 226 + tmp *= raw - mt->vts[sensno] - 3350; 227 + tmp >>= 3; 228 + 229 + return mt->degc_cali * 500 - tmp; 230 + } 231 + 232 + /** 233 + * mtk_thermal_get_bank - get bank 234 + * @bank: The bank 235 + * 236 + * The bank registers are banked, we have to select a bank in the 237 + * PTPCORESEL register to access it. 238 + */ 239 + static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank) 240 + { 241 + struct mtk_thermal *mt = bank->mt; 242 + u32 val; 243 + 244 + mutex_lock(&mt->lock); 245 + 246 + val = readl(mt->thermal_base + PTPCORESEL); 247 + val &= ~0xf; 248 + val |= bank->id; 249 + writel(val, mt->thermal_base + PTPCORESEL); 250 + } 251 + 252 + /** 253 + * mtk_thermal_put_bank - release bank 254 + * @bank: The bank 255 + * 256 + * release a bank previously taken with mtk_thermal_get_bank, 257 + */ 258 + static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) 259 + { 260 + struct mtk_thermal *mt = bank->mt; 261 + 262 + mutex_unlock(&mt->lock); 263 + } 264 + 265 + /** 266 + * mtk_thermal_bank_temperature - get the temperature of a bank 267 + * @bank: The bank 268 + * 269 + * The temperature of a bank is considered the maximum temperature of 270 + * the sensors associated to the bank. 271 + */ 272 + static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) 273 + { 274 + struct mtk_thermal *mt = bank->mt; 275 + int i, temp = INT_MIN, max = INT_MIN; 276 + u32 raw; 277 + 278 + for (i = 0; i < bank_data[bank->id].num_sensors; i++) { 279 + raw = readl(mt->thermal_base + sensing_points[i].msr); 280 + 281 + temp = raw_to_mcelsius(mt, bank_data[bank->id].sensors[i], raw); 282 + 283 + /* 284 + * The first read of a sensor often contains very high bogus 285 + * temperature value. Filter these out so that the system does 286 + * not immediately shut down. 287 + */ 288 + if (temp > 200000) 289 + temp = 0; 290 + 291 + if (temp > max) 292 + max = temp; 293 + } 294 + 295 + return max; 296 + } 297 + 298 + static int mtk_read_temp(void *data, int *temperature) 299 + { 300 + struct mtk_thermal *mt = data; 301 + int i; 302 + int tempmax = INT_MIN; 303 + 304 + for (i = 0; i < MT8173_NUM_ZONES; i++) { 305 + struct mtk_thermal_bank *bank = &mt->banks[i]; 306 + 307 + mtk_thermal_get_bank(bank); 308 + 309 + tempmax = max(tempmax, mtk_thermal_bank_temperature(bank)); 310 + 311 + mtk_thermal_put_bank(bank); 312 + } 313 + 314 + *temperature = tempmax; 315 + 316 + return 0; 317 + } 318 + 319 + static const struct thermal_zone_of_device_ops mtk_thermal_ops = { 320 + .get_temp = mtk_read_temp, 321 + }; 322 + 323 + static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num, 324 + u32 apmixed_phys_base, u32 auxadc_phys_base) 325 + { 326 + struct mtk_thermal_bank *bank = &mt->banks[num]; 327 + const struct mtk_thermal_bank_cfg *cfg = &bank_data[num]; 328 + int i; 329 + 330 + bank->id = num; 331 + bank->mt = mt; 332 + 333 + mtk_thermal_get_bank(bank); 334 + 335 + /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */ 336 + writel(TEMP_MONCTL1_PERIOD_UNIT(12), mt->thermal_base + TEMP_MONCTL1); 337 + 338 + /* 339 + * filt interval is 1 * 46.540us = 46.54us, 340 + * sen interval is 429 * 46.540us = 19.96ms 341 + */ 342 + writel(TEMP_MONCTL2_FILTER_INTERVAL(1) | 343 + TEMP_MONCTL2_SENSOR_INTERVAL(429), 344 + mt->thermal_base + TEMP_MONCTL2); 345 + 346 + /* poll is set to 10u */ 347 + writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768), 348 + mt->thermal_base + TEMP_AHBPOLL); 349 + 350 + /* temperature sampling control, 1 sample */ 351 + writel(0x0, mt->thermal_base + TEMP_MSRCTL0); 352 + 353 + /* exceed this polling time, IRQ would be inserted */ 354 + writel(0xffffffff, mt->thermal_base + TEMP_AHBTO); 355 + 356 + /* number of interrupts per event, 1 is enough */ 357 + writel(0x0, mt->thermal_base + TEMP_MONIDET0); 358 + writel(0x0, mt->thermal_base + TEMP_MONIDET1); 359 + 360 + /* 361 + * The MT8173 thermal controller does not have its own ADC. Instead it 362 + * uses AHB bus accesses to control the AUXADC. To do this the thermal 363 + * controller has to be programmed with the physical addresses of the 364 + * AUXADC registers and with the various bit positions in the AUXADC. 365 + * Also the thermal controller controls a mux in the APMIXEDSYS register 366 + * space. 367 + */ 368 + 369 + /* 370 + * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0) 371 + * automatically by hw 372 + */ 373 + writel(BIT(MT8173_TEMP_AUXADC_CHANNEL), mt->thermal_base + TEMP_ADCMUX); 374 + 375 + /* AHB address for auxadc mux selection */ 376 + writel(auxadc_phys_base + AUXADC_CON1_CLR_V, 377 + mt->thermal_base + TEMP_ADCMUXADDR); 378 + 379 + /* AHB address for pnp sensor mux selection */ 380 + writel(apmixed_phys_base + APMIXED_SYS_TS_CON1, 381 + mt->thermal_base + TEMP_PNPMUXADDR); 382 + 383 + /* AHB value for auxadc enable */ 384 + writel(BIT(MT8173_TEMP_AUXADC_CHANNEL), mt->thermal_base + TEMP_ADCEN); 385 + 386 + /* AHB address for auxadc enable (channel 0 immediate mode selected) */ 387 + writel(auxadc_phys_base + AUXADC_CON1_SET_V, 388 + mt->thermal_base + TEMP_ADCENADDR); 389 + 390 + /* AHB address for auxadc valid bit */ 391 + writel(auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL), 392 + mt->thermal_base + TEMP_ADCVALIDADDR); 393 + 394 + /* AHB address for auxadc voltage output */ 395 + writel(auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL), 396 + mt->thermal_base + TEMP_ADCVOLTADDR); 397 + 398 + /* read valid & voltage are at the same register */ 399 + writel(0x0, mt->thermal_base + TEMP_RDCTRL); 400 + 401 + /* indicate where the valid bit is */ 402 + writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12), 403 + mt->thermal_base + TEMP_ADCVALIDMASK); 404 + 405 + /* no shift */ 406 + writel(0x0, mt->thermal_base + TEMP_ADCVOLTAGESHIFT); 407 + 408 + /* enable auxadc mux write transaction */ 409 + writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE, 410 + mt->thermal_base + TEMP_ADCWRITECTRL); 411 + 412 + for (i = 0; i < cfg->num_sensors; i++) 413 + writel(sensor_mux_values[cfg->sensors[i]], 414 + mt->thermal_base + sensing_points[i].adcpnp); 415 + 416 + writel((1 << cfg->num_sensors) - 1, mt->thermal_base + TEMP_MONCTL0); 417 + 418 + writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE | 419 + TEMP_ADCWRITECTRL_ADC_MUX_WRITE, 420 + mt->thermal_base + TEMP_ADCWRITECTRL); 421 + 422 + mtk_thermal_put_bank(bank); 423 + } 424 + 425 + static u64 of_get_phys_base(struct device_node *np) 426 + { 427 + u64 size64; 428 + const __be32 *regaddr_p; 429 + 430 + regaddr_p = of_get_address(np, 0, &size64, NULL); 431 + if (!regaddr_p) 432 + return OF_BAD_ADDR; 433 + 434 + return of_translate_address(np, regaddr_p); 435 + } 436 + 437 + static int mtk_thermal_get_calibration_data(struct device *dev, 438 + struct mtk_thermal *mt) 439 + { 440 + struct nvmem_cell *cell; 441 + u32 *buf; 442 + size_t len; 443 + int i, ret = 0; 444 + 445 + /* Start with default values */ 446 + mt->adc_ge = 512; 447 + for (i = 0; i < MT8173_NUM_SENSORS; i++) 448 + mt->vts[i] = 260; 449 + mt->degc_cali = 40; 450 + mt->o_slope = 0; 451 + 452 + cell = nvmem_cell_get(dev, "calibration-data"); 453 + if (IS_ERR(cell)) { 454 + if (PTR_ERR(cell) == -EPROBE_DEFER) 455 + return PTR_ERR(cell); 456 + return 0; 457 + } 458 + 459 + buf = (u32 *)nvmem_cell_read(cell, &len); 460 + 461 + nvmem_cell_put(cell); 462 + 463 + if (IS_ERR(buf)) 464 + return PTR_ERR(buf); 465 + 466 + if (len < 3 * sizeof(u32)) { 467 + dev_warn(dev, "invalid calibration data\n"); 468 + ret = -EINVAL; 469 + goto out; 470 + } 471 + 472 + if (buf[0] & MT8173_CALIB_BUF0_VALID) { 473 + mt->adc_ge = MT8173_CALIB_BUF1_ADC_GE(buf[1]); 474 + mt->vts[MT8173_TS1] = MT8173_CALIB_BUF0_VTS_TS1(buf[0]); 475 + mt->vts[MT8173_TS2] = MT8173_CALIB_BUF0_VTS_TS2(buf[0]); 476 + mt->vts[MT8173_TS3] = MT8173_CALIB_BUF1_VTS_TS3(buf[1]); 477 + mt->vts[MT8173_TS4] = MT8173_CALIB_BUF2_VTS_TS4(buf[2]); 478 + mt->vts[MT8173_TSABB] = MT8173_CALIB_BUF2_VTS_TSABB(buf[2]); 479 + mt->degc_cali = MT8173_CALIB_BUF0_DEGC_CALI(buf[0]); 480 + mt->o_slope = MT8173_CALIB_BUF0_O_SLOPE(buf[0]); 481 + } else { 482 + dev_info(dev, "Device not calibrated, using default calibration values\n"); 483 + } 484 + 485 + out: 486 + kfree(buf); 487 + 488 + return ret; 489 + } 490 + 491 + static int mtk_thermal_probe(struct platform_device *pdev) 492 + { 493 + int ret, i; 494 + struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node; 495 + struct mtk_thermal *mt; 496 + struct resource *res; 497 + u64 auxadc_phys_base, apmixed_phys_base; 498 + 499 + mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); 500 + if (!mt) 501 + return -ENOMEM; 502 + 503 + mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm"); 504 + if (IS_ERR(mt->clk_peri_therm)) 505 + return PTR_ERR(mt->clk_peri_therm); 506 + 507 + mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc"); 508 + if (IS_ERR(mt->clk_auxadc)) 509 + return PTR_ERR(mt->clk_auxadc); 510 + 511 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 512 + mt->thermal_base = devm_ioremap_resource(&pdev->dev, res); 513 + if (IS_ERR(mt->thermal_base)) 514 + return PTR_ERR(mt->thermal_base); 515 + 516 + ret = mtk_thermal_get_calibration_data(&pdev->dev, mt); 517 + if (ret) 518 + return ret; 519 + 520 + mutex_init(&mt->lock); 521 + 522 + mt->dev = &pdev->dev; 523 + 524 + auxadc = of_parse_phandle(np, "mediatek,auxadc", 0); 525 + if (!auxadc) { 526 + dev_err(&pdev->dev, "missing auxadc node\n"); 527 + return -ENODEV; 528 + } 529 + 530 + auxadc_phys_base = of_get_phys_base(auxadc); 531 + 532 + of_node_put(auxadc); 533 + 534 + if (auxadc_phys_base == OF_BAD_ADDR) { 535 + dev_err(&pdev->dev, "Can't get auxadc phys address\n"); 536 + return -EINVAL; 537 + } 538 + 539 + apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0); 540 + if (!apmixedsys) { 541 + dev_err(&pdev->dev, "missing apmixedsys node\n"); 542 + return -ENODEV; 543 + } 544 + 545 + apmixed_phys_base = of_get_phys_base(apmixedsys); 546 + 547 + of_node_put(apmixedsys); 548 + 549 + if (apmixed_phys_base == OF_BAD_ADDR) { 550 + dev_err(&pdev->dev, "Can't get auxadc phys address\n"); 551 + return -EINVAL; 552 + } 553 + 554 + ret = clk_prepare_enable(mt->clk_auxadc); 555 + if (ret) { 556 + dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret); 557 + return ret; 558 + } 559 + 560 + ret = device_reset(&pdev->dev); 561 + if (ret) 562 + goto err_disable_clk_auxadc; 563 + 564 + ret = clk_prepare_enable(mt->clk_peri_therm); 565 + if (ret) { 566 + dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret); 567 + goto err_disable_clk_auxadc; 568 + } 569 + 570 + for (i = 0; i < MT8173_NUM_ZONES; i++) 571 + mtk_thermal_init_bank(mt, i, apmixed_phys_base, 572 + auxadc_phys_base); 573 + 574 + platform_set_drvdata(pdev, mt); 575 + 576 + mt->tzd = thermal_zone_of_sensor_register(&pdev->dev, 0, mt, 577 + &mtk_thermal_ops); 578 + if (IS_ERR(mt->tzd)) 579 + goto err_register; 580 + 581 + return 0; 582 + 583 + err_register: 584 + clk_disable_unprepare(mt->clk_peri_therm); 585 + 586 + err_disable_clk_auxadc: 587 + clk_disable_unprepare(mt->clk_auxadc); 588 + 589 + return ret; 590 + } 591 + 592 + static int mtk_thermal_remove(struct platform_device *pdev) 593 + { 594 + struct mtk_thermal *mt = platform_get_drvdata(pdev); 595 + 596 + thermal_zone_of_sensor_unregister(&pdev->dev, mt->tzd); 597 + 598 + clk_disable_unprepare(mt->clk_peri_therm); 599 + clk_disable_unprepare(mt->clk_auxadc); 600 + 601 + return 0; 602 + } 603 + 604 + static const struct of_device_id mtk_thermal_of_match[] = { 605 + { 606 + .compatible = "mediatek,mt8173-thermal", 607 + }, { 608 + }, 609 + }; 610 + 611 + static struct platform_driver mtk_thermal_driver = { 612 + .probe = mtk_thermal_probe, 613 + .remove = mtk_thermal_remove, 614 + .driver = { 615 + .name = THERMAL_NAME, 616 + .of_match_table = mtk_thermal_of_match, 617 + }, 618 + }; 619 + 620 + module_platform_driver(mtk_thermal_driver); 621 + 622 + MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); 623 + MODULE_AUTHOR("Hanyi Wu <hanyi.wu@mediatek.com>"); 624 + MODULE_DESCRIPTION("Mediatek thermal driver"); 625 + MODULE_LICENSE("GPL v2");
+81
drivers/thermal/of-thermal.c
··· 555 555 } 556 556 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister); 557 557 558 + static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res) 559 + { 560 + thermal_zone_of_sensor_unregister(dev, 561 + *(struct thermal_zone_device **)res); 562 + } 563 + 564 + static int devm_thermal_zone_of_sensor_match(struct device *dev, void *res, 565 + void *data) 566 + { 567 + struct thermal_zone_device **r = res; 568 + 569 + if (WARN_ON(!r || !*r)) 570 + return 0; 571 + 572 + return *r == data; 573 + } 574 + 575 + /** 576 + * devm_thermal_zone_of_sensor_register - Resource managed version of 577 + * thermal_zone_of_sensor_register() 578 + * @dev: a valid struct device pointer of a sensor device. Must contain 579 + * a valid .of_node, for the sensor node. 580 + * @sensor_id: a sensor identifier, in case the sensor IP has more 581 + * than one sensors 582 + * @data: a private pointer (owned by the caller) that will be passed 583 + * back, when a temperature reading is needed. 584 + * @ops: struct thermal_zone_of_device_ops *. Must contain at least .get_temp. 585 + * 586 + * Refer thermal_zone_of_sensor_register() for more details. 587 + * 588 + * Return: On success returns a valid struct thermal_zone_device, 589 + * otherwise, it returns a corresponding ERR_PTR(). Caller must 590 + * check the return value with help of IS_ERR() helper. 591 + * Registered hermal_zone_device device will automatically be 592 + * released when device is unbounded. 593 + */ 594 + struct thermal_zone_device *devm_thermal_zone_of_sensor_register( 595 + struct device *dev, int sensor_id, 596 + void *data, const struct thermal_zone_of_device_ops *ops) 597 + { 598 + struct thermal_zone_device **ptr, *tzd; 599 + 600 + ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr), 601 + GFP_KERNEL); 602 + if (!ptr) 603 + return ERR_PTR(-ENOMEM); 604 + 605 + tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops); 606 + if (IS_ERR(tzd)) { 607 + devres_free(ptr); 608 + return tzd; 609 + } 610 + 611 + *ptr = tzd; 612 + devres_add(dev, ptr); 613 + 614 + return tzd; 615 + } 616 + EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_register); 617 + 618 + /** 619 + * devm_thermal_zone_of_sensor_unregister - Resource managed version of 620 + * thermal_zone_of_sensor_unregister(). 621 + * @dev: Device for which which resource was allocated. 622 + * @tzd: a pointer to struct thermal_zone_device where the sensor is registered. 623 + * 624 + * This function removes the sensor callbacks and private data from the 625 + * thermal zone device registered with devm_thermal_zone_of_sensor_register() 626 + * API. It will also silent the zone by remove the .get_temp() and .get_trend() 627 + * thermal zone device callbacks. 628 + * Normally this function will not need to be called and the resource 629 + * management code will ensure that the resource is freed. 630 + */ 631 + void devm_thermal_zone_of_sensor_unregister(struct device *dev, 632 + struct thermal_zone_device *tzd) 633 + { 634 + WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release, 635 + devm_thermal_zone_of_sensor_match, tzd)); 636 + } 637 + EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister); 638 + 558 639 /*** functions parsing device tree nodes ***/ 559 640 560 641 /**
+1 -2
drivers/thermal/rcar_thermal.c
··· 430 430 struct rcar_thermal_priv *priv; 431 431 struct device *dev = &pdev->dev; 432 432 struct resource *res, *irq; 433 - const struct of_device_id *of_id = of_match_device(rcar_thermal_dt_ids, dev); 434 - unsigned long of_data = (unsigned long)of_id->data; 433 + unsigned long of_data = (unsigned long)of_device_get_match_data(dev); 435 434 int mres = 0; 436 435 int i; 437 436 int ret = -ENODEV;
+140 -107
drivers/thermal/rockchip_thermal.c
··· 58 58 59 59 /** 60 60 * The conversion table has the adc value and temperature. 61 - * ADC_DECREMENT: the adc value is of diminishing.(e.g. v2_code_table) 62 - * ADC_INCREMENT: the adc value is incremental.(e.g. v3_code_table) 61 + * ADC_DECREMENT: the adc value is of diminishing.(e.g. rk3288_code_table) 62 + * ADC_INCREMENT: the adc value is incremental.(e.g. rk3368_code_table) 63 63 */ 64 64 enum adc_sort_mode { 65 65 ADC_DECREMENT = 0, ··· 135 135 enum tshut_polarity tshut_polarity; 136 136 }; 137 137 138 - /* TSADC Sensor info define: */ 138 + /** 139 + * TSADC Sensor Register description: 140 + * 141 + * TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it. 142 + * TSADCV3_* are used for newer SoCs than RK3288. (e.g: RK3228, RK3399) 143 + * 144 + */ 139 145 #define TSADCV2_AUTO_CON 0x04 140 146 #define TSADCV2_INT_EN 0x08 141 147 #define TSADCV2_INT_PD 0x0c ··· 155 149 #define TSADCV2_AUTO_EN BIT(0) 156 150 #define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn)) 157 151 #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8) 152 + /** 153 + * TSADCV1_AUTO_Q_SEL_EN: 154 + * whether select (1024 - tsadc_q) as output 155 + * 1'b0:use tsadc_q as output(temperature-code is rising sequence) 156 + * 1'b1:use(1024 - tsadc_q) as output (temperature-code is falling sequence) 157 + */ 158 + #define TSADCV3_AUTO_Q_SEL_EN BIT(1) 158 159 159 160 #define TSADCV2_INT_SRC_EN(chn) BIT(chn) 160 161 #define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) 161 162 #define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) 162 163 163 - #define TSADCV1_INT_PD_CLEAR_MASK ~BIT(16) 164 164 #define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8) 165 + #define TSADCV3_INT_PD_CLEAR_MASK ~BIT(16) 165 166 166 167 #define TSADCV2_DATA_MASK 0xfff 167 168 #define TSADCV3_DATA_MASK 0x3ff ··· 190 177 * linearly interpolated. 191 178 * Code to Temperature mapping should be updated based on sillcon results. 192 179 */ 193 - static const struct tsadc_table v1_code_table[] = { 194 - {TSADCV3_DATA_MASK, -40000}, 195 - {436, -40000}, 196 - {431, -35000}, 197 - {426, -30000}, 198 - {421, -25000}, 199 - {416, -20000}, 200 - {411, -15000}, 201 - {406, -10000}, 202 - {401, -5000}, 203 - {395, 0}, 204 - {390, 5000}, 205 - {385, 10000}, 206 - {380, 15000}, 207 - {375, 20000}, 208 - {370, 25000}, 209 - {364, 30000}, 210 - {359, 35000}, 211 - {354, 40000}, 212 - {349, 45000}, 213 - {343, 50000}, 214 - {338, 55000}, 215 - {333, 60000}, 216 - {328, 65000}, 217 - {322, 70000}, 218 - {317, 75000}, 219 - {312, 80000}, 220 - {307, 85000}, 221 - {301, 90000}, 222 - {296, 95000}, 223 - {291, 100000}, 224 - {286, 105000}, 225 - {280, 110000}, 226 - {275, 115000}, 227 - {270, 120000}, 228 - {264, 125000}, 180 + static const struct tsadc_table rk3228_code_table[] = { 181 + {0, -40000}, 182 + {588, -40000}, 183 + {593, -35000}, 184 + {598, -30000}, 185 + {603, -25000}, 186 + {608, -20000}, 187 + {613, -15000}, 188 + {618, -10000}, 189 + {623, -5000}, 190 + {629, 0}, 191 + {634, 5000}, 192 + {639, 10000}, 193 + {644, 15000}, 194 + {649, 20000}, 195 + {654, 25000}, 196 + {660, 30000}, 197 + {665, 35000}, 198 + {670, 40000}, 199 + {675, 45000}, 200 + {681, 50000}, 201 + {686, 55000}, 202 + {691, 60000}, 203 + {696, 65000}, 204 + {702, 70000}, 205 + {707, 75000}, 206 + {712, 80000}, 207 + {717, 85000}, 208 + {723, 90000}, 209 + {728, 95000}, 210 + {733, 100000}, 211 + {738, 105000}, 212 + {744, 110000}, 213 + {749, 115000}, 214 + {754, 120000}, 215 + {760, 125000}, 216 + {TSADCV2_DATA_MASK, 125000}, 229 217 }; 230 218 231 - static const struct tsadc_table v2_code_table[] = { 219 + static const struct tsadc_table rk3288_code_table[] = { 232 220 {TSADCV2_DATA_MASK, -40000}, 233 221 {3800, -40000}, 234 222 {3792, -35000}, ··· 267 253 {3421, 125000}, 268 254 }; 269 255 270 - static const struct tsadc_table v3_code_table[] = { 256 + static const struct tsadc_table rk3368_code_table[] = { 271 257 {0, -40000}, 272 258 {106, -40000}, 273 259 {108, -35000}, ··· 306 292 {TSADCV3_DATA_MASK, 125000}, 307 293 }; 308 294 309 - static const struct tsadc_table v4_code_table[] = { 310 - {TSADCV3_DATA_MASK, -40000}, 311 - {431, -40000}, 312 - {426, -35000}, 313 - {421, -30000}, 314 - {415, -25000}, 315 - {410, -20000}, 316 - {405, -15000}, 317 - {399, -10000}, 318 - {394, -5000}, 319 - {389, 0}, 320 - {383, 5000}, 321 - {378, 10000}, 322 - {373, 15000}, 323 - {367, 20000}, 324 - {362, 25000}, 325 - {357, 30000}, 326 - {351, 35000}, 327 - {346, 40000}, 328 - {340, 45000}, 329 - {335, 50000}, 330 - {330, 55000}, 331 - {324, 60000}, 332 - {319, 65000}, 333 - {313, 70000}, 334 - {308, 75000}, 335 - {302, 80000}, 336 - {297, 85000}, 337 - {291, 90000}, 338 - {286, 95000}, 339 - {281, 100000}, 340 - {275, 105000}, 341 - {270, 110000}, 342 - {264, 115000}, 343 - {259, 120000}, 344 - {253, 125000}, 295 + static const struct tsadc_table rk3399_code_table[] = { 296 + {0, -40000}, 297 + {593, -40000}, 298 + {598, -35000}, 299 + {603, -30000}, 300 + {609, -25000}, 301 + {614, -20000}, 302 + {619, -15000}, 303 + {625, -10000}, 304 + {630, -5000}, 305 + {635, 0}, 306 + {641, 5000}, 307 + {646, 10000}, 308 + {651, 15000}, 309 + {657, 20000}, 310 + {662, 25000}, 311 + {667, 30000}, 312 + {673, 35000}, 313 + {678, 40000}, 314 + {684, 45000}, 315 + {689, 50000}, 316 + {694, 55000}, 317 + {700, 60000}, 318 + {705, 65000}, 319 + {711, 70000}, 320 + {716, 75000}, 321 + {722, 80000}, 322 + {727, 85000}, 323 + {733, 90000}, 324 + {738, 95000}, 325 + {743, 100000}, 326 + {749, 105000}, 327 + {754, 110000}, 328 + {760, 115000}, 329 + {765, 120000}, 330 + {771, 125000}, 331 + {TSADCV3_DATA_MASK, 125000}, 345 332 }; 346 333 347 334 static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, ··· 426 411 * temperature between 2 table entries is linear and interpolate 427 412 * to produce less granular result. 428 413 */ 429 - num = table.id[mid].temp - v2_code_table[mid - 1].temp; 414 + num = table.id[mid].temp - table.id[mid - 1].temp; 430 415 num *= abs(table.id[mid - 1].code - code); 431 416 denom = abs(table.id[mid - 1].code - table.id[mid].code); 432 417 *temp = table.id[mid - 1].temp + (num / denom); ··· 468 453 regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); 469 454 } 470 455 471 - static void rk_tsadcv1_irq_ack(void __iomem *regs) 472 - { 473 - u32 val; 474 - 475 - val = readl_relaxed(regs + TSADCV2_INT_PD); 476 - writel_relaxed(val & TSADCV1_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); 477 - } 478 - 479 456 static void rk_tsadcv2_irq_ack(void __iomem *regs) 480 457 { 481 458 u32 val; 482 459 483 460 val = readl_relaxed(regs + TSADCV2_INT_PD); 484 461 writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); 462 + } 463 + 464 + static void rk_tsadcv3_irq_ack(void __iomem *regs) 465 + { 466 + u32 val; 467 + 468 + val = readl_relaxed(regs + TSADCV2_INT_PD); 469 + writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); 485 470 } 486 471 487 472 static void rk_tsadcv2_control(void __iomem *regs, bool enable) ··· 491 476 val = readl_relaxed(regs + TSADCV2_AUTO_CON); 492 477 if (enable) 493 478 val |= TSADCV2_AUTO_EN; 479 + else 480 + val &= ~TSADCV2_AUTO_EN; 481 + 482 + writel_relaxed(val, regs + TSADCV2_AUTO_CON); 483 + } 484 + 485 + /** 486 + * @rk_tsadcv3_control: 487 + * TSADC controller works at auto mode, and some SoCs need set the tsadc_q_sel 488 + * bit on TSADCV2_AUTO_CON[1]. The (1024 - tsadc_q) as output adc value if 489 + * setting this bit to enable. 490 + */ 491 + static void rk_tsadcv3_control(void __iomem *regs, bool enable) 492 + { 493 + u32 val; 494 + 495 + val = readl_relaxed(regs + TSADCV2_AUTO_CON); 496 + if (enable) 497 + val |= TSADCV2_AUTO_EN | TSADCV3_AUTO_Q_SEL_EN; 494 498 else 495 499 val &= ~TSADCV2_AUTO_EN; 496 500 ··· 565 531 .tshut_temp = 95000, 566 532 567 533 .initialize = rk_tsadcv2_initialize, 568 - .irq_ack = rk_tsadcv1_irq_ack, 569 - .control = rk_tsadcv2_control, 534 + .irq_ack = rk_tsadcv3_irq_ack, 535 + .control = rk_tsadcv3_control, 570 536 .get_temp = rk_tsadcv2_get_temp, 571 537 .set_tshut_temp = rk_tsadcv2_tshut_temp, 572 538 .set_tshut_mode = rk_tsadcv2_tshut_mode, 573 539 574 540 .table = { 575 - .id = v1_code_table, 576 - .length = ARRAY_SIZE(v1_code_table), 541 + .id = rk3228_code_table, 542 + .length = ARRAY_SIZE(rk3228_code_table), 577 543 .data_mask = TSADCV3_DATA_MASK, 578 - .mode = ADC_DECREMENT, 544 + .mode = ADC_INCREMENT, 579 545 }, 580 546 }; 581 547 ··· 596 562 .set_tshut_mode = rk_tsadcv2_tshut_mode, 597 563 598 564 .table = { 599 - .id = v2_code_table, 600 - .length = ARRAY_SIZE(v2_code_table), 565 + .id = rk3288_code_table, 566 + .length = ARRAY_SIZE(rk3288_code_table), 601 567 .data_mask = TSADCV2_DATA_MASK, 602 568 .mode = ADC_DECREMENT, 603 569 }, ··· 620 586 .set_tshut_mode = rk_tsadcv2_tshut_mode, 621 587 622 588 .table = { 623 - .id = v3_code_table, 624 - .length = ARRAY_SIZE(v3_code_table), 589 + .id = rk3368_code_table, 590 + .length = ARRAY_SIZE(rk3368_code_table), 625 591 .data_mask = TSADCV3_DATA_MASK, 626 592 .mode = ADC_INCREMENT, 627 593 }, ··· 637 603 .tshut_temp = 95000, 638 604 639 605 .initialize = rk_tsadcv2_initialize, 640 - .irq_ack = rk_tsadcv1_irq_ack, 641 - .control = rk_tsadcv2_control, 606 + .irq_ack = rk_tsadcv3_irq_ack, 607 + .control = rk_tsadcv3_control, 642 608 .get_temp = rk_tsadcv2_get_temp, 643 609 .set_tshut_temp = rk_tsadcv2_tshut_temp, 644 610 .set_tshut_mode = rk_tsadcv2_tshut_mode, 645 611 646 612 .table = { 647 - .id = v4_code_table, 648 - .length = ARRAY_SIZE(v4_code_table), 613 + .id = rk3399_code_table, 614 + .length = ARRAY_SIZE(rk3399_code_table), 649 615 .data_mask = TSADCV3_DATA_MASK, 650 - .mode = ADC_DECREMENT, 616 + .mode = ADC_INCREMENT, 651 617 }, 652 618 }; 653 619 ··· 727 693 thermal->chip->tshut_temp); 728 694 thermal->tshut_temp = thermal->chip->tshut_temp; 729 695 } else { 696 + if (shut_temp > INT_MAX) { 697 + dev_err(dev, "Invalid tshut temperature specified: %d\n", 698 + shut_temp); 699 + return -ERANGE; 700 + } 730 701 thermal->tshut_temp = shut_temp; 731 - } 732 - 733 - if (thermal->tshut_temp > INT_MAX) { 734 - dev_err(dev, "Invalid tshut temperature specified: %d\n", 735 - thermal->tshut_temp); 736 - return -ERANGE; 737 702 } 738 703 739 704 if (of_property_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) {
+1
drivers/thermal/samsung/Kconfig
··· 1 1 config EXYNOS_THERMAL 2 2 tristate "Exynos thermal management unit driver" 3 3 depends on THERMAL_OF 4 + depends on HAS_IOMEM 4 5 help 5 6 If you say yes here you get support for the TMU (Thermal Management 6 7 Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises
+18 -1
drivers/thermal/samsung/exynos_tmu.c
··· 184 184 * @temp_error2: fused value of the second point trim. 185 185 * @regulator: pointer to the TMU regulator structure. 186 186 * @reg_conf: pointer to structure to register with core thermal. 187 + * @ntrip: number of supported trip points. 187 188 * @tmu_initialize: SoC specific TMU initialization method 188 189 * @tmu_control: SoC specific TMU control method 189 190 * @tmu_read: SoC specific TMU temperature read method ··· 204 203 u16 temp_error1, temp_error2; 205 204 struct regulator *regulator; 206 205 struct thermal_zone_device *tzd; 206 + unsigned int ntrip; 207 207 208 208 int (*tmu_initialize)(struct platform_device *pdev); 209 209 void (*tmu_control)(struct platform_device *pdev, bool on); ··· 347 345 { 348 346 struct exynos_tmu_data *data = platform_get_drvdata(pdev); 349 347 int ret; 348 + 349 + if (of_thermal_get_ntrips(data->tzd) > data->ntrip) { 350 + dev_info(&pdev->dev, 351 + "More trip points than supported by this TMU.\n"); 352 + dev_info(&pdev->dev, 353 + "%d trip points should be configured in polling mode.\n", 354 + (of_thermal_get_ntrips(data->tzd) - data->ntrip)); 355 + } 350 356 351 357 mutex_lock(&data->lock); 352 358 clk_enable(data->clk); ··· 1220 1210 data->tmu_control = exynos4210_tmu_control; 1221 1211 data->tmu_read = exynos4210_tmu_read; 1222 1212 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1213 + data->ntrip = 4; 1223 1214 break; 1224 1215 case SOC_ARCH_EXYNOS3250: 1225 1216 case SOC_ARCH_EXYNOS4412: ··· 1233 1222 data->tmu_read = exynos4412_tmu_read; 1234 1223 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 1235 1224 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1225 + data->ntrip = 4; 1236 1226 break; 1237 1227 case SOC_ARCH_EXYNOS5433: 1238 1228 data->tmu_initialize = exynos5433_tmu_initialize; ··· 1241 1229 data->tmu_read = exynos4412_tmu_read; 1242 1230 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 1243 1231 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1232 + data->ntrip = 8; 1244 1233 break; 1245 1234 case SOC_ARCH_EXYNOS5440: 1246 1235 data->tmu_initialize = exynos5440_tmu_initialize; ··· 1249 1236 data->tmu_read = exynos5440_tmu_read; 1250 1237 data->tmu_set_emulation = exynos5440_tmu_set_emulation; 1251 1238 data->tmu_clear_irqs = exynos5440_tmu_clear_irqs; 1239 + data->ntrip = 4; 1252 1240 break; 1253 1241 case SOC_ARCH_EXYNOS7: 1254 1242 data->tmu_initialize = exynos7_tmu_initialize; ··· 1257 1243 data->tmu_read = exynos7_tmu_read; 1258 1244 data->tmu_set_emulation = exynos4412_tmu_set_emulation; 1259 1245 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; 1246 + data->ntrip = 8; 1260 1247 break; 1261 1248 default: 1262 1249 dev_err(&pdev->dev, "Platform not supported\n"); ··· 1310 1295 * TODO: Add regulator as an SOC feature, so that regulator enable 1311 1296 * is a compulsory call. 1312 1297 */ 1313 - data->regulator = devm_regulator_get(&pdev->dev, "vtmu"); 1298 + data->regulator = devm_regulator_get_optional(&pdev->dev, "vtmu"); 1314 1299 if (!IS_ERR(data->regulator)) { 1315 1300 ret = regulator_enable(data->regulator); 1316 1301 if (ret) { ··· 1318 1303 return ret; 1319 1304 } 1320 1305 } else { 1306 + if (PTR_ERR(data->regulator) == -EPROBE_DEFER) 1307 + return -EPROBE_DEFER; 1321 1308 dev_info(&pdev->dev, "Regulator node (vtmu) not found\n"); 1322 1309 } 1323 1310
+1 -1
drivers/thermal/tegra_soctherm.c
··· 57 57 #define READBACK_VALUE_MASK 0xff00 58 58 #define READBACK_VALUE_SHIFT 8 59 59 #define READBACK_ADD_HALF BIT(7) 60 - #define READBACK_NEGATE BIT(1) 60 + #define READBACK_NEGATE BIT(0) 61 61 62 62 #define FUSE_TSENSOR8_CALIB 0x180 63 63 #define FUSE_SPARE_REALIGNMENT_REG_0 0x1fc
+4 -6
drivers/thermal/ti-soc-thermal/ti-bandgap.c
··· 1265 1265 int ti_bandgap_probe(struct platform_device *pdev) 1266 1266 { 1267 1267 struct ti_bandgap *bgp; 1268 - int clk_rate, ret = 0, i; 1268 + int clk_rate, ret, i; 1269 1269 1270 1270 bgp = ti_bandgap_build(pdev); 1271 1271 if (IS_ERR(bgp)) { ··· 1288 1288 } 1289 1289 1290 1290 bgp->fclock = clk_get(NULL, bgp->conf->fclock_name); 1291 - ret = IS_ERR(bgp->fclock); 1292 - if (ret) { 1291 + if (IS_ERR(bgp->fclock)) { 1293 1292 dev_err(&pdev->dev, "failed to request fclock reference\n"); 1294 1293 ret = PTR_ERR(bgp->fclock); 1295 1294 goto free_irqs; 1296 1295 } 1297 1296 1298 1297 bgp->div_clk = clk_get(NULL, bgp->conf->div_ck_name); 1299 - ret = IS_ERR(bgp->div_clk); 1300 - if (ret) { 1298 + if (IS_ERR(bgp->div_clk)) { 1301 1299 dev_err(&pdev->dev, "failed to request div_ts_ck clock ref\n"); 1302 1300 ret = PTR_ERR(bgp->div_clk); 1303 1301 goto free_irqs; ··· 1312 1314 * may not be accurate 1313 1315 */ 1314 1316 val = ti_bandgap_readl(bgp, tsr->bgap_efuse); 1315 - if (ret || !val) 1317 + if (!val) 1316 1318 dev_info(&pdev->dev, 1317 1319 "Non-trimmed BGAP, Temp not accurate\n"); 1318 1320 }
+18
include/linux/thermal.h
··· 362 362 const struct thermal_zone_of_device_ops *ops); 363 363 void thermal_zone_of_sensor_unregister(struct device *dev, 364 364 struct thermal_zone_device *tz); 365 + struct thermal_zone_device *devm_thermal_zone_of_sensor_register( 366 + struct device *dev, int id, void *data, 367 + const struct thermal_zone_of_device_ops *ops); 368 + void devm_thermal_zone_of_sensor_unregister(struct device *dev, 369 + struct thermal_zone_device *tz); 365 370 #else 366 371 static inline struct thermal_zone_device * 367 372 thermal_zone_of_sensor_register(struct device *dev, int id, void *data, ··· 378 373 static inline 379 374 void thermal_zone_of_sensor_unregister(struct device *dev, 380 375 struct thermal_zone_device *tz) 376 + { 377 + } 378 + 379 + static inline struct thermal_zone_device *devm_thermal_zone_of_sensor_register( 380 + struct device *dev, int id, void *data, 381 + const struct thermal_zone_of_device_ops *ops) 382 + { 383 + return ERR_PTR(-ENODEV); 384 + } 385 + 386 + static inline 387 + void devm_thermal_zone_of_sensor_unregister(struct device *dev, 388 + struct thermal_zone_device *tz) 381 389 { 382 390 } 383 391