1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Universal power supply monitor class 4 * 5 * Copyright © 2007 Anton Vorontsov <cbou@mail.ru> 6 * Copyright © 2004 Szabolcs Gyurko 7 * Copyright © 2003 Ian Molton <spyro@f2s.com> 8 * 9 * Modified: 2004, Oct Szabolcs Gyurko 10 */ 11 12 #include <linux/cleanup.h> 13 #include <linux/module.h> 14 #include <linux/types.h> 15 #include <linux/init.h> 16 #include <linux/slab.h> 17 #include <linux/delay.h> 18 #include <linux/device.h> 19 #include <linux/notifier.h> 20 #include <linux/err.h> 21 #include <linux/power_supply.h> 22 #include <linux/property.h> 23 #include <linux/thermal.h> 24 #include <linux/fixp-arith.h> 25 #include "power_supply.h" 26 #include "samsung-sdi-battery.h" 27 28 static const struct class power_supply_class = { 29 .name = "power_supply", 30 .dev_uevent = power_supply_uevent, 31 }; 32 33 static BLOCKING_NOTIFIER_HEAD(power_supply_notifier); 34 35 static const struct device_type power_supply_dev_type = { 36 .name = "power_supply", 37 .groups = power_supply_attr_groups, 38 }; 39 40 #define POWER_SUPPLY_DEFERRED_REGISTER_TIME msecs_to_jiffies(10) 41 42 static bool __power_supply_is_supplied_by(struct power_supply *supplier, 43 struct power_supply *supply) 44 { 45 int i; 46 47 if (!supply->supplied_from && !supplier->supplied_to) 48 return false; 49 50 /* Support both supplied_to and supplied_from modes */ 51 if (supply->supplied_from) { 52 if (!supplier->desc->name) 53 return false; 54 for (i = 0; i < supply->num_supplies; i++) 55 if (!strcmp(supplier->desc->name, supply->supplied_from[i])) 56 return true; 57 } else { 58 if (!supply->desc->name) 59 return false; 60 for (i = 0; i < supplier->num_supplicants; i++) 61 if (!strcmp(supplier->supplied_to[i], supply->desc->name)) 62 return true; 63 } 64 65 return false; 66 } 67 68 static int __power_supply_changed_work(struct power_supply *pst, void *data) 69 { 70 struct power_supply *psy = data; 71 72 if (__power_supply_is_supplied_by(psy, pst)) 73 power_supply_external_power_changed(pst); 74 75 return 0; 76 } 77 78 static void power_supply_changed_work(struct work_struct *work) 79 { 80 int ret; 81 unsigned long flags; 82 struct power_supply *psy = container_of(work, struct power_supply, 83 changed_work); 84 85 dev_dbg(&psy->dev, "%s\n", __func__); 86 87 spin_lock_irqsave(&psy->changed_lock, flags); 88 89 if (unlikely(psy->update_groups)) { 90 psy->update_groups = false; 91 spin_unlock_irqrestore(&psy->changed_lock, flags); 92 ret = sysfs_update_groups(&psy->dev.kobj, power_supply_dev_type.groups); 93 if (ret) 94 dev_warn(&psy->dev, "failed to update sysfs groups: %pe\n", ERR_PTR(ret)); 95 spin_lock_irqsave(&psy->changed_lock, flags); 96 } 97 98 /* 99 * Check 'changed' here to avoid issues due to race between 100 * power_supply_changed() and this routine. In worst case 101 * power_supply_changed() can be called again just before we take above 102 * lock. During the first call of this routine we will mark 'changed' as 103 * false and it will stay false for the next call as well. 104 */ 105 if (likely(psy->changed)) { 106 psy->changed = false; 107 spin_unlock_irqrestore(&psy->changed_lock, flags); 108 power_supply_for_each_psy(psy, __power_supply_changed_work); 109 power_supply_update_leds(psy); 110 blocking_notifier_call_chain(&power_supply_notifier, 111 PSY_EVENT_PROP_CHANGED, psy); 112 kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE); 113 spin_lock_irqsave(&psy->changed_lock, flags); 114 } 115 116 /* 117 * Hold the wakeup_source until all events are processed. 118 * power_supply_changed() might have called again and have set 'changed' 119 * to true. 120 */ 121 if (likely(!psy->changed)) 122 pm_relax(&psy->dev); 123 spin_unlock_irqrestore(&psy->changed_lock, flags); 124 } 125 126 struct psy_for_each_psy_cb_data { 127 int (*fn)(struct power_supply *psy, void *data); 128 void *data; 129 }; 130 131 static int psy_for_each_psy_cb(struct device *dev, void *data) 132 { 133 struct psy_for_each_psy_cb_data *cb_data = data; 134 struct power_supply *psy = dev_to_psy(dev); 135 136 return cb_data->fn(psy, cb_data->data); 137 } 138 139 int power_supply_for_each_psy(void *data, int (*fn)(struct power_supply *psy, void *data)) 140 { 141 struct psy_for_each_psy_cb_data cb_data = { 142 .fn = fn, 143 .data = data, 144 }; 145 146 return class_for_each_device(&power_supply_class, NULL, &cb_data, psy_for_each_psy_cb); 147 } 148 EXPORT_SYMBOL_GPL(power_supply_for_each_psy); 149 150 void power_supply_changed(struct power_supply *psy) 151 { 152 unsigned long flags; 153 154 dev_dbg(&psy->dev, "%s\n", __func__); 155 156 spin_lock_irqsave(&psy->changed_lock, flags); 157 psy->changed = true; 158 pm_stay_awake(&psy->dev); 159 spin_unlock_irqrestore(&psy->changed_lock, flags); 160 schedule_work(&psy->changed_work); 161 } 162 EXPORT_SYMBOL_GPL(power_supply_changed); 163 164 /* 165 * Notify that power supply was registered after parent finished the probing. 166 * 167 * Often power supply is registered from driver's probe function. However 168 * calling power_supply_changed() directly from power_supply_register() 169 * would lead to execution of get_property() function provided by the driver 170 * too early - before the probe ends. 171 * 172 * Avoid that by waiting on parent's mutex. 173 */ 174 static void power_supply_deferred_register_work(struct work_struct *work) 175 { 176 struct power_supply *psy = container_of(work, struct power_supply, 177 deferred_register_work.work); 178 179 if (psy->dev.parent) { 180 while (!device_trylock(psy->dev.parent)) { 181 if (psy->removing) 182 return; 183 msleep(10); 184 } 185 } 186 187 power_supply_changed(psy); 188 189 if (psy->dev.parent) 190 device_unlock(psy->dev.parent); 191 } 192 193 #ifdef CONFIG_OF 194 static int __power_supply_populate_supplied_from(struct power_supply *epsy, 195 void *data) 196 { 197 struct power_supply *psy = data; 198 struct fwnode_handle *np; 199 int i = 0; 200 201 do { 202 np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", i++); 203 if (IS_ERR(np)) 204 break; 205 206 if (np == epsy->dev.fwnode) { 207 dev_dbg(&psy->dev, "%s: Found supply : %s\n", 208 psy->desc->name, epsy->desc->name); 209 psy->supplied_from[i-1] = (char *)epsy->desc->name; 210 psy->num_supplies++; 211 fwnode_handle_put(np); 212 break; 213 } 214 fwnode_handle_put(np); 215 } while (true); 216 217 return 0; 218 } 219 220 static int power_supply_populate_supplied_from(struct power_supply *psy) 221 { 222 int error; 223 224 error = power_supply_for_each_psy(psy, __power_supply_populate_supplied_from); 225 226 dev_dbg(&psy->dev, "%s %d\n", __func__, error); 227 228 return error; 229 } 230 231 static int __power_supply_find_supply_from_node(struct power_supply *epsy, 232 void *data) 233 { 234 struct fwnode_handle *fwnode = data; 235 236 /* returning non-zero breaks out of power_supply_for_each_psy loop */ 237 if (epsy->dev.fwnode == fwnode) 238 return 1; 239 240 return 0; 241 } 242 243 static int power_supply_find_supply_from_fwnode(struct fwnode_handle *supply_node) 244 { 245 int error; 246 247 /* 248 * power_supply_for_each_psy() either returns its own errors or values 249 * returned by __power_supply_find_supply_from_node(). 250 * 251 * __power_supply_find_supply_from_fwnode() will return 0 (no match) 252 * or 1 (match). 253 * 254 * We return 0 if power_supply_for_each_psy() returned 1, -EPROBE_DEFER if 255 * it returned 0, or error as returned by it. 256 */ 257 error = power_supply_for_each_psy(supply_node, __power_supply_find_supply_from_node); 258 259 return error ? (error == 1 ? 0 : error) : -EPROBE_DEFER; 260 } 261 262 static int power_supply_check_supplies(struct power_supply *psy) 263 { 264 struct fwnode_handle *np; 265 int cnt = 0; 266 267 /* If there is already a list honor it */ 268 if (psy->supplied_from && psy->num_supplies > 0) 269 return 0; 270 271 /* No device node found, nothing to do */ 272 if (!psy->dev.fwnode) 273 return 0; 274 275 do { 276 int ret; 277 278 np = fwnode_find_reference(psy->dev.fwnode, "power-supplies", cnt++); 279 if (IS_ERR(np)) 280 break; 281 282 ret = power_supply_find_supply_from_fwnode(np); 283 fwnode_handle_put(np); 284 285 if (ret) { 286 dev_dbg(&psy->dev, "Failed to find supply!\n"); 287 return ret; 288 } 289 } while (!IS_ERR(np)); 290 291 /* Missing valid "power-supplies" entries */ 292 if (cnt == 1) 293 return 0; 294 295 /* All supplies found, allocate char * array for filling */ 296 psy->supplied_from = devm_kcalloc(&psy->dev, 297 cnt - 1, sizeof(*psy->supplied_from), 298 GFP_KERNEL); 299 if (!psy->supplied_from) 300 return -ENOMEM; 301 302 return power_supply_populate_supplied_from(psy); 303 } 304 #else 305 static int power_supply_check_supplies(struct power_supply *psy) 306 { 307 int nval, ret; 308 309 if (!psy->dev.parent) 310 return 0; 311 312 nval = device_property_string_array_count(psy->dev.parent, "supplied-from"); 313 if (nval <= 0) 314 return 0; 315 316 psy->supplied_from = devm_kmalloc_array(&psy->dev, nval, 317 sizeof(char *), GFP_KERNEL); 318 if (!psy->supplied_from) 319 return -ENOMEM; 320 321 ret = device_property_read_string_array(psy->dev.parent, 322 "supplied-from", (const char **)psy->supplied_from, nval); 323 if (ret < 0) 324 return ret; 325 326 psy->num_supplies = nval; 327 328 return 0; 329 } 330 #endif 331 332 struct psy_am_i_supplied_data { 333 struct power_supply *psy; 334 unsigned int count; 335 }; 336 337 static int __power_supply_am_i_supplied(struct power_supply *epsy, void *_data) 338 { 339 union power_supply_propval ret = {0,}; 340 struct psy_am_i_supplied_data *data = _data; 341 342 if (__power_supply_is_supplied_by(epsy, data->psy)) { 343 data->count++; 344 if (!epsy->desc->get_property(epsy, POWER_SUPPLY_PROP_ONLINE, 345 &ret)) 346 return ret.intval; 347 } 348 349 return 0; 350 } 351 352 int power_supply_am_i_supplied(struct power_supply *psy) 353 { 354 struct psy_am_i_supplied_data data = { psy, 0 }; 355 int error; 356 357 error = power_supply_for_each_psy(&data, __power_supply_am_i_supplied); 358 359 dev_dbg(&psy->dev, "%s count %u err %d\n", __func__, data.count, error); 360 361 if (data.count == 0) 362 return -ENODEV; 363 364 return error; 365 } 366 EXPORT_SYMBOL_GPL(power_supply_am_i_supplied); 367 368 static int __power_supply_is_system_supplied(struct power_supply *psy, void *data) 369 { 370 union power_supply_propval ret = {0,}; 371 unsigned int *count = data; 372 373 if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) 374 if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) 375 return 0; 376 377 (*count)++; 378 if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) 379 if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, 380 &ret)) 381 return ret.intval; 382 383 return 0; 384 } 385 386 int power_supply_is_system_supplied(void) 387 { 388 int error; 389 unsigned int count = 0; 390 391 error = power_supply_for_each_psy(&count, __power_supply_is_system_supplied); 392 393 /* 394 * If no system scope power class device was found at all, most probably we 395 * are running on a desktop system, so assume we are on mains power. 396 */ 397 if (count == 0) 398 return 1; 399 400 return error; 401 } 402 EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); 403 404 struct psy_get_supplier_prop_data { 405 struct power_supply *psy; 406 enum power_supply_property psp; 407 union power_supply_propval *val; 408 }; 409 410 static int __power_supply_get_supplier_property(struct power_supply *epsy, void *_data) 411 { 412 struct psy_get_supplier_prop_data *data = _data; 413 414 if (__power_supply_is_supplied_by(epsy, data->psy)) 415 if (!power_supply_get_property(epsy, data->psp, data->val)) 416 return 1; /* Success */ 417 418 return 0; /* Continue iterating */ 419 } 420 421 int power_supply_get_property_from_supplier(struct power_supply *psy, 422 enum power_supply_property psp, 423 union power_supply_propval *val) 424 { 425 struct psy_get_supplier_prop_data data = { 426 .psy = psy, 427 .psp = psp, 428 .val = val, 429 }; 430 int ret; 431 432 /* 433 * This function is not intended for use with a supply with multiple 434 * suppliers, we simply pick the first supply to report the psp. 435 */ 436 ret = power_supply_for_each_psy(&data, __power_supply_get_supplier_property); 437 if (ret < 0) 438 return ret; 439 if (ret == 0) 440 return -ENODEV; 441 442 return 0; 443 } 444 EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier); 445 446 static int power_supply_match_device_by_name(struct device *dev, const void *data) 447 { 448 const char *name = data; 449 struct power_supply *psy = dev_to_psy(dev); 450 451 return strcmp(psy->desc->name, name) == 0; 452 } 453 454 /** 455 * power_supply_get_by_name() - Search for a power supply and returns its ref 456 * @name: Power supply name to fetch 457 * 458 * If power supply was found, it increases reference count for the 459 * internal power supply's device. The user should power_supply_put() 460 * after usage. 461 * 462 * Return: On success returns a reference to a power supply with 463 * matching name equals to @name, a NULL otherwise. 464 */ 465 struct power_supply *power_supply_get_by_name(const char *name) 466 { 467 struct power_supply *psy = NULL; 468 struct device *dev = class_find_device(&power_supply_class, NULL, name, 469 power_supply_match_device_by_name); 470 471 if (dev) { 472 psy = dev_to_psy(dev); 473 atomic_inc(&psy->use_cnt); 474 } 475 476 return psy; 477 } 478 EXPORT_SYMBOL_GPL(power_supply_get_by_name); 479 480 /** 481 * power_supply_put() - Drop reference obtained with power_supply_get_by_name 482 * @psy: Reference to put 483 * 484 * The reference to power supply should be put before unregistering 485 * the power supply. 486 */ 487 void power_supply_put(struct power_supply *psy) 488 { 489 atomic_dec(&psy->use_cnt); 490 put_device(&psy->dev); 491 } 492 EXPORT_SYMBOL_GPL(power_supply_put); 493 494 static int power_supply_match_device_fwnode(struct device *dev, const void *data) 495 { 496 return dev->parent && dev_fwnode(dev->parent) == data; 497 } 498 499 /** 500 * power_supply_get_by_reference() - Search for a power supply and returns its ref 501 * @fwnode: Pointer to fwnode holding phandle property 502 * @property: Name of property holding a power supply name 503 * 504 * If power supply was found, it increases reference count for the 505 * internal power supply's device. The user should power_supply_put() 506 * after usage. 507 * 508 * Return: On success returns a reference to a power supply with 509 * matching name equals to value under @property, NULL or ERR_PTR otherwise. 510 */ 511 struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode, 512 const char *property) 513 { 514 struct fwnode_handle *power_supply_fwnode; 515 struct power_supply *psy = NULL; 516 struct device *dev; 517 518 power_supply_fwnode = fwnode_find_reference(fwnode, property, 0); 519 if (IS_ERR(power_supply_fwnode)) 520 return ERR_CAST(power_supply_fwnode); 521 522 dev = class_find_device(&power_supply_class, NULL, power_supply_fwnode, 523 power_supply_match_device_fwnode); 524 525 fwnode_handle_put(power_supply_fwnode); 526 527 if (dev) { 528 psy = dev_to_psy(dev); 529 atomic_inc(&psy->use_cnt); 530 } 531 532 return psy; 533 } 534 EXPORT_SYMBOL_GPL(power_supply_get_by_reference); 535 536 static void devm_power_supply_put(struct device *dev, void *res) 537 { 538 struct power_supply **psy = res; 539 540 power_supply_put(*psy); 541 } 542 543 /** 544 * devm_power_supply_get_by_reference() - Resource managed version of 545 * power_supply_get_by_reference() 546 * @dev: Pointer to device holding phandle property 547 * @property: Name of property holding a power supply phandle 548 * 549 * Return: On success returns a reference to a power supply with 550 * matching name equals to value under @property, NULL or ERR_PTR otherwise. 551 */ 552 struct power_supply *devm_power_supply_get_by_reference(struct device *dev, 553 const char *property) 554 { 555 struct power_supply **ptr, *psy; 556 557 if (!dev_fwnode(dev)) 558 return ERR_PTR(-ENODEV); 559 560 ptr = devres_alloc(devm_power_supply_put, sizeof(*ptr), GFP_KERNEL); 561 if (!ptr) 562 return ERR_PTR(-ENOMEM); 563 564 psy = power_supply_get_by_reference(dev_fwnode(dev), property); 565 if (IS_ERR_OR_NULL(psy)) { 566 devres_free(ptr); 567 } else { 568 *ptr = psy; 569 devres_add(dev, ptr); 570 } 571 return psy; 572 } 573 EXPORT_SYMBOL_GPL(devm_power_supply_get_by_reference); 574 575 int power_supply_get_battery_info(struct power_supply *psy, 576 struct power_supply_battery_info **info_out) 577 { 578 struct power_supply_resistance_temp_table *resist_table; 579 struct power_supply_battery_info *info; 580 struct fwnode_handle *srcnode, *fwnode; 581 const char *value; 582 int err, len, index, proplen; 583 u32 *propdata __free(kfree) = NULL; 584 u32 min_max[2]; 585 586 srcnode = dev_fwnode(&psy->dev); 587 if (!srcnode && psy->dev.parent) 588 srcnode = dev_fwnode(psy->dev.parent); 589 590 fwnode = fwnode_find_reference(srcnode, "monitored-battery", 0); 591 if (IS_ERR(fwnode)) 592 return PTR_ERR(fwnode); 593 594 err = fwnode_property_read_string(fwnode, "compatible", &value); 595 if (err) 596 goto out_put_node; 597 598 599 /* Try static batteries first */ 600 err = samsung_sdi_battery_get_info(&psy->dev, value, &info); 601 if (!err) 602 goto out_ret_pointer; 603 else if (err == -ENODEV) 604 /* 605 * Device does not have a static battery. 606 * Proceed to look for a simple battery. 607 */ 608 err = 0; 609 610 if (strcmp("simple-battery", value)) { 611 err = -ENODEV; 612 goto out_put_node; 613 } 614 615 info = devm_kzalloc(&psy->dev, sizeof(*info), GFP_KERNEL); 616 if (!info) { 617 err = -ENOMEM; 618 goto out_put_node; 619 } 620 621 info->technology = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 622 info->energy_full_design_uwh = -EINVAL; 623 info->charge_full_design_uah = -EINVAL; 624 info->voltage_min_design_uv = -EINVAL; 625 info->voltage_max_design_uv = -EINVAL; 626 info->precharge_current_ua = -EINVAL; 627 info->charge_term_current_ua = -EINVAL; 628 info->constant_charge_current_max_ua = -EINVAL; 629 info->constant_charge_voltage_max_uv = -EINVAL; 630 info->tricklecharge_current_ua = -EINVAL; 631 info->precharge_voltage_max_uv = -EINVAL; 632 info->charge_restart_voltage_uv = -EINVAL; 633 info->overvoltage_limit_uv = -EINVAL; 634 info->maintenance_charge = NULL; 635 info->alert_low_temp_charge_current_ua = -EINVAL; 636 info->alert_low_temp_charge_voltage_uv = -EINVAL; 637 info->alert_high_temp_charge_current_ua = -EINVAL; 638 info->alert_high_temp_charge_voltage_uv = -EINVAL; 639 info->temp_ambient_alert_min = INT_MIN; 640 info->temp_ambient_alert_max = INT_MAX; 641 info->temp_alert_min = INT_MIN; 642 info->temp_alert_max = INT_MAX; 643 info->temp_min = INT_MIN; 644 info->temp_max = INT_MAX; 645 info->factory_internal_resistance_uohm = -EINVAL; 646 info->resist_table = NULL; 647 info->bti_resistance_ohm = -EINVAL; 648 info->bti_resistance_tolerance = -EINVAL; 649 650 for (index = 0; index < POWER_SUPPLY_OCV_TEMP_MAX; index++) { 651 info->ocv_table[index] = NULL; 652 info->ocv_temp[index] = -EINVAL; 653 info->ocv_table_size[index] = -EINVAL; 654 } 655 656 /* The property and field names below must correspond to elements 657 * in enum power_supply_property. For reasoning, see 658 * Documentation/power/power_supply_class.rst. 659 */ 660 661 if (!fwnode_property_read_string(fwnode, "device-chemistry", &value)) { 662 if (!strcmp("nickel-cadmium", value)) 663 info->technology = POWER_SUPPLY_TECHNOLOGY_NiCd; 664 else if (!strcmp("nickel-metal-hydride", value)) 665 info->technology = POWER_SUPPLY_TECHNOLOGY_NiMH; 666 else if (!strcmp("lithium-ion", value)) 667 /* Imprecise lithium-ion type */ 668 info->technology = POWER_SUPPLY_TECHNOLOGY_LION; 669 else if (!strcmp("lithium-ion-polymer", value)) 670 info->technology = POWER_SUPPLY_TECHNOLOGY_LIPO; 671 else if (!strcmp("lithium-ion-iron-phosphate", value)) 672 info->technology = POWER_SUPPLY_TECHNOLOGY_LiFe; 673 else if (!strcmp("lithium-ion-manganese-oxide", value)) 674 info->technology = POWER_SUPPLY_TECHNOLOGY_LiMn; 675 else 676 dev_warn(&psy->dev, "%s unknown battery type\n", value); 677 } 678 679 fwnode_property_read_u32(fwnode, "energy-full-design-microwatt-hours", 680 &info->energy_full_design_uwh); 681 fwnode_property_read_u32(fwnode, "charge-full-design-microamp-hours", 682 &info->charge_full_design_uah); 683 fwnode_property_read_u32(fwnode, "voltage-min-design-microvolt", 684 &info->voltage_min_design_uv); 685 fwnode_property_read_u32(fwnode, "voltage-max-design-microvolt", 686 &info->voltage_max_design_uv); 687 fwnode_property_read_u32(fwnode, "trickle-charge-current-microamp", 688 &info->tricklecharge_current_ua); 689 fwnode_property_read_u32(fwnode, "precharge-current-microamp", 690 &info->precharge_current_ua); 691 fwnode_property_read_u32(fwnode, "precharge-upper-limit-microvolt", 692 &info->precharge_voltage_max_uv); 693 fwnode_property_read_u32(fwnode, "charge-term-current-microamp", 694 &info->charge_term_current_ua); 695 fwnode_property_read_u32(fwnode, "re-charge-voltage-microvolt", 696 &info->charge_restart_voltage_uv); 697 fwnode_property_read_u32(fwnode, "over-voltage-threshold-microvolt", 698 &info->overvoltage_limit_uv); 699 fwnode_property_read_u32(fwnode, "constant-charge-current-max-microamp", 700 &info->constant_charge_current_max_ua); 701 fwnode_property_read_u32(fwnode, "constant-charge-voltage-max-microvolt", 702 &info->constant_charge_voltage_max_uv); 703 fwnode_property_read_u32(fwnode, "factory-internal-resistance-micro-ohms", 704 &info->factory_internal_resistance_uohm); 705 706 if (!fwnode_property_read_u32_array(fwnode, "ambient-celsius", 707 min_max, ARRAY_SIZE(min_max))) { 708 info->temp_ambient_alert_min = min_max[0]; 709 info->temp_ambient_alert_max = min_max[1]; 710 } 711 if (!fwnode_property_read_u32_array(fwnode, "alert-celsius", 712 min_max, ARRAY_SIZE(min_max))) { 713 info->temp_alert_min = min_max[0]; 714 info->temp_alert_max = min_max[1]; 715 } 716 if (!fwnode_property_read_u32_array(fwnode, "operating-range-celsius", 717 min_max, ARRAY_SIZE(min_max))) { 718 info->temp_min = min_max[0]; 719 info->temp_max = min_max[1]; 720 } 721 722 len = fwnode_property_count_u32(fwnode, "ocv-capacity-celsius"); 723 if (len < 0 && len != -EINVAL) { 724 err = len; 725 goto out_put_node; 726 } else if (len > POWER_SUPPLY_OCV_TEMP_MAX) { 727 dev_err(&psy->dev, "Too many temperature values\n"); 728 err = -EINVAL; 729 goto out_put_node; 730 } else if (len > 0) { 731 fwnode_property_read_u32_array(fwnode, "ocv-capacity-celsius", 732 info->ocv_temp, len); 733 } 734 735 for (index = 0; index < len; index++) { 736 struct power_supply_battery_ocv_table *table; 737 int i, tab_len; 738 739 char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", 740 index); 741 if (!propname) { 742 power_supply_put_battery_info(psy, info); 743 err = -ENOMEM; 744 goto out_put_node; 745 } 746 proplen = fwnode_property_count_u32(fwnode, propname); 747 if (proplen < 0 || proplen % 2 != 0) { 748 dev_err(&psy->dev, "failed to get %s\n", propname); 749 power_supply_put_battery_info(psy, info); 750 err = -EINVAL; 751 goto out_put_node; 752 } 753 754 u32 *propdata __free(kfree) = kcalloc(proplen, sizeof(*propdata), GFP_KERNEL); 755 if (!propdata) { 756 power_supply_put_battery_info(psy, info); 757 err = -EINVAL; 758 goto out_put_node; 759 } 760 err = fwnode_property_read_u32_array(fwnode, propname, propdata, proplen); 761 if (err < 0) { 762 dev_err(&psy->dev, "failed to get %s\n", propname); 763 power_supply_put_battery_info(psy, info); 764 goto out_put_node; 765 } 766 767 tab_len = proplen / 2; 768 info->ocv_table_size[index] = tab_len; 769 770 info->ocv_table[index] = table = 771 devm_kcalloc(&psy->dev, tab_len, sizeof(*table), GFP_KERNEL); 772 if (!info->ocv_table[index]) { 773 power_supply_put_battery_info(psy, info); 774 err = -ENOMEM; 775 goto out_put_node; 776 } 777 778 for (i = 0; i < tab_len; i++) { 779 table[i].ocv = propdata[i*2]; 780 table[i].capacity = propdata[i*2+1]; 781 } 782 } 783 784 proplen = fwnode_property_count_u32(fwnode, "resistance-temp-table"); 785 if (proplen == 0 || proplen == -EINVAL) { 786 err = 0; 787 goto out_ret_pointer; 788 } else if (proplen < 0 || proplen % 2 != 0) { 789 power_supply_put_battery_info(psy, info); 790 err = (proplen < 0) ? proplen : -EINVAL; 791 goto out_put_node; 792 } 793 794 propdata = kcalloc(proplen, sizeof(*propdata), GFP_KERNEL); 795 if (!propdata) { 796 power_supply_put_battery_info(psy, info); 797 err = -ENOMEM; 798 goto out_put_node; 799 } 800 801 err = fwnode_property_read_u32_array(fwnode, "resistance-temp-table", 802 propdata, proplen); 803 if (err < 0) { 804 power_supply_put_battery_info(psy, info); 805 goto out_put_node; 806 } 807 808 info->resist_table_size = proplen / 2; 809 info->resist_table = resist_table = devm_kcalloc(&psy->dev, 810 info->resist_table_size, 811 sizeof(*resist_table), 812 GFP_KERNEL); 813 if (!info->resist_table) { 814 power_supply_put_battery_info(psy, info); 815 err = -ENOMEM; 816 goto out_put_node; 817 } 818 819 for (index = 0; index < info->resist_table_size; index++) { 820 resist_table[index].temp = propdata[index*2]; 821 resist_table[index].resistance = propdata[index*2+1]; 822 } 823 824 out_ret_pointer: 825 /* Finally return the whole thing */ 826 *info_out = info; 827 828 out_put_node: 829 fwnode_handle_put(fwnode); 830 return err; 831 } 832 EXPORT_SYMBOL_GPL(power_supply_get_battery_info); 833 834 void power_supply_put_battery_info(struct power_supply *psy, 835 struct power_supply_battery_info *info) 836 { 837 int i; 838 839 for (i = 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) { 840 if (info->ocv_table[i]) 841 devm_kfree(&psy->dev, info->ocv_table[i]); 842 } 843 844 if (info->resist_table) 845 devm_kfree(&psy->dev, info->resist_table); 846 847 devm_kfree(&psy->dev, info); 848 } 849 EXPORT_SYMBOL_GPL(power_supply_put_battery_info); 850 851 const enum power_supply_property power_supply_battery_info_properties[] = { 852 POWER_SUPPLY_PROP_TECHNOLOGY, 853 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 854 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 855 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 856 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 857 POWER_SUPPLY_PROP_PRECHARGE_CURRENT, 858 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, 859 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 860 POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 861 POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN, 862 POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX, 863 POWER_SUPPLY_PROP_TEMP_ALERT_MIN, 864 POWER_SUPPLY_PROP_TEMP_ALERT_MAX, 865 POWER_SUPPLY_PROP_TEMP_MIN, 866 POWER_SUPPLY_PROP_TEMP_MAX, 867 }; 868 EXPORT_SYMBOL_GPL(power_supply_battery_info_properties); 869 870 const size_t power_supply_battery_info_properties_size = ARRAY_SIZE(power_supply_battery_info_properties); 871 EXPORT_SYMBOL_GPL(power_supply_battery_info_properties_size); 872 873 bool power_supply_battery_info_has_prop(struct power_supply_battery_info *info, 874 enum power_supply_property psp) 875 { 876 if (!info) 877 return false; 878 879 switch (psp) { 880 case POWER_SUPPLY_PROP_TECHNOLOGY: 881 return info->technology != POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 882 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 883 return info->energy_full_design_uwh >= 0; 884 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 885 return info->charge_full_design_uah >= 0; 886 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 887 return info->voltage_min_design_uv >= 0; 888 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 889 return info->voltage_max_design_uv >= 0; 890 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: 891 return info->precharge_current_ua >= 0; 892 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 893 return info->charge_term_current_ua >= 0; 894 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 895 return info->constant_charge_current_max_ua >= 0; 896 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 897 return info->constant_charge_voltage_max_uv >= 0; 898 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN: 899 return info->temp_ambient_alert_min > INT_MIN; 900 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX: 901 return info->temp_ambient_alert_max < INT_MAX; 902 case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: 903 return info->temp_alert_min > INT_MIN; 904 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 905 return info->temp_alert_max < INT_MAX; 906 case POWER_SUPPLY_PROP_TEMP_MIN: 907 return info->temp_min > INT_MIN; 908 case POWER_SUPPLY_PROP_TEMP_MAX: 909 return info->temp_max < INT_MAX; 910 default: 911 return false; 912 } 913 } 914 EXPORT_SYMBOL_GPL(power_supply_battery_info_has_prop); 915 916 int power_supply_battery_info_get_prop(struct power_supply_battery_info *info, 917 enum power_supply_property psp, 918 union power_supply_propval *val) 919 { 920 if (!info) 921 return -EINVAL; 922 923 if (!power_supply_battery_info_has_prop(info, psp)) 924 return -EINVAL; 925 926 switch (psp) { 927 case POWER_SUPPLY_PROP_TECHNOLOGY: 928 val->intval = info->technology; 929 return 0; 930 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 931 val->intval = info->energy_full_design_uwh; 932 return 0; 933 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 934 val->intval = info->charge_full_design_uah; 935 return 0; 936 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 937 val->intval = info->voltage_min_design_uv; 938 return 0; 939 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 940 val->intval = info->voltage_max_design_uv; 941 return 0; 942 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: 943 val->intval = info->precharge_current_ua; 944 return 0; 945 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 946 val->intval = info->charge_term_current_ua; 947 return 0; 948 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 949 val->intval = info->constant_charge_current_max_ua; 950 return 0; 951 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 952 val->intval = info->constant_charge_voltage_max_uv; 953 return 0; 954 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN: 955 val->intval = info->temp_ambient_alert_min; 956 return 0; 957 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX: 958 val->intval = info->temp_ambient_alert_max; 959 return 0; 960 case POWER_SUPPLY_PROP_TEMP_ALERT_MIN: 961 val->intval = info->temp_alert_min; 962 return 0; 963 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX: 964 val->intval = info->temp_alert_max; 965 return 0; 966 case POWER_SUPPLY_PROP_TEMP_MIN: 967 val->intval = info->temp_min; 968 return 0; 969 case POWER_SUPPLY_PROP_TEMP_MAX: 970 val->intval = info->temp_max; 971 return 0; 972 default: 973 return -EINVAL; 974 } 975 } 976 EXPORT_SYMBOL_GPL(power_supply_battery_info_get_prop); 977 978 /** 979 * power_supply_temp2resist_simple() - find the battery internal resistance 980 * percent from temperature 981 * @table: Pointer to battery resistance temperature table 982 * @table_len: The table length 983 * @temp: Current temperature 984 * 985 * This helper function is used to look up battery internal resistance percent 986 * according to current temperature value from the resistance temperature table, 987 * and the table must be ordered descending. Then the actual battery internal 988 * resistance = the ideal battery internal resistance * percent / 100. 989 * 990 * Return: the battery internal resistance percent 991 */ 992 int power_supply_temp2resist_simple(const struct power_supply_resistance_temp_table *table, 993 int table_len, int temp) 994 { 995 int i, high, low; 996 997 for (i = 0; i < table_len; i++) 998 if (temp > table[i].temp) 999 break; 1000 1001 /* The library function will deal with high == low */ 1002 if (i == 0) 1003 high = low = i; 1004 else if (i == table_len) 1005 high = low = i - 1; 1006 else 1007 high = (low = i) - 1; 1008 1009 return fixp_linear_interpolate(table[low].temp, 1010 table[low].resistance, 1011 table[high].temp, 1012 table[high].resistance, 1013 temp); 1014 } 1015 EXPORT_SYMBOL_GPL(power_supply_temp2resist_simple); 1016 1017 /** 1018 * power_supply_vbat2ri() - find the battery internal resistance 1019 * from the battery voltage 1020 * @info: The battery information container 1021 * @vbat_uv: The battery voltage in microvolt 1022 * @charging: If we are charging (true) or not (false) 1023 * 1024 * This helper function is used to look up battery internal resistance 1025 * according to current battery voltage. Depending on whether the battery 1026 * is currently charging or not, different resistance will be returned. 1027 * 1028 * Returns the internal resistance in microohm or negative error code. 1029 */ 1030 int power_supply_vbat2ri(struct power_supply_battery_info *info, 1031 int vbat_uv, bool charging) 1032 { 1033 const struct power_supply_vbat_ri_table *vbat2ri; 1034 int table_len; 1035 int i, high, low; 1036 1037 /* 1038 * If we are charging, and the battery supplies a separate table 1039 * for this state, we use that in order to compensate for the 1040 * charging voltage. Otherwise we use the main table. 1041 */ 1042 if (charging && info->vbat2ri_charging) { 1043 vbat2ri = info->vbat2ri_charging; 1044 table_len = info->vbat2ri_charging_size; 1045 } else { 1046 vbat2ri = info->vbat2ri_discharging; 1047 table_len = info->vbat2ri_discharging_size; 1048 } 1049 1050 /* 1051 * If no tables are specified, or if we are above the highest voltage in 1052 * the voltage table, just return the factory specified internal resistance. 1053 */ 1054 if (!vbat2ri || (table_len <= 0) || (vbat_uv > vbat2ri[0].vbat_uv)) { 1055 if (charging && (info->factory_internal_resistance_charging_uohm > 0)) 1056 return info->factory_internal_resistance_charging_uohm; 1057 else 1058 return info->factory_internal_resistance_uohm; 1059 } 1060 1061 /* Break loop at table_len - 1 because that is the highest index */ 1062 for (i = 0; i < table_len - 1; i++) 1063 if (vbat_uv > vbat2ri[i].vbat_uv) 1064 break; 1065 1066 /* The library function will deal with high == low */ 1067 if ((i == 0) || (i == (table_len - 1))) 1068 high = i; 1069 else 1070 high = i - 1; 1071 low = i; 1072 1073 return fixp_linear_interpolate(vbat2ri[low].vbat_uv, 1074 vbat2ri[low].ri_uohm, 1075 vbat2ri[high].vbat_uv, 1076 vbat2ri[high].ri_uohm, 1077 vbat_uv); 1078 } 1079 EXPORT_SYMBOL_GPL(power_supply_vbat2ri); 1080 1081 const struct power_supply_maintenance_charge_table * 1082 power_supply_get_maintenance_charging_setting(struct power_supply_battery_info *info, 1083 int index) 1084 { 1085 if (index >= info->maintenance_charge_size) 1086 return NULL; 1087 return &info->maintenance_charge[index]; 1088 } 1089 EXPORT_SYMBOL_GPL(power_supply_get_maintenance_charging_setting); 1090 1091 /** 1092 * power_supply_ocv2cap_simple() - find the battery capacity 1093 * @table: Pointer to battery OCV lookup table 1094 * @table_len: OCV table length 1095 * @ocv: Current OCV value 1096 * 1097 * This helper function is used to look up battery capacity according to 1098 * current OCV value from one OCV table, and the OCV table must be ordered 1099 * descending. 1100 * 1101 * Return: the battery capacity. 1102 */ 1103 int power_supply_ocv2cap_simple(const struct power_supply_battery_ocv_table *table, 1104 int table_len, int ocv) 1105 { 1106 int i, high, low; 1107 1108 for (i = 0; i < table_len; i++) 1109 if (ocv > table[i].ocv) 1110 break; 1111 1112 /* The library function will deal with high == low */ 1113 if (i == 0) 1114 high = low = i; 1115 else if (i == table_len) 1116 high = low = i - 1; 1117 else 1118 high = (low = i) - 1; 1119 1120 return fixp_linear_interpolate(table[low].ocv, 1121 table[low].capacity, 1122 table[high].ocv, 1123 table[high].capacity, 1124 ocv); 1125 } 1126 EXPORT_SYMBOL_GPL(power_supply_ocv2cap_simple); 1127 1128 const struct power_supply_battery_ocv_table * 1129 power_supply_find_ocv2cap_table(struct power_supply_battery_info *info, 1130 int temp, int *table_len) 1131 { 1132 int best_temp_diff = INT_MAX, temp_diff; 1133 u8 i, best_index = 0; 1134 1135 if (!info->ocv_table[0]) 1136 return NULL; 1137 1138 for (i = 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) { 1139 /* Out of capacity tables */ 1140 if (!info->ocv_table[i]) 1141 break; 1142 1143 temp_diff = abs(info->ocv_temp[i] - temp); 1144 1145 if (temp_diff < best_temp_diff) { 1146 best_temp_diff = temp_diff; 1147 best_index = i; 1148 } 1149 } 1150 1151 *table_len = info->ocv_table_size[best_index]; 1152 return info->ocv_table[best_index]; 1153 } 1154 EXPORT_SYMBOL_GPL(power_supply_find_ocv2cap_table); 1155 1156 int power_supply_batinfo_ocv2cap(struct power_supply_battery_info *info, 1157 int ocv, int temp) 1158 { 1159 const struct power_supply_battery_ocv_table *table; 1160 int table_len; 1161 1162 table = power_supply_find_ocv2cap_table(info, temp, &table_len); 1163 if (!table) 1164 return -EINVAL; 1165 1166 return power_supply_ocv2cap_simple(table, table_len, ocv); 1167 } 1168 EXPORT_SYMBOL_GPL(power_supply_batinfo_ocv2cap); 1169 1170 bool power_supply_battery_bti_in_range(struct power_supply_battery_info *info, 1171 int resistance) 1172 { 1173 int low, high; 1174 1175 /* Nothing like this can be checked */ 1176 if (info->bti_resistance_ohm <= 0) 1177 return false; 1178 1179 /* This will be extremely strict and unlikely to work */ 1180 if (info->bti_resistance_tolerance <= 0) 1181 return (info->bti_resistance_ohm == resistance); 1182 1183 low = info->bti_resistance_ohm - 1184 (info->bti_resistance_ohm * info->bti_resistance_tolerance) / 100; 1185 high = info->bti_resistance_ohm + 1186 (info->bti_resistance_ohm * info->bti_resistance_tolerance) / 100; 1187 1188 return ((resistance >= low) && (resistance <= high)); 1189 } 1190 EXPORT_SYMBOL_GPL(power_supply_battery_bti_in_range); 1191 1192 static bool psy_desc_has_property(const struct power_supply_desc *psy_desc, 1193 enum power_supply_property psp) 1194 { 1195 bool found = false; 1196 int i; 1197 1198 for (i = 0; i < psy_desc->num_properties; i++) { 1199 if (psy_desc->properties[i] == psp) { 1200 found = true; 1201 break; 1202 } 1203 } 1204 1205 return found; 1206 } 1207 1208 bool power_supply_ext_has_property(const struct power_supply_ext *psy_ext, 1209 enum power_supply_property psp) 1210 { 1211 int i; 1212 1213 for (i = 0; i < psy_ext->num_properties; i++) 1214 if (psy_ext->properties[i] == psp) 1215 return true; 1216 1217 return false; 1218 } 1219 1220 bool power_supply_has_property(struct power_supply *psy, 1221 enum power_supply_property psp) 1222 { 1223 struct power_supply_ext_registration *reg; 1224 1225 if (psy_desc_has_property(psy->desc, psp)) 1226 return true; 1227 1228 if (power_supply_battery_info_has_prop(psy->battery_info, psp)) 1229 return true; 1230 1231 power_supply_for_each_extension(reg, psy) { 1232 if (power_supply_ext_has_property(reg->ext, psp)) 1233 return true; 1234 } 1235 1236 return false; 1237 } 1238 1239 static int __power_supply_get_property(struct power_supply *psy, enum power_supply_property psp, 1240 union power_supply_propval *val, bool use_extensions) 1241 { 1242 struct power_supply_ext_registration *reg; 1243 1244 if (atomic_read(&psy->use_cnt) <= 0) { 1245 if (!psy->initialized) 1246 return -EAGAIN; 1247 return -ENODEV; 1248 } 1249 1250 if (use_extensions) { 1251 scoped_guard(rwsem_read, &psy->extensions_sem) { 1252 power_supply_for_each_extension(reg, psy) { 1253 if (!power_supply_ext_has_property(reg->ext, psp)) 1254 continue; 1255 1256 return reg->ext->get_property(psy, reg->ext, reg->data, psp, val); 1257 } 1258 } 1259 } 1260 1261 if (psy_desc_has_property(psy->desc, psp)) 1262 return psy->desc->get_property(psy, psp, val); 1263 else if (power_supply_battery_info_has_prop(psy->battery_info, psp)) 1264 return power_supply_battery_info_get_prop(psy->battery_info, psp, val); 1265 else 1266 return -EINVAL; 1267 } 1268 1269 int power_supply_get_property(struct power_supply *psy, enum power_supply_property psp, 1270 union power_supply_propval *val) 1271 { 1272 return __power_supply_get_property(psy, psp, val, true); 1273 } 1274 EXPORT_SYMBOL_GPL(power_supply_get_property); 1275 1276 /** 1277 * power_supply_get_property_direct - Read a power supply property without checking for extensions 1278 * @psy: The power supply 1279 * @psp: The power supply property to read 1280 * @val: The resulting value of the power supply property 1281 * 1282 * Read a power supply property without taking into account any power supply extensions registered 1283 * on the given power supply. This is mostly useful for power supply extensions that want to access 1284 * their own power supply as using power_supply_get_property() directly will result in a potential 1285 * deadlock. 1286 * 1287 * Return: 0 on success or negative error code on failure. 1288 */ 1289 int power_supply_get_property_direct(struct power_supply *psy, enum power_supply_property psp, 1290 union power_supply_propval *val) 1291 { 1292 return __power_supply_get_property(psy, psp, val, false); 1293 } 1294 EXPORT_SYMBOL_GPL(power_supply_get_property_direct); 1295 1296 1297 static int __power_supply_set_property(struct power_supply *psy, enum power_supply_property psp, 1298 const union power_supply_propval *val, bool use_extensions) 1299 { 1300 struct power_supply_ext_registration *reg; 1301 1302 if (atomic_read(&psy->use_cnt) <= 0) 1303 return -ENODEV; 1304 1305 if (use_extensions) { 1306 scoped_guard(rwsem_read, &psy->extensions_sem) { 1307 power_supply_for_each_extension(reg, psy) { 1308 if (!power_supply_ext_has_property(reg->ext, psp)) 1309 continue; 1310 1311 if (reg->ext->set_property) 1312 return reg->ext->set_property(psy, reg->ext, reg->data, 1313 psp, val); 1314 else 1315 return -ENODEV; 1316 } 1317 } 1318 } 1319 1320 if (!psy->desc->set_property) 1321 return -ENODEV; 1322 1323 return psy->desc->set_property(psy, psp, val); 1324 } 1325 1326 int power_supply_set_property(struct power_supply *psy, enum power_supply_property psp, 1327 const union power_supply_propval *val) 1328 { 1329 return __power_supply_set_property(psy, psp, val, true); 1330 } 1331 EXPORT_SYMBOL_GPL(power_supply_set_property); 1332 1333 /** 1334 * power_supply_set_property_direct - Write a power supply property without checking for extensions 1335 * @psy: The power supply 1336 * @psp: The power supply property to write 1337 * @val: The value to write to the power supply property 1338 * 1339 * Write a power supply property without taking into account any power supply extensions registered 1340 * on the given power supply. This is mostly useful for power supply extensions that want to access 1341 * their own power supply as using power_supply_set_property() directly will result in a potential 1342 * deadlock. 1343 * 1344 * Return: 0 on success or negative error code on failure. 1345 */ 1346 int power_supply_set_property_direct(struct power_supply *psy, enum power_supply_property psp, 1347 const union power_supply_propval *val) 1348 { 1349 return __power_supply_set_property(psy, psp, val, false); 1350 } 1351 EXPORT_SYMBOL_GPL(power_supply_set_property_direct); 1352 1353 int power_supply_property_is_writeable(struct power_supply *psy, 1354 enum power_supply_property psp) 1355 { 1356 struct power_supply_ext_registration *reg; 1357 1358 power_supply_for_each_extension(reg, psy) { 1359 if (power_supply_ext_has_property(reg->ext, psp)) { 1360 if (reg->ext->property_is_writeable) 1361 return reg->ext->property_is_writeable(psy, reg->ext, 1362 reg->data, psp); 1363 else 1364 return 0; 1365 } 1366 } 1367 1368 if (!psy->desc->property_is_writeable) 1369 return 0; 1370 1371 return psy->desc->property_is_writeable(psy, psp); 1372 } 1373 1374 void power_supply_external_power_changed(struct power_supply *psy) 1375 { 1376 if (atomic_read(&psy->use_cnt) <= 0 || 1377 !psy->desc->external_power_changed) 1378 return; 1379 1380 psy->desc->external_power_changed(psy); 1381 } 1382 EXPORT_SYMBOL_GPL(power_supply_external_power_changed); 1383 1384 int power_supply_powers(struct power_supply *psy, struct device *dev) 1385 { 1386 return sysfs_create_link(&psy->dev.kobj, &dev->kobj, "powers"); 1387 } 1388 EXPORT_SYMBOL_GPL(power_supply_powers); 1389 1390 static int power_supply_update_sysfs_and_hwmon(struct power_supply *psy) 1391 { 1392 unsigned long flags; 1393 1394 spin_lock_irqsave(&psy->changed_lock, flags); 1395 psy->update_groups = true; 1396 spin_unlock_irqrestore(&psy->changed_lock, flags); 1397 1398 power_supply_changed(psy); 1399 1400 power_supply_remove_hwmon_sysfs(psy); 1401 return power_supply_add_hwmon_sysfs(psy); 1402 } 1403 1404 int power_supply_register_extension(struct power_supply *psy, const struct power_supply_ext *ext, 1405 struct device *dev, void *data) 1406 { 1407 struct power_supply_ext_registration *reg; 1408 size_t i; 1409 int ret; 1410 1411 if (!psy || !dev || !ext || !ext->name || !ext->properties || !ext->num_properties) 1412 return -EINVAL; 1413 1414 guard(rwsem_write)(&psy->extensions_sem); 1415 1416 power_supply_for_each_extension(reg, psy) 1417 if (strcmp(ext->name, reg->ext->name) == 0) 1418 return -EEXIST; 1419 1420 for (i = 0; i < ext->num_properties; i++) 1421 if (power_supply_has_property(psy, ext->properties[i])) 1422 return -EEXIST; 1423 1424 reg = kmalloc_obj(*reg); 1425 if (!reg) 1426 return -ENOMEM; 1427 1428 reg->ext = ext; 1429 reg->dev = dev; 1430 reg->data = data; 1431 list_add(®->list_head, &psy->extensions); 1432 1433 ret = power_supply_sysfs_add_extension(psy, ext, dev); 1434 if (ret) 1435 goto sysfs_add_failed; 1436 1437 ret = power_supply_update_sysfs_and_hwmon(psy); 1438 if (ret) 1439 goto sysfs_hwmon_failed; 1440 1441 return 0; 1442 1443 sysfs_hwmon_failed: 1444 power_supply_sysfs_remove_extension(psy, ext); 1445 sysfs_add_failed: 1446 list_del(®->list_head); 1447 kfree(reg); 1448 return ret; 1449 } 1450 EXPORT_SYMBOL_GPL(power_supply_register_extension); 1451 1452 void power_supply_unregister_extension(struct power_supply *psy, const struct power_supply_ext *ext) 1453 { 1454 struct power_supply_ext_registration *reg; 1455 1456 guard(rwsem_write)(&psy->extensions_sem); 1457 1458 power_supply_for_each_extension(reg, psy) { 1459 if (reg->ext == ext) { 1460 list_del(®->list_head); 1461 power_supply_sysfs_remove_extension(psy, ext); 1462 kfree(reg); 1463 power_supply_update_sysfs_and_hwmon(psy); 1464 return; 1465 } 1466 } 1467 1468 dev_warn(&psy->dev, "Trying to unregister invalid extension"); 1469 } 1470 EXPORT_SYMBOL_GPL(power_supply_unregister_extension); 1471 1472 static void power_supply_dev_release(struct device *dev) 1473 { 1474 struct power_supply *psy = to_power_supply(dev); 1475 1476 dev_dbg(dev, "%s\n", __func__); 1477 kfree(psy); 1478 } 1479 1480 int power_supply_reg_notifier(struct notifier_block *nb) 1481 { 1482 return blocking_notifier_chain_register(&power_supply_notifier, nb); 1483 } 1484 EXPORT_SYMBOL_GPL(power_supply_reg_notifier); 1485 1486 void power_supply_unreg_notifier(struct notifier_block *nb) 1487 { 1488 blocking_notifier_chain_unregister(&power_supply_notifier, nb); 1489 } 1490 EXPORT_SYMBOL_GPL(power_supply_unreg_notifier); 1491 1492 #ifdef CONFIG_THERMAL 1493 static int power_supply_read_temp(struct thermal_zone_device *tzd, 1494 int *temp) 1495 { 1496 struct power_supply *psy; 1497 union power_supply_propval val; 1498 int ret; 1499 1500 WARN_ON(tzd == NULL); 1501 psy = thermal_zone_device_priv(tzd); 1502 ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &val); 1503 if (ret) 1504 return ret; 1505 1506 /* Convert tenths of degree Celsius to milli degree Celsius. */ 1507 *temp = val.intval * 100; 1508 1509 return ret; 1510 } 1511 1512 static const struct thermal_zone_device_ops psy_tzd_ops = { 1513 .get_temp = power_supply_read_temp, 1514 }; 1515 1516 static int psy_register_thermal(struct power_supply *psy) 1517 { 1518 int ret; 1519 1520 if (psy->desc->no_thermal) 1521 return 0; 1522 1523 /* Register battery zone device psy reports temperature */ 1524 if (psy_desc_has_property(psy->desc, POWER_SUPPLY_PROP_TEMP)) { 1525 /* Prefer our hwmon device and avoid duplicates */ 1526 struct thermal_zone_params tzp = { 1527 .no_hwmon = IS_ENABLED(CONFIG_POWER_SUPPLY_HWMON) 1528 }; 1529 psy->tzd = thermal_tripless_zone_device_register(psy->desc->name, 1530 psy, &psy_tzd_ops, &tzp); 1531 if (IS_ERR(psy->tzd)) 1532 return PTR_ERR(psy->tzd); 1533 ret = thermal_zone_device_enable(psy->tzd); 1534 if (ret) 1535 thermal_zone_device_unregister(psy->tzd); 1536 return ret; 1537 } 1538 1539 return 0; 1540 } 1541 1542 static void psy_unregister_thermal(struct power_supply *psy) 1543 { 1544 if (IS_ERR_OR_NULL(psy->tzd)) 1545 return; 1546 thermal_zone_device_unregister(psy->tzd); 1547 } 1548 1549 #else 1550 static int psy_register_thermal(struct power_supply *psy) 1551 { 1552 return 0; 1553 } 1554 1555 static void psy_unregister_thermal(struct power_supply *psy) 1556 { 1557 } 1558 #endif 1559 1560 static struct power_supply *__must_check 1561 __power_supply_register(struct device *parent, 1562 const struct power_supply_desc *desc, 1563 const struct power_supply_config *cfg) 1564 { 1565 struct device *dev; 1566 struct power_supply *psy; 1567 int rc; 1568 1569 if (!desc || !desc->name || !desc->properties || !desc->num_properties) 1570 return ERR_PTR(-EINVAL); 1571 1572 if (!parent) 1573 pr_warn("%s: Expected proper parent device for '%s'\n", 1574 __func__, desc->name); 1575 1576 psy = kzalloc(sizeof(*psy), GFP_KERNEL); 1577 if (!psy) 1578 return ERR_PTR(-ENOMEM); 1579 1580 dev = &psy->dev; 1581 1582 device_initialize(dev); 1583 1584 dev->class = &power_supply_class; 1585 dev->type = &power_supply_dev_type; 1586 dev->parent = parent; 1587 dev->release = power_supply_dev_release; 1588 dev_set_drvdata(dev, psy); 1589 psy->desc = desc; 1590 if (cfg) { 1591 device_set_node(dev, cfg->fwnode); 1592 dev->groups = cfg->attr_grp; 1593 psy->drv_data = cfg->drv_data; 1594 psy->supplied_to = cfg->supplied_to; 1595 psy->num_supplicants = cfg->num_supplicants; 1596 } 1597 1598 rc = dev_set_name(dev, "%s", desc->name); 1599 if (rc) 1600 goto dev_set_name_failed; 1601 1602 INIT_WORK(&psy->changed_work, power_supply_changed_work); 1603 INIT_DELAYED_WORK(&psy->deferred_register_work, 1604 power_supply_deferred_register_work); 1605 1606 rc = power_supply_check_supplies(psy); 1607 if (rc) { 1608 dev_dbg(dev, "Not all required supplies found, defer probe\n"); 1609 goto check_supplies_failed; 1610 } 1611 1612 /* 1613 * Expose constant battery info, if it is available. While there are 1614 * some chargers accessing constant battery data, we only want to 1615 * expose battery data to userspace for battery devices. 1616 */ 1617 if (desc->type == POWER_SUPPLY_TYPE_BATTERY) { 1618 rc = power_supply_get_battery_info(psy, &psy->battery_info); 1619 if (rc && rc != -ENODEV && rc != -ENOENT) 1620 goto check_supplies_failed; 1621 } 1622 1623 spin_lock_init(&psy->changed_lock); 1624 init_rwsem(&psy->extensions_sem); 1625 INIT_LIST_HEAD(&psy->extensions); 1626 1627 rc = device_add(dev); 1628 if (rc) 1629 goto device_add_failed; 1630 1631 rc = device_init_wakeup(dev, cfg ? !cfg->no_wakeup_source : true); 1632 if (rc) 1633 goto wakeup_init_failed; 1634 1635 rc = psy_register_thermal(psy); 1636 if (rc) 1637 goto register_thermal_failed; 1638 1639 rc = power_supply_create_triggers(psy); 1640 if (rc) 1641 goto create_triggers_failed; 1642 1643 scoped_guard(rwsem_read, &psy->extensions_sem) { 1644 rc = power_supply_add_hwmon_sysfs(psy); 1645 if (rc) 1646 goto add_hwmon_sysfs_failed; 1647 } 1648 1649 /* 1650 * Update use_cnt after any uevents (most notably from device_add()). 1651 * We are here still during driver's probe but 1652 * the power_supply_uevent() calls back driver's get_property 1653 * method so: 1654 * 1. Driver did not assigned the returned struct power_supply, 1655 * 2. Driver could not finish initialization (anything in its probe 1656 * after calling power_supply_register()). 1657 */ 1658 atomic_inc(&psy->use_cnt); 1659 psy->initialized = true; 1660 1661 queue_delayed_work(system_power_efficient_wq, 1662 &psy->deferred_register_work, 1663 POWER_SUPPLY_DEFERRED_REGISTER_TIME); 1664 1665 return psy; 1666 1667 add_hwmon_sysfs_failed: 1668 power_supply_remove_triggers(psy); 1669 create_triggers_failed: 1670 psy_unregister_thermal(psy); 1671 register_thermal_failed: 1672 wakeup_init_failed: 1673 device_del(dev); 1674 device_add_failed: 1675 check_supplies_failed: 1676 dev_set_name_failed: 1677 put_device(dev); 1678 return ERR_PTR(rc); 1679 } 1680 1681 /** 1682 * power_supply_register() - Register new power supply 1683 * @parent: Device to be a parent of power supply's device, usually 1684 * the device which probe function calls this 1685 * @desc: Description of power supply, must be valid through whole 1686 * lifetime of this power supply 1687 * @cfg: Run-time specific configuration accessed during registering, 1688 * may be NULL 1689 * 1690 * Return: A pointer to newly allocated power_supply on success 1691 * or ERR_PTR otherwise. 1692 * Use power_supply_unregister() on returned power_supply pointer to release 1693 * resources. 1694 */ 1695 struct power_supply *__must_check power_supply_register(struct device *parent, 1696 const struct power_supply_desc *desc, 1697 const struct power_supply_config *cfg) 1698 { 1699 return __power_supply_register(parent, desc, cfg); 1700 } 1701 EXPORT_SYMBOL_GPL(power_supply_register); 1702 1703 static void devm_power_supply_release(struct device *dev, void *res) 1704 { 1705 struct power_supply **psy = res; 1706 1707 power_supply_unregister(*psy); 1708 } 1709 1710 /** 1711 * devm_power_supply_register() - Register managed power supply 1712 * @parent: Device to be a parent of power supply's device, usually 1713 * the device which probe function calls this 1714 * @desc: Description of power supply, must be valid through whole 1715 * lifetime of this power supply 1716 * @cfg: Run-time specific configuration accessed during registering, 1717 * may be NULL 1718 * 1719 * Return: A pointer to newly allocated power_supply on success 1720 * or ERR_PTR otherwise. 1721 * The returned power_supply pointer will be automatically unregistered 1722 * on driver detach. 1723 */ 1724 struct power_supply *__must_check 1725 devm_power_supply_register(struct device *parent, 1726 const struct power_supply_desc *desc, 1727 const struct power_supply_config *cfg) 1728 { 1729 struct power_supply **ptr, *psy; 1730 1731 ptr = devres_alloc(devm_power_supply_release, sizeof(*ptr), GFP_KERNEL); 1732 1733 if (!ptr) 1734 return ERR_PTR(-ENOMEM); 1735 psy = __power_supply_register(parent, desc, cfg); 1736 if (IS_ERR(psy)) { 1737 devres_free(ptr); 1738 } else { 1739 *ptr = psy; 1740 devres_add(parent, ptr); 1741 } 1742 return psy; 1743 } 1744 EXPORT_SYMBOL_GPL(devm_power_supply_register); 1745 1746 /** 1747 * power_supply_unregister() - Remove this power supply from system 1748 * @psy: Pointer to power supply to unregister 1749 * 1750 * Remove this power supply from the system. The resources of power supply 1751 * will be freed here or on last power_supply_put() call. 1752 */ 1753 void power_supply_unregister(struct power_supply *psy) 1754 { 1755 WARN_ON(atomic_dec_return(&psy->use_cnt)); 1756 psy->removing = true; 1757 cancel_work_sync(&psy->changed_work); 1758 cancel_delayed_work_sync(&psy->deferred_register_work); 1759 sysfs_remove_link(&psy->dev.kobj, "powers"); 1760 power_supply_remove_hwmon_sysfs(psy); 1761 power_supply_remove_triggers(psy); 1762 psy_unregister_thermal(psy); 1763 device_init_wakeup(&psy->dev, false); 1764 device_unregister(&psy->dev); 1765 } 1766 EXPORT_SYMBOL_GPL(power_supply_unregister); 1767 1768 void *power_supply_get_drvdata(struct power_supply *psy) 1769 { 1770 return psy->drv_data; 1771 } 1772 EXPORT_SYMBOL_GPL(power_supply_get_drvdata); 1773 1774 static int __init power_supply_class_init(void) 1775 { 1776 power_supply_init_attrs(); 1777 return class_register(&power_supply_class); 1778 } 1779 1780 static void __exit power_supply_class_exit(void) 1781 { 1782 class_unregister(&power_supply_class); 1783 } 1784 1785 subsys_initcall(power_supply_class_init); 1786 module_exit(power_supply_class_exit); 1787 1788 MODULE_DESCRIPTION("Universal power supply monitor class"); 1789 MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); 1790 MODULE_AUTHOR("Szabolcs Gyurko"); 1791 MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>"); 1792