History

Merge tag 'for-v3.18-rc' of git://git.infradead.org/battery-2.6

Pull power supply updates from Sebastian Reichel: "Power supply and reset changes for the v3.18-rc: - misc. charger-manager fixes - year 2038 fix in ab8500_fg - fix error handling of bq2415x_charger" * tag 'for-v3.18-rc' of git://git.infradead.org/battery-2.6: power: charger-manager: Fix accessing invalidated power supply after charger unbind power: charger-manager: Fix accessing invalidated power supply after fuel gauge unbind power: charger-manager: Avoid recursive thermal get_temp call power_supply: Add no_thermal property to prevent recursive get_temp calls power: bq2415x_charger: Fix memory leak on DTS parsing error power: bq2415x_charger: Properly handle ENODEV from power_supply_get_by_phandle power: ab8500_fg.c: use 64-bit time types

Linus Torvalds committed 11 years ago

Commit ec7de652 parents e061167 cdaf3e16 files · +144 −72Browse files

Unified · Split

6 files
  1. drivers/power/ab8500_fg.c +9 −8
  2. drivers/power/bq2415x_charger.c +15 −8
  3. drivers/power/charger-manager.c +111 −53
  4. drivers/power/power_supply_core.c +3 −0
  5. include/linux/power/charger-manager.h +0 −3
  6. include/linux/power_supply.h +6 −0
drivers/power/ab8500_fg.c+9−8
@@ -25,6 +25,7 @@ · 24 unmodified lines
25#include <linux/slab.h>25#include <linux/slab.h>
26#include <linux/delay.h>26#include <linux/delay.h>
27#include <linux/time.h>27#include <linux/time.h>
28#include <linux/time64.h>
28#include <linux/of.h>29#include <linux/of.h>
29#include <linux/completion.h>30#include <linux/completion.h>
30#include <linux/mfd/core.h>31#include <linux/mfd/core.h>
@@ -108,7 +109,7 @@ enum ab8500_fg_calibration_state { · 77 unmodified lines
108struct ab8500_fg_avg_cap {109struct ab8500_fg_avg_cap {
109 int avg;110 int avg;
110 int samples[NBR_AVG_SAMPLES];111 int samples[NBR_AVG_SAMPLES];
111 __kernel_time_t time_stamps[NBR_AVG_SAMPLES];112 time64_t time_stamps[NBR_AVG_SAMPLES];
112 int pos;113 int pos;
113 int nbr_samples;114 int nbr_samples;
114 int sum;115 int sum;
@@ -386,15 +387,15 @@ static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr) · 271 unmodified lines
386 */387 */
387static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)388static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample)
388{389{
389 struct timespec ts;390 struct timespec64 ts64;
390 struct ab8500_fg_avg_cap *avg = &di->avg_cap;391 struct ab8500_fg_avg_cap *avg = &di->avg_cap;
391 392
392 getnstimeofday(&ts);393 getnstimeofday64(&ts64);
393 394
394 do {395 do {
395 avg->sum += sample - avg->samples[avg->pos];396 avg->sum += sample - avg->samples[avg->pos];
396 avg->samples[avg->pos] = sample;397 avg->samples[avg->pos] = sample;
397 avg->time_stamps[avg->pos] = ts.tv_sec;398 avg->time_stamps[avg->pos] = ts64.tv_sec;
398 avg->pos++;399 avg->pos++;
399 400
400 if (avg->pos == NBR_AVG_SAMPLES)401 if (avg->pos == NBR_AVG_SAMPLES)
@@ -407,7 +408,7 @@ static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample) · 6 unmodified lines
407 * Check the time stamp for each sample. If too old,408 * Check the time stamp for each sample. If too old,
408 * replace with latest sample409 * replace with latest sample
409 */410 */
410 } while (ts.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);411 } while (ts64.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]);
411 412
412 avg->avg = avg->sum / avg->nbr_samples;413 avg->avg = avg->sum / avg->nbr_samples;
413 414
@@ -446,14 +447,14 @@ static void ab8500_fg_clear_cap_samples(struct ab8500_fg *di) · 32 unmodified lines
446static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample)447static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample)
447{448{
448 int i;449 int i;
449 struct timespec ts;450 struct timespec64 ts64;
450 struct ab8500_fg_avg_cap *avg = &di->avg_cap;451 struct ab8500_fg_avg_cap *avg = &di->avg_cap;
451 452
452 getnstimeofday(&ts);453 getnstimeofday64(&ts64);
453 454
454 for (i = 0; i < NBR_AVG_SAMPLES; i++) {455 for (i = 0; i < NBR_AVG_SAMPLES; i++) {
455 avg->samples[i] = sample;456 avg->samples[i] = sample;
456 avg->time_stamps[i] = ts.tv_sec;457 avg->time_stamps[i] = ts64.tv_sec;
457 }458 }
458 459
459 avg->pos = 0;460 avg->pos = 0;
drivers/power/bq2415x_charger.c+15−8
@@ -1579,8 +1579,15 @@ static int bq2415x_probe(struct i2c_client *client, · 1578 unmodified lines
1579 if (np) {1579 if (np) {
1580 bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");1580 bq->notify_psy = power_supply_get_by_phandle(np, "ti,usb-charger-detection");
1581 1581
1582 if (!bq->notify_psy)1582 if (IS_ERR(bq->notify_psy)) {
1583 return -EPROBE_DEFER;1583 dev_info(&client->dev,
1584 "no 'ti,usb-charger-detection' property (err=%ld)\n",
1585 PTR_ERR(bq->notify_psy));
1586 bq->notify_psy = NULL;
1587 } else if (!bq->notify_psy) {
1588 ret = -EPROBE_DEFER;
1589 goto error_2;
1590 }
1584 }1591 }
1585 else if (pdata->notify_device)1592 else if (pdata->notify_device)
1586 bq->notify_psy = power_supply_get_by_name(pdata->notify_device);1593 bq->notify_psy = power_supply_get_by_name(pdata->notify_device);
@@ -1602,27 +1609,27 @@ static int bq2415x_probe(struct i2c_client *client, · 15 unmodified lines
1602 ret = of_property_read_u32(np, "ti,current-limit",1609 ret = of_property_read_u32(np, "ti,current-limit",
1603 &bq->init_data.current_limit);1610 &bq->init_data.current_limit);
1604 if (ret)1611 if (ret)
1605 return ret;1612 goto error_2;
1606 ret = of_property_read_u32(np, "ti,weak-battery-voltage",1613 ret = of_property_read_u32(np, "ti,weak-battery-voltage",
1607 &bq->init_data.weak_battery_voltage);1614 &bq->init_data.weak_battery_voltage);
1608 if (ret)1615 if (ret)
1609 return ret;1616 goto error_2;
1610 ret = of_property_read_u32(np, "ti,battery-regulation-voltage",1617 ret = of_property_read_u32(np, "ti,battery-regulation-voltage",
1611 &bq->init_data.battery_regulation_voltage);1618 &bq->init_data.battery_regulation_voltage);
1612 if (ret)1619 if (ret)
1613 return ret;1620 goto error_2;
1614 ret = of_property_read_u32(np, "ti,charge-current",1621 ret = of_property_read_u32(np, "ti,charge-current",
1615 &bq->init_data.charge_current);1622 &bq->init_data.charge_current);
1616 if (ret)1623 if (ret)
1617 return ret;1624 goto error_2;
1618 ret = of_property_read_u32(np, "ti,termination-current",1625 ret = of_property_read_u32(np, "ti,termination-current",
1619 &bq->init_data.termination_current);1626 &bq->init_data.termination_current);
1620 if (ret)1627 if (ret)
1621 return ret;1628 goto error_2;
1622 ret = of_property_read_u32(np, "ti,resistor-sense",1629 ret = of_property_read_u32(np, "ti,resistor-sense",
1623 &bq->init_data.resistor_sense);1630 &bq->init_data.resistor_sense);
1624 if (ret)1631 if (ret)
1625 return ret;1632 goto error_2;
1626 } else {1633 } else {
1627 memcpy(&bq->init_data, pdata, sizeof(bq->init_data));1634 memcpy(&bq->init_data, pdata, sizeof(bq->init_data));
1628 }1635 }
drivers/power/charger-manager.c+111−53
@@ -97,6 +97,7 @@ static struct charger_global_desc *g_desc; /* init with setup_charger_manager */ · 96 unmodified lines
97static bool is_batt_present(struct charger_manager *cm)97static bool is_batt_present(struct charger_manager *cm)
98{98{
99 union power_supply_propval val;99 union power_supply_propval val;
100 struct power_supply *psy;
100 bool present = false;101 bool present = false;
101 int i, ret;102 int i, ret;
102 103
@@ -107,16 +108,27 @@ static bool is_batt_present(struct charger_manager *cm) · 4 unmodified lines
107 case CM_NO_BATTERY:108 case CM_NO_BATTERY:
108 break;109 break;
109 case CM_FUEL_GAUGE:110 case CM_FUEL_GAUGE:
110 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,111 psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
112 if (!psy)
113 break;
114
115 ret = psy->get_property(psy,
111 POWER_SUPPLY_PROP_PRESENT, &val);116 POWER_SUPPLY_PROP_PRESENT, &val);
112 if (ret == 0 && val.intval)117 if (ret == 0 && val.intval)
113 present = true;118 present = true;
114 break;119 break;
115 case CM_CHARGER_STAT:120 case CM_CHARGER_STAT:
116 for (i = 0; cm->charger_stat[i]; i++) {121 for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
117 ret = cm->charger_stat[i]->get_property(122 psy = power_supply_get_by_name(
118 cm->charger_stat[i],123 cm->desc->psy_charger_stat[i]);
119 POWER_SUPPLY_PROP_PRESENT, &val);124 if (!psy) {
125 dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
126 cm->desc->psy_charger_stat[i]);
127 continue;
128 }
129
130 ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT,
131 &val);
120 if (ret == 0 && val.intval) {132 if (ret == 0 && val.intval) {
121 present = true;133 present = true;
122 break;134 break;
@@ -139,14 +151,20 @@ static bool is_batt_present(struct charger_manager *cm) · 16 unmodified lines
139static bool is_ext_pwr_online(struct charger_manager *cm)151static bool is_ext_pwr_online(struct charger_manager *cm)
140{152{
141 union power_supply_propval val;153 union power_supply_propval val;
154 struct power_supply *psy;
142 bool online = false;155 bool online = false;
143 int i, ret;156 int i, ret;
144 157
145 /* If at least one of them has one, it's yes. */158 /* If at least one of them has one, it's yes. */
146 for (i = 0; cm->charger_stat[i]; i++) {159 for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
147 ret = cm->charger_stat[i]->get_property(160 psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
148 cm->charger_stat[i],161 if (!psy) {
149 POWER_SUPPLY_PROP_ONLINE, &val);162 dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
163 cm->desc->psy_charger_stat[i]);
164 continue;
165 }
166
167 ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
150 if (ret == 0 && val.intval) {168 if (ret == 0 && val.intval) {
151 online = true;169 online = true;
152 break;170 break;
@@ -167,12 +185,14 @@ static bool is_ext_pwr_online(struct charger_manager *cm) · 14 unmodified lines
167static int get_batt_uV(struct charger_manager *cm, int *uV)185static int get_batt_uV(struct charger_manager *cm, int *uV)
168{186{
169 union power_supply_propval val;187 union power_supply_propval val;
188 struct power_supply *fuel_gauge;
170 int ret;189 int ret;
171 190
172 if (!cm->fuel_gauge)191 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
192 if (!fuel_gauge)
173 return -ENODEV;193 return -ENODEV;
174 194
175 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,195 ret = fuel_gauge->get_property(fuel_gauge,
176 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);196 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
177 if (ret)197 if (ret)
178 return ret;198 return ret;
@@ -189,6 +209,7 @@ static bool is_charging(struct charger_manager *cm) · 10 unmodified lines
189{209{
190 int i, ret;210 int i, ret;
191 bool charging = false;211 bool charging = false;
212 struct power_supply *psy;
192 union power_supply_propval val;213 union power_supply_propval val;
193 214
194 /* If there is no battery, it cannot be charged */215 /* If there is no battery, it cannot be charged */
@@ -196,17 +217,22 @@ static bool is_charging(struct charger_manager *cm) · 1 unmodified line
196 return false;217 return false;
197 218
198 /* If at least one of the charger is charging, return yes */219 /* If at least one of the charger is charging, return yes */
199 for (i = 0; cm->charger_stat[i]; i++) {220 for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
200 /* 1. The charger sholuld not be DISABLED */221 /* 1. The charger sholuld not be DISABLED */
201 if (cm->emergency_stop)222 if (cm->emergency_stop)
202 continue;223 continue;
203 if (!cm->charger_enabled)224 if (!cm->charger_enabled)
204 continue;225 continue;
205 226
227 psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]);
228 if (!psy) {
229 dev_err(cm->dev, "Cannot find power supply \"%s\"\n",
230 cm->desc->psy_charger_stat[i]);
231 continue;
232 }
233
206 /* 2. The charger should be online (ext-power) */234 /* 2. The charger should be online (ext-power) */
207 ret = cm->charger_stat[i]->get_property(235 ret = psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &val);
208 cm->charger_stat[i],
209 POWER_SUPPLY_PROP_ONLINE, &val);
210 if (ret) {236 if (ret) {
211 dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",237 dev_warn(cm->dev, "Cannot read ONLINE value from %s\n",
212 cm->desc->psy_charger_stat[i]);238 cm->desc->psy_charger_stat[i]);
@@ -219,9 +245,7 @@ static bool is_charging(struct charger_manager *cm) · 6 unmodified lines
219 * 3. The charger should not be FULL, DISCHARGING,245 * 3. The charger should not be FULL, DISCHARGING,
220 * or NOT_CHARGING.246 * or NOT_CHARGING.
221 */247 */
222 ret = cm->charger_stat[i]->get_property(248 ret = psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &val);
223 cm->charger_stat[i],
224 POWER_SUPPLY_PROP_STATUS, &val);
225 if (ret) {249 if (ret) {
226 dev_warn(cm->dev, "Cannot read STATUS value from %s\n",250 dev_warn(cm->dev, "Cannot read STATUS value from %s\n",
227 cm->desc->psy_charger_stat[i]);251 cm->desc->psy_charger_stat[i]);
@@ -248,6 +272,7 @@ static bool is_full_charged(struct charger_manager *cm) · 20 unmodified lines
248{272{
249 struct charger_desc *desc = cm->desc;273 struct charger_desc *desc = cm->desc;
250 union power_supply_propval val;274 union power_supply_propval val;
275 struct power_supply *fuel_gauge;
251 int ret = 0;276 int ret = 0;
252 int uV;277 int uV;
253 278
@@ -255,11 +280,15 @@ static bool is_full_charged(struct charger_manager *cm) · 1 unmodified line
255 if (!is_batt_present(cm))280 if (!is_batt_present(cm))
256 return false;281 return false;
257 282
258 if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {283 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
284 if (!fuel_gauge)
285 return false;
286
287 if (desc->fullbatt_full_capacity > 0) {
259 val.intval = 0;288 val.intval = 0;
260 289
261 /* Not full if capacity of fuel gauge isn't full */290 /* Not full if capacity of fuel gauge isn't full */
262 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,291 ret = fuel_gauge->get_property(fuel_gauge,
263 POWER_SUPPLY_PROP_CHARGE_FULL, &val);292 POWER_SUPPLY_PROP_CHARGE_FULL, &val);
264 if (!ret && val.intval > desc->fullbatt_full_capacity)293 if (!ret && val.intval > desc->fullbatt_full_capacity)
265 return true;294 return true;
@@ -273,10 +302,10 @@ static bool is_full_charged(struct charger_manager *cm) · 7 unmodified lines
273 }302 }
274 303
275 /* Full, if the capacity is more than fullbatt_soc */304 /* Full, if the capacity is more than fullbatt_soc */
276 if (cm->fuel_gauge && desc->fullbatt_soc > 0) {305 if (desc->fullbatt_soc > 0) {
277 val.intval = 0;306 val.intval = 0;
278 307
279 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,308 ret = fuel_gauge->get_property(fuel_gauge,
280 POWER_SUPPLY_PROP_CAPACITY, &val);309 POWER_SUPPLY_PROP_CAPACITY, &val);
281 if (!ret && val.intval >= desc->fullbatt_soc)310 if (!ret && val.intval >= desc->fullbatt_soc)
282 return true;311 return true;
@@ -551,6 +580,20 @@ static int check_charging_duration(struct charger_manager *cm) · 268 unmodified lines
551 return ret;580 return ret;
552}581}
553 582
583static int cm_get_battery_temperature_by_psy(struct charger_manager *cm,
584 int *temp)
585{
586 struct power_supply *fuel_gauge;
587
588 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
589 if (!fuel_gauge)
590 return -ENODEV;
591
592 return fuel_gauge->get_property(fuel_gauge,
593 POWER_SUPPLY_PROP_TEMP,
594 (union power_supply_propval *)temp);
595}
596
554static int cm_get_battery_temperature(struct charger_manager *cm,597static int cm_get_battery_temperature(struct charger_manager *cm,
555 int *temp)598 int *temp)
556{599{
@@ -560,15 +603,18 @@ static int cm_get_battery_temperature(struct charger_manager *cm, · 3 unmodified lines
560 return -ENODEV;603 return -ENODEV;
561 604
562#ifdef CONFIG_THERMAL605#ifdef CONFIG_THERMAL
563 ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);606 if (cm->tzd_batt) {
564 if (!ret)607 ret = thermal_zone_get_temp(cm->tzd_batt, (unsigned long *)temp);
565 /* Calibrate temperature unit */608 if (!ret)
566 *temp /= 100;609 /* Calibrate temperature unit */
567#else610 *temp /= 100;
568 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,611 } else
569 POWER_SUPPLY_PROP_TEMP,
570 (union power_supply_propval *)temp);
571#endif612#endif
613 {
614 /* if-else continued from CONFIG_THERMAL */
615 ret = cm_get_battery_temperature_by_psy(cm, temp);
616 }
617
572 return ret;618 return ret;
573}619}
574 620
@@ -827,6 +873,7 @@ static int charger_get_property(struct power_supply *psy, · 252 unmodified lines
827 struct charger_manager *cm = container_of(psy,873 struct charger_manager *cm = container_of(psy,
828 struct charger_manager, charger_psy);874 struct charger_manager, charger_psy);
829 struct charger_desc *desc = cm->desc;875 struct charger_desc *desc = cm->desc;
876 struct power_supply *fuel_gauge;
830 int ret = 0;877 int ret = 0;
831 int uV;878 int uV;
832 879
@@ -857,14 +904,20 @@ static int charger_get_property(struct power_supply *psy, · 24 unmodified lines
857 ret = get_batt_uV(cm, &val->intval);904 ret = get_batt_uV(cm, &val->intval);
858 break;905 break;
859 case POWER_SUPPLY_PROP_CURRENT_NOW:906 case POWER_SUPPLY_PROP_CURRENT_NOW:
860 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,907 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
908 if (!fuel_gauge) {
909 ret = -ENODEV;
910 break;
911 }
912 ret = fuel_gauge->get_property(fuel_gauge,
861 POWER_SUPPLY_PROP_CURRENT_NOW, val);913 POWER_SUPPLY_PROP_CURRENT_NOW, val);
862 break;914 break;
863 case POWER_SUPPLY_PROP_TEMP:915 case POWER_SUPPLY_PROP_TEMP:
864 case POWER_SUPPLY_PROP_TEMP_AMBIENT:916 case POWER_SUPPLY_PROP_TEMP_AMBIENT:
865 return cm_get_battery_temperature(cm, &val->intval);917 return cm_get_battery_temperature(cm, &val->intval);
866 case POWER_SUPPLY_PROP_CAPACITY:918 case POWER_SUPPLY_PROP_CAPACITY:
867 if (!cm->fuel_gauge) {919 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge);
920 if (!fuel_gauge) {
868 ret = -ENODEV;921 ret = -ENODEV;
869 break;922 break;
870 }923 }
@@ -875,7 +928,7 @@ static int charger_get_property(struct power_supply *psy, · 4 unmodified lines
875 break;928 break;
876 }929 }
877 930
878 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,931 ret = fuel_gauge->get_property(fuel_gauge,
879 POWER_SUPPLY_PROP_CAPACITY, val);932 POWER_SUPPLY_PROP_CAPACITY, val);
880 if (ret)933 if (ret)
881 break;934 break;
@@ -924,7 +977,14 @@ static int charger_get_property(struct power_supply *psy, · 42 unmodified lines
924 break;977 break;
925 case POWER_SUPPLY_PROP_CHARGE_NOW:978 case POWER_SUPPLY_PROP_CHARGE_NOW:
926 if (is_charging(cm)) {979 if (is_charging(cm)) {
927 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,980 fuel_gauge = power_supply_get_by_name(
981 cm->desc->psy_fuel_gauge);
982 if (!fuel_gauge) {
983 ret = -ENODEV;
984 break;
985 }
986
987 ret = fuel_gauge->get_property(fuel_gauge,
928 POWER_SUPPLY_PROP_CHARGE_NOW,988 POWER_SUPPLY_PROP_CHARGE_NOW,
929 val);989 val);
930 if (ret) {990 if (ret) {
@@ -970,6 +1030,7 @@ static struct power_supply psy_default = { · 39 unmodified lines
970 .properties = default_charger_props,1030 .properties = default_charger_props,
971 .num_properties = ARRAY_SIZE(default_charger_props),1031 .num_properties = ARRAY_SIZE(default_charger_props),
972 .get_property = charger_get_property,1032 .get_property = charger_get_property,
1033 .no_thermal = true,
973};1034};
974 1035
975/**1036/**
@@ -1485,14 +1546,15 @@ err: · 509 unmodified lines
1485 return ret;1546 return ret;
1486}1547}
1487 1548
1488static int cm_init_thermal_data(struct charger_manager *cm)1549static int cm_init_thermal_data(struct charger_manager *cm,
1550 struct power_supply *fuel_gauge)
1489{1551{
1490 struct charger_desc *desc = cm->desc;1552 struct charger_desc *desc = cm->desc;
1491 union power_supply_propval val;1553 union power_supply_propval val;
1492 int ret;1554 int ret;
1493 1555
1494 /* Verify whether fuel gauge provides battery temperature */1556 /* Verify whether fuel gauge provides battery temperature */
1495 ret = cm->fuel_gauge->get_property(cm->fuel_gauge,1557 ret = fuel_gauge->get_property(fuel_gauge,
1496 POWER_SUPPLY_PROP_TEMP, &val);1558 POWER_SUPPLY_PROP_TEMP, &val);
1497 1559
1498 if (!ret) {1560 if (!ret) {
@@ -1502,8 +1564,6 @@ static int cm_init_thermal_data(struct charger_manager *cm) · 3 unmodified lines
1502 cm->desc->measure_battery_temp = true;1564 cm->desc->measure_battery_temp = true;
1503 }1565 }
1504#ifdef CONFIG_THERMAL1566#ifdef CONFIG_THERMAL
1505 cm->tzd_batt = cm->fuel_gauge->tzd;
1506
1507 if (ret && desc->thermal_zone) {1567 if (ret && desc->thermal_zone) {
1508 cm->tzd_batt =1568 cm->tzd_batt =
1509 thermal_zone_get_zone_by_name(desc->thermal_zone);1569 thermal_zone_get_zone_by_name(desc->thermal_zone);
@@ -1666,6 +1726,7 @@ static int charger_manager_probe(struct platform_device *pdev) · 156 unmodified lines
1666 int ret = 0, i = 0;1726 int ret = 0, i = 0;
1667 int j = 0;1727 int j = 0;
1668 union power_supply_propval val;1728 union power_supply_propval val;
1729 struct power_supply *fuel_gauge;
1669 1730
1670 if (g_desc && !rtc_dev && g_desc->rtc_name) {1731 if (g_desc && !rtc_dev && g_desc->rtc_name) {
1671 rtc_dev = rtc_class_open(g_desc->rtc_name);1732 rtc_dev = rtc_class_open(g_desc->rtc_name);
@@ -1729,23 +1790,20 @@ static int charger_manager_probe(struct platform_device *pdev) · 57 unmodified lines
1729 while (desc->psy_charger_stat[i])1790 while (desc->psy_charger_stat[i])
1730 i++;1791 i++;
1731 1792
1732 cm->charger_stat = devm_kzalloc(&pdev->dev,1793 /* Check if charger's supplies are present at probe */
1733 sizeof(struct power_supply *) * i, GFP_KERNEL);
1734 if (!cm->charger_stat)
1735 return -ENOMEM;
1736
1737 for (i = 0; desc->psy_charger_stat[i]; i++) {1794 for (i = 0; desc->psy_charger_stat[i]; i++) {
1738 cm->charger_stat[i] = power_supply_get_by_name(1795 struct power_supply *psy;
1739 desc->psy_charger_stat[i]);1796
1740 if (!cm->charger_stat[i]) {1797 psy = power_supply_get_by_name(desc->psy_charger_stat[i]);
1798 if (!psy) {
1741 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",1799 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
1742 desc->psy_charger_stat[i]);1800 desc->psy_charger_stat[i]);
1743 return -ENODEV;1801 return -ENODEV;
1744 }1802 }
1745 }1803 }
1746 1804
1747 cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);1805 fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
1748 if (!cm->fuel_gauge) {1806 if (!fuel_gauge) {
1749 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",1807 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
1750 desc->psy_fuel_gauge);1808 desc->psy_fuel_gauge);
1751 return -ENODEV;1809 return -ENODEV;
@@ -1788,13 +1846,13 @@ static int charger_manager_probe(struct platform_device *pdev) · 36 unmodified lines
1788 cm->charger_psy.num_properties = psy_default.num_properties;1846 cm->charger_psy.num_properties = psy_default.num_properties;
1789 1847
1790 /* Find which optional psy-properties are available */1848 /* Find which optional psy-properties are available */
1791 if (!cm->fuel_gauge->get_property(cm->fuel_gauge,1849 if (!fuel_gauge->get_property(fuel_gauge,
1792 POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {1850 POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
1793 cm->charger_psy.properties[cm->charger_psy.num_properties] =1851 cm->charger_psy.properties[cm->charger_psy.num_properties] =
1794 POWER_SUPPLY_PROP_CHARGE_NOW;1852 POWER_SUPPLY_PROP_CHARGE_NOW;
1795 cm->charger_psy.num_properties++;1853 cm->charger_psy.num_properties++;
1796 }1854 }
1797 if (!cm->fuel_gauge->get_property(cm->fuel_gauge,1855 if (!fuel_gauge->get_property(fuel_gauge,
1798 POWER_SUPPLY_PROP_CURRENT_NOW,1856 POWER_SUPPLY_PROP_CURRENT_NOW,
1799 &val)) {1857 &val)) {
1800 cm->charger_psy.properties[cm->charger_psy.num_properties] =1858 cm->charger_psy.properties[cm->charger_psy.num_properties] =
@@ -1802,7 +1860,7 @@ static int charger_manager_probe(struct platform_device *pdev) · 1 unmodified line
1802 cm->charger_psy.num_properties++;1860 cm->charger_psy.num_properties++;
1803 }1861 }
1804 1862
1805 ret = cm_init_thermal_data(cm);1863 ret = cm_init_thermal_data(cm, fuel_gauge);
1806 if (ret) {1864 if (ret) {
1807 dev_err(&pdev->dev, "Failed to initialize thermal data\n");1865 dev_err(&pdev->dev, "Failed to initialize thermal data\n");
1808 cm->desc->measure_battery_temp = false;1866 cm->desc->measure_battery_temp = false;
@@ -2066,8 +2124,8 @@ static bool find_power_supply(struct charger_manager *cm, · 257 unmodified lines
2066 int i;2124 int i;
2067 bool found = false;2125 bool found = false;
2068 2126
2069 for (i = 0; cm->charger_stat[i]; i++) {2127 for (i = 0; cm->desc->psy_charger_stat[i]; i++) {
2070 if (psy == cm->charger_stat[i]) {2128 if (!strcmp(psy->name, cm->desc->psy_charger_stat[i])) {
2071 found = true;2129 found = true;
2072 break;2130 break;
2073 }2131 }
drivers/power/power_supply_core.c+3−0
@@ -417,6 +417,9 @@ static int psy_register_thermal(struct power_supply *psy) · 416 unmodified lines
417{417{
418 int i;418 int i;
419 419
420 if (psy->no_thermal)
421 return 0;
422
420 /* Register battery zone device psy reports temperature */423 /* Register battery zone device psy reports temperature */
421 for (i = 0; i < psy->num_properties; i++) {424 for (i = 0; i < psy->num_properties; i++) {
422 if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {425 if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
include/linux/power/charger-manager.h+0−3
@@ -253,9 +253,6 @@ struct charger_manager { · 252 unmodified lines
253 struct device *dev;253 struct device *dev;
254 struct charger_desc *desc;254 struct charger_desc *desc;
255 255
256 struct power_supply *fuel_gauge;
257 struct power_supply **charger_stat;
258
259#ifdef CONFIG_THERMAL256#ifdef CONFIG_THERMAL
260 struct thermal_zone_device *tzd_batt;257 struct thermal_zone_device *tzd_batt;
261#endif258#endif
include/linux/power_supply.h+6−0
@@ -200,6 +200,12 @@ struct power_supply { · 199 unmodified lines
200 void (*external_power_changed)(struct power_supply *psy);200 void (*external_power_changed)(struct power_supply *psy);
201 void (*set_charged)(struct power_supply *psy);201 void (*set_charged)(struct power_supply *psy);
202 202
203 /*
204 * Set if thermal zone should not be created for this power supply.
205 * For example for virtual supplies forwarding calls to actual
206 * sensors or other supplies.
207 */
208 bool no_thermal;
203 /* For APM emulation, think legacy userspace. */209 /* For APM emulation, think legacy userspace. */
204 int use_for_apm;210 int use_for_apm;
205 211