diff options
| -rw-r--r-- | drivers/thermal/of-thermal.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index f8eb625b8400..62143ba31001 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c | |||
| @@ -387,15 +387,18 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, | |||
| 387 | int (*get_trend)(void *, long *)) | 387 | int (*get_trend)(void *, long *)) |
| 388 | { | 388 | { |
| 389 | struct device_node *np, *child, *sensor_np; | 389 | struct device_node *np, *child, *sensor_np; |
| 390 | struct thermal_zone_device *tzd = ERR_PTR(-ENODEV); | ||
| 390 | 391 | ||
| 391 | np = of_find_node_by_name(NULL, "thermal-zones"); | 392 | np = of_find_node_by_name(NULL, "thermal-zones"); |
| 392 | if (!np) | 393 | if (!np) |
| 393 | return ERR_PTR(-ENODEV); | 394 | return ERR_PTR(-ENODEV); |
| 394 | 395 | ||
| 395 | if (!dev || !dev->of_node) | 396 | if (!dev || !dev->of_node) { |
| 397 | of_node_put(np); | ||
| 396 | return ERR_PTR(-EINVAL); | 398 | return ERR_PTR(-EINVAL); |
| 399 | } | ||
| 397 | 400 | ||
| 398 | sensor_np = dev->of_node; | 401 | sensor_np = of_node_get(dev->of_node); |
| 399 | 402 | ||
| 400 | for_each_child_of_node(np, child) { | 403 | for_each_child_of_node(np, child) { |
| 401 | struct of_phandle_args sensor_specs; | 404 | struct of_phandle_args sensor_specs; |
| @@ -422,16 +425,21 @@ thermal_zone_of_sensor_register(struct device *dev, int sensor_id, | |||
| 422 | } | 425 | } |
| 423 | 426 | ||
| 424 | if (sensor_specs.np == sensor_np && id == sensor_id) { | 427 | if (sensor_specs.np == sensor_np && id == sensor_id) { |
| 425 | of_node_put(np); | 428 | tzd = thermal_zone_of_add_sensor(child, sensor_np, |
| 426 | return thermal_zone_of_add_sensor(child, sensor_np, | 429 | data, |
| 427 | data, | 430 | get_temp, |
| 428 | get_temp, | 431 | get_trend); |
| 429 | get_trend); | 432 | of_node_put(sensor_specs.np); |
| 433 | of_node_put(child); | ||
| 434 | goto exit; | ||
| 430 | } | 435 | } |
| 436 | of_node_put(sensor_specs.np); | ||
| 431 | } | 437 | } |
| 438 | exit: | ||
| 439 | of_node_put(sensor_np); | ||
| 432 | of_node_put(np); | 440 | of_node_put(np); |
| 433 | 441 | ||
| 434 | return ERR_PTR(-ENODEV); | 442 | return tzd; |
| 435 | } | 443 | } |
| 436 | EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register); | 444 | EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register); |
| 437 | 445 | ||
| @@ -623,6 +631,7 @@ static int thermal_of_populate_trip(struct device_node *np, | |||
| 623 | 631 | ||
| 624 | /* Required for cooling map matching */ | 632 | /* Required for cooling map matching */ |
| 625 | trip->np = np; | 633 | trip->np = np; |
| 634 | of_node_get(np); | ||
| 626 | 635 | ||
| 627 | return 0; | 636 | return 0; |
| 628 | } | 637 | } |
| @@ -730,9 +739,14 @@ finish: | |||
| 730 | return tz; | 739 | return tz; |
| 731 | 740 | ||
| 732 | free_tbps: | 741 | free_tbps: |
| 742 | for (i = 0; i < tz->num_tbps; i++) | ||
| 743 | of_node_put(tz->tbps[i].cooling_device); | ||
| 733 | kfree(tz->tbps); | 744 | kfree(tz->tbps); |
| 734 | free_trips: | 745 | free_trips: |
| 746 | for (i = 0; i < tz->ntrips; i++) | ||
| 747 | of_node_put(tz->trips[i].np); | ||
| 735 | kfree(tz->trips); | 748 | kfree(tz->trips); |
| 749 | of_node_put(gchild); | ||
| 736 | free_tz: | 750 | free_tz: |
| 737 | kfree(tz); | 751 | kfree(tz); |
| 738 | of_node_put(child); | 752 | of_node_put(child); |
| @@ -742,7 +756,13 @@ free_tz: | |||
| 742 | 756 | ||
| 743 | static inline void of_thermal_free_zone(struct __thermal_zone *tz) | 757 | static inline void of_thermal_free_zone(struct __thermal_zone *tz) |
| 744 | { | 758 | { |
| 759 | int i; | ||
| 760 | |||
| 761 | for (i = 0; i < tz->num_tbps; i++) | ||
| 762 | of_node_put(tz->tbps[i].cooling_device); | ||
| 745 | kfree(tz->tbps); | 763 | kfree(tz->tbps); |
| 764 | for (i = 0; i < tz->ntrips; i++) | ||
| 765 | of_node_put(tz->trips[i].np); | ||
| 746 | kfree(tz->trips); | 766 | kfree(tz->trips); |
| 747 | kfree(tz); | 767 | kfree(tz); |
| 748 | } | 768 | } |
| @@ -814,10 +834,13 @@ int __init of_parse_thermal_zones(void) | |||
| 814 | /* attempting to build remaining zones still */ | 834 | /* attempting to build remaining zones still */ |
| 815 | } | 835 | } |
| 816 | } | 836 | } |
| 837 | of_node_put(np); | ||
| 817 | 838 | ||
| 818 | return 0; | 839 | return 0; |
| 819 | 840 | ||
| 820 | exit_free: | 841 | exit_free: |
| 842 | of_node_put(child); | ||
| 843 | of_node_put(np); | ||
| 821 | of_thermal_free_zone(tz); | 844 | of_thermal_free_zone(tz); |
| 822 | 845 | ||
| 823 | /* no memory available, so free what we have built */ | 846 | /* no memory available, so free what we have built */ |
| @@ -859,4 +882,5 @@ void of_thermal_destroy_zones(void) | |||
| 859 | kfree(zone->ops); | 882 | kfree(zone->ops); |
| 860 | of_thermal_free_zone(zone->devdata); | 883 | of_thermal_free_zone(zone->devdata); |
| 861 | } | 884 | } |
| 885 | of_node_put(np); | ||
| 862 | } | 886 | } |
