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 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux

Pull thermal management fixes from Zhang Rui:

- fix a regression that thermal zone dynamically allocated sysfs
attributes are freed before they're removed, which is introduced in
4.10-rc1 (Jacob von Chorus)

- fix a boot warning because deprecated hwmon API is used (Fabio
Estevam)

- a couple of fixes for rockchip thermal driver (Brian Norris, Caesar
Wang)

* 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux:
thermal: rockchip: fixes the conversion table
thermal: core: move tz->device.groups cleanup to thermal_release
thermal: thermal_hwmon: Convert to hwmon_device_register_with_info()
thermal: rockchip: handle set_trips without the trip points
thermal: rockchip: optimize the conversion table
thermal: rockchip: fixes invalid temperature case
thermal: rockchip: don't pass table structs by value
thermal: rockchip: improve conversion error messages

+108 -75
+100 -53
drivers/thermal/rockchip_thermal.c
··· 118 118 void (*control)(void __iomem *reg, bool on); 119 119 120 120 /* Per-sensor methods */ 121 - int (*get_temp)(struct chip_tsadc_table table, 121 + int (*get_temp)(const struct chip_tsadc_table *table, 122 122 int chn, void __iomem *reg, int *temp); 123 - void (*set_alarm_temp)(struct chip_tsadc_table table, 124 - int chn, void __iomem *reg, int temp); 125 - void (*set_tshut_temp)(struct chip_tsadc_table table, 126 - int chn, void __iomem *reg, int temp); 123 + int (*set_alarm_temp)(const struct chip_tsadc_table *table, 124 + int chn, void __iomem *reg, int temp); 125 + int (*set_tshut_temp)(const struct chip_tsadc_table *table, 126 + int chn, void __iomem *reg, int temp); 127 127 void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m); 128 128 129 129 /* Per-table methods */ ··· 317 317 {3452, 115000}, 318 318 {3437, 120000}, 319 319 {3421, 125000}, 320 + {0, 125000}, 320 321 }; 321 322 322 323 static const struct tsadc_table rk3368_code_table[] = { ··· 398 397 {TSADCV3_DATA_MASK, 125000}, 399 398 }; 400 399 401 - static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, 400 + static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table, 402 401 int temp) 403 402 { 404 403 int high, low, mid; 405 - u32 error = 0; 404 + unsigned long num; 405 + unsigned int denom; 406 + u32 error = table->data_mask; 406 407 407 408 low = 0; 408 - high = table.length - 1; 409 + high = (table->length - 1) - 1; /* ignore the last check for table */ 409 410 mid = (high + low) / 2; 410 411 411 412 /* Return mask code data when the temp is over table range */ 412 - if (temp < table.id[low].temp || temp > table.id[high].temp) { 413 - error = table.data_mask; 413 + if (temp < table->id[low].temp || temp > table->id[high].temp) 414 414 goto exit; 415 - } 416 415 417 416 while (low <= high) { 418 - if (temp == table.id[mid].temp) 419 - return table.id[mid].code; 420 - else if (temp < table.id[mid].temp) 417 + if (temp == table->id[mid].temp) 418 + return table->id[mid].code; 419 + else if (temp < table->id[mid].temp) 421 420 high = mid - 1; 422 421 else 423 422 low = mid + 1; 424 423 mid = (low + high) / 2; 425 424 } 426 425 426 + /* 427 + * The conversion code granularity provided by the table. Let's 428 + * assume that the relationship between temperature and 429 + * analog value between 2 table entries is linear and interpolate 430 + * to produce less granular result. 431 + */ 432 + num = abs(table->id[mid + 1].code - table->id[mid].code); 433 + num *= temp - table->id[mid].temp; 434 + denom = table->id[mid + 1].temp - table->id[mid].temp; 435 + 436 + switch (table->mode) { 437 + case ADC_DECREMENT: 438 + return table->id[mid].code - (num / denom); 439 + case ADC_INCREMENT: 440 + return table->id[mid].code + (num / denom); 441 + default: 442 + pr_err("%s: unknown table mode: %d\n", __func__, table->mode); 443 + return error; 444 + } 445 + 427 446 exit: 428 - pr_err("Invalid the conversion, error=%d\n", error); 447 + pr_err("%s: invalid temperature, temp=%d error=%d\n", 448 + __func__, temp, error); 429 449 return error; 430 450 } 431 451 432 - static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, 433 - int *temp) 452 + static int rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table, 453 + u32 code, int *temp) 434 454 { 435 455 unsigned int low = 1; 436 - unsigned int high = table.length - 1; 456 + unsigned int high = table->length - 1; 437 457 unsigned int mid = (low + high) / 2; 438 458 unsigned int num; 439 459 unsigned long denom; 440 460 441 - WARN_ON(table.length < 2); 461 + WARN_ON(table->length < 2); 442 462 443 - switch (table.mode) { 463 + switch (table->mode) { 444 464 case ADC_DECREMENT: 445 - code &= table.data_mask; 446 - if (code < table.id[high].code) 465 + code &= table->data_mask; 466 + if (code <= table->id[high].code) 447 467 return -EAGAIN; /* Incorrect reading */ 448 468 449 469 while (low <= high) { 450 - if (code >= table.id[mid].code && 451 - code < table.id[mid - 1].code) 470 + if (code >= table->id[mid].code && 471 + code < table->id[mid - 1].code) 452 472 break; 453 - else if (code < table.id[mid].code) 473 + else if (code < table->id[mid].code) 454 474 low = mid + 1; 455 475 else 456 476 high = mid - 1; ··· 480 458 } 481 459 break; 482 460 case ADC_INCREMENT: 483 - code &= table.data_mask; 484 - if (code < table.id[low].code) 461 + code &= table->data_mask; 462 + if (code < table->id[low].code) 485 463 return -EAGAIN; /* Incorrect reading */ 486 464 487 465 while (low <= high) { 488 - if (code <= table.id[mid].code && 489 - code > table.id[mid - 1].code) 466 + if (code <= table->id[mid].code && 467 + code > table->id[mid - 1].code) 490 468 break; 491 - else if (code > table.id[mid].code) 469 + else if (code > table->id[mid].code) 492 470 low = mid + 1; 493 471 else 494 472 high = mid - 1; ··· 497 475 } 498 476 break; 499 477 default: 500 - pr_err("Invalid the conversion table\n"); 478 + pr_err("%s: unknown table mode: %d\n", __func__, table->mode); 479 + return -EINVAL; 501 480 } 502 481 503 482 /* ··· 507 484 * temperature between 2 table entries is linear and interpolate 508 485 * to produce less granular result. 509 486 */ 510 - num = table.id[mid].temp - table.id[mid - 1].temp; 511 - num *= abs(table.id[mid - 1].code - code); 512 - denom = abs(table.id[mid - 1].code - table.id[mid].code); 513 - *temp = table.id[mid - 1].temp + (num / denom); 487 + num = table->id[mid].temp - table->id[mid - 1].temp; 488 + num *= abs(table->id[mid - 1].code - code); 489 + denom = abs(table->id[mid - 1].code - table->id[mid].code); 490 + *temp = table->id[mid - 1].temp + (num / denom); 514 491 515 492 return 0; 516 493 } ··· 661 638 writel_relaxed(val, regs + TSADCV2_AUTO_CON); 662 639 } 663 640 664 - static int rk_tsadcv2_get_temp(struct chip_tsadc_table table, 641 + static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table, 665 642 int chn, void __iomem *regs, int *temp) 666 643 { 667 644 u32 val; ··· 671 648 return rk_tsadcv2_code_to_temp(table, val, temp); 672 649 } 673 650 674 - static void rk_tsadcv2_alarm_temp(struct chip_tsadc_table table, 675 - int chn, void __iomem *regs, int temp) 651 + static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table, 652 + int chn, void __iomem *regs, int temp) 676 653 { 677 - u32 alarm_value, int_en; 654 + u32 alarm_value; 655 + u32 int_en, int_clr; 656 + 657 + /* 658 + * In some cases, some sensors didn't need the trip points, the 659 + * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm 660 + * in the end, ignore this case and disable the high temperature 661 + * interrupt. 662 + */ 663 + if (temp == INT_MAX) { 664 + int_clr = readl_relaxed(regs + TSADCV2_INT_EN); 665 + int_clr &= ~TSADCV2_INT_SRC_EN(chn); 666 + writel_relaxed(int_clr, regs + TSADCV2_INT_EN); 667 + return 0; 668 + } 678 669 679 670 /* Make sure the value is valid */ 680 671 alarm_value = rk_tsadcv2_temp_to_code(table, temp); 681 - if (alarm_value == table.data_mask) 682 - return; 672 + if (alarm_value == table->data_mask) 673 + return -ERANGE; 683 674 684 - writel_relaxed(alarm_value & table.data_mask, 675 + writel_relaxed(alarm_value & table->data_mask, 685 676 regs + TSADCV2_COMP_INT(chn)); 686 677 687 678 int_en = readl_relaxed(regs + TSADCV2_INT_EN); 688 679 int_en |= TSADCV2_INT_SRC_EN(chn); 689 680 writel_relaxed(int_en, regs + TSADCV2_INT_EN); 681 + 682 + return 0; 690 683 } 691 684 692 - static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table, 693 - int chn, void __iomem *regs, int temp) 685 + static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table, 686 + int chn, void __iomem *regs, int temp) 694 687 { 695 688 u32 tshut_value, val; 696 689 697 690 /* Make sure the value is valid */ 698 691 tshut_value = rk_tsadcv2_temp_to_code(table, temp); 699 - if (tshut_value == table.data_mask) 700 - return; 692 + if (tshut_value == table->data_mask) 693 + return -ERANGE; 701 694 702 695 writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); 703 696 704 697 /* TSHUT will be valid */ 705 698 val = readl_relaxed(regs + TSADCV2_AUTO_CON); 706 699 writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON); 700 + 701 + return 0; 707 702 } 708 703 709 704 static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, ··· 924 883 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n", 925 884 __func__, sensor->id, low, high); 926 885 927 - tsadc->set_alarm_temp(tsadc->table, 928 - sensor->id, thermal->regs, high); 929 - 930 - return 0; 886 + return tsadc->set_alarm_temp(&tsadc->table, 887 + sensor->id, thermal->regs, high); 931 888 } 932 889 933 890 static int rockchip_thermal_get_temp(void *_sensor, int *out_temp) ··· 935 896 const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; 936 897 int retval; 937 898 938 - retval = tsadc->get_temp(tsadc->table, 899 + retval = tsadc->get_temp(&tsadc->table, 939 900 sensor->id, thermal->regs, out_temp); 940 901 dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n", 941 902 sensor->id, *out_temp, retval); ··· 1021 982 int error; 1022 983 1023 984 tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); 1024 - tsadc->set_tshut_temp(tsadc->table, id, thermal->regs, 985 + 986 + error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs, 1025 987 thermal->tshut_temp); 988 + if (error) 989 + dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n", 990 + __func__, thermal->tshut_temp, error); 1026 991 1027 992 sensor->thermal = thermal; 1028 993 sensor->id = id; ··· 1239 1196 1240 1197 thermal->chip->set_tshut_mode(id, thermal->regs, 1241 1198 thermal->tshut_mode); 1242 - thermal->chip->set_tshut_temp(thermal->chip->table, 1199 + 1200 + error = thermal->chip->set_tshut_temp(&thermal->chip->table, 1243 1201 id, thermal->regs, 1244 1202 thermal->tshut_temp); 1203 + if (error) 1204 + dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n", 1205 + __func__, thermal->tshut_temp, error); 1245 1206 } 1246 1207 1247 1208 thermal->chip->control(thermal->regs, true);
+5 -5
drivers/thermal/thermal_core.c
··· 799 799 if (!strncmp(dev_name(dev), "thermal_zone", 800 800 sizeof("thermal_zone") - 1)) { 801 801 tz = to_thermal_zone(dev); 802 + kfree(tz->trip_type_attrs); 803 + kfree(tz->trip_temp_attrs); 804 + kfree(tz->trip_hyst_attrs); 805 + kfree(tz->trips_attribute_group.attrs); 806 + kfree(tz->device.groups); 802 807 kfree(tz); 803 808 } else if (!strncmp(dev_name(dev), "cooling_device", 804 809 sizeof("cooling_device") - 1)) { ··· 1310 1305 1311 1306 thermal_zone_device_set_polling(tz, 0); 1312 1307 1313 - kfree(tz->trip_type_attrs); 1314 - kfree(tz->trip_temp_attrs); 1315 - kfree(tz->trip_hyst_attrs); 1316 - kfree(tz->trips_attribute_group.attrs); 1317 1308 thermal_set_governor(tz, NULL); 1318 1309 1319 1310 thermal_remove_hwmon_sysfs(tz); ··· 1317 1316 idr_destroy(&tz->idr); 1318 1317 mutex_destroy(&tz->lock); 1319 1318 device_unregister(&tz->device); 1320 - kfree(tz->device.groups); 1321 1319 } 1322 1320 EXPORT_SYMBOL_GPL(thermal_zone_device_unregister); 1323 1321
+3 -17
drivers/thermal/thermal_hwmon.c
··· 59 59 static DEFINE_MUTEX(thermal_hwmon_list_lock); 60 60 61 61 static ssize_t 62 - name_show(struct device *dev, struct device_attribute *attr, char *buf) 63 - { 64 - struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev); 65 - return sprintf(buf, "%s\n", hwmon->type); 66 - } 67 - static DEVICE_ATTR_RO(name); 68 - 69 - static ssize_t 70 62 temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) 71 63 { 72 64 int temperature; ··· 157 165 158 166 INIT_LIST_HEAD(&hwmon->tz_list); 159 167 strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH); 160 - hwmon->device = hwmon_device_register(NULL); 168 + hwmon->device = hwmon_device_register_with_info(NULL, hwmon->type, 169 + hwmon, NULL, NULL); 161 170 if (IS_ERR(hwmon->device)) { 162 171 result = PTR_ERR(hwmon->device); 163 172 goto free_mem; 164 173 } 165 - dev_set_drvdata(hwmon->device, hwmon); 166 - result = device_create_file(hwmon->device, &dev_attr_name); 167 - if (result) 168 - goto free_mem; 169 174 170 175 register_sys_interface: 171 176 temp = kzalloc(sizeof(*temp), GFP_KERNEL); ··· 211 222 free_temp_mem: 212 223 kfree(temp); 213 224 unregister_name: 214 - if (new_hwmon_device) { 215 - device_remove_file(hwmon->device, &dev_attr_name); 225 + if (new_hwmon_device) 216 226 hwmon_device_unregister(hwmon->device); 217 - } 218 227 free_mem: 219 228 if (new_hwmon_device) 220 229 kfree(hwmon); ··· 254 267 list_del(&hwmon->node); 255 268 mutex_unlock(&thermal_hwmon_list_lock); 256 269 257 - device_remove_file(hwmon->device, &dev_attr_name); 258 270 hwmon_device_unregister(hwmon->device); 259 271 kfree(hwmon); 260 272 }