aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/hub.c12
-rw-r--r--drivers/usb/core/usb.c3
3 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index bbe2b924aae8..89613a744236 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -248,7 +248,7 @@ struct hc_driver {
248 /* xHCI specific functions */ 248 /* xHCI specific functions */
249 /* Called by usb_alloc_dev to alloc HC device structures */ 249 /* Called by usb_alloc_dev to alloc HC device structures */
250 int (*alloc_dev)(struct usb_hcd *, struct usb_device *); 250 int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
251 /* Called by usb_release_dev to free HC device structures */ 251 /* Called by usb_disconnect to free HC device structures */
252 void (*free_dev)(struct usb_hcd *, struct usb_device *); 252 void (*free_dev)(struct usb_hcd *, struct usb_device *);
253 253
254 /* Bandwidth computation functions */ 254 /* Bandwidth computation functions */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 35cc8b9ba1f5..9cc0abae7923 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1554,6 +1554,15 @@ static inline void usb_stop_pm(struct usb_device *udev)
1554 1554
1555#endif 1555#endif
1556 1556
1557static void hub_free_dev(struct usb_device *udev)
1558{
1559 struct usb_hcd *hcd = bus_to_hcd(udev->bus);
1560
1561 /* Root hubs aren't real devices, so don't free HCD resources */
1562 if (hcd->driver->free_dev && udev->parent)
1563 hcd->driver->free_dev(hcd, udev);
1564}
1565
1557/** 1566/**
1558 * usb_disconnect - disconnect a device (usbcore-internal) 1567 * usb_disconnect - disconnect a device (usbcore-internal)
1559 * @pdev: pointer to device being disconnected 1568 * @pdev: pointer to device being disconnected
@@ -1624,6 +1633,8 @@ void usb_disconnect(struct usb_device **pdev)
1624 1633
1625 usb_stop_pm(udev); 1634 usb_stop_pm(udev);
1626 1635
1636 hub_free_dev(udev);
1637
1627 put_device(&udev->dev); 1638 put_device(&udev->dev);
1628} 1639}
1629 1640
@@ -3191,6 +3202,7 @@ loop_disable:
3191loop: 3202loop:
3192 usb_ep0_reinit(udev); 3203 usb_ep0_reinit(udev);
3193 release_address(udev); 3204 release_address(udev);
3205 hub_free_dev(udev);
3194 usb_put_dev(udev); 3206 usb_put_dev(udev);
3195 if ((status == -ENOTCONN) || (status == -ENOTSUPP)) 3207 if ((status == -ENOTCONN) || (status == -ENOTSUPP))
3196 break; 3208 break;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 0daff0d968ba..ced0776b9ee9 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -228,9 +228,6 @@ static void usb_release_dev(struct device *dev)
228 hcd = bus_to_hcd(udev->bus); 228 hcd = bus_to_hcd(udev->bus);
229 229
230 usb_destroy_configuration(udev); 230 usb_destroy_configuration(udev);
231 /* Root hubs aren't real devices, so don't free HCD resources */
232 if (hcd->driver->free_dev && udev->parent)
233 hcd->driver->free_dev(hcd, udev);
234 usb_put_hcd(hcd); 231 usb_put_hcd(hcd);
235 kfree(udev->product); 232 kfree(udev->product);
236 kfree(udev->manufacturer); 233 kfree(udev->manufacturer);