mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
power: supply: Add helpers to get and put arrays of power supply handles
Add power_supply_get_system_batteries() to allow drivers to obtain a list of registered battery type power supply references in the system. Also add power_supply_put_system_batteries() to perform cleanup after the former function is called. Signed-off-by: Amit Sunil Dhamne <amitsd@google.com> Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com> Link: https://patch.msgid.link/20260714-batt-status-v5-1-9de4aa900b69@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1e6be4bd53
commit
3b17c8d8d6
|
|
@ -477,6 +477,159 @@ struct power_supply *power_supply_get_by_name(const char *name)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(power_supply_get_by_name);
|
||||
|
||||
static bool power_supply_is_system_battery(struct power_supply *psy)
|
||||
{
|
||||
union power_supply_propval val;
|
||||
|
||||
if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY)
|
||||
return false;
|
||||
|
||||
if (!power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_SCOPE,
|
||||
&val))
|
||||
if (val.intval == POWER_SUPPLY_SCOPE_DEVICE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __power_supply_get_num_system_batteries(struct power_supply *epsy,
|
||||
void *data)
|
||||
{
|
||||
int *count = data;
|
||||
|
||||
if (power_supply_is_system_battery(epsy))
|
||||
(*count)++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int power_supply_get_num_system_batteries(struct device *dev)
|
||||
{
|
||||
int ret, count = 0;
|
||||
|
||||
ret = power_supply_for_each_psy(&count,
|
||||
__power_supply_get_num_system_batteries);
|
||||
|
||||
dev_dbg(dev, "%s: count: %d ret %d\n", __func__, count, ret);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
struct psy_get_supplies_data {
|
||||
int cnt;
|
||||
int size;
|
||||
struct power_supply **psys;
|
||||
};
|
||||
|
||||
static int
|
||||
__power_supply_populate_system_batteries_array(struct power_supply *epsy,
|
||||
void *_data)
|
||||
{
|
||||
struct psy_get_supplies_data *data = _data;
|
||||
|
||||
if (power_supply_is_system_battery(epsy)) {
|
||||
if (data->size <= data->cnt)
|
||||
return -EOVERFLOW;
|
||||
|
||||
get_device(&epsy->dev);
|
||||
data->psys[data->cnt] = epsy;
|
||||
atomic_inc(&epsy->use_cnt);
|
||||
data->cnt++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
power_supply_populate_system_batteries_array(struct device *dev, int size,
|
||||
struct power_supply **batteries)
|
||||
{
|
||||
int ret;
|
||||
|
||||
struct psy_get_supplies_data data = {
|
||||
.cnt = 0,
|
||||
.size = size,
|
||||
.psys = batteries,
|
||||
};
|
||||
|
||||
ret = power_supply_for_each_psy(&data,
|
||||
__power_supply_populate_system_batteries_array);
|
||||
|
||||
dev_dbg(dev, "%s Found %d batteries with array size %d ret %d\n",
|
||||
__func__, data.cnt, data.size, ret);
|
||||
|
||||
if (ret < 0 || !data.cnt) {
|
||||
power_supply_put_system_batteries(batteries, data.cnt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return data.cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* power_supply_get_system_batteries() - Fetches references to battery type
|
||||
* power supplies in the system.
|
||||
* @dev: Pointer to device requesting the power supply refs.
|
||||
* @psys: Pointer to an array of power supply refs.
|
||||
*
|
||||
* Helper function to get handles to battery type power supplies in the system.
|
||||
* If acquiring a ref to a power supply fails, then the search for battery type
|
||||
* power supplies will abort and the acquired power supply references will be
|
||||
* released.
|
||||
*
|
||||
* Return: Indicates the number of battery type power supplies returned on
|
||||
* success or a negative error code on failure.
|
||||
*
|
||||
* Call power_supply_put_system_batteries() after use to cleanup resources.
|
||||
*/
|
||||
int __must_check power_supply_get_system_batteries(struct device *dev,
|
||||
struct power_supply ***psys)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!psys)
|
||||
return -EINVAL;
|
||||
|
||||
ret = power_supply_get_num_system_batteries(dev);
|
||||
if (ret <= 0) {
|
||||
*psys = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*psys = kzalloc_objs(**psys, ret);
|
||||
if (!*psys)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = power_supply_populate_system_batteries_array(dev, ret, *psys);
|
||||
if (ret <= 0)
|
||||
*psys = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(power_supply_get_system_batteries);
|
||||
|
||||
/**
|
||||
* power_supply_put_system_batteries() - Cleanup resources allocated by
|
||||
* power_supply_get_system_batteries()
|
||||
* @psys: Array of power supply references to release and free.
|
||||
* @count: Number of elements in the array.
|
||||
*/
|
||||
void power_supply_put_system_batteries(struct power_supply **psys, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (psys[i])
|
||||
power_supply_put(psys[i]);
|
||||
}
|
||||
|
||||
kfree(psys);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(power_supply_put_system_batteries);
|
||||
|
||||
/**
|
||||
* power_supply_put() - Drop reference obtained with power_supply_get_by_name
|
||||
* @psy: Reference to put
|
||||
|
|
|
|||
|
|
@ -806,11 +806,26 @@ extern int power_supply_reg_notifier(struct notifier_block *nb);
|
|||
extern void power_supply_unreg_notifier(struct notifier_block *nb);
|
||||
#if IS_ENABLED(CONFIG_POWER_SUPPLY)
|
||||
extern struct power_supply *power_supply_get_by_name(const char *name);
|
||||
extern int __must_check power_supply_get_system_batteries(struct device *dev,
|
||||
struct power_supply ***psys);
|
||||
extern void power_supply_put_system_batteries(struct power_supply **psys, int count);
|
||||
extern void power_supply_put(struct power_supply *psy);
|
||||
#else
|
||||
static inline void power_supply_put(struct power_supply *psy) {}
|
||||
static inline struct power_supply *power_supply_get_by_name(const char *name)
|
||||
{ return NULL; }
|
||||
static inline int __must_check power_supply_get_system_batteries(struct device *dev,
|
||||
struct power_supply ***psys)
|
||||
{
|
||||
if (psys)
|
||||
*psys = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void power_supply_put_system_batteries(struct power_supply **psys,
|
||||
int count)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
extern struct power_supply *power_supply_get_by_reference(struct fwnode_handle *fwnode,
|
||||
const char *property);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user