|
@@ -314,7 +314,9 @@ EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
|
|
|
|
|
|
int power_supply_set_battery_charged(struct power_supply *psy)
|
|
|
{
|
|
|
- if (psy->type == POWER_SUPPLY_TYPE_BATTERY && psy->set_charged) {
|
|
|
+ if (atomic_read(&psy->use_cnt) >= 0 &&
|
|
|
+ psy->type == POWER_SUPPLY_TYPE_BATTERY &&
|
|
|
+ psy->set_charged) {
|
|
|
psy->set_charged(psy);
|
|
|
return 0;
|
|
|
}
|
|
@@ -366,6 +368,47 @@ struct power_supply *power_supply_get_by_phandle(struct device_node *np,
|
|
|
EXPORT_SYMBOL_GPL(power_supply_get_by_phandle);
|
|
|
#endif /* CONFIG_OF */
|
|
|
|
|
|
+int power_supply_get_property(struct power_supply *psy,
|
|
|
+ enum power_supply_property psp,
|
|
|
+ union power_supply_propval *val)
|
|
|
+{
|
|
|
+ if (atomic_read(&psy->use_cnt) <= 0)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return psy->get_property(psy, psp, val);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(power_supply_get_property);
|
|
|
+
|
|
|
+int power_supply_set_property(struct power_supply *psy,
|
|
|
+ enum power_supply_property psp,
|
|
|
+ const union power_supply_propval *val)
|
|
|
+{
|
|
|
+ if (atomic_read(&psy->use_cnt) <= 0 || !psy->set_property)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return psy->set_property(psy, psp, val);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(power_supply_set_property);
|
|
|
+
|
|
|
+int power_supply_property_is_writeable(struct power_supply *psy,
|
|
|
+ enum power_supply_property psp)
|
|
|
+{
|
|
|
+ if (atomic_read(&psy->use_cnt) <= 0 || !psy->property_is_writeable)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ return psy->property_is_writeable(psy, psp);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(power_supply_property_is_writeable);
|
|
|
+
|
|
|
+void power_supply_external_power_changed(struct power_supply *psy)
|
|
|
+{
|
|
|
+ if (atomic_read(&psy->use_cnt) <= 0 || !psy->external_power_changed)
|
|
|
+ return;
|
|
|
+
|
|
|
+ psy->external_power_changed(psy);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(power_supply_external_power_changed);
|
|
|
+
|
|
|
int power_supply_powers(struct power_supply *psy, struct device *dev)
|
|
|
{
|
|
|
return sysfs_create_link(&psy->dev->kobj, &dev->kobj, "powers");
|
|
@@ -555,6 +598,7 @@ static int __power_supply_register(struct device *parent,
|
|
|
dev->release = power_supply_dev_release;
|
|
|
dev_set_drvdata(dev, psy);
|
|
|
psy->dev = dev;
|
|
|
+ atomic_inc(&psy->use_cnt);
|
|
|
if (cfg) {
|
|
|
psy->drv_data = cfg->drv_data;
|
|
|
psy->of_node = cfg->of_node;
|
|
@@ -676,6 +720,7 @@ EXPORT_SYMBOL_GPL(devm_power_supply_register_no_ws);
|
|
|
|
|
|
void power_supply_unregister(struct power_supply *psy)
|
|
|
{
|
|
|
+ WARN_ON(atomic_dec_return(&psy->use_cnt));
|
|
|
cancel_work_sync(&psy->changed_work);
|
|
|
sysfs_remove_link(&psy->dev->kobj, "powers");
|
|
|
power_supply_remove_triggers(psy);
|