Re: [PATCH] usb: hcd: allow wakeups while suspended for Moorestown

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 7 Apr 2011, Greg KH wrote:

> Here's Thomas's first cut at doing this, totally untested and written
> during a legal track at the LF Collab summit.
> 
> Kristen, can you take this and test and see if it works for you?
> 
> thanks,
> 
> greg k-h
> 
> 
> Subject: usb.patch
> From: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Date: Thu, 07 Apr 2011 23:35:16 +0200
> 
> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> ---
>  drivers/usb/core/hcd.c      |   42 ++++++++++++++++++++----------------------
>  drivers/usb/host/ehci-hcd.c |   33 +++++++++++++++++++++++++++------
>  drivers/usb/host/ehci-pci.c |    1 +
>  include/linux/usb/hcd.h     |    1 +
>  4 files changed, 49 insertions(+), 28 deletions(-)

This isn't correct, for a couple of reasons.  The most important reason 
shows up here:

> Index: linux-2.6/drivers/usb/host/ehci-hcd.c
> ===================================================================
> --- linux-2.6.orig/drivers/usb/host/ehci-hcd.c
> +++ linux-2.6/drivers/usb/host/ehci-hcd.c
> @@ -764,10 +764,35 @@ 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;
> +
> +	spin_lock(&ehci->lock);
> +
> +	status = ehci_readl(ehci, &ehci->regs->status);
> +	if (status & INTR_MASK)
> +		ehci_writel(ehci, 0, &ehci->regs->intr_enable);
> +
> +	spin_unlock(&ehci->lock);
> +
> +	return status & INTR_MASK ? IRQ_WAKE_THREAD : IRQ_NONE;
> +}

The status information gets thrown away.  It has to be saved for later 
use.

> +
> +static irqreturn_t ehci_thread_irq (struct usb_hcd *hcd)
> +{
> +	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
>  	u32			status, masked_status, pcd_status = 0, cmd;
>  	int			bh;
>  
> -	spin_lock (&ehci->lock);
> +	/*
> +	 * The scope of this lock wants to be reduced to protect the
> +	 * status register access. Serializiation at the thread level
> +	 * should simply use a mutex, which is not simple either as
> +	 * you have to deal with the watchdog timer stuff. Needs some
> +	 * thought. Making it spin_lock_bh() now should be fine. We
> +	 * just need to disable interrupts right before we write the
> +	 * interrupt mask register.
> +	 */
> +	spin_lock_irq(&ehci->lock);

This comment is also wrong.  The spinlock does not merely protect the 
hardware registers; it also protects the driver's data structures, 
which can be accessed by code running in_interrupt (i.e., within other 
non-threaded interrupt handlers).

Alan Stern

--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux