diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 046ecba2074f..653484529579 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3589,6 +3589,8 @@ static int ffs_func_set_alt(struct usb_function *f, { struct ffs_function *func = ffs_func_from_usb(f); struct ffs_data *ffs = func->ffs; + struct f_fs_opts *opts = + container_of(f->fi, struct f_fs_opts, func_inst); int ret = 0, intf; ffs_log("enter: alt %d", (int)alt); @@ -3602,6 +3604,9 @@ static int ffs_func_set_alt(struct usb_function *f, if (ffs->func) { ffs_func_eps_disable(ffs->func); ffs->func = NULL; + /* matching put to allow LPM on disconnect */ + if (!strcmp(opts->dev->name, "adb")) + usb_gadget_autopm_put_async(ffs->gadget); } if (ffs->state == FFS_DEACTIVATED) { @@ -3622,8 +3627,15 @@ static int ffs_func_set_alt(struct usb_function *f, ffs->func = func; ret = ffs_func_eps_enable(func); - if (likely(ret >= 0)) + if (likely(ret >= 0)) { ffs_event_add(ffs, FUNCTIONFS_ENABLE); + /* Disable USB LPM later on bus_suspend for adb */ + if (!strcmp(opts->dev->name, "adb")) + usb_gadget_autopm_get_async(ffs->gadget); + } + + ffs_log("exit: ret %d", ret); + return ret; } @@ -3634,6 +3646,7 @@ static void ffs_func_disable(struct usb_function *f) ffs_log("enter"); ffs_func_set_alt(f, 0, (unsigned)-1); + ffs_log("exit"); } static int ffs_func_setup(struct usb_function *f, diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 3daf39be7f3c..bd8890914517 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -650,6 +650,8 @@ static int eth_stop(struct net_device *net) dev->net->stats.rx_errors, dev->net->stats.tx_errors ); + usb_gadget_autopm_get(dev->gadget); + /* ensure there are no more active requests */ spin_lock_irqsave(&dev->lock, flags); if (dev->port_usb) { @@ -682,6 +684,7 @@ static int eth_stop(struct net_device *net) } } spin_unlock_irqrestore(&dev->lock, flags); + usb_gadget_autopm_put_async(dev->gadget); return 0; }