]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/core/hcd.c
USB: usb dev_name() instead of dev->bus_id
[linux-2.6-omap-h63xx.git] / drivers / usb / core / hcd.c
index 09a53e7f33278ad58f555b15792c7b89c676a458..f7bfd72ef115bae2855e05c9b622ff41588477b1 100644 (file)
@@ -900,14 +900,14 @@ static int register_root_hub(struct usb_hcd *hcd)
        if (retval != sizeof usb_dev->descriptor) {
                mutex_unlock(&usb_bus_list_lock);
                dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
-                               usb_dev->dev.bus_id, retval);
+                               dev_name(&usb_dev->dev), retval);
                return (retval < 0) ? retval : -EMSGSIZE;
        }
 
        retval = usb_new_device (usb_dev);
        if (retval) {
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
-                               usb_dev->dev.bus_id, retval);
+                               dev_name(&usb_dev->dev), retval);
        }
        mutex_unlock(&usb_bus_list_lock);
 
@@ -924,6 +924,15 @@ static int register_root_hub(struct usb_hcd *hcd)
        return retval;
 }
 
+void usb_enable_root_hub_irq (struct usb_bus *bus)
+{
+       struct usb_hcd *hcd;
+
+       hcd = container_of (bus, struct usb_hcd, self);
+       if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
+               hcd->driver->hub_irq_enable (hcd);
+}
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -1684,19 +1693,30 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
 irqreturn_t usb_hcd_irq (int irq, void *__hcd)
 {
        struct usb_hcd          *hcd = __hcd;
-       int                     start = hcd->state;
+       unsigned long           flags;
+       irqreturn_t             rc;
 
-       if (unlikely(start == HC_STATE_HALT ||
-           !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
-               return IRQ_NONE;
-       if (hcd->driver->irq (hcd) == IRQ_NONE)
-               return IRQ_NONE;
+       /* IRQF_DISABLED doesn't work correctly with shared IRQs
+        * when the first handler doesn't use it.  So let's just
+        * assume it's never used.
+        */
+       local_irq_save(flags);
 
-       set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
+       if (unlikely(hcd->state == HC_STATE_HALT ||
+                    !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
+               rc = IRQ_NONE;
+       } else if (hcd->driver->irq(hcd) == IRQ_NONE) {
+               rc = IRQ_NONE;
+       } else {
+               set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
+
+               if (unlikely(hcd->state == HC_STATE_HALT))
+                       usb_hc_died(hcd);
+               rc = IRQ_HANDLED;
+       }
 
-       if (unlikely(hcd->state == HC_STATE_HALT))
-               usb_hc_died (hcd);
-       return IRQ_HANDLED;
+       local_irq_restore(flags);
+       return rc;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1744,7 +1764,7 @@ EXPORT_SYMBOL_GPL (usb_hc_died);
  * If memory is unavailable, returns NULL.
  */
 struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
-               struct device *dev, char *bus_name)
+               struct device *dev, const char *bus_name)
 {
        struct usb_hcd *hcd;
 
@@ -1860,6 +1880,13 @@ int usb_add_hcd(struct usb_hcd *hcd,
 
        /* enable irqs just before we start the controller */
        if (hcd->driver->irq) {
+
+               /* IRQF_DISABLED doesn't work as advertised when used together
+                * with IRQF_SHARED. As usb_hcd_irq() will always disable
+                * interrupts we can remove it here.
+                */
+               irqflags &= ~IRQF_DISABLED;
+
                snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
                                hcd->driver->description, hcd->self.busnum);
                if ((retval = request_irq(irqnum, &usb_hcd_irq, irqflags,