This patch adds a new field to the ehci-hcd private structure, for
holding the value of the EHCI Interrupt Enable register, together with
an inline routine for setting this value.

The ehci->intr-enable field will used in a following patch, when a
tasklet's bottom-half handler needs to restore the correct interrupt
mask.

Not-yet-signed-off-by: Alan Stern <st...@rowland.harvard.edu>

---


 drivers/usb/host/ehci-hcd.c   |   21 ++++++++++++++-------
 drivers/usb/host/ehci-hub.c   |    6 +++---
 drivers/usb/host/ehci-timer.c |    2 +-
 drivers/usb/host/ehci.h       |    1 +
 4 files changed, 19 insertions(+), 11 deletions(-)

Index: usb-3.11/drivers/usb/host/ehci-hcd.c
===================================================================
--- usb-3.11.orig/drivers/usb/host/ehci-hcd.c
+++ usb-3.11/drivers/usb/host/ehci-hcd.c
@@ -134,6 +134,12 @@ static inline unsigned ehci_read_frame_i
        return ehci_readl(ehci, &ehci->regs->frame_index);
 }
 
+static inline void ehci_set_intr_enable(struct ehci_hcd *ehci, u32 mask)
+{
+       ehci->intr_mask = mask;
+       ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+}
+
 #include "ehci-dbg.c"
 
 /*-------------------------------------------------------------------------*/
@@ -194,7 +200,7 @@ static int ehci_halt (struct ehci_hcd *e
        spin_lock_irq(&ehci->lock);
 
        /* disable any irqs left enabled by previous code */
-       ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+       ehci_set_intr_enable(ehci, 0);
 
        if (ehci_is_TDI(ehci) && !tdi_in_host_mode(ehci)) {
                spin_unlock_irq(&ehci->lock);
@@ -639,8 +645,9 @@ static int ehci_run (struct usb_hcd *hcd
                temp >> 8, temp & 0xff,
                ignore_oc ? ", overcurrent ignored" : "");
 
-       ehci_writel(ehci, INTR_MASK,
-                   &ehci->regs->intr_enable); /* Turn On Interrupts */
+       spin_lock_irq(&ehci->lock);
+       ehci_set_intr_enable(ehci, INTR_MASK);  /* 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()
@@ -817,7 +824,7 @@ dead:
                ehci->rh_state = EHCI_RH_STOPPING;
                ehci->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
                ehci_writel(ehci, ehci->command, &ehci->regs->command);
-               ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+               ehci_set_intr_enable(ehci, 0);
                ehci_handle_controller_death(ehci);
 
                /* Handle completions when the controller stops */
@@ -1080,7 +1087,7 @@ int ehci_suspend(struct usb_hcd *hcd, bo
        ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup);
 
        spin_lock_irq(&ehci->lock);
-       ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+       ehci_set_intr_enable(ehci, 0);
        (void) ehci_readl(ehci, &ehci->regs->intr_enable);
 
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -1111,7 +1118,7 @@ int ehci_resume(struct usb_hcd *hcd, boo
         */
        if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF &&
                        !hibernated) {
-               int     mask = INTR_MASK;
+               u32     mask = INTR_MASK;
 
                ehci_prepare_ports_for_controller_resume(ehci);
 
@@ -1121,7 +1128,7 @@ int ehci_resume(struct usb_hcd *hcd, boo
 
                if (!hcd->self.root_hub->do_remote_wakeup)
                        mask &= ~STS_PCD;
-               ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+               ehci_set_intr_enable(ehci, mask);
                ehci_readl(ehci, &ehci->regs->intr_enable);
  skip:
                spin_unlock_irq(&ehci->lock);
Index: usb-3.11/drivers/usb/host/ehci-hub.c
===================================================================
--- usb-3.11.orig/drivers/usb/host/ehci-hub.c
+++ usb-3.11/drivers/usb/host/ehci-hub.c
@@ -352,7 +352,7 @@ static int ehci_bus_suspend (struct usb_
        mask = INTR_MASK;
        if (!hcd->self.root_hub->do_remote_wakeup)
                mask &= ~STS_PCD;
-       ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+       ehci_set_intr_enable(ehci, mask);
        ehci_readl(ehci, &ehci->regs->intr_enable);
 
  done:
@@ -401,7 +401,7 @@ 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_set_intr_enable(ehci, 0);
 
        /* re-init operational registers */
        ehci_writel(ehci, 0, &ehci->regs->segment);
@@ -495,7 +495,7 @@ static int ehci_bus_resume (struct usb_h
        spin_lock_irq(&ehci->lock);
        if (ehci->shutdown)
                goto shutdown;
-       ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
+       ehci_set_intr_enable(ehci, INTR_MASK);
        (void) ehci_readl(ehci, &ehci->regs->intr_enable);
        spin_unlock_irq(&ehci->lock);
 
Index: usb-3.11/drivers/usb/host/ehci.h
===================================================================
--- usb-3.11.orig/drivers/usb/host/ehci.h
+++ usb-3.11/drivers/usb/host/ehci.h
@@ -186,6 +186,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;
Index: usb-3.11/drivers/usb/host/ehci-timer.c
===================================================================
--- usb-3.11.orig/drivers/usb/host/ehci-timer.c
+++ usb-3.11/drivers/usb/host/ehci-timer.c
@@ -208,7 +208,7 @@ static void ehci_handle_controller_death
        /* Clean up the mess */
        ehci->rh_state = EHCI_RH_HALTED;
        ehci_writel(ehci, 0, &ehci->regs->configured_flag);
-       ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+       ehci_set_intr_enable(ehci, 0);
        ehci_work(ehci);
        end_unlink_async(ehci);
 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to