Browse Source

USB: switch ehci-hcd to new polling scheme

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>
Marcelo Tosatti 18 years ago
parent
commit
1d619f128b
1 changed files with 7 additions and 1 deletions
  1. 7 1
      drivers/usb/host/ehci-hcd.c

+ 7 - 1
drivers/usb/host/ehci-hcd.c

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