USB: switch ehci-hcd to new polling scheme
authorMarcelo Tosatti <marcelo@kvack.org>
Sun, 21 Jan 2007 21:45:59 +0000 (19:45 -0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Feb 2007 23:44:39 +0000 (15:44 -0800)
Switch ehci-hcd to use the new polling scheme, which reports root
hub status changes via the interrupt handler, in an asynchronous
fashion. Doing so disables polling for status changes (whose handler is
rh_timer_func).

Tested on a Geode GX machine, which is now capable of running at =~ 5
timer interrupts per second (in the -rt tree), resulting in significant
power savings.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-hcd.c

index 92c62911f57440ce6d4dbe365788d6e2d82c8ff0..185721dba42be006384012184eb38bf256b257c8 100644 (file)
@@ -501,6 +501,9 @@ static int ehci_run (struct usb_hcd *hcd)
        u32                     temp;
        u32                     hcc_params;
 
+       hcd->uses_new_polling = 1;
+       hcd->poll_rh = 0;
+
        /* EHCI spec section 4.1 */
        if ((retval = ehci_reset(ehci)) != 0) {
                ehci_mem_cleanup(ehci);
@@ -574,7 +577,7 @@ static int ehci_run (struct usb_hcd *hcd)
 static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
-       u32                     status;
+       u32                     status, pcd_status = 0;
        int                     bh;
 
        spin_lock (&ehci->lock);
@@ -624,6 +627,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        /* remote wakeup [4.3.1] */
        if (status & STS_PCD) {
                unsigned        i = HCS_N_PORTS (ehci->hcs_params);
+               pcd_status = status;
 
                /* resume root hub? */
                if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
@@ -670,6 +674,8 @@ dead:
        if (bh)
                ehci_work (ehci);
        spin_unlock (&ehci->lock);
+       if (pcd_status & STS_PCD)
+               usb_hcd_poll_rh_status(hcd);
        return IRQ_HANDLED;
 }