]> Pileus Git - ~andy/linux/blobdiff - drivers/usb/core/hcd.c
Merge tag 'usb-3.9-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[~andy/linux] / drivers / usb / core / hcd.c
index 4225d5e721312a6ec87a96352d05c7db8a682593..f9ec44cbb82fb1ff6fa8e620367de8a9daec2c70 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/unaligned.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
@@ -619,6 +620,10 @@ nongeneric:
                status = hcd->driver->hub_control (hcd,
                        typeReq, wValue, wIndex,
                        tbuf, wLength);
+
+               if (typeReq == GetHubDescriptor)
+                       usb_hub_adjust_deviceremovable(hcd->self.root_hub,
+                               (struct usb_hub_descriptor *)tbuf);
                break;
 error:
                /* "protocol stall" on error */
@@ -1025,6 +1030,49 @@ static int register_root_hub(struct usb_hcd *hcd)
        return retval;
 }
 
+/*
+ * usb_hcd_start_port_resume - a root-hub port is sending a resume signal
+ * @bus: the bus which the root hub belongs to
+ * @portnum: the port which is being resumed
+ *
+ * HCDs should call this function when they know that a resume signal is
+ * being sent to a root-hub port.  The root hub will be prevented from
+ * going into autosuspend until usb_hcd_end_port_resume() is called.
+ *
+ * The bus's private lock must be held by the caller.
+ */
+void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum)
+{
+       unsigned bit = 1 << portnum;
+
+       if (!(bus->resuming_ports & bit)) {
+               bus->resuming_ports |= bit;
+               pm_runtime_get_noresume(&bus->root_hub->dev);
+       }
+}
+EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume);
+
+/*
+ * usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal
+ * @bus: the bus which the root hub belongs to
+ * @portnum: the port which is being resumed
+ *
+ * HCDs should call this function when they know that a resume signal has
+ * stopped being sent to a root-hub port.  The root hub will be allowed to
+ * autosuspend again.
+ *
+ * The bus's private lock must be held by the caller.
+ */
+void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum)
+{
+       unsigned bit = 1 << portnum;
+
+       if (bus->resuming_ports & bit) {
+               bus->resuming_ports &= ~bit;
+               pm_runtime_put_noidle(&bus->root_hub->dev);
+       }
+}
+EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume);
 
 /*-------------------------------------------------------------------------*/
 
@@ -2364,6 +2412,14 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
 
+int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+       if (!hcd->driver->find_raw_port_number)
+               return port1;
+
+       return hcd->driver->find_raw_port_number(hcd, port1);
+}
+
 static int usb_hcd_request_irqs(struct usb_hcd *hcd,
                unsigned int irqnum, unsigned long irqflags)
 {
@@ -2506,7 +2562,6 @@ int usb_add_hcd(struct usb_hcd *hcd,
        }
 
        /* starting here, usbcore will pay attention to this root hub */
-       rhdev->bus_mA = min(500u, hcd->power_budget);
        if ((retval = register_root_hub(hcd)) != 0)
                goto err_register_root_hub;