]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.1.9/ohci-final-fix-for-nvidia-problems-i-hope.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.1.9 / ohci-final-fix-for-nvidia-problems-i-hope.patch
CommitLineData
3b552f3c
GKH
1From c61875977458637226ab093a35d200f2d5789787 Mon Sep 17 00:00:00 2001
2From: Alan Stern <stern@rowland.harvard.edu>
3Date: Thu, 17 Nov 2011 16:41:45 -0500
4Subject: OHCI: final fix for NVIDIA problems (I hope)
5
6From: Alan Stern <stern@rowland.harvard.edu>
7
8commit c61875977458637226ab093a35d200f2d5789787 upstream.
9
10Problems with NVIDIA's OHCI host controllers persist. After looking
11carefully through the spec, I finally realized that when a controller
12is reset it then automatically goes into a SUSPEND state in which it
13is completely quiescent (no DMA and no IRQs) and from which it will
14not awaken until the system puts it into the OPERATIONAL state.
15
16Therefore there's no need to worry about controllers being in the
17RESET state for extended periods, or remaining in the OPERATIONAL
18state during system shutdown. The proper action for device
19initialization is to put the controller into the RESET state (if it's
20not there already) and then to issue a software reset. Similarly, the
21proper action for device shutdown is simply to do a software reset.
22
23This patch (as1499) implements such an approach. It simplifies
24initialization and shutdown, and allows the NVIDIA shutdown-quirk code
25to be removed.
26
27Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
28Tested-by: Andre "Osku" Schmidt <andre.osku.schmidt@googlemail.com>
29Tested-by: Arno Augustin <Arno.Augustin@web.de>
30Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
31
32---
33 drivers/usb/host/ohci-hcd.c | 15 ++++-------
34 drivers/usb/host/ohci-pci.c | 26 --------------------
35 drivers/usb/host/ohci.h | 1
36 drivers/usb/host/pci-quirks.c | 54 ++++++++++++++++++------------------------
37 4 files changed, 30 insertions(+), 66 deletions(-)
38
39--- a/drivers/usb/host/ohci-hcd.c
40+++ b/drivers/usb/host/ohci-hcd.c
41@@ -389,17 +389,14 @@ ohci_shutdown (struct usb_hcd *hcd)
42 struct ohci_hcd *ohci;
43
44 ohci = hcd_to_ohci (hcd);
45- ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
46- ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
47+ ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable);
48
49- /* If the SHUTDOWN quirk is set, don't put the controller in RESET */
50- ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ?
51- OHCI_CTRL_RWC | OHCI_CTRL_HCFS :
52- OHCI_CTRL_RWC);
53- ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
54+ /* Software reset, after which the controller goes into SUSPEND */
55+ ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus);
56+ ohci_readl(ohci, &ohci->regs->cmdstatus); /* flush the writes */
57+ udelay(10);
58
59- /* flush the writes */
60- (void) ohci_readl (ohci, &ohci->regs->control);
61+ ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
62 }
63
64 static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
65--- a/drivers/usb/host/ohci-pci.c
66+++ b/drivers/usb/host/ohci-pci.c
67@@ -175,28 +175,6 @@ static int ohci_quirk_amd700(struct usb_
68 return 0;
69 }
70
71-/* nVidia controllers continue to drive Reset signalling on the bus
72- * even after system shutdown, wasting power. This flag tells the
73- * shutdown routine to leave the controller OPERATIONAL instead of RESET.
74- */
75-static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd)
76-{
77- struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
78- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
79-
80- /* Evidently nVidia fixed their later hardware; this is a guess at
81- * the changeover point.
82- */
83-#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d
84-
85- if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) {
86- ohci->flags |= OHCI_QUIRK_SHUTDOWN;
87- ohci_dbg(ohci, "enabled nVidia shutdown quirk\n");
88- }
89-
90- return 0;
91-}
92-
93 static void sb800_prefetch(struct ohci_hcd *ohci, int on)
94 {
95 struct pci_dev *pdev;
96@@ -260,10 +238,6 @@ static const struct pci_device_id ohci_p
97 PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
98 .driver_data = (unsigned long)ohci_quirk_amd700,
99 },
100- {
101- PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
102- .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown,
103- },
104
105 /* FIXME for some of the early AMD 760 southbridges, OHCI
106 * won't work at all. blacklist them.
107--- a/drivers/usb/host/ohci.h
108+++ b/drivers/usb/host/ohci.h
109@@ -403,7 +403,6 @@ struct ohci_hcd {
110 #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
111 #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/
112 #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
113-#define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */
114 // there are also chip quirks/bugs in init logic
115
116 struct work_struct nec_work; /* Worker for NEC quirk */
117--- a/drivers/usb/host/pci-quirks.c
118+++ b/drivers/usb/host/pci-quirks.c
119@@ -36,6 +36,7 @@
120 #define OHCI_INTRENABLE 0x10
121 #define OHCI_INTRDISABLE 0x14
122 #define OHCI_FMINTERVAL 0x34
123+#define OHCI_HCFS (3 << 6) /* hc functional state */
124 #define OHCI_HCR (1 << 0) /* host controller reset */
125 #define OHCI_OCR (1 << 3) /* ownership change request */
126 #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
127@@ -465,6 +466,8 @@ static void __devinit quirk_usb_handoff_
128 {
129 void __iomem *base;
130 u32 control;
131+ u32 fminterval;
132+ int cnt;
133
134 if (!mmio_resource_enabled(pdev, 0))
135 return;
136@@ -497,41 +500,32 @@ static void __devinit quirk_usb_handoff_
137 }
138 #endif
139
140- /* reset controller, preserving RWC (and possibly IR) */
141- writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
142- readl(base + OHCI_CONTROL);
143-
144- /* Some NVIDIA controllers stop working if kept in RESET for too long */
145- if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
146- u32 fminterval;
147- int cnt;
148+ /* disable interrupts */
149+ writel((u32) ~0, base + OHCI_INTRDISABLE);
150
151- /* drive reset for at least 50 ms (7.1.7.5) */
152- msleep(50);
153-
154- /* software reset of the controller, preserving HcFmInterval */
155- fminterval = readl(base + OHCI_FMINTERVAL);
156- writel(OHCI_HCR, base + OHCI_CMDSTATUS);
157-
158- /* reset requires max 10 us delay */
159- for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
160- if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
161- break;
162- udelay(1);
163- }
164- writel(fminterval, base + OHCI_FMINTERVAL);
165+ /* Reset the USB bus, if the controller isn't already in RESET */
166+ if (control & OHCI_HCFS) {
167+ /* Go into RESET, preserving RWC (and possibly IR) */
168+ writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
169+ readl(base + OHCI_CONTROL);
170
171- /* Now we're in the SUSPEND state with all devices reset
172- * and wakeups and interrupts disabled
173- */
174+ /* drive bus reset for at least 50 ms (7.1.7.5) */
175+ msleep(50);
176 }
177
178- /*
179- * disable interrupts
180- */
181- writel(~(u32)0, base + OHCI_INTRDISABLE);
182- writel(~(u32)0, base + OHCI_INTRSTATUS);
183+ /* software reset of the controller, preserving HcFmInterval */
184+ fminterval = readl(base + OHCI_FMINTERVAL);
185+ writel(OHCI_HCR, base + OHCI_CMDSTATUS);
186+
187+ /* reset requires max 10 us delay */
188+ for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
189+ if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
190+ break;
191+ udelay(1);
192+ }
193+ writel(fminterval, base + OHCI_FMINTERVAL);
194
195+ /* Now the controller is safely in SUSPEND and nothing can wake it up */
196 iounmap(base);
197 }
198