diff options
Diffstat (limited to 'drivers/thermal/of-thermal.c')
-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 | } |