On Wed, 13 Apr 2011, Kristen Carlson Accardi wrote: > So are you going to send an updated patch? Here is the promised patch. I haven't tested it, but it look looks okay and compiles without errors. Alan Stern drivers/usb/host/ehci-au1xxx.c | 12 +++++++----- drivers/usb/host/ehci-hcd.c | 12 ++++++++++-- drivers/usb/host/ehci-hub.c | 13 +++++++------ drivers/usb/host/ehci-pci.c | 12 +++++++----- drivers/usb/host/ehci.h | 1 + 5 files changed, 32 insertions(+), 18 deletions(-) Index: usb-2.6/drivers/usb/host/ehci-au1xxx.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-au1xxx.c +++ usb-2.6/drivers/usb/host/ehci-au1xxx.c @@ -229,7 +229,8 @@ static int ehci_hcd_au1xxx_drv_suspend(s */ ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev)); spin_lock_irqsave(&ehci->lock, flags); - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + ehci->intr_mask = 0; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); @@ -262,13 +263,14 @@ static int ehci_hcd_au1xxx_drv_resume(st * Just undo the effect of ehci_pci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { - int mask = INTR_MASK; - ehci_prepare_ports_for_controller_resume(ehci); + spin_lock_irq(&ehci->lock); + ehci->intr_mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) - mask &= ~STS_PCD; - ehci_writel(ehci, mask, &ehci->regs->intr_enable); + ehci->intr_mask &= ~STS_PCD; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); + spin_unlock_irq(&ehci->lock); return 0; } Index: usb-2.6/drivers/usb/host/ehci-hcd.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-hcd.c +++ usb-2.6/drivers/usb/host/ehci-hcd.c @@ -212,7 +212,8 @@ static int ehci_halt (struct ehci_hcd *e u32 temp = ehci_readl(ehci, &ehci->regs->status); /* disable any irqs left enabled by previous code */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + ehci->intr_mask = 0; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); if (ehci_is_TDI(ehci) && tdi_in_host_mode(ehci) == 0) { return 0; @@ -746,8 +747,11 @@ static int ehci_run (struct usb_hcd *hcd temp >> 8, temp & 0xff, ignore_oc ? ", overcurrent ignored" : ""); - ehci_writel(ehci, INTR_MASK, + spin_lock_irq(&ehci->lock); + ehci->intr_mask = INTR_MASK; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); /* Turn On Interrupts */ + spin_unlock_irq(&ehci->lock); /* GRR this is run-once init(), being done every time the HC starts. * So long as they're part of class devices, we can't do it init() @@ -881,6 +885,10 @@ dead: if (bh) ehci_work (ehci); + + /* Threaded interrupt handler must re-enable interrupts */ + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); + spin_unlock (&ehci->lock); if (pcd_status) usb_hcd_poll_rh_status(hcd); Index: usb-2.6/drivers/usb/host/ehci-hub.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-hub.c +++ usb-2.6/drivers/usb/host/ehci-hub.c @@ -204,7 +204,6 @@ static int ehci_bus_suspend (struct usb_ { struct ehci_hcd *ehci = hcd_to_ehci (hcd); int port; - int mask; int changed; ehci_dbg(ehci, "suspend root hub\n"); @@ -318,10 +317,10 @@ static int ehci_bus_suspend (struct usb_ end_unlink_async(ehci); /* allow remote wakeup */ - mask = INTR_MASK; + ehci->intr_mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) - mask &= ~STS_PCD; - ehci_writel(ehci, mask, &ehci->regs->intr_enable); + ehci->intr_mask &= ~STS_PCD; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); ehci->next_statechange = jiffies + msecs_to_jiffies(10); @@ -372,7 +371,8 @@ static int ehci_bus_resume (struct usb_h /* at least some APM implementations will try to deliver * IRQs right away, so delay them until we're ready. */ - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + ehci->intr_mask = 0; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); /* re-init operational registers */ ehci_writel(ehci, 0, &ehci->regs->segment); @@ -454,7 +454,8 @@ static int ehci_bus_resume (struct usb_h hcd->state = HC_STATE_RUNNING; /* Now we can safely re-enable irqs */ - ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); + ehci->intr_mask = INTR_MASK; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); spin_unlock_irq (&ehci->lock); ehci_handover_companion_ports(ehci); Index: usb-2.6/drivers/usb/host/ehci-pci.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-pci.c +++ usb-2.6/drivers/usb/host/ehci-pci.c @@ -336,7 +336,8 @@ static int ehci_pci_suspend(struct usb_h */ ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); spin_lock_irqsave (&ehci->lock, flags); - ehci_writel(ehci, 0, &ehci->regs->intr_enable); + ehci->intr_mask = 0; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); @@ -367,13 +368,14 @@ static int ehci_pci_resume(struct usb_hc */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF && !hibernated) { - int mask = INTR_MASK; - ehci_prepare_ports_for_controller_resume(ehci); + spin_lock_irq(&ehci->lock); + ehci->intr_mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) - mask &= ~STS_PCD; - ehci_writel(ehci, mask, &ehci->regs->intr_enable); + ehci->intr_mask &= ~STS_PCD; + ehci_writel(ehci, ehci->intr_mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); + spin_unlock_irq(&ehci->lock); return 0; } Index: usb-2.6/drivers/usb/host/ehci.h =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci.h +++ usb-2.6/drivers/usb/host/ehci.h @@ -122,6 +122,7 @@ struct ehci_hcd { /* one per controlle unsigned long next_statechange; ktime_t last_periodic_enable; u32 command; + u32 intr_mask; /* SILICON QUIRKS */ unsigned no_selective_suspend:1; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html