Hi, On Mon, Nov 12, 2018 at 06:52:35PM +0800, Baolin Wang wrote: > Since the USB notifier context is atomic, we can not start or stop charging > in atomic context. Thus this patch adds one work to help to charge or > discharge. > > Signed-off-by: Baolin Wang > --- Thanks, patchset queued. -- Sebastian > drivers/power/supply/sc2731_charger.c | 30 ++++++++++++++++++++++-------- > 1 file changed, 22 insertions(+), 8 deletions(-) > > diff --git a/drivers/power/supply/sc2731_charger.c b/drivers/power/supply/sc2731_charger.c > index 525a820..393ba98 100644 > --- a/drivers/power/supply/sc2731_charger.c > +++ b/drivers/power/supply/sc2731_charger.c > @@ -57,9 +57,11 @@ struct sc2731_charger_info { > struct usb_phy *usb_phy; > struct notifier_block usb_notify; > struct power_supply *psy_usb; > + struct work_struct work; > struct mutex lock; > bool charging; > u32 base; > + u32 limit; > }; > > static void sc2731_charger_stop_charge(struct sc2731_charger_info *info) > @@ -318,22 +320,21 @@ static int sc2731_charger_property_is_writeable(struct power_supply *psy, > .property_is_writeable = sc2731_charger_property_is_writeable, > }; > > -static int sc2731_charger_usb_change(struct notifier_block *nb, > - unsigned long limit, void *data) > +static void sc2731_charger_work(struct work_struct *data) > { > struct sc2731_charger_info *info = > - container_of(nb, struct sc2731_charger_info, usb_notify); > - int ret = 0; > + container_of(data, struct sc2731_charger_info, work); > + int ret; > > mutex_lock(&info->lock); > > - if (limit > 0) { > + if (info->limit > 0) { > /* set current limitation and start to charge */ > - ret = sc2731_charger_set_current_limit(info, limit); > + ret = sc2731_charger_set_current_limit(info, info->limit); > if (ret) > goto out; > > - ret = sc2731_charger_set_current(info, limit); > + ret = sc2731_charger_set_current(info, info->limit); > if (ret) > goto out; > > @@ -350,7 +351,19 @@ static int sc2731_charger_usb_change(struct notifier_block *nb, > > out: > mutex_unlock(&info->lock); > - return ret; > +} > + > +static int sc2731_charger_usb_change(struct notifier_block *nb, > + unsigned long limit, void *data) > +{ > + struct sc2731_charger_info *info = > + container_of(nb, struct sc2731_charger_info, usb_notify); > + > + info->limit = limit; > + > + schedule_work(&info->work); > + > + return NOTIFY_OK; > } > > static int sc2731_charger_hw_init(struct sc2731_charger_info *info) > @@ -432,6 +445,7 @@ static int sc2731_charger_probe(struct platform_device *pdev) > > mutex_init(&info->lock); > info->dev = &pdev->dev; > + INIT_WORK(&info->work, sc2731_charger_work); > > info->regmap = dev_get_regmap(pdev->dev.parent, NULL); > if (!info->regmap) { > -- > 1.7.9.5 >