linux/drivers/power/power_supply_core.c
<<
>>
Prefs
   1/*
   2 *  Universal power supply monitor class
   3 *
   4 *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
   5 *  Copyright © 2004  Szabolcs Gyurko
   6 *  Copyright © 2003  Ian Molton <spyro@f2s.com>
   7 *
   8 *  Modified: 2004, Oct     Szabolcs Gyurko
   9 *
  10 *  You may use this code as per GPL version 2
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/types.h>
  15#include <linux/init.h>
  16#include <linux/slab.h>
  17#include <linux/device.h>
  18#include <linux/notifier.h>
  19#include <linux/err.h>
  20#include <linux/power_supply.h>
  21#include <linux/thermal.h>
  22#include "power_supply.h"
  23
  24/* exported for the APM Power driver, APM emulation */
  25struct class *power_supply_class;
  26EXPORT_SYMBOL_GPL(power_supply_class);
  27
  28ATOMIC_NOTIFIER_HEAD(power_supply_notifier);
  29EXPORT_SYMBOL_GPL(power_supply_notifier);
  30
  31static struct device_type power_supply_dev_type;
  32
  33static bool __power_supply_is_supplied_by(struct power_supply *supplier,
  34                                         struct power_supply *supply)
  35{
  36        int i;
  37
  38        if (!supply->supplied_from && !supplier->supplied_to)
  39                return false;
  40
  41        /* Support both supplied_to and supplied_from modes */
  42        if (supply->supplied_from) {
  43                if (!supplier->desc->name)
  44                        return false;
  45                for (i = 0; i < supply->num_supplies; i++)
  46                        if (!strcmp(supplier->desc->name, supply->supplied_from[i]))
  47                                return true;
  48        } else {
  49                if (!supply->desc->name)
  50                        return false;
  51                for (i = 0; i < supplier->num_supplicants; i++)
  52                        if (!strcmp(supplier->supplied_to[i], supply->desc->name))
  53                                return true;
  54        }
  55
  56        return false;
  57}
  58
  59static int __power_supply_changed_work(struct device *dev, void *data)
  60{
  61        struct power_supply *psy = data;
  62        struct power_supply *pst = dev_get_drvdata(dev);
  63
  64        if (__power_supply_is_supplied_by(psy, pst)) {
  65                if (pst->desc->external_power_changed)
  66                        pst->desc->external_power_changed(pst);
  67        }
  68
  69        return 0;
  70}
  71
  72static void power_supply_changed_work(struct work_struct *work)
  73{
  74        unsigned long flags;
  75        struct power_supply *psy = container_of(work, struct power_supply,
  76                                                changed_work);
  77
  78        dev_dbg(&psy->dev, "%s\n", __func__);
  79
  80        spin_lock_irqsave(&psy->changed_lock, flags);
  81        /*
  82         * Check 'changed' here to avoid issues due to race between
  83         * power_supply_changed() and this routine. In worst case
  84         * power_supply_changed() can be called again just before we take above
  85         * lock. During the first call of this routine we will mark 'changed' as
  86         * false and it will stay false for the next call as well.
  87         */
  88        if (likely(psy->changed)) {
  89                psy->changed = false;
  90                spin_unlock_irqrestore(&psy->changed_lock, flags);
  91                class_for_each_device(power_supply_class, NULL, psy,
  92                                      __power_supply_changed_work);
  93                power_supply_update_leds(psy);
  94                atomic_notifier_call_chain(&power_supply_notifier,
  95                                PSY_EVENT_PROP_CHANGED, psy);
  96                kobject_uevent(&psy->dev.kobj, KOBJ_CHANGE);
  97                spin_lock_irqsave(&psy->changed_lock, flags);
  98        }
  99
 100        /*
 101         * Hold the wakeup_source until all events are processed.
 102         * power_supply_changed() might have called again and have set 'changed'
 103         * to true.
 104         */
 105        if (likely(!psy->changed))
 106                pm_relax(&psy->dev);
 107        spin_unlock_irqrestore(&psy->changed_lock, flags);
 108}
 109
 110void power_supply_changed(struct power_supply *psy)
 111{
 112        unsigned long flags;
 113
 114        dev_dbg(&psy->dev, "%s\n", __func__);
 115
 116        spin_lock_irqsave(&psy->changed_lock, flags);
 117        psy->changed = true;
 118        pm_stay_awake(&psy->dev);
 119        spin_unlock_irqrestore(&psy->changed_lock, flags);
 120        schedule_work(&psy->changed_work);
 121}
 122EXPORT_SYMBOL_GPL(power_supply_changed);
 123
 124#ifdef CONFIG_OF
 125#include <linux/of.h>
 126
 127static int __power_supply_populate_supplied_from(struct device *dev,
 128                                                 void *data)
 129{
 130        struct power_supply *psy = data;
 131        struct power_supply *epsy = dev_get_drvdata(dev);
 132        struct device_node *np;
 133        int i = 0;
 134
 135        do {
 136                np = of_parse_phandle(psy->of_node, "power-supplies", i++);
 137                if (!np)
 138                        break;
 139
 140                if (np == epsy->of_node) {
 141                        dev_info(&psy->dev, "%s: Found supply : %s\n",
 142                                psy->desc->name, epsy->desc->name);
 143                        psy->supplied_from[i-1] = (char *)epsy->desc->name;
 144                        psy->num_supplies++;
 145                        of_node_put(np);
 146                        break;
 147                }
 148                of_node_put(np);
 149        } while (np);
 150
 151        return 0;
 152}
 153
 154static int power_supply_populate_supplied_from(struct power_supply *psy)
 155{
 156        int error;
 157
 158        error = class_for_each_device(power_supply_class, NULL, psy,
 159                                      __power_supply_populate_supplied_from);
 160
 161        dev_dbg(&psy->dev, "%s %d\n", __func__, error);
 162
 163        return error;
 164}
 165
 166static int  __power_supply_find_supply_from_node(struct device *dev,
 167                                                 void *data)
 168{
 169        struct device_node *np = data;
 170        struct power_supply *epsy = dev_get_drvdata(dev);
 171
 172        /* returning non-zero breaks out of class_for_each_device loop */
 173        if (epsy->of_node == np)
 174                return 1;
 175
 176        return 0;
 177}
 178
 179static int power_supply_find_supply_from_node(struct device_node *supply_node)
 180{
 181        int error;
 182
 183        /*
 184         * class_for_each_device() either returns its own errors or values
 185         * returned by __power_supply_find_supply_from_node().
 186         *
 187         * __power_supply_find_supply_from_node() will return 0 (no match)
 188         * or 1 (match).
 189         *
 190         * We return 0 if class_for_each_device() returned 1, -EPROBE_DEFER if
 191         * it returned 0, or error as returned by it.
 192         */
 193        error = class_for_each_device(power_supply_class, NULL, supply_node,
 194                                       __power_supply_find_supply_from_node);
 195
 196        return error ? (error == 1 ? 0 : error) : -EPROBE_DEFER;
 197}
 198
 199static int power_supply_check_supplies(struct power_supply *psy)
 200{
 201        struct device_node *np;
 202        int cnt = 0;
 203
 204        /* If there is already a list honor it */
 205        if (psy->supplied_from && psy->num_supplies > 0)
 206                return 0;
 207
 208        /* No device node found, nothing to do */
 209        if (!psy->of_node)
 210                return 0;
 211
 212        do {
 213                int ret;
 214
 215                np = of_parse_phandle(psy->of_node, "power-supplies", cnt++);
 216                if (!np)
 217                        break;
 218
 219                ret = power_supply_find_supply_from_node(np);
 220                of_node_put(np);
 221
 222                if (ret) {
 223                        dev_dbg(&psy->dev, "Failed to find supply!\n");
 224                        return ret;
 225                }
 226        } while (np);
 227
 228        /* Missing valid "power-supplies" entries */
 229        if (cnt == 1)
 230                return 0;
 231
 232        /* All supplies found, allocate char ** array for filling */
 233        psy->supplied_from = devm_kzalloc(&psy->dev, sizeof(psy->supplied_from),
 234                                          GFP_KERNEL);
 235        if (!psy->supplied_from) {
 236                dev_err(&psy->dev, "Couldn't allocate memory for supply list\n");
 237                return -ENOMEM;
 238        }
 239
 240        *psy->supplied_from = devm_kzalloc(&psy->dev,
 241                                           sizeof(char *) * (cnt - 1),
 242                                           GFP_KERNEL);
 243        if (!*psy->supplied_from) {
 244                dev_err(&psy->dev, "Couldn't allocate memory for supply list\n");
 245                return -ENOMEM;
 246        }
 247
 248        return power_supply_populate_supplied_from(psy);
 249}
 250#else
 251static inline int power_supply_check_supplies(struct power_supply *psy)
 252{
 253        return 0;
 254}
 255#endif
 256
 257static int __power_supply_am_i_supplied(struct device *dev, void *data)
 258{
 259        union power_supply_propval ret = {0,};
 260        struct power_supply *psy = data;
 261        struct power_supply *epsy = dev_get_drvdata(dev);
 262
 263        if (__power_supply_is_supplied_by(epsy, psy))
 264                if (!epsy->desc->get_property(epsy, POWER_SUPPLY_PROP_ONLINE,
 265                                        &ret))
 266                        return ret.intval;
 267
 268        return 0;
 269}
 270
 271int power_supply_am_i_supplied(struct power_supply *psy)
 272{
 273        int error;
 274
 275        error = class_for_each_device(power_supply_class, NULL, psy,
 276                                      __power_supply_am_i_supplied);
 277
 278        dev_dbg(&psy->dev, "%s %d\n", __func__, error);
 279
 280        return error;
 281}
 282EXPORT_SYMBOL_GPL(power_supply_am_i_supplied);
 283
 284static int __power_supply_is_system_supplied(struct device *dev, void *data)
 285{
 286        union power_supply_propval ret = {0,};
 287        struct power_supply *psy = dev_get_drvdata(dev);
 288        unsigned int *count = data;
 289
 290        (*count)++;
 291        if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY)
 292                if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE,
 293                                        &ret))
 294                        return ret.intval;
 295
 296        return 0;
 297}
 298
 299int power_supply_is_system_supplied(void)
 300{
 301        int error;
 302        unsigned int count = 0;
 303
 304        error = class_for_each_device(power_supply_class, NULL, &count,
 305                                      __power_supply_is_system_supplied);
 306
 307        /*
 308         * If no power class device was found at all, most probably we are
 309         * running on a desktop system, so assume we are on mains power.
 310         */
 311        if (count == 0)
 312                return 1;
 313
 314        return error;
 315}
 316EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
 317
 318int power_supply_set_battery_charged(struct power_supply *psy)
 319{
 320        if (atomic_read(&psy->use_cnt) >= 0 &&
 321                        psy->desc->type == POWER_SUPPLY_TYPE_BATTERY &&
 322                        psy->desc->set_charged) {
 323                psy->desc->set_charged(psy);
 324                return 0;
 325        }
 326
 327        return -EINVAL;
 328}
 329EXPORT_SYMBOL_GPL(power_supply_set_battery_charged);
 330
 331static int power_supply_match_device_by_name(struct device *dev, const void *data)
 332{
 333        const char *name = data;
 334        struct power_supply *psy = dev_get_drvdata(dev);
 335
 336        return strcmp(psy->desc->name, name) == 0;
 337}
 338
 339/**
 340 * power_supply_get_by_name() - Search for a power supply and returns its ref
 341 * @name: Power supply name to fetch
 342 *
 343 * If power supply was found, it increases reference count for the
 344 * internal power supply's device. The user should power_supply_put()
 345 * after usage.
 346 *
 347 * Return: On success returns a reference to a power supply with
 348 * matching name equals to @name, a NULL otherwise.
 349 */
 350struct power_supply *power_supply_get_by_name(const char *name)
 351{
 352        struct power_supply *psy = NULL;
 353        struct device *dev = class_find_device(power_supply_class, NULL, name,
 354                                        power_supply_match_device_by_name);
 355
 356        if (dev) {
 357                psy = dev_get_drvdata(dev);
 358                atomic_inc(&psy->use_cnt);
 359        }
 360
 361        return psy;
 362}
 363EXPORT_SYMBOL_GPL(power_supply_get_by_name);
 364
 365/**
 366 * power_supply_put() - Drop reference obtained with power_supply_get_by_name
 367 * @psy: Reference to put
 368 *
 369 * The reference to power supply should be put before unregistering
 370 * the power supply.
 371 */
 372void power_supply_put(struct power_supply *psy)
 373{
 374        might_sleep();
 375
 376        atomic_dec(&psy->use_cnt);
 377        put_device(&psy->dev);
 378}
 379EXPORT_SYMBOL_GPL(power_supply_put);
 380
 381#ifdef CONFIG_OF
 382static int power_supply_match_device_node(struct device *dev, const void *data)
 383{
 384        return dev->parent && dev->parent->of_node == data;
 385}
 386
 387/**
 388 * power_supply_get_by_phandle() - Search for a power supply and returns its ref
 389 * @np: Pointer to device node holding phandle property
 390 * @phandle_name: Name of property holding a power supply name
 391 *
 392 * If power supply was found, it increases reference count for the
 393 * internal power supply's device. The user should power_supply_put()
 394 * after usage.
 395 *
 396 * Return: On success returns a reference to a power supply with
 397 * matching name equals to value under @property, NULL or ERR_PTR otherwise.
 398 */
 399struct power_supply *power_supply_get_by_phandle(struct device_node *np,
 400                                                        const char *property)
 401{
 402        struct device_node *power_supply_np;
 403        struct power_supply *psy = NULL;
 404        struct device *dev;
 405
 406        power_supply_np = of_parse_phandle(np, property, 0);
 407        if (!power_supply_np)
 408                return ERR_PTR(-ENODEV);
 409
 410        dev = class_find_device(power_supply_class, NULL, power_supply_np,
 411                                                power_supply_match_device_node);
 412
 413        of_node_put(power_supply_np);
 414
 415        if (dev) {
 416                psy = dev_get_drvdata(dev);
 417                atomic_inc(&psy->use_cnt);
 418        }
 419
 420        return psy;
 421}
 422EXPORT_SYMBOL_GPL(power_supply_get_by_phandle);
 423#endif /* CONFIG_OF */
 424
 425int power_supply_get_property(struct power_supply *psy,
 426                            enum power_supply_property psp,
 427                            union power_supply_propval *val)
 428{
 429        if (atomic_read(&psy->use_cnt) <= 0)
 430                return -ENODEV;
 431
 432        return psy->desc->get_property(psy, psp, val);
 433}
 434EXPORT_SYMBOL_GPL(power_supply_get_property);
 435
 436int power_supply_set_property(struct power_supply *psy,
 437                            enum power_supply_property psp,
 438                            const union power_supply_propval *val)
 439{
 440        if (atomic_read(&psy->use_cnt) <= 0 || !psy->desc->set_property)
 441                return -ENODEV;
 442
 443        return psy->desc->set_property(psy, psp, val);
 444}
 445EXPORT_SYMBOL_GPL(power_supply_set_property);
 446
 447int power_supply_property_is_writeable(struct power_supply *psy,
 448                                        enum power_supply_property psp)
 449{
 450        if (atomic_read(&psy->use_cnt) <= 0 ||
 451                        !psy->desc->property_is_writeable)
 452                return -ENODEV;
 453
 454        return psy->desc->property_is_writeable(psy, psp);
 455}
 456EXPORT_SYMBOL_GPL(power_supply_property_is_writeable);
 457
 458void power_supply_external_power_changed(struct power_supply *psy)
 459{
 460        if (atomic_read(&psy->use_cnt) <= 0 ||
 461                        !psy->desc->external_power_changed)
 462                return;
 463
 464        psy->desc->external_power_changed(psy);
 465}
 466EXPORT_SYMBOL_GPL(power_supply_external_power_changed);
 467
 468int power_supply_powers(struct power_supply *psy, struct device *dev)
 469{
 470        return sysfs_create_link(&psy->dev.kobj, &dev->kobj, "powers");
 471}
 472EXPORT_SYMBOL_GPL(power_supply_powers);
 473
 474static void power_supply_dev_release(struct device *dev)
 475{
 476        struct power_supply *psy = container_of(dev, struct power_supply, dev);
 477        pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
 478        kfree(psy);
 479}
 480
 481int power_supply_reg_notifier(struct notifier_block *nb)
 482{
 483        return atomic_notifier_chain_register(&power_supply_notifier, nb);
 484}
 485EXPORT_SYMBOL_GPL(power_supply_reg_notifier);
 486
 487void power_supply_unreg_notifier(struct notifier_block *nb)
 488{
 489        atomic_notifier_chain_unregister(&power_supply_notifier, nb);
 490}
 491EXPORT_SYMBOL_GPL(power_supply_unreg_notifier);
 492
 493#ifdef CONFIG_THERMAL
 494static int power_supply_read_temp(struct thermal_zone_device *tzd,
 495                unsigned long *temp)
 496{
 497        struct power_supply *psy;
 498        union power_supply_propval val;
 499        int ret;
 500
 501        WARN_ON(tzd == NULL);
 502        psy = tzd->devdata;
 503        ret = psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
 504
 505        /* Convert tenths of degree Celsius to milli degree Celsius. */
 506        if (!ret)
 507                *temp = val.intval * 100;
 508
 509        return ret;
 510}
 511
 512static struct thermal_zone_device_ops psy_tzd_ops = {
 513        .get_temp = power_supply_read_temp,
 514};
 515
 516static int psy_register_thermal(struct power_supply *psy)
 517{
 518        int i;
 519
 520        if (psy->desc->no_thermal)
 521                return 0;
 522
 523        /* Register battery zone device psy reports temperature */
 524        for (i = 0; i < psy->desc->num_properties; i++) {
 525                if (psy->desc->properties[i] == POWER_SUPPLY_PROP_TEMP) {
 526                        psy->tzd = thermal_zone_device_register(psy->desc->name,
 527                                        0, 0, psy, &psy_tzd_ops, NULL, 0, 0);
 528                        return PTR_ERR_OR_ZERO(psy->tzd);
 529                }
 530        }
 531        return 0;
 532}
 533
 534static void psy_unregister_thermal(struct power_supply *psy)
 535{
 536        if (IS_ERR_OR_NULL(psy->tzd))
 537                return;
 538        thermal_zone_device_unregister(psy->tzd);
 539}
 540
 541/* thermal cooling device callbacks */
 542static int ps_get_max_charge_cntl_limit(struct thermal_cooling_device *tcd,
 543                                        unsigned long *state)
 544{
 545        struct power_supply *psy;
 546        union power_supply_propval val;
 547        int ret;
 548
 549        psy = tcd->devdata;
 550        ret = psy->desc->get_property(psy,
 551                POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val);
 552        if (!ret)
 553                *state = val.intval;
 554
 555        return ret;
 556}
 557
 558static int ps_get_cur_chrage_cntl_limit(struct thermal_cooling_device *tcd,
 559                                        unsigned long *state)
 560{
 561        struct power_supply *psy;
 562        union power_supply_propval val;
 563        int ret;
 564
 565        psy = tcd->devdata;
 566        ret = psy->desc->get_property(psy,
 567                POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val);
 568        if (!ret)
 569                *state = val.intval;
 570
 571        return ret;
 572}
 573
 574static int ps_set_cur_charge_cntl_limit(struct thermal_cooling_device *tcd,
 575                                        unsigned long state)
 576{
 577        struct power_supply *psy;
 578        union power_supply_propval val;
 579        int ret;
 580
 581        psy = tcd->devdata;
 582        val.intval = state;
 583        ret = psy->desc->set_property(psy,
 584                POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val);
 585
 586        return ret;
 587}
 588
 589static struct thermal_cooling_device_ops psy_tcd_ops = {
 590        .get_max_state = ps_get_max_charge_cntl_limit,
 591        .get_cur_state = ps_get_cur_chrage_cntl_limit,
 592        .set_cur_state = ps_set_cur_charge_cntl_limit,
 593};
 594
 595static int psy_register_cooler(struct power_supply *psy)
 596{
 597        int i;
 598
 599        /* Register for cooling device if psy can control charging */
 600        for (i = 0; i < psy->desc->num_properties; i++) {
 601                if (psy->desc->properties[i] ==
 602                                POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) {
 603                        psy->tcd = thermal_cooling_device_register(
 604                                                        (char *)psy->desc->name,
 605                                                        psy, &psy_tcd_ops);
 606                        return PTR_ERR_OR_ZERO(psy->tcd);
 607                }
 608        }
 609        return 0;
 610}
 611
 612static void psy_unregister_cooler(struct power_supply *psy)
 613{
 614        if (IS_ERR_OR_NULL(psy->tcd))
 615                return;
 616        thermal_cooling_device_unregister(psy->tcd);
 617}
 618#else
 619static int psy_register_thermal(struct power_supply *psy)
 620{
 621        return 0;
 622}
 623
 624static void psy_unregister_thermal(struct power_supply *psy)
 625{
 626}
 627
 628static int psy_register_cooler(struct power_supply *psy)
 629{
 630        return 0;
 631}
 632
 633static void psy_unregister_cooler(struct power_supply *psy)
 634{
 635}
 636#endif
 637
 638static struct power_supply *__must_check
 639__power_supply_register(struct device *parent,
 640                                   const struct power_supply_desc *desc,
 641                                   const struct power_supply_config *cfg,
 642                                   bool ws)
 643{
 644        struct device *dev;
 645        struct power_supply *psy;
 646        int rc;
 647
 648        psy = kzalloc(sizeof(*psy), GFP_KERNEL);
 649        if (!psy)
 650                return ERR_PTR(-ENOMEM);
 651
 652        dev = &psy->dev;
 653
 654        device_initialize(dev);
 655
 656        dev->class = power_supply_class;
 657        dev->type = &power_supply_dev_type;
 658        dev->parent = parent;
 659        dev->release = power_supply_dev_release;
 660        dev_set_drvdata(dev, psy);
 661        psy->desc = desc;
 662        atomic_inc(&psy->use_cnt);
 663        if (cfg) {
 664                psy->drv_data = cfg->drv_data;
 665                psy->of_node = cfg->of_node;
 666                psy->supplied_to = cfg->supplied_to;
 667                psy->num_supplicants = cfg->num_supplicants;
 668        }
 669
 670        rc = dev_set_name(dev, "%s", desc->name);
 671        if (rc)
 672                goto dev_set_name_failed;
 673
 674        INIT_WORK(&psy->changed_work, power_supply_changed_work);
 675
 676        rc = power_supply_check_supplies(psy);
 677        if (rc) {
 678                dev_info(dev, "Not all required supplies found, defer probe\n");
 679                goto check_supplies_failed;
 680        }
 681
 682        spin_lock_init(&psy->changed_lock);
 683        rc = device_init_wakeup(dev, ws);
 684        if (rc)
 685                goto wakeup_init_failed;
 686
 687        rc = device_add(dev);
 688        if (rc)
 689                goto device_add_failed;
 690
 691        rc = psy_register_thermal(psy);
 692        if (rc)
 693                goto register_thermal_failed;
 694
 695        rc = psy_register_cooler(psy);
 696        if (rc)
 697                goto register_cooler_failed;
 698
 699        rc = power_supply_create_triggers(psy);
 700        if (rc)
 701                goto create_triggers_failed;
 702
 703        power_supply_changed(psy);
 704
 705        return psy;
 706
 707create_triggers_failed:
 708        psy_unregister_cooler(psy);
 709register_cooler_failed:
 710        psy_unregister_thermal(psy);
 711register_thermal_failed:
 712        device_del(dev);
 713device_add_failed:
 714wakeup_init_failed:
 715check_supplies_failed:
 716dev_set_name_failed:
 717        put_device(dev);
 718        return ERR_PTR(rc);
 719}
 720
 721/**
 722 * power_supply_register() - Register new power supply
 723 * @parent:     Device to be a parent of power supply's device
 724 * @desc:       Description of power supply, must be valid through whole
 725 *              lifetime of this power supply
 726 * @cfg:        Run-time specific configuration accessed during registering,
 727 *              may be NULL
 728 *
 729 * Return: A pointer to newly allocated power_supply on success
 730 * or ERR_PTR otherwise.
 731 * Use power_supply_unregister() on returned power_supply pointer to release
 732 * resources.
 733 */
 734struct power_supply *__must_check power_supply_register(struct device *parent,
 735                const struct power_supply_desc *desc,
 736                const struct power_supply_config *cfg)
 737{
 738        return __power_supply_register(parent, desc, cfg, true);
 739}
 740EXPORT_SYMBOL_GPL(power_supply_register);
 741
 742/**
 743 * power_supply_register() - Register new non-waking-source power supply
 744 * @parent:     Device to be a parent of power supply's device
 745 * @desc:       Description of power supply, must be valid through whole
 746 *              lifetime of this power supply
 747 * @cfg:        Run-time specific configuration accessed during registering,
 748 *              may be NULL
 749 *
 750 * Return: A pointer to newly allocated power_supply on success
 751 * or ERR_PTR otherwise.
 752 * Use power_supply_unregister() on returned power_supply pointer to release
 753 * resources.
 754 */
 755struct power_supply *__must_check
 756power_supply_register_no_ws(struct device *parent,
 757                const struct power_supply_desc *desc,
 758                const struct power_supply_config *cfg)
 759{
 760        return __power_supply_register(parent, desc, cfg, false);
 761}
 762EXPORT_SYMBOL_GPL(power_supply_register_no_ws);
 763
 764static void devm_power_supply_release(struct device *dev, void *res)
 765{
 766        struct power_supply **psy = res;
 767
 768        power_supply_unregister(*psy);
 769}
 770
 771/**
 772 * power_supply_register() - Register managed power supply
 773 * @parent:     Device to be a parent of power supply's device
 774 * @desc:       Description of power supply, must be valid through whole
 775 *              lifetime of this power supply
 776 * @cfg:        Run-time specific configuration accessed during registering,
 777 *              may be NULL
 778 *
 779 * Return: A pointer to newly allocated power_supply on success
 780 * or ERR_PTR otherwise.
 781 * The returned power_supply pointer will be automatically unregistered
 782 * on driver detach.
 783 */
 784struct power_supply *__must_check
 785devm_power_supply_register(struct device *parent,
 786                const struct power_supply_desc *desc,
 787                const struct power_supply_config *cfg)
 788{
 789        struct power_supply **ptr, *psy;
 790
 791        ptr = devres_alloc(devm_power_supply_release, sizeof(*ptr), GFP_KERNEL);
 792
 793        if (!ptr)
 794                return ERR_PTR(-ENOMEM);
 795        psy = __power_supply_register(parent, desc, cfg, true);
 796        if (IS_ERR(psy)) {
 797                devres_free(ptr);
 798        } else {
 799                *ptr = psy;
 800                devres_add(parent, ptr);
 801        }
 802        return psy;
 803}
 804EXPORT_SYMBOL_GPL(devm_power_supply_register);
 805
 806/**
 807 * power_supply_register() - Register managed non-waking-source power supply
 808 * @parent:     Device to be a parent of power supply's device
 809 * @desc:       Description of power supply, must be valid through whole
 810 *              lifetime of this power supply
 811 * @cfg:        Run-time specific configuration accessed during registering,
 812 *              may be NULL
 813 *
 814 * Return: A pointer to newly allocated power_supply on success
 815 * or ERR_PTR otherwise.
 816 * The returned power_supply pointer will be automatically unregistered
 817 * on driver detach.
 818 */
 819struct power_supply *__must_check
 820devm_power_supply_register_no_ws(struct device *parent,
 821                const struct power_supply_desc *desc,
 822                const struct power_supply_config *cfg)
 823{
 824        struct power_supply **ptr, *psy;
 825
 826        ptr = devres_alloc(devm_power_supply_release, sizeof(*ptr), GFP_KERNEL);
 827
 828        if (!ptr)
 829                return ERR_PTR(-ENOMEM);
 830        psy = __power_supply_register(parent, desc, cfg, false);
 831        if (IS_ERR(psy)) {
 832                devres_free(ptr);
 833        } else {
 834                *ptr = psy;
 835                devres_add(parent, ptr);
 836        }
 837        return psy;
 838}
 839EXPORT_SYMBOL_GPL(devm_power_supply_register_no_ws);
 840
 841/**
 842 * power_supply_unregister() - Remove this power supply from system
 843 * @psy:        Pointer to power supply to unregister
 844 *
 845 * Remove this power supply from the system. The resources of power supply
 846 * will be freed here or on last power_supply_put() call.
 847 */
 848void power_supply_unregister(struct power_supply *psy)
 849{
 850        WARN_ON(atomic_dec_return(&psy->use_cnt));
 851        cancel_work_sync(&psy->changed_work);
 852        sysfs_remove_link(&psy->dev.kobj, "powers");
 853        power_supply_remove_triggers(psy);
 854        psy_unregister_cooler(psy);
 855        psy_unregister_thermal(psy);
 856        device_init_wakeup(&psy->dev, false);
 857        device_unregister(&psy->dev);
 858}
 859EXPORT_SYMBOL_GPL(power_supply_unregister);
 860
 861void *power_supply_get_drvdata(struct power_supply *psy)
 862{
 863        return psy->drv_data;
 864}
 865EXPORT_SYMBOL_GPL(power_supply_get_drvdata);
 866
 867static int __init power_supply_class_init(void)
 868{
 869        power_supply_class = class_create(THIS_MODULE, "power_supply");
 870
 871        if (IS_ERR(power_supply_class))
 872                return PTR_ERR(power_supply_class);
 873
 874        power_supply_class->dev_uevent = power_supply_uevent;
 875        power_supply_init_attrs(&power_supply_dev_type);
 876
 877        return 0;
 878}
 879
 880static void __exit power_supply_class_exit(void)
 881{
 882        class_destroy(power_supply_class);
 883}
 884
 885subsys_initcall(power_supply_class_init);
 886module_exit(power_supply_class_exit);
 887
 888MODULE_DESCRIPTION("Universal power supply monitor class");
 889MODULE_AUTHOR("Ian Molton <spyro@f2s.com>, "
 890              "Szabolcs Gyurko, "
 891              "Anton Vorontsov <cbou@mail.ru>");
 892MODULE_LICENSE("GPL");
 893