| .. | .. |
|---|
| 358 | 358 | struct power_supply *psy = dev_get_drvdata(dev); |
|---|
| 359 | 359 | unsigned int *count = data; |
|---|
| 360 | 360 | |
|---|
| 361 | + if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) |
|---|
| 362 | + if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) |
|---|
| 363 | + return 0; |
|---|
| 364 | + |
|---|
| 361 | 365 | (*count)++; |
|---|
| 362 | 366 | if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) |
|---|
| 363 | 367 | if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, |
|---|
| .. | .. |
|---|
| 376 | 380 | __power_supply_is_system_supplied); |
|---|
| 377 | 381 | |
|---|
| 378 | 382 | /* |
|---|
| 379 | | - * If no power class device was found at all, most probably we are |
|---|
| 380 | | - * running on a desktop system, so assume we are on mains power. |
|---|
| 383 | + * If no system scope power class device was found at all, most probably we |
|---|
| 384 | + * are running on a desktop system, so assume we are on mains power. |
|---|
| 381 | 385 | */ |
|---|
| 382 | 386 | if (count == 0) |
|---|
| 383 | 387 | return 1; |
|---|
| .. | .. |
|---|
| 386 | 390 | } |
|---|
| 387 | 391 | EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); |
|---|
| 388 | 392 | |
|---|
| 389 | | -static int __power_supply_get_supplier_max_current(struct device *dev, |
|---|
| 390 | | - void *data) |
|---|
| 393 | +struct psy_get_supplier_prop_data { |
|---|
| 394 | + struct power_supply *psy; |
|---|
| 395 | + enum power_supply_property psp; |
|---|
| 396 | + union power_supply_propval *val; |
|---|
| 397 | +}; |
|---|
| 398 | + |
|---|
| 399 | +static int __power_supply_get_supplier_property(struct device *dev, void *_data) |
|---|
| 391 | 400 | { |
|---|
| 392 | | - union power_supply_propval ret = {0,}; |
|---|
| 393 | 401 | struct power_supply *epsy = dev_get_drvdata(dev); |
|---|
| 394 | | - struct power_supply *psy = data; |
|---|
| 402 | + struct psy_get_supplier_prop_data *data = _data; |
|---|
| 395 | 403 | |
|---|
| 396 | | - if (__power_supply_is_supplied_by(epsy, psy)) |
|---|
| 397 | | - if (!epsy->desc->get_property(epsy, |
|---|
| 398 | | - POWER_SUPPLY_PROP_CURRENT_MAX, |
|---|
| 399 | | - &ret)) |
|---|
| 400 | | - return ret.intval; |
|---|
| 404 | + if (__power_supply_is_supplied_by(epsy, data->psy)) |
|---|
| 405 | + if (!epsy->desc->get_property(epsy, data->psp, data->val)) |
|---|
| 406 | + return 1; /* Success */ |
|---|
| 401 | 407 | |
|---|
| 402 | | - return 0; |
|---|
| 408 | + return 0; /* Continue iterating */ |
|---|
| 403 | 409 | } |
|---|
| 404 | 410 | |
|---|
| 405 | | -int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy) |
|---|
| 411 | +int power_supply_get_property_from_supplier(struct power_supply *psy, |
|---|
| 412 | + enum power_supply_property psp, |
|---|
| 413 | + union power_supply_propval *val) |
|---|
| 406 | 414 | { |
|---|
| 407 | | - union power_supply_propval val = {0,}; |
|---|
| 408 | | - int curr; |
|---|
| 409 | | - |
|---|
| 410 | | - if (!psy->desc->set_property) |
|---|
| 411 | | - return -EINVAL; |
|---|
| 415 | + struct psy_get_supplier_prop_data data = { |
|---|
| 416 | + .psy = psy, |
|---|
| 417 | + .psp = psp, |
|---|
| 418 | + .val = val, |
|---|
| 419 | + }; |
|---|
| 420 | + int ret; |
|---|
| 412 | 421 | |
|---|
| 413 | 422 | /* |
|---|
| 414 | 423 | * This function is not intended for use with a supply with multiple |
|---|
| 415 | | - * suppliers, we simply pick the first supply to report a non 0 |
|---|
| 416 | | - * max-current. |
|---|
| 424 | + * suppliers, we simply pick the first supply to report the psp. |
|---|
| 417 | 425 | */ |
|---|
| 418 | | - curr = class_for_each_device(power_supply_class, NULL, psy, |
|---|
| 419 | | - __power_supply_get_supplier_max_current); |
|---|
| 420 | | - if (curr <= 0) |
|---|
| 421 | | - return (curr == 0) ? -ENODEV : curr; |
|---|
| 426 | + ret = class_for_each_device(power_supply_class, NULL, &data, |
|---|
| 427 | + __power_supply_get_supplier_property); |
|---|
| 428 | + if (ret < 0) |
|---|
| 429 | + return ret; |
|---|
| 430 | + if (ret == 0) |
|---|
| 431 | + return -ENODEV; |
|---|
| 422 | 432 | |
|---|
| 423 | | - val.intval = curr; |
|---|
| 424 | | - |
|---|
| 425 | | - return psy->desc->set_property(psy, |
|---|
| 426 | | - POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); |
|---|
| 433 | + return 0; |
|---|
| 427 | 434 | } |
|---|
| 428 | | -EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier); |
|---|
| 435 | +EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier); |
|---|
| 429 | 436 | |
|---|
| 430 | 437 | int power_supply_set_battery_charged(struct power_supply *psy) |
|---|
| 431 | 438 | { |
|---|
| .. | .. |
|---|
| 759 | 766 | int i, tab_len, size; |
|---|
| 760 | 767 | |
|---|
| 761 | 768 | propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index); |
|---|
| 769 | + if (!propname) { |
|---|
| 770 | + power_supply_put_battery_info(psy, info); |
|---|
| 771 | + err = -ENOMEM; |
|---|
| 772 | + goto out_put_node; |
|---|
| 773 | + } |
|---|
| 762 | 774 | list = of_get_property(battery_np, propname, &size); |
|---|
| 763 | 775 | if (!list || !size) { |
|---|
| 764 | 776 | dev_err(&psy->dev, "failed to get %s\n", propname); |
|---|
| .. | .. |
|---|
| 1283 | 1295 | create_triggers_failed: |
|---|
| 1284 | 1296 | psy_unregister_thermal(psy); |
|---|
| 1285 | 1297 | register_thermal_failed: |
|---|
| 1286 | | - device_del(dev); |
|---|
| 1287 | 1298 | wakeup_init_failed: |
|---|
| 1299 | + device_del(dev); |
|---|
| 1288 | 1300 | device_add_failed: |
|---|
| 1289 | 1301 | check_supplies_failed: |
|---|
| 1290 | 1302 | dev_set_name_failed: |
|---|