| From 5c290a5e42c3387e82de86965784d30e6c5270fd Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Tue, 1 Oct 2019 10:49:05 +0200 |
| Subject: USB: usb-skeleton: fix runtime PM after driver unbind |
| |
| From: Johan Hovold <johan@kernel.org> |
| |
| commit 5c290a5e42c3387e82de86965784d30e6c5270fd upstream. |
| |
| Since commit c2b71462d294 ("USB: core: Fix bug caused by duplicate |
| interface PM usage counter") USB drivers must always balance their |
| runtime PM gets and puts, including when the driver has already been |
| unbound from the interface. |
| |
| Leaving the interface with a positive PM usage counter would prevent a |
| later bound driver from suspending the device. |
| |
| Fixes: c2b71462d294 ("USB: core: Fix bug caused by duplicate interface PM usage counter") |
| Cc: stable <stable@vger.kernel.org> |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Link: https://lore.kernel.org/r/20191001084908.2003-2-johan@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/usb-skeleton.c | 8 +++----- |
| 1 file changed, 3 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/usb/usb-skeleton.c |
| +++ b/drivers/usb/usb-skeleton.c |
| @@ -75,6 +75,7 @@ static void skel_delete(struct kref *kre |
| struct usb_skel *dev = to_skel_dev(kref); |
| |
| usb_free_urb(dev->bulk_in_urb); |
| + usb_put_intf(dev->interface); |
| usb_put_dev(dev->udev); |
| kfree(dev->bulk_in_buffer); |
| kfree(dev); |
| @@ -126,10 +127,7 @@ static int skel_release(struct inode *in |
| return -ENODEV; |
| |
| /* allow the device to be autosuspended */ |
| - mutex_lock(&dev->io_mutex); |
| - if (dev->interface) |
| - usb_autopm_put_interface(dev->interface); |
| - mutex_unlock(&dev->io_mutex); |
| + usb_autopm_put_interface(dev->interface); |
| |
| /* decrement the count on our device */ |
| kref_put(&dev->kref, skel_delete); |
| @@ -511,7 +509,7 @@ static int skel_probe(struct usb_interfa |
| init_waitqueue_head(&dev->bulk_in_wait); |
| |
| dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
| - dev->interface = interface; |
| + dev->interface = usb_get_intf(interface); |
| |
| /* set up the endpoint information */ |
| /* use only the first bulk-in and bulk-out endpoints */ |