aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-pci.c')
-rw-r--r--drivers/usb/host/ohci-pci.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index ca62cb583221..a5e2eb85d073 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -111,6 +111,18 @@ static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
111#endif 111#endif
112} 112}
113 113
114/* Check for NEC chip and apply quirk for allegedly lost interrupts.
115 */
116static int ohci_quirk_nec(struct usb_hcd *hcd)
117{
118 struct ohci_hcd *ohci = hcd_to_ohci (hcd);
119
120 ohci->flags |= OHCI_QUIRK_NEC;
121 ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n");
122
123 return 0;
124}
125
114/* List of quirks for OHCI */ 126/* List of quirks for OHCI */
115static const struct pci_device_id ohci_pci_quirks[] = { 127static const struct pci_device_id ohci_pci_quirks[] = {
116 { 128 {
@@ -134,6 +146,10 @@ static const struct pci_device_id ohci_pci_quirks[] = {
134 .driver_data = (unsigned long)ohci_quirk_toshiba_scc, 146 .driver_data = (unsigned long)ohci_quirk_toshiba_scc,
135 }, 147 },
136 { 148 {
149 PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB),
150 .driver_data = (unsigned long)ohci_quirk_nec,
151 },
152 {
137 /* Toshiba portege 4000 */ 153 /* Toshiba portege 4000 */
138 .vendor = PCI_VENDOR_ID_AL, 154 .vendor = PCI_VENDOR_ID_AL,
139 .device = 0x5237, 155 .device = 0x5237,
@@ -202,6 +218,42 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
202 return ret; 218 return ret;
203} 219}
204 220
221#if defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \
222 defined(CONFIG_USB_EHCI_HCD_MODULE))
223
224/* Following a power loss, we must prepare to regain control of the ports
225 * we used to own. This means turning on the port power before ehci-hcd
226 * tries to switch ownership.
227 *
228 * This isn't a 100% perfect solution. On most systems the OHCI controllers
229 * lie at lower PCI addresses than the EHCI controller, so they will be
230 * discovered (and hence resumed) first. But there is no guarantee things
231 * will always work this way. If the EHCI controller is resumed first and
232 * the OHCI ports are unpowered, then the handover will fail.
233 */
234static void prepare_for_handover(struct usb_hcd *hcd)
235{
236 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
237 int port;
238
239 /* Here we "know" root ports should always stay powered */
240 ohci_dbg(ohci, "powerup ports\n");
241 for (port = 0; port < ohci->num_ports; port++)
242 ohci_writel(ohci, RH_PS_PPS,
243 &ohci->regs->roothub.portstatus[port]);
244
245 /* Flush those writes */
246 ohci_readl(ohci, &ohci->regs->control);
247 msleep(20);
248}
249
250#else
251
252static inline void prepare_for_handover(struct usb_hcd *hcd)
253{ }
254
255#endif /* CONFIG_USB_PERSIST etc. */
256
205#ifdef CONFIG_PM 257#ifdef CONFIG_PM
206 258
207static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) 259static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
@@ -241,7 +293,10 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
241static int ohci_pci_resume (struct usb_hcd *hcd) 293static int ohci_pci_resume (struct usb_hcd *hcd)
242{ 294{
243 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 295 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
244 usb_hcd_resume_root_hub(hcd); 296
297 /* FIXME: we should try to detect loss of VBUS power here */
298 prepare_for_handover(hcd);
299
245 return 0; 300 return 0;
246} 301}
247 302