From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Eddy Petrisor <eddy.petrisor@gmail.com>
Cc: linuxppc-dev list <linuxppc-dev@ozlabs.org>,
"debian-powerpc@lists.debian.org"
<debian-powerpc@lists.debian.org>
Subject: Re: 2.6.14 USB vs. sleep issues
Date: Sat, 12 Nov 2005 08:52:26 +1100 [thread overview]
Message-ID: <1131745946.24637.251.camel@gaston> (raw)
In-Reply-To: <43751182.1020009@gmail.com>
The latest patch that is candidate for upstream is:
Index: 2.6.14-ben/drivers/usb/core/hcd-pci.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/core/hcd-pci.c
+++ 2.6.14-ben/drivers/usb/core/hcd-pci.c
@@ -32,6 +32,13 @@
#include <linux/usb.h>
#include "hcd.h"
+#ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#endif
+
/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
@@ -278,6 +285,18 @@ int usb_hcd_pci_suspend (struct pci_dev
break;
}
+#ifdef CONFIG_PPC_PMAC
+ if (retval == 0 && _machine == _MACH_Pmac) {
+ struct device_node *of_node;
+
+ /* Disable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.
+ controller));
+ if (of_node)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
+ }
+#endif /* CONFIG_PPC_PMAC */
+
/* update power_state **ONLY** to make sysfs happier */
if (retval == 0)
dev->dev.power.power_state = message;
@@ -303,6 +322,18 @@ int usb_hcd_pci_resume (struct pci_dev *
return 0;
}
+#ifdef CONFIG_PPC_PMAC
+ if (_machine == _MACH_Pmac) {
+ struct device_node *of_node;
+
+ /* Re-enable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.
+ controller));
+ if (of_node)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
+ }
+#endif /* CONFIG_PPC_PMAC */
+
/* NOTE: chip docs cover clean "real suspend" cases (what Linux
* calls "standby", "suspend to RAM", and so on). There are also
* dirty cases when swsusp fakes a suspend in "shutdown" mode.
Index: 2.6.14-ben/drivers/usb/core/hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/core/hcd.c
+++ 2.6.14-ben/drivers/usb/core/hcd.c
@@ -1600,7 +1600,8 @@ irqreturn_t usb_hcd_irq (int irq, void *
struct usb_hcd *hcd = __hcd;
int start = hcd->state;
- if (start == HC_STATE_HALT)
+ if (start == HC_STATE_HALT ||
+ !test_bit(HC_FLAG_IRQ_ON, &hcd->bitflags))
return IRQ_NONE;
if (hcd->driver->irq (hcd, r) == IRQ_NONE)
return IRQ_NONE;
@@ -1736,6 +1737,9 @@ int usb_add_hcd(struct usb_hcd *hcd,
if (hcd->driver->irq) {
char buf[8], *bufp = buf;
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ mb();
+
#ifdef __sparc__
bufp = __irq_itoa(irqnum);
#else
Index: 2.6.14-ben/drivers/usb/core/hcd.h
===================================================================
--- 2.6.14-ben.orig/drivers/usb/core/hcd.h
+++ 2.6.14-ben/drivers/usb/core/hcd.h
@@ -71,6 +71,9 @@ struct usb_hcd { /* usb_bus.hcpriv point
/*
* hardware info/state
*/
+ unsigned long bitflags; /* various single-bit flags */
+#define HC_FLAG_IRQ_ON 0
+
const struct hc_driver *driver; /* hw-specific hooks */
unsigned saw_irq : 1;
unsigned can_wakeup:1; /* hw supports wakeup? */
Index: 2.6.14-ben/drivers/usb/host/ehci-hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ehci-hcd.c
+++ 2.6.14-ben/drivers/usb/host/ehci-hcd.c
@@ -750,6 +750,12 @@ static int ehci_suspend (struct usb_hcd
if (time_before (jiffies, ehci->next_statechange))
msleep (100);
+ /* Disable emission of interrupts during suspend */
+ writel(0, &ehci->regs->intr_enable);
+ mb();
+ clear_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ synchronize_irq(to_pci_dev(hcd->self.controller)->irq);
+
#ifdef CONFIG_USB_SUSPEND
(void) usb_suspend_device (hcd->self.root_hub, message);
#else
@@ -776,6 +782,8 @@ static int ehci_resume (struct usb_hcd *
if (time_before (jiffies, ehci->next_statechange))
msleep (100);
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+
/* If any port is suspended (or owned by the companion),
* we know we can/must resume the HC (and mustn't reset it).
*/
Index: 2.6.14-ben/drivers/usb/host/ehci-q.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ehci-q.c
+++ 2.6.14-ben/drivers/usb/host/ehci-q.c
@@ -926,6 +926,11 @@ submit_async (
#endif
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ return -ESHUTDOWN;
+ }
+
qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
/* Control/bulk operations through TTs don't need scheduling,
Index: 2.6.14-ben/drivers/usb/host/ehci-sched.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ehci-sched.c
+++ 2.6.14-ben/drivers/usb/host/ehci-sched.c
@@ -602,6 +602,11 @@ static int intr_submit (
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ return -ESHUTDOWN;
+ }
+
/* get qh and force any scheduling errors */
INIT_LIST_HEAD (&empty);
qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
@@ -1456,6 +1461,11 @@ static int itd_submit (struct ehci_hcd *
/* schedule ... need to lock */
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ status = -ESHUTDOWN;
+ goto done;
+ }
status = iso_stream_schedule (ehci, urb, stream);
if (likely (status == 0))
itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
@@ -1815,6 +1825,11 @@ static int sitd_submit (struct ehci_hcd
/* schedule ... need to lock */
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ status = -ESHUTDOWN;
+ goto done;
+ }
status = iso_stream_schedule (ehci, urb, stream);
if (status == 0)
sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
Index: 2.6.14-ben/drivers/usb/host/ohci-hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ohci-hcd.c
+++ 2.6.14-ben/drivers/usb/host/ohci-hcd.c
@@ -252,6 +252,10 @@ static int ohci_urb_enqueue (
spin_lock_irqsave (&ohci->lock, flags);
+ if (HC_IS_SUSPENDED(hcd->state)) {
+ retval = -ESHUTDOWN;
+ goto fail;
+ }
/* don't submit to a dead HC */
if (!HC_IS_RUNNING(hcd->state)) {
retval = -ENODEV;
Index: 2.6.14-ben/drivers/usb/host/ohci-hub.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ohci-hub.c
+++ 2.6.14-ben/drivers/usb/host/ohci-hub.c
@@ -219,13 +219,6 @@ static int ohci_hub_resume (struct usb_h
/* Sometimes PCI D3 suspend trashes frame timings ... */
periodic_reinit (ohci);
- /* interrupts might have been disabled */
- ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
- if (ohci->ed_rm_list)
- ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
- ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
- &ohci->regs->intrstatus);
-
/* Then re-enable operations */
ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control);
(void) ohci_readl (ohci, &ohci->regs->control);
@@ -241,6 +234,13 @@ static int ohci_hub_resume (struct usb_h
/* TRSMRCY */
msleep (10);
+ /* interrupts might have been disabled */
+ ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
+ if (ohci->ed_rm_list)
+ ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
+ ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
+ &ohci->regs->intrstatus);
+
/* keep it alive for ~5x suspend + resume costs */
ohci->next_statechange = jiffies + msecs_to_jiffies (250);
Index: 2.6.14-ben/drivers/usb/host/ohci-pci.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ohci-pci.c
+++ 2.6.14-ben/drivers/usb/host/ohci-pci.c
@@ -14,13 +14,6 @@
* This file is licenced under the GPL.
*/
-#ifdef CONFIG_PPC_PMAC
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/pci-bridge.h>
-#include <asm/prom.h>
-#endif
-
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
@@ -118,6 +111,12 @@ static int ohci_pci_suspend (struct usb_
if (time_before (jiffies, ohci->next_statechange))
msleep (100);
+ /* Disable emission of interrupts during suspend */
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ mb();
+ clear_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ synchronize_irq(to_pci_dev(hcd->self.controller)->irq);
+
#ifdef CONFIG_USB_SUSPEND
(void) usb_suspend_device (hcd->self.root_hub, message);
#else
@@ -129,16 +128,6 @@ static int ohci_pci_suspend (struct usb_
/* let things settle down a bit */
msleep (100);
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac) {
- struct device_node *of_node;
-
- /* Disable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
- if (of_node)
- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
- }
-#endif /* CONFIG_PPC_PMAC */
return 0;
}
@@ -148,20 +137,11 @@ static int ohci_pci_resume (struct usb_h
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int retval = 0;
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac) {
- struct device_node *of_node;
-
- /* Re-enable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
- if (of_node)
- pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
- }
-#endif /* CONFIG_PPC_PMAC */
-
/* resume root hub */
if (time_before (jiffies, ohci->next_statechange))
msleep (100);
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+
#ifdef CONFIG_USB_SUSPEND
/* get extra cleanup even if remote wakeup isn't in use */
retval = usb_resume_device (hcd->self.root_hub);
Index: 2.6.14-ben/drivers/usb/host/uhci-hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/uhci-hcd.c
+++ 2.6.14-ben/drivers/usb/host/uhci-hcd.c
@@ -797,6 +797,11 @@ static int uhci_suspend(struct usb_hcd *
done:
spin_unlock_irq(&uhci->lock);
+ if (rc == 0) {
+ mb();
+ clear_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ synchronize_irq(hcd->irq);
+ }
return rc;
}
@@ -818,6 +823,8 @@ static int uhci_resume(struct usb_hcd *h
* system wakeup. Check it and reconfigure to avoid problems.
*/
check_and_reset_hc(uhci);
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ mb();
configure_hc(uhci);
#ifndef CONFIG_USB_SUSPEND
next prev parent reply other threads:[~2005-11-11 21:55 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-03 6:33 2.6.14 USB vs. sleep issues Benjamin Herrenschmidt
2005-11-03 9:03 ` Eddy Petrişor
2005-11-03 21:21 ` Benjamin Herrenschmidt
2005-11-04 7:13 ` Eddy Petrişor
2005-11-04 7:18 ` Benjamin Herrenschmidt
2005-11-04 19:32 ` Vivenzio Pagliari
2005-11-04 21:48 ` Benjamin Herrenschmidt
2005-11-05 21:58 ` Bin Zhang
2005-11-05 22:17 ` Benjamin Herrenschmidt
2005-11-06 10:54 ` Bin Zhang
2005-11-11 21:47 ` Eddy Petrisor
2005-11-11 21:52 ` Benjamin Herrenschmidt [this message]
2005-11-12 8:53 ` Eddy Petrisor
2005-11-12 9:45 ` Eddy Petrişor
2005-11-14 7:19 ` Arkadiusz Miskiewicz
2005-11-14 8:06 ` Benjamin Herrenschmidt
2005-11-23 21:55 ` Gaudenz Steinlin
2005-11-23 22:09 ` Benjamin Herrenschmidt
2005-11-07 9:13 ` Charles-Edouard Ruault
2005-11-07 14:54 ` Wolfram Quester
2005-11-07 21:00 ` Benjamin Herrenschmidt
2005-11-10 1:12 ` Eddy Petrişor
2005-11-10 1:51 ` Benjamin Herrenschmidt
2005-11-11 0:24 ` Wolfgang Pfeiffer
2005-11-16 18:09 ` Wolfgang Pfeiffer
2005-11-16 18:25 ` Wolfgang Pfeiffer
2005-11-16 21:01 ` Benjamin Herrenschmidt
2005-11-16 23:21 ` Eddy Petrisor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1131745946.24637.251.camel@gaston \
--to=benh@kernel.crashing.org \
--cc=debian-powerpc@lists.debian.org \
--cc=eddy.petrisor@gmail.com \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.