USB: HCDs use the do_remote_wakeup flag
When a USB device is suspended, whether or not it is enabled for remote wakeup depends on the device_may_wakeup() setting. The setting is then saved in the do_remote_wakeup flag. Later on, however, the device_may_wakeup() value can change because of user activity. So when testing whether a suspended device is or should be enabled for remote wakeup, we should always test do_remote_wakeup instead of device_may_wakeup(). This patch (as1076) makes that change for root hubs in several places. The patch also adjusts uhci-hcd so that when an autostopped controller is suspended, the remote wakeup setting agrees with the value recorded in the root hub's do_remote_wakeup flag. And the patch adjusts ehci-hcd so that wakeup events on selectively suspended ports (i.e., the bus itself isn't suspended) don't turn on the PME# wakeup signal. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
b950bdbc67
commit
58a97ffeb2
@@ -30,6 +30,8 @@
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
|
||||
|
||||
static int ehci_hub_control(
|
||||
struct usb_hcd *hcd,
|
||||
u16 typeReq,
|
||||
@@ -149,10 +151,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
||||
}
|
||||
|
||||
/* enable remote wakeup on all ports */
|
||||
if (device_may_wakeup(&hcd->self.root_hub->dev))
|
||||
t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
|
||||
if (hcd->self.root_hub->do_remote_wakeup)
|
||||
t2 |= PORT_WAKE_BITS;
|
||||
else
|
||||
t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
|
||||
t2 &= ~PORT_WAKE_BITS;
|
||||
|
||||
if (t1 != t2) {
|
||||
ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
|
||||
@@ -174,7 +176,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
||||
|
||||
/* allow remote wakeup */
|
||||
mask = INTR_MASK;
|
||||
if (!device_may_wakeup(&hcd->self.root_hub->dev))
|
||||
if (!hcd->self.root_hub->do_remote_wakeup)
|
||||
mask &= ~STS_PCD;
|
||||
ehci_writel(ehci, mask, &ehci->regs->intr_enable);
|
||||
ehci_readl(ehci, &ehci->regs->intr_enable);
|
||||
@@ -232,8 +234,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
||||
i = HCS_N_PORTS (ehci->hcs_params);
|
||||
while (i--) {
|
||||
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
|
||||
temp &= ~(PORT_RWC_BITS
|
||||
| PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
|
||||
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
|
||||
if (test_bit(i, &ehci->bus_suspended) &&
|
||||
(temp & PORT_SUSPEND)) {
|
||||
ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
|
||||
@@ -534,8 +535,6 @@ ehci_hub_descriptor (
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
|
||||
|
||||
static int ehci_hub_control (
|
||||
struct usb_hcd *hcd,
|
||||
u16 typeReq,
|
||||
@@ -801,8 +800,6 @@ static int ehci_hub_control (
|
||||
if ((temp & PORT_PE) == 0
|
||||
|| (temp & PORT_RESET) != 0)
|
||||
goto error;
|
||||
if (device_may_wakeup(&hcd->self.root_hub->dev))
|
||||
temp |= PORT_WAKE_BITS;
|
||||
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
|
||||
break;
|
||||
case USB_PORT_FEAT_POWER:
|
||||
|
Reference in New Issue
Block a user