0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010
0011 #include <linux/err.h>
0012 #include <linux/export.h>
0013 #include <linux/of_device.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/slab.h>
0016 #include <linux/thermal.h>
0017 #include <linux/types.h>
0018 #include <linux/string.h>
0019
0020 #include "thermal_core.h"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 struct __thermal_cooling_bind_param {
0032 struct device_node *cooling_device;
0033 unsigned long min;
0034 unsigned long max;
0035 };
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 struct __thermal_bind_params {
0046 struct __thermal_cooling_bind_param *tcbp;
0047 unsigned int count;
0048 unsigned int trip_id;
0049 unsigned int usage;
0050 };
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 struct __thermal_zone {
0067 int passive_delay;
0068 int polling_delay;
0069 int slope;
0070 int offset;
0071
0072
0073 int ntrips;
0074 struct thermal_trip *trips;
0075
0076
0077 int num_tbps;
0078 struct __thermal_bind_params *tbps;
0079
0080
0081 void *sensor_data;
0082 const struct thermal_zone_of_device_ops *ops;
0083 };
0084
0085
0086
0087 static int of_thermal_get_temp(struct thermal_zone_device *tz,
0088 int *temp)
0089 {
0090 struct __thermal_zone *data = tz->devdata;
0091
0092 if (!data->ops || !data->ops->get_temp)
0093 return -EINVAL;
0094
0095 return data->ops->get_temp(data->sensor_data, temp);
0096 }
0097
0098 static int of_thermal_set_trips(struct thermal_zone_device *tz,
0099 int low, int high)
0100 {
0101 struct __thermal_zone *data = tz->devdata;
0102
0103 if (!data->ops || !data->ops->set_trips)
0104 return -EINVAL;
0105
0106 return data->ops->set_trips(data->sensor_data, low, high);
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 int of_thermal_get_ntrips(struct thermal_zone_device *tz)
0120 {
0121 return tz->num_trips;
0122 }
0123 EXPORT_SYMBOL_GPL(of_thermal_get_ntrips);
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, int trip)
0136 {
0137 if (trip >= tz->num_trips || trip < 0)
0138 return false;
0139
0140 return true;
0141 }
0142 EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid);
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 const struct thermal_trip *
0155 of_thermal_get_trip_points(struct thermal_zone_device *tz)
0156 {
0157 return tz->trips;
0158 }
0159 EXPORT_SYMBOL_GPL(of_thermal_get_trip_points);
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172 static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
0173 int temp)
0174 {
0175 struct __thermal_zone *data = tz->devdata;
0176
0177 if (!data->ops || !data->ops->set_emul_temp)
0178 return -EINVAL;
0179
0180 return data->ops->set_emul_temp(data->sensor_data, temp);
0181 }
0182
0183 static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
0184 enum thermal_trend *trend)
0185 {
0186 struct __thermal_zone *data = tz->devdata;
0187
0188 if (!data->ops || !data->ops->get_trend)
0189 return -EINVAL;
0190
0191 return data->ops->get_trend(data->sensor_data, trip, trend);
0192 }
0193
0194 static int of_thermal_change_mode(struct thermal_zone_device *tz,
0195 enum thermal_device_mode mode)
0196 {
0197 struct __thermal_zone *data = tz->devdata;
0198
0199 return data->ops->change_mode(data->sensor_data, mode);
0200 }
0201
0202 static int of_thermal_bind(struct thermal_zone_device *thermal,
0203 struct thermal_cooling_device *cdev)
0204 {
0205 struct __thermal_zone *data = thermal->devdata;
0206 struct __thermal_bind_params *tbp;
0207 struct __thermal_cooling_bind_param *tcbp;
0208 int i, j;
0209
0210 if (!data || IS_ERR(data))
0211 return -ENODEV;
0212
0213
0214 for (i = 0; i < data->num_tbps; i++) {
0215 tbp = data->tbps + i;
0216
0217 for (j = 0; j < tbp->count; j++) {
0218 tcbp = tbp->tcbp + j;
0219
0220 if (tcbp->cooling_device == cdev->np) {
0221 int ret;
0222
0223 ret = thermal_zone_bind_cooling_device(thermal,
0224 tbp->trip_id, cdev,
0225 tcbp->max,
0226 tcbp->min,
0227 tbp->usage);
0228 if (ret)
0229 return ret;
0230 }
0231 }
0232 }
0233
0234 return 0;
0235 }
0236
0237 static int of_thermal_unbind(struct thermal_zone_device *thermal,
0238 struct thermal_cooling_device *cdev)
0239 {
0240 struct __thermal_zone *data = thermal->devdata;
0241 struct __thermal_bind_params *tbp;
0242 struct __thermal_cooling_bind_param *tcbp;
0243 int i, j;
0244
0245 if (!data || IS_ERR(data))
0246 return -ENODEV;
0247
0248
0249 for (i = 0; i < data->num_tbps; i++) {
0250 tbp = data->tbps + i;
0251
0252 for (j = 0; j < tbp->count; j++) {
0253 tcbp = tbp->tcbp + j;
0254
0255 if (tcbp->cooling_device == cdev->np) {
0256 int ret;
0257
0258 ret = thermal_zone_unbind_cooling_device(thermal,
0259 tbp->trip_id, cdev);
0260 if (ret)
0261 return ret;
0262 }
0263 }
0264 }
0265
0266 return 0;
0267 }
0268
0269 static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip,
0270 enum thermal_trip_type *type)
0271 {
0272 if (trip >= tz->num_trips || trip < 0)
0273 return -EDOM;
0274
0275 *type = tz->trips[trip].type;
0276
0277 return 0;
0278 }
0279
0280 static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip,
0281 int *temp)
0282 {
0283 if (trip >= tz->num_trips || trip < 0)
0284 return -EDOM;
0285
0286 *temp = tz->trips[trip].temperature;
0287
0288 return 0;
0289 }
0290
0291 static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip,
0292 int temp)
0293 {
0294 struct __thermal_zone *data = tz->devdata;
0295
0296 if (trip >= tz->num_trips || trip < 0)
0297 return -EDOM;
0298
0299 if (data->ops && data->ops->set_trip_temp) {
0300 int ret;
0301
0302 ret = data->ops->set_trip_temp(data->sensor_data, trip, temp);
0303 if (ret)
0304 return ret;
0305 }
0306
0307
0308 tz->trips[trip].temperature = temp;
0309
0310 return 0;
0311 }
0312
0313 static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip,
0314 int *hyst)
0315 {
0316 if (trip >= tz->num_trips || trip < 0)
0317 return -EDOM;
0318
0319 *hyst = tz->trips[trip].hysteresis;
0320
0321 return 0;
0322 }
0323
0324 static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip,
0325 int hyst)
0326 {
0327 if (trip >= tz->num_trips || trip < 0)
0328 return -EDOM;
0329
0330
0331 tz->trips[trip].hysteresis = hyst;
0332
0333 return 0;
0334 }
0335
0336 static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
0337 int *temp)
0338 {
0339 int i;
0340
0341 for (i = 0; i < tz->num_trips; i++)
0342 if (tz->trips[i].type == THERMAL_TRIP_CRITICAL) {
0343 *temp = tz->trips[i].temperature;
0344 return 0;
0345 }
0346
0347 return -EINVAL;
0348 }
0349
0350 static struct thermal_zone_device_ops of_thermal_ops = {
0351 .get_trip_type = of_thermal_get_trip_type,
0352 .get_trip_temp = of_thermal_get_trip_temp,
0353 .set_trip_temp = of_thermal_set_trip_temp,
0354 .get_trip_hyst = of_thermal_get_trip_hyst,
0355 .set_trip_hyst = of_thermal_set_trip_hyst,
0356 .get_crit_temp = of_thermal_get_crit_temp,
0357
0358 .bind = of_thermal_bind,
0359 .unbind = of_thermal_unbind,
0360 };
0361
0362
0363
0364 static struct thermal_zone_device *
0365 thermal_zone_of_add_sensor(struct device_node *zone,
0366 struct device_node *sensor, void *data,
0367 const struct thermal_zone_of_device_ops *ops)
0368 {
0369 struct thermal_zone_device *tzd;
0370 struct __thermal_zone *tz;
0371
0372 tzd = thermal_zone_get_zone_by_name(zone->name);
0373 if (IS_ERR(tzd))
0374 return ERR_PTR(-EPROBE_DEFER);
0375
0376 tz = tzd->devdata;
0377
0378 if (!ops)
0379 return ERR_PTR(-EINVAL);
0380
0381 mutex_lock(&tzd->lock);
0382 tz->ops = ops;
0383 tz->sensor_data = data;
0384
0385 tzd->ops->get_temp = of_thermal_get_temp;
0386 tzd->ops->get_trend = of_thermal_get_trend;
0387
0388
0389
0390
0391
0392 if (ops->set_trips)
0393 tzd->ops->set_trips = of_thermal_set_trips;
0394
0395 if (ops->set_emul_temp)
0396 tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
0397
0398 if (ops->change_mode)
0399 tzd->ops->change_mode = of_thermal_change_mode;
0400
0401 mutex_unlock(&tzd->lock);
0402
0403 return tzd;
0404 }
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 int thermal_zone_of_get_sensor_id(struct device_node *tz_np,
0419 struct device_node *sensor_np,
0420 u32 *id)
0421 {
0422 struct of_phandle_args sensor_specs;
0423 int ret;
0424
0425 ret = of_parse_phandle_with_args(tz_np,
0426 "thermal-sensors",
0427 "#thermal-sensor-cells",
0428 0,
0429 &sensor_specs);
0430 if (ret)
0431 return ret;
0432
0433 if (sensor_specs.np != sensor_np) {
0434 of_node_put(sensor_specs.np);
0435 return -ENODEV;
0436 }
0437
0438 if (sensor_specs.args_count > 1)
0439 pr_warn("%pOFn: too many cells in sensor specifier %d\n",
0440 sensor_specs.np, sensor_specs.args_count);
0441
0442 *id = sensor_specs.args_count ? sensor_specs.args[0] : 0;
0443
0444 of_node_put(sensor_specs.np);
0445
0446 return 0;
0447 }
0448 EXPORT_SYMBOL_GPL(thermal_zone_of_get_sensor_id);
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482 struct thermal_zone_device *
0483 thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data,
0484 const struct thermal_zone_of_device_ops *ops)
0485 {
0486 struct device_node *np, *child, *sensor_np;
0487 struct thermal_zone_device *tzd = ERR_PTR(-ENODEV);
0488
0489 np = of_find_node_by_name(NULL, "thermal-zones");
0490 if (!np)
0491 return ERR_PTR(-ENODEV);
0492
0493 if (!dev || !dev->of_node) {
0494 of_node_put(np);
0495 return ERR_PTR(-ENODEV);
0496 }
0497
0498 sensor_np = of_node_get(dev->of_node);
0499
0500 for_each_available_child_of_node(np, child) {
0501 int ret, id;
0502
0503
0504 ret = thermal_zone_of_get_sensor_id(child, sensor_np, &id);
0505 if (ret)
0506 continue;
0507
0508 if (id == sensor_id) {
0509 tzd = thermal_zone_of_add_sensor(child, sensor_np,
0510 data, ops);
0511 if (!IS_ERR(tzd))
0512 thermal_zone_device_enable(tzd);
0513
0514 of_node_put(child);
0515 goto exit;
0516 }
0517 }
0518 exit:
0519 of_node_put(sensor_np);
0520 of_node_put(np);
0521
0522 return tzd;
0523 }
0524 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_register);
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541 void thermal_zone_of_sensor_unregister(struct device *dev,
0542 struct thermal_zone_device *tzd)
0543 {
0544 struct __thermal_zone *tz;
0545
0546 if (!dev || !tzd || !tzd->devdata)
0547 return;
0548
0549 tz = tzd->devdata;
0550
0551
0552 if (!tz)
0553 return;
0554
0555
0556 thermal_zone_device_disable(tzd);
0557
0558 mutex_lock(&tzd->lock);
0559 tzd->ops->get_temp = NULL;
0560 tzd->ops->get_trend = NULL;
0561 tzd->ops->set_emul_temp = NULL;
0562 tzd->ops->change_mode = NULL;
0563
0564 tz->ops = NULL;
0565 tz->sensor_data = NULL;
0566 mutex_unlock(&tzd->lock);
0567 }
0568 EXPORT_SYMBOL_GPL(thermal_zone_of_sensor_unregister);
0569
0570 static void devm_thermal_zone_of_sensor_release(struct device *dev, void *res)
0571 {
0572 thermal_zone_of_sensor_unregister(dev,
0573 *(struct thermal_zone_device **)res);
0574 }
0575
0576 static int devm_thermal_zone_of_sensor_match(struct device *dev, void *res,
0577 void *data)
0578 {
0579 struct thermal_zone_device **r = res;
0580
0581 if (WARN_ON(!r || !*r))
0582 return 0;
0583
0584 return *r == data;
0585 }
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 struct thermal_zone_device *devm_thermal_zone_of_sensor_register(
0607 struct device *dev, int sensor_id,
0608 void *data, const struct thermal_zone_of_device_ops *ops)
0609 {
0610 struct thermal_zone_device **ptr, *tzd;
0611
0612 ptr = devres_alloc(devm_thermal_zone_of_sensor_release, sizeof(*ptr),
0613 GFP_KERNEL);
0614 if (!ptr)
0615 return ERR_PTR(-ENOMEM);
0616
0617 tzd = thermal_zone_of_sensor_register(dev, sensor_id, data, ops);
0618 if (IS_ERR(tzd)) {
0619 devres_free(ptr);
0620 return tzd;
0621 }
0622
0623 *ptr = tzd;
0624 devres_add(dev, ptr);
0625
0626 return tzd;
0627 }
0628 EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_register);
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643 void devm_thermal_zone_of_sensor_unregister(struct device *dev,
0644 struct thermal_zone_device *tzd)
0645 {
0646 WARN_ON(devres_release(dev, devm_thermal_zone_of_sensor_release,
0647 devm_thermal_zone_of_sensor_match, tzd));
0648 }
0649 EXPORT_SYMBOL_GPL(devm_thermal_zone_of_sensor_unregister);
0650
0651
0652
0653 static int of_find_trip_id(struct device_node *np, struct device_node *trip)
0654 {
0655 struct device_node *trips;
0656 struct device_node *t;
0657 int i = 0;
0658
0659 trips = of_get_child_by_name(np, "trips");
0660 if (!trips) {
0661 pr_err("Failed to find 'trips' node\n");
0662 return -EINVAL;
0663 }
0664
0665
0666
0667
0668 for_each_child_of_node(trips, t) {
0669
0670 if (t == trip)
0671 goto out;
0672 i++;
0673 }
0674
0675 i = -ENXIO;
0676 out:
0677 of_node_put(trips);
0678
0679 return i;
0680 }
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696 static int thermal_of_populate_bind_params(struct device_node *tz_np,
0697 struct device_node *np,
0698 struct __thermal_bind_params *__tbp)
0699 {
0700 struct of_phandle_args cooling_spec;
0701 struct __thermal_cooling_bind_param *__tcbp;
0702 struct device_node *trip;
0703 int ret, i, count;
0704 int trip_id;
0705 u32 prop;
0706
0707
0708 __tbp->usage = THERMAL_WEIGHT_DEFAULT;
0709 ret = of_property_read_u32(np, "contribution", &prop);
0710 if (ret == 0)
0711 __tbp->usage = prop;
0712
0713 trip = of_parse_phandle(np, "trip", 0);
0714 if (!trip) {
0715 pr_err("missing trip property\n");
0716 return -ENODEV;
0717 }
0718
0719 trip_id = of_find_trip_id(tz_np, trip);
0720 if (trip_id < 0) {
0721 ret = trip_id;
0722 goto end;
0723 }
0724
0725 __tbp->trip_id = trip_id;
0726
0727 count = of_count_phandle_with_args(np, "cooling-device",
0728 "#cooling-cells");
0729 if (count <= 0) {
0730 pr_err("Add a cooling_device property with at least one device\n");
0731 ret = -ENOENT;
0732 goto end;
0733 }
0734
0735 __tcbp = kcalloc(count, sizeof(*__tcbp), GFP_KERNEL);
0736 if (!__tcbp) {
0737 ret = -ENOMEM;
0738 goto end;
0739 }
0740
0741 for (i = 0; i < count; i++) {
0742 ret = of_parse_phandle_with_args(np, "cooling-device",
0743 "#cooling-cells", i, &cooling_spec);
0744 if (ret < 0) {
0745 pr_err("Invalid cooling-device entry\n");
0746 goto free_tcbp;
0747 }
0748
0749 __tcbp[i].cooling_device = cooling_spec.np;
0750
0751 if (cooling_spec.args_count >= 2) {
0752 __tcbp[i].min = cooling_spec.args[0];
0753 __tcbp[i].max = cooling_spec.args[1];
0754 } else {
0755 pr_err("wrong reference to cooling device, missing limits\n");
0756 }
0757 }
0758
0759 __tbp->tcbp = __tcbp;
0760 __tbp->count = count;
0761
0762 goto end;
0763
0764 free_tcbp:
0765 for (i = i - 1; i >= 0; i--)
0766 of_node_put(__tcbp[i].cooling_device);
0767 kfree(__tcbp);
0768 end:
0769 of_node_put(trip);
0770
0771 return ret;
0772 }
0773
0774
0775
0776
0777
0778 static const char * const trip_types[] = {
0779 [THERMAL_TRIP_ACTIVE] = "active",
0780 [THERMAL_TRIP_PASSIVE] = "passive",
0781 [THERMAL_TRIP_HOT] = "hot",
0782 [THERMAL_TRIP_CRITICAL] = "critical",
0783 };
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795 static int thermal_of_get_trip_type(struct device_node *np,
0796 enum thermal_trip_type *type)
0797 {
0798 const char *t;
0799 int err, i;
0800
0801 err = of_property_read_string(np, "type", &t);
0802 if (err < 0)
0803 return err;
0804
0805 for (i = 0; i < ARRAY_SIZE(trip_types); i++)
0806 if (!strcasecmp(t, trip_types[i])) {
0807 *type = i;
0808 return 0;
0809 }
0810
0811 return -ENODEV;
0812 }
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824 static int thermal_of_populate_trip(struct device_node *np,
0825 struct thermal_trip *trip)
0826 {
0827 int prop;
0828 int ret;
0829
0830 ret = of_property_read_u32(np, "temperature", &prop);
0831 if (ret < 0) {
0832 pr_err("missing temperature property\n");
0833 return ret;
0834 }
0835 trip->temperature = prop;
0836
0837 ret = of_property_read_u32(np, "hysteresis", &prop);
0838 if (ret < 0) {
0839 pr_err("missing hysteresis property\n");
0840 return ret;
0841 }
0842 trip->hysteresis = prop;
0843
0844 ret = thermal_of_get_trip_type(np, &trip->type);
0845 if (ret < 0) {
0846 pr_err("wrong trip type property\n");
0847 return ret;
0848 }
0849
0850 return 0;
0851 }
0852
0853 static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *ntrips)
0854 {
0855 struct thermal_trip *tt;
0856 struct device_node *trips, *trip;
0857 int ret, count;
0858
0859 trips = of_get_child_by_name(np, "trips");
0860 if (!trips) {
0861 pr_err("Failed to find 'trips' node\n");
0862 return ERR_PTR(-EINVAL);
0863 }
0864
0865 count = of_get_child_count(trips);
0866 if (!count) {
0867 pr_err("No trip point defined\n");
0868 ret = -EINVAL;
0869 goto out_of_node_put;
0870 }
0871
0872 tt = kzalloc(sizeof(*tt) * count, GFP_KERNEL);
0873 if (!tt) {
0874 ret = -ENOMEM;
0875 goto out_of_node_put;
0876 }
0877
0878 *ntrips = count;
0879
0880 count = 0;
0881 for_each_child_of_node(trips, trip) {
0882 ret = thermal_of_populate_trip(trip, &tt[count++]);
0883 if (ret)
0884 goto out_kfree;
0885 }
0886
0887 of_node_put(trips);
0888
0889 return tt;
0890
0891 out_kfree:
0892 kfree(tt);
0893 *ntrips = 0;
0894 out_of_node_put:
0895 of_node_put(trips);
0896
0897 return ERR_PTR(ret);
0898 }
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 static struct __thermal_zone
0915 __init *thermal_of_build_thermal_zone(struct device_node *np)
0916 {
0917 struct device_node *child = NULL, *gchild;
0918 struct __thermal_zone *tz;
0919 int ret, i;
0920 u32 prop, coef[2];
0921
0922 if (!np) {
0923 pr_err("no thermal zone np\n");
0924 return ERR_PTR(-EINVAL);
0925 }
0926
0927 tz = kzalloc(sizeof(*tz), GFP_KERNEL);
0928 if (!tz)
0929 return ERR_PTR(-ENOMEM);
0930
0931 ret = of_property_read_u32(np, "polling-delay-passive", &prop);
0932 if (ret < 0) {
0933 pr_err("%pOFn: missing polling-delay-passive property\n", np);
0934 goto free_tz;
0935 }
0936 tz->passive_delay = prop;
0937
0938 ret = of_property_read_u32(np, "polling-delay", &prop);
0939 if (ret < 0) {
0940 pr_err("%pOFn: missing polling-delay property\n", np);
0941 goto free_tz;
0942 }
0943 tz->polling_delay = prop;
0944
0945
0946
0947
0948
0949
0950 ret = of_property_read_u32_array(np, "coefficients", coef, 2);
0951 if (ret == 0) {
0952 tz->slope = coef[0];
0953 tz->offset = coef[1];
0954 } else {
0955 tz->slope = 1;
0956 tz->offset = 0;
0957 }
0958
0959 tz->trips = thermal_of_trips_init(np, &tz->ntrips);
0960 if (IS_ERR(tz->trips)) {
0961 ret = PTR_ERR(tz->trips);
0962 goto finish;
0963 }
0964
0965
0966 child = of_get_child_by_name(np, "cooling-maps");
0967
0968
0969 if (!child)
0970 goto finish;
0971
0972 tz->num_tbps = of_get_child_count(child);
0973 if (tz->num_tbps == 0)
0974 goto finish;
0975
0976 tz->tbps = kcalloc(tz->num_tbps, sizeof(*tz->tbps), GFP_KERNEL);
0977 if (!tz->tbps) {
0978 ret = -ENOMEM;
0979 goto free_trips;
0980 }
0981
0982 i = 0;
0983 for_each_child_of_node(child, gchild) {
0984 ret = thermal_of_populate_bind_params(np, gchild, &tz->tbps[i++]);
0985 if (ret) {
0986 of_node_put(gchild);
0987 goto free_tbps;
0988 }
0989 }
0990
0991 finish:
0992 of_node_put(child);
0993
0994 return tz;
0995
0996 free_tbps:
0997 for (i = i - 1; i >= 0; i--) {
0998 struct __thermal_bind_params *tbp = tz->tbps + i;
0999 int j;
1000
1001 for (j = 0; j < tbp->count; j++)
1002 of_node_put(tbp->tcbp[j].cooling_device);
1003
1004 kfree(tbp->tcbp);
1005 }
1006
1007 kfree(tz->tbps);
1008 free_trips:
1009 kfree(tz->trips);
1010 free_tz:
1011 kfree(tz);
1012 of_node_put(child);
1013
1014 return ERR_PTR(ret);
1015 }
1016
1017 static __init void of_thermal_free_zone(struct __thermal_zone *tz)
1018 {
1019 struct __thermal_bind_params *tbp;
1020 int i, j;
1021
1022 for (i = 0; i < tz->num_tbps; i++) {
1023 tbp = tz->tbps + i;
1024
1025 for (j = 0; j < tbp->count; j++)
1026 of_node_put(tbp->tcbp[j].cooling_device);
1027
1028 kfree(tbp->tcbp);
1029 }
1030
1031 kfree(tz->tbps);
1032 kfree(tz->trips);
1033 kfree(tz);
1034 }
1035
1036
1037
1038
1039
1040
1041
1042
1043 static __init void of_thermal_destroy_zones(void)
1044 {
1045 struct device_node *np, *child;
1046
1047 np = of_find_node_by_name(NULL, "thermal-zones");
1048 if (!np) {
1049 pr_debug("unable to find thermal zones\n");
1050 return;
1051 }
1052
1053 for_each_available_child_of_node(np, child) {
1054 struct thermal_zone_device *zone;
1055
1056 zone = thermal_zone_get_zone_by_name(child->name);
1057 if (IS_ERR(zone))
1058 continue;
1059
1060 thermal_zone_device_unregister(zone);
1061 kfree(zone->tzp);
1062 kfree(zone->ops);
1063 of_thermal_free_zone(zone->devdata);
1064 }
1065 of_node_put(np);
1066 }
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080 int __init of_parse_thermal_zones(void)
1081 {
1082 struct device_node *np, *child;
1083 struct __thermal_zone *tz;
1084 struct thermal_zone_device_ops *ops;
1085
1086 np = of_find_node_by_name(NULL, "thermal-zones");
1087 if (!np) {
1088 pr_debug("unable to find thermal zones\n");
1089 return 0;
1090 }
1091
1092 for_each_available_child_of_node(np, child) {
1093 struct thermal_zone_device *zone;
1094 struct thermal_zone_params *tzp;
1095 int i, mask = 0;
1096 u32 prop;
1097
1098 tz = thermal_of_build_thermal_zone(child);
1099 if (IS_ERR(tz)) {
1100 pr_err("failed to build thermal zone %pOFn: %ld\n",
1101 child,
1102 PTR_ERR(tz));
1103 continue;
1104 }
1105
1106 ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL);
1107 if (!ops)
1108 goto exit_free;
1109
1110 tzp = kzalloc(sizeof(*tzp), GFP_KERNEL);
1111 if (!tzp) {
1112 kfree(ops);
1113 goto exit_free;
1114 }
1115
1116
1117 tzp->no_hwmon = true;
1118
1119 if (!of_property_read_u32(child, "sustainable-power", &prop))
1120 tzp->sustainable_power = prop;
1121
1122 for (i = 0; i < tz->ntrips; i++)
1123 mask |= 1 << i;
1124
1125
1126 tzp->slope = tz->slope;
1127 tzp->offset = tz->offset;
1128
1129 zone = thermal_zone_device_register_with_trips(child->name, tz->trips, tz->ntrips,
1130 mask, tz, ops, tzp, tz->passive_delay,
1131 tz->polling_delay);
1132 if (IS_ERR(zone)) {
1133 pr_err("Failed to build %pOFn zone %ld\n", child,
1134 PTR_ERR(zone));
1135 kfree(tzp);
1136 kfree(ops);
1137 of_thermal_free_zone(tz);
1138
1139 }
1140 }
1141 of_node_put(np);
1142
1143 return 0;
1144
1145 exit_free:
1146 of_node_put(child);
1147 of_node_put(np);
1148 of_thermal_free_zone(tz);
1149
1150
1151 of_thermal_destroy_zones();
1152
1153 return -ENOMEM;
1154 }