diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index fe48dfc6ff7b..00d8bc98d588 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1777,6 +1777,14 @@ __power_supply_register(struct device *parent, init_rwsem(&psy->extensions_sem); INIT_LIST_HEAD(&psy->extensions); + if (desc->init) { + rc = desc->init(psy); + if (WARN_ON_ONCE(rc > 0)) + rc = -EINVAL; + if (rc) + goto check_supplies_failed; + } + rc = device_add(dev); if (rc) goto device_add_failed; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index d9c8cce9faad..a9c056f13077 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -285,6 +285,15 @@ struct power_supply_desc { int (*property_is_writeable)(struct power_supply *psy, enum power_supply_property psp); void (*external_power_changed)(struct power_supply *psy); + /* + * Optional registration-time initialization. This runs in sleepable + * process context after driver data and any battery info are available, + * but before the device is added. The callback must not publish changes or + * start asynchronous activity that can access the power supply before + * registration completes. Return 0 on success or a negative errno on + * failure. + */ + int (*init)(struct power_supply *psy); /* * Set if thermal zone should not be created for this power supply.