LCOV - code coverage report
Current view: top level - drivers/power/supply - power_supply_core.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 411 1.5 %
Date: 2022-12-09 01:23:36 Functions: 1 43 2.3 %

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

Generated by: LCOV version 1.14