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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal SoC updates from Eduardo Valentin:
"This is a really small pull in the midst of a lot of pending patches.

We are in the middle of restructuring how we are maintaining the
thermal subsystem, as per discussion in our last LPC. For now, I am
sending just some changes that were pending in my tree. Looking
forward to get a more streamlined process in the next merge window"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal:
thermal: db8500: Rewrite to be a pure OF sensor
thermal: db8500: Use dev helper variable
thermal: db8500: Finalize device tree conversion
thermal: thermal_mmio: remove some dead code

+114 -463
+1 -52
drivers/mfd/db8500-prcmu.c
··· 36 36 #include <linux/regulator/db8500-prcmu.h> 37 37 #include <linux/regulator/machine.h> 38 38 #include <linux/platform_data/ux500_wdt.h> 39 - #include <linux/platform_data/db8500_thermal.h> 40 39 #include "dbx500-prcmu-regs.h" 41 40 42 41 /* Index of different voltages to be used when accessing AVSData */ ··· 3013 3014 .timeout = 600, /* 10 minutes */ 3014 3015 .has_28_bits_resolution = true, 3015 3016 }; 3016 - /* 3017 - * Thermal Sensor 3018 - */ 3019 - 3020 - static struct resource db8500_thsens_resources[] = { 3021 - { 3022 - .name = "IRQ_HOTMON_LOW", 3023 - .start = IRQ_PRCMU_HOTMON_LOW, 3024 - .end = IRQ_PRCMU_HOTMON_LOW, 3025 - .flags = IORESOURCE_IRQ, 3026 - }, 3027 - { 3028 - .name = "IRQ_HOTMON_HIGH", 3029 - .start = IRQ_PRCMU_HOTMON_HIGH, 3030 - .end = IRQ_PRCMU_HOTMON_HIGH, 3031 - .flags = IORESOURCE_IRQ, 3032 - }, 3033 - }; 3034 - 3035 - static struct db8500_thsens_platform_data db8500_thsens_data = { 3036 - .trip_points[0] = { 3037 - .temp = 70000, 3038 - .type = THERMAL_TRIP_ACTIVE, 3039 - .cdev_name = { 3040 - [0] = "thermal-cpufreq-0", 3041 - }, 3042 - }, 3043 - .trip_points[1] = { 3044 - .temp = 75000, 3045 - .type = THERMAL_TRIP_ACTIVE, 3046 - .cdev_name = { 3047 - [0] = "thermal-cpufreq-0", 3048 - }, 3049 - }, 3050 - .trip_points[2] = { 3051 - .temp = 80000, 3052 - .type = THERMAL_TRIP_ACTIVE, 3053 - .cdev_name = { 3054 - [0] = "thermal-cpufreq-0", 3055 - }, 3056 - }, 3057 - .trip_points[3] = { 3058 - .temp = 85000, 3059 - .type = THERMAL_TRIP_CRITICAL, 3060 - }, 3061 - .num_trips = 4, 3062 - }; 3063 3017 3064 3018 static const struct mfd_cell common_prcmu_devs[] = { 3065 3019 { ··· 3036 3084 }, 3037 3085 { 3038 3086 .name = "db8500-thermal", 3039 - .num_resources = ARRAY_SIZE(db8500_thsens_resources), 3040 - .resources = db8500_thsens_resources, 3041 - .platform_data = &db8500_thsens_data, 3042 - .pdata_size = sizeof(db8500_thsens_data), 3087 + .of_compatible = "stericsson,db8500-thermal", 3043 3088 }, 3044 3089 }; 3045 3090
+1 -1
drivers/thermal/Kconfig
··· 310 310 311 311 config DB8500_THERMAL 312 312 tristate "DB8500 thermal management" 313 - depends on MFD_DB8500_PRCMU 313 + depends on MFD_DB8500_PRCMU && OF 314 314 default y 315 315 help 316 316 Adds DB8500 thermal management implementation according to the thermal
+112 -374
drivers/thermal/db8500_thermal.c
··· 3 3 * db8500_thermal.c - DB8500 Thermal Management Implementation 4 4 * 5 5 * Copyright (C) 2012 ST-Ericsson 6 - * Copyright (C) 2012 Linaro Ltd. 6 + * Copyright (C) 2012-2019 Linaro Ltd. 7 7 * 8 - * Author: Hongbo Zhang <hongbo.zhang@linaro.com> 8 + * Authors: Hongbo Zhang, Linus Walleij 9 9 */ 10 10 11 11 #include <linux/cpu_cooling.h> ··· 13 13 #include <linux/mfd/dbx500-prcmu.h> 14 14 #include <linux/module.h> 15 15 #include <linux/of.h> 16 - #include <linux/platform_data/db8500_thermal.h> 17 16 #include <linux/platform_device.h> 18 17 #include <linux/slab.h> 19 18 #include <linux/thermal.h> ··· 20 21 #define PRCMU_DEFAULT_MEASURE_TIME 0xFFF 21 22 #define PRCMU_DEFAULT_LOW_TEMP 0 22 23 24 + /** 25 + * db8500_thermal_points - the interpolation points that trigger 26 + * interrupts 27 + */ 28 + static const unsigned long db8500_thermal_points[] = { 29 + 15000, 30 + 20000, 31 + 25000, 32 + 30000, 33 + 35000, 34 + 40000, 35 + 45000, 36 + 50000, 37 + 55000, 38 + 60000, 39 + 65000, 40 + 70000, 41 + 75000, 42 + 80000, 43 + /* 44 + * This is where things start to get really bad for the 45 + * SoC and the thermal zones should be set up to trigger 46 + * critical temperature at 85000 mC so we don't get above 47 + * this point. 48 + */ 49 + 85000, 50 + 90000, 51 + 95000, 52 + 100000, 53 + }; 54 + 23 55 struct db8500_thermal_zone { 24 - struct thermal_zone_device *therm_dev; 25 - struct mutex th_lock; 26 - struct work_struct therm_work; 27 - struct db8500_thsens_platform_data *trip_tab; 28 - enum thermal_device_mode mode; 56 + struct thermal_zone_device *tz; 29 57 enum thermal_trend trend; 30 - unsigned long cur_temp_pseudo; 58 + unsigned long interpolated_temp; 31 59 unsigned int cur_index; 32 60 }; 33 61 34 - /* Local function to check if thermal zone matches cooling devices */ 35 - static int db8500_thermal_match_cdev(struct thermal_cooling_device *cdev, 36 - struct db8500_trip_point *trip_point) 37 - { 38 - int i; 39 - 40 - if (!strlen(cdev->type)) 41 - return -EINVAL; 42 - 43 - for (i = 0; i < COOLING_DEV_MAX; i++) { 44 - if (!strcmp(trip_point->cdev_name[i], cdev->type)) 45 - return 0; 46 - } 47 - 48 - return -ENODEV; 49 - } 50 - 51 - /* Callback to bind cooling device to thermal zone */ 52 - static int db8500_cdev_bind(struct thermal_zone_device *thermal, 53 - struct thermal_cooling_device *cdev) 54 - { 55 - struct db8500_thermal_zone *pzone = thermal->devdata; 56 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 57 - unsigned long max_state, upper, lower; 58 - int i, ret = -EINVAL; 59 - 60 - cdev->ops->get_max_state(cdev, &max_state); 61 - 62 - for (i = 0; i < ptrips->num_trips; i++) { 63 - if (db8500_thermal_match_cdev(cdev, &ptrips->trip_points[i])) 64 - continue; 65 - 66 - upper = lower = i > max_state ? max_state : i; 67 - 68 - ret = thermal_zone_bind_cooling_device(thermal, i, cdev, 69 - upper, lower, THERMAL_WEIGHT_DEFAULT); 70 - 71 - dev_info(&cdev->device, "%s bind to %d: %d-%s\n", cdev->type, 72 - i, ret, ret ? "fail" : "succeed"); 73 - } 74 - 75 - return ret; 76 - } 77 - 78 - /* Callback to unbind cooling device from thermal zone */ 79 - static int db8500_cdev_unbind(struct thermal_zone_device *thermal, 80 - struct thermal_cooling_device *cdev) 81 - { 82 - struct db8500_thermal_zone *pzone = thermal->devdata; 83 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 84 - int i, ret = -EINVAL; 85 - 86 - for (i = 0; i < ptrips->num_trips; i++) { 87 - if (db8500_thermal_match_cdev(cdev, &ptrips->trip_points[i])) 88 - continue; 89 - 90 - ret = thermal_zone_unbind_cooling_device(thermal, i, cdev); 91 - 92 - dev_info(&cdev->device, "%s unbind from %d: %s\n", cdev->type, 93 - i, ret ? "fail" : "succeed"); 94 - } 95 - 96 - return ret; 97 - } 98 - 99 62 /* Callback to get current temperature */ 100 - static int db8500_sys_get_temp(struct thermal_zone_device *thermal, int *temp) 63 + static int db8500_thermal_get_temp(void *data, int *temp) 101 64 { 102 - struct db8500_thermal_zone *pzone = thermal->devdata; 65 + struct db8500_thermal_zone *th = data; 103 66 104 67 /* 105 68 * TODO: There is no PRCMU interface to get temperature data currently, 106 69 * so a pseudo temperature is returned , it works for thermal framework 107 70 * and this will be fixed when the PRCMU interface is available. 108 71 */ 109 - *temp = pzone->cur_temp_pseudo; 72 + *temp = th->interpolated_temp; 110 73 111 74 return 0; 112 75 } 113 76 114 77 /* Callback to get temperature changing trend */ 115 - static int db8500_sys_get_trend(struct thermal_zone_device *thermal, 116 - int trip, enum thermal_trend *trend) 78 + static int db8500_thermal_get_trend(void *data, int trip, enum thermal_trend *trend) 117 79 { 118 - struct db8500_thermal_zone *pzone = thermal->devdata; 80 + struct db8500_thermal_zone *th = data; 119 81 120 - *trend = pzone->trend; 82 + *trend = th->trend; 121 83 122 84 return 0; 123 85 } 124 86 125 - /* Callback to get thermal zone mode */ 126 - static int db8500_sys_get_mode(struct thermal_zone_device *thermal, 127 - enum thermal_device_mode *mode) 128 - { 129 - struct db8500_thermal_zone *pzone = thermal->devdata; 130 - 131 - mutex_lock(&pzone->th_lock); 132 - *mode = pzone->mode; 133 - mutex_unlock(&pzone->th_lock); 134 - 135 - return 0; 136 - } 137 - 138 - /* Callback to set thermal zone mode */ 139 - static int db8500_sys_set_mode(struct thermal_zone_device *thermal, 140 - enum thermal_device_mode mode) 141 - { 142 - struct db8500_thermal_zone *pzone = thermal->devdata; 143 - 144 - mutex_lock(&pzone->th_lock); 145 - 146 - pzone->mode = mode; 147 - if (mode == THERMAL_DEVICE_ENABLED) 148 - schedule_work(&pzone->therm_work); 149 - 150 - mutex_unlock(&pzone->th_lock); 151 - 152 - return 0; 153 - } 154 - 155 - /* Callback to get trip point type */ 156 - static int db8500_sys_get_trip_type(struct thermal_zone_device *thermal, 157 - int trip, enum thermal_trip_type *type) 158 - { 159 - struct db8500_thermal_zone *pzone = thermal->devdata; 160 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 161 - 162 - if (trip >= ptrips->num_trips) 163 - return -EINVAL; 164 - 165 - *type = ptrips->trip_points[trip].type; 166 - 167 - return 0; 168 - } 169 - 170 - /* Callback to get trip point temperature */ 171 - static int db8500_sys_get_trip_temp(struct thermal_zone_device *thermal, 172 - int trip, int *temp) 173 - { 174 - struct db8500_thermal_zone *pzone = thermal->devdata; 175 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 176 - 177 - if (trip >= ptrips->num_trips) 178 - return -EINVAL; 179 - 180 - *temp = ptrips->trip_points[trip].temp; 181 - 182 - return 0; 183 - } 184 - 185 - /* Callback to get critical trip point temperature */ 186 - static int db8500_sys_get_crit_temp(struct thermal_zone_device *thermal, 187 - int *temp) 188 - { 189 - struct db8500_thermal_zone *pzone = thermal->devdata; 190 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 191 - int i; 192 - 193 - for (i = ptrips->num_trips - 1; i > 0; i--) { 194 - if (ptrips->trip_points[i].type == THERMAL_TRIP_CRITICAL) { 195 - *temp = ptrips->trip_points[i].temp; 196 - return 0; 197 - } 198 - } 199 - 200 - return -EINVAL; 201 - } 202 - 203 - static struct thermal_zone_device_ops thdev_ops = { 204 - .bind = db8500_cdev_bind, 205 - .unbind = db8500_cdev_unbind, 206 - .get_temp = db8500_sys_get_temp, 207 - .get_trend = db8500_sys_get_trend, 208 - .get_mode = db8500_sys_get_mode, 209 - .set_mode = db8500_sys_set_mode, 210 - .get_trip_type = db8500_sys_get_trip_type, 211 - .get_trip_temp = db8500_sys_get_trip_temp, 212 - .get_crit_temp = db8500_sys_get_crit_temp, 87 + static struct thermal_zone_of_device_ops thdev_ops = { 88 + .get_temp = db8500_thermal_get_temp, 89 + .get_trend = db8500_thermal_get_trend, 213 90 }; 214 91 215 - static void db8500_thermal_update_config(struct db8500_thermal_zone *pzone, 216 - unsigned int idx, enum thermal_trend trend, 217 - unsigned long next_low, unsigned long next_high) 92 + static void db8500_thermal_update_config(struct db8500_thermal_zone *th, 93 + unsigned int idx, 94 + enum thermal_trend trend, 95 + unsigned long next_low, 96 + unsigned long next_high) 218 97 { 219 98 prcmu_stop_temp_sense(); 220 99 221 - pzone->cur_index = idx; 222 - pzone->cur_temp_pseudo = (next_low + next_high)/2; 223 - pzone->trend = trend; 100 + th->cur_index = idx; 101 + th->interpolated_temp = (next_low + next_high)/2; 102 + th->trend = trend; 224 103 104 + /* 105 + * The PRCMU accept absolute temperatures in celsius so divide 106 + * down the millicelsius with 1000 107 + */ 225 108 prcmu_config_hotmon((u8)(next_low/1000), (u8)(next_high/1000)); 226 109 prcmu_start_temp_sense(PRCMU_DEFAULT_MEASURE_TIME); 227 110 } 228 111 229 112 static irqreturn_t prcmu_low_irq_handler(int irq, void *irq_data) 230 113 { 231 - struct db8500_thermal_zone *pzone = irq_data; 232 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 233 - unsigned int idx = pzone->cur_index; 114 + struct db8500_thermal_zone *th = irq_data; 115 + unsigned int idx = th->cur_index; 234 116 unsigned long next_low, next_high; 235 117 236 - if (unlikely(idx == 0)) 118 + if (idx == 0) 237 119 /* Meaningless for thermal management, ignoring it */ 238 120 return IRQ_HANDLED; 239 121 240 122 if (idx == 1) { 241 - next_high = ptrips->trip_points[0].temp; 123 + next_high = db8500_thermal_points[0]; 242 124 next_low = PRCMU_DEFAULT_LOW_TEMP; 243 125 } else { 244 - next_high = ptrips->trip_points[idx-1].temp; 245 - next_low = ptrips->trip_points[idx-2].temp; 126 + next_high = db8500_thermal_points[idx - 1]; 127 + next_low = db8500_thermal_points[idx - 2]; 246 128 } 247 129 idx -= 1; 248 130 249 - db8500_thermal_update_config(pzone, idx, THERMAL_TREND_DROPPING, 250 - next_low, next_high); 251 - 252 - dev_dbg(&pzone->therm_dev->device, 131 + db8500_thermal_update_config(th, idx, THERMAL_TREND_DROPPING, 132 + next_low, next_high); 133 + dev_dbg(&th->tz->device, 253 134 "PRCMU set max %ld, min %ld\n", next_high, next_low); 254 135 255 - schedule_work(&pzone->therm_work); 136 + thermal_zone_device_update(th->tz, THERMAL_EVENT_UNSPECIFIED); 256 137 257 138 return IRQ_HANDLED; 258 139 } 259 140 260 141 static irqreturn_t prcmu_high_irq_handler(int irq, void *irq_data) 261 142 { 262 - struct db8500_thermal_zone *pzone = irq_data; 263 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 264 - unsigned int idx = pzone->cur_index; 143 + struct db8500_thermal_zone *th = irq_data; 144 + unsigned int idx = th->cur_index; 265 145 unsigned long next_low, next_high; 146 + int num_points = ARRAY_SIZE(db8500_thermal_points); 266 147 267 - if (idx < ptrips->num_trips - 1) { 268 - next_high = ptrips->trip_points[idx+1].temp; 269 - next_low = ptrips->trip_points[idx].temp; 148 + if (idx < num_points - 1) { 149 + next_high = db8500_thermal_points[idx+1]; 150 + next_low = db8500_thermal_points[idx]; 270 151 idx += 1; 271 152 272 - db8500_thermal_update_config(pzone, idx, THERMAL_TREND_RAISING, 273 - next_low, next_high); 153 + db8500_thermal_update_config(th, idx, THERMAL_TREND_RAISING, 154 + next_low, next_high); 274 155 275 - dev_dbg(&pzone->therm_dev->device, 276 - "PRCMU set max %ld, min %ld\n", next_high, next_low); 277 - } else if (idx == ptrips->num_trips - 1) 278 - pzone->cur_temp_pseudo = ptrips->trip_points[idx].temp + 1; 156 + dev_info(&th->tz->device, 157 + "PRCMU set max %ld, min %ld\n", next_high, next_low); 158 + } else if (idx == num_points - 1) 159 + /* So we roof out 1 degree over the max point */ 160 + th->interpolated_temp = db8500_thermal_points[idx] + 1; 279 161 280 - schedule_work(&pzone->therm_work); 162 + thermal_zone_device_update(th->tz, THERMAL_EVENT_UNSPECIFIED); 281 163 282 164 return IRQ_HANDLED; 283 165 } 284 166 285 - static void db8500_thermal_work(struct work_struct *work) 286 - { 287 - enum thermal_device_mode cur_mode; 288 - struct db8500_thermal_zone *pzone; 289 - 290 - pzone = container_of(work, struct db8500_thermal_zone, therm_work); 291 - 292 - mutex_lock(&pzone->th_lock); 293 - cur_mode = pzone->mode; 294 - mutex_unlock(&pzone->th_lock); 295 - 296 - if (cur_mode == THERMAL_DEVICE_DISABLED) 297 - return; 298 - 299 - thermal_zone_device_update(pzone->therm_dev, THERMAL_EVENT_UNSPECIFIED); 300 - dev_dbg(&pzone->therm_dev->device, "thermal work finished.\n"); 301 - } 302 - 303 - #ifdef CONFIG_OF 304 - static struct db8500_thsens_platform_data* 305 - db8500_thermal_parse_dt(struct platform_device *pdev) 306 - { 307 - struct db8500_thsens_platform_data *ptrips; 308 - struct device_node *np = pdev->dev.of_node; 309 - char prop_name[32]; 310 - const char *tmp_str; 311 - u32 tmp_data; 312 - int i, j; 313 - 314 - ptrips = devm_kzalloc(&pdev->dev, sizeof(*ptrips), GFP_KERNEL); 315 - if (!ptrips) 316 - return NULL; 317 - 318 - if (of_property_read_u32(np, "num-trips", &tmp_data)) 319 - goto err_parse_dt; 320 - 321 - if (tmp_data > THERMAL_MAX_TRIPS) 322 - goto err_parse_dt; 323 - 324 - ptrips->num_trips = tmp_data; 325 - 326 - for (i = 0; i < ptrips->num_trips; i++) { 327 - sprintf(prop_name, "trip%d-temp", i); 328 - if (of_property_read_u32(np, prop_name, &tmp_data)) 329 - goto err_parse_dt; 330 - 331 - ptrips->trip_points[i].temp = tmp_data; 332 - 333 - sprintf(prop_name, "trip%d-type", i); 334 - if (of_property_read_string(np, prop_name, &tmp_str)) 335 - goto err_parse_dt; 336 - 337 - if (!strcmp(tmp_str, "active")) 338 - ptrips->trip_points[i].type = THERMAL_TRIP_ACTIVE; 339 - else if (!strcmp(tmp_str, "passive")) 340 - ptrips->trip_points[i].type = THERMAL_TRIP_PASSIVE; 341 - else if (!strcmp(tmp_str, "hot")) 342 - ptrips->trip_points[i].type = THERMAL_TRIP_HOT; 343 - else if (!strcmp(tmp_str, "critical")) 344 - ptrips->trip_points[i].type = THERMAL_TRIP_CRITICAL; 345 - else 346 - goto err_parse_dt; 347 - 348 - sprintf(prop_name, "trip%d-cdev-num", i); 349 - if (of_property_read_u32(np, prop_name, &tmp_data)) 350 - goto err_parse_dt; 351 - 352 - if (tmp_data > COOLING_DEV_MAX) 353 - goto err_parse_dt; 354 - 355 - for (j = 0; j < tmp_data; j++) { 356 - sprintf(prop_name, "trip%d-cdev-name%d", i, j); 357 - if (of_property_read_string(np, prop_name, &tmp_str)) 358 - goto err_parse_dt; 359 - 360 - if (strlen(tmp_str) >= THERMAL_NAME_LENGTH) 361 - goto err_parse_dt; 362 - 363 - strcpy(ptrips->trip_points[i].cdev_name[j], tmp_str); 364 - } 365 - } 366 - return ptrips; 367 - 368 - err_parse_dt: 369 - dev_err(&pdev->dev, "Parsing device tree data error.\n"); 370 - return NULL; 371 - } 372 - #else 373 - static inline struct db8500_thsens_platform_data* 374 - db8500_thermal_parse_dt(struct platform_device *pdev) 375 - { 376 - return NULL; 377 - } 378 - #endif 379 - 380 167 static int db8500_thermal_probe(struct platform_device *pdev) 381 168 { 382 - struct db8500_thermal_zone *pzone = NULL; 383 - struct db8500_thsens_platform_data *ptrips = NULL; 384 - struct device_node *np = pdev->dev.of_node; 169 + struct db8500_thermal_zone *th = NULL; 170 + struct device *dev = &pdev->dev; 385 171 int low_irq, high_irq, ret = 0; 386 - unsigned long dft_low, dft_high; 387 172 388 - if (np) 389 - ptrips = db8500_thermal_parse_dt(pdev); 390 - else 391 - ptrips = dev_get_platdata(&pdev->dev); 392 - 393 - if (!ptrips) 394 - return -EINVAL; 395 - 396 - pzone = devm_kzalloc(&pdev->dev, sizeof(*pzone), GFP_KERNEL); 397 - if (!pzone) 173 + th = devm_kzalloc(dev, sizeof(*th), GFP_KERNEL); 174 + if (!th) 398 175 return -ENOMEM; 399 - 400 - mutex_init(&pzone->th_lock); 401 - mutex_lock(&pzone->th_lock); 402 - 403 - pzone->mode = THERMAL_DEVICE_DISABLED; 404 - pzone->trip_tab = ptrips; 405 - 406 - INIT_WORK(&pzone->therm_work, db8500_thermal_work); 407 176 408 177 low_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_LOW"); 409 178 if (low_irq < 0) { 410 - dev_err(&pdev->dev, "Get IRQ_HOTMON_LOW failed.\n"); 411 - ret = low_irq; 412 - goto out_unlock; 179 + dev_err(dev, "Get IRQ_HOTMON_LOW failed\n"); 180 + return low_irq; 413 181 } 414 182 415 - ret = devm_request_threaded_irq(&pdev->dev, low_irq, NULL, 183 + ret = devm_request_threaded_irq(dev, low_irq, NULL, 416 184 prcmu_low_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT, 417 - "dbx500_temp_low", pzone); 185 + "dbx500_temp_low", th); 418 186 if (ret < 0) { 419 - dev_err(&pdev->dev, "Failed to allocate temp low irq.\n"); 420 - goto out_unlock; 187 + dev_err(dev, "failed to allocate temp low irq\n"); 188 + return ret; 421 189 } 422 190 423 191 high_irq = platform_get_irq_byname(pdev, "IRQ_HOTMON_HIGH"); 424 192 if (high_irq < 0) { 425 - dev_err(&pdev->dev, "Get IRQ_HOTMON_HIGH failed.\n"); 426 - ret = high_irq; 427 - goto out_unlock; 193 + dev_err(dev, "Get IRQ_HOTMON_HIGH failed\n"); 194 + return high_irq; 428 195 } 429 196 430 - ret = devm_request_threaded_irq(&pdev->dev, high_irq, NULL, 197 + ret = devm_request_threaded_irq(dev, high_irq, NULL, 431 198 prcmu_high_irq_handler, IRQF_NO_SUSPEND | IRQF_ONESHOT, 432 - "dbx500_temp_high", pzone); 199 + "dbx500_temp_high", th); 433 200 if (ret < 0) { 434 - dev_err(&pdev->dev, "Failed to allocate temp high irq.\n"); 435 - goto out_unlock; 201 + dev_err(dev, "failed to allocate temp high irq\n"); 202 + return ret; 436 203 } 437 204 438 - pzone->therm_dev = thermal_zone_device_register("db8500_thermal_zone", 439 - ptrips->num_trips, 0, pzone, &thdev_ops, NULL, 0, 0); 440 - 441 - if (IS_ERR(pzone->therm_dev)) { 442 - dev_err(&pdev->dev, "Register thermal zone device failed.\n"); 443 - ret = PTR_ERR(pzone->therm_dev); 444 - goto out_unlock; 205 + /* register of thermal sensor and get info from DT */ 206 + th->tz = devm_thermal_zone_of_sensor_register(dev, 0, th, &thdev_ops); 207 + if (IS_ERR(th->tz)) { 208 + dev_err(dev, "register thermal zone sensor failed\n"); 209 + return PTR_ERR(th->tz); 445 210 } 446 - dev_info(&pdev->dev, "Thermal zone device registered.\n"); 211 + dev_info(dev, "thermal zone sensor registered\n"); 447 212 448 - dft_low = PRCMU_DEFAULT_LOW_TEMP; 449 - dft_high = ptrips->trip_points[0].temp; 213 + /* Start measuring at the lowest point */ 214 + db8500_thermal_update_config(th, 0, THERMAL_TREND_STABLE, 215 + PRCMU_DEFAULT_LOW_TEMP, 216 + db8500_thermal_points[0]); 450 217 451 - db8500_thermal_update_config(pzone, 0, THERMAL_TREND_STABLE, 452 - dft_low, dft_high); 453 - 454 - platform_set_drvdata(pdev, pzone); 455 - pzone->mode = THERMAL_DEVICE_ENABLED; 456 - 457 - out_unlock: 458 - mutex_unlock(&pzone->th_lock); 459 - 460 - return ret; 461 - } 462 - 463 - static int db8500_thermal_remove(struct platform_device *pdev) 464 - { 465 - struct db8500_thermal_zone *pzone = platform_get_drvdata(pdev); 466 - 467 - thermal_zone_device_unregister(pzone->therm_dev); 468 - cancel_work_sync(&pzone->therm_work); 469 - mutex_destroy(&pzone->th_lock); 218 + platform_set_drvdata(pdev, th); 470 219 471 220 return 0; 472 221 } ··· 222 475 static int db8500_thermal_suspend(struct platform_device *pdev, 223 476 pm_message_t state) 224 477 { 225 - struct db8500_thermal_zone *pzone = platform_get_drvdata(pdev); 226 - 227 - flush_work(&pzone->therm_work); 228 478 prcmu_stop_temp_sense(); 229 479 230 480 return 0; ··· 229 485 230 486 static int db8500_thermal_resume(struct platform_device *pdev) 231 487 { 232 - struct db8500_thermal_zone *pzone = platform_get_drvdata(pdev); 233 - struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; 234 - unsigned long dft_low, dft_high; 488 + struct db8500_thermal_zone *th = platform_get_drvdata(pdev); 235 489 236 - dft_low = PRCMU_DEFAULT_LOW_TEMP; 237 - dft_high = ptrips->trip_points[0].temp; 238 - 239 - db8500_thermal_update_config(pzone, 0, THERMAL_TREND_STABLE, 240 - dft_low, dft_high); 490 + /* Resume and start measuring at the lowest point */ 491 + db8500_thermal_update_config(th, 0, THERMAL_TREND_STABLE, 492 + PRCMU_DEFAULT_LOW_TEMP, 493 + db8500_thermal_points[0]); 241 494 242 495 return 0; 243 496 } 244 497 245 - #ifdef CONFIG_OF 246 498 static const struct of_device_id db8500_thermal_match[] = { 247 499 { .compatible = "stericsson,db8500-thermal" }, 248 500 {}, 249 501 }; 250 502 MODULE_DEVICE_TABLE(of, db8500_thermal_match); 251 - #endif 252 503 253 504 static struct platform_driver db8500_thermal_driver = { 254 505 .driver = { ··· 253 514 .probe = db8500_thermal_probe, 254 515 .suspend = db8500_thermal_suspend, 255 516 .resume = db8500_thermal_resume, 256 - .remove = db8500_thermal_remove, 257 517 }; 258 518 259 519 module_platform_driver(db8500_thermal_driver);
-7
drivers/thermal/thermal_mmio.c
··· 53 53 return -ENOMEM; 54 54 55 55 resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); 56 - if (IS_ERR(resource)) { 57 - dev_err(&pdev->dev, 58 - "fail to get platform memory resource (%ld)\n", 59 - PTR_ERR(resource)); 60 - return PTR_ERR(resource); 61 - } 62 - 63 56 sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource); 64 57 if (IS_ERR(sensor->mmio_base)) { 65 58 dev_err(&pdev->dev, "failed to ioremap memory (%ld)\n",
-29
include/linux/platform_data/db8500_thermal.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - /* 3 - * db8500_thermal.h - DB8500 Thermal Management Implementation 4 - * 5 - * Copyright (C) 2012 ST-Ericsson 6 - * Copyright (C) 2012 Linaro Ltd. 7 - * 8 - * Author: Hongbo Zhang <hongbo.zhang@linaro.com> 9 - */ 10 - 11 - #ifndef _DB8500_THERMAL_H_ 12 - #define _DB8500_THERMAL_H_ 13 - 14 - #include <linux/thermal.h> 15 - 16 - #define COOLING_DEV_MAX 8 17 - 18 - struct db8500_trip_point { 19 - unsigned long temp; 20 - enum thermal_trip_type type; 21 - char cdev_name[COOLING_DEV_MAX][THERMAL_NAME_LENGTH]; 22 - }; 23 - 24 - struct db8500_thsens_platform_data { 25 - struct db8500_trip_point trip_points[THERMAL_MAX_TRIPS]; 26 - int num_trips; 27 - }; 28 - 29 - #endif /* _DB8500_THERMAL_H_ */