15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-1.0+
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * OHCI HCD (Host Controller Driver) for USB.
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
61da177e4SLinus Torvalds * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
71da177e4SLinus Torvalds *
81da177e4SLinus Torvalds * [ Initialisation is based on Linus' ]
91da177e4SLinus Torvalds * [ uhci code and gregs ohci fragments ]
101da177e4SLinus Torvalds * [ (C) Copyright 1999 Linus Torvalds ]
111da177e4SLinus Torvalds * [ (C) Copyright 1999 Gregory P. Smith]
121da177e4SLinus Torvalds *
131da177e4SLinus Torvalds * PCI Bus Glue
141da177e4SLinus Torvalds *
151da177e4SLinus Torvalds * This file is licenced under the GPL.
161da177e4SLinus Torvalds */
171da177e4SLinus Torvalds
18ab1666c1SLibin Yang #include <linux/io.h>
19c1117afbSManjunath Goudar #include <linux/kernel.h>
20c1117afbSManjunath Goudar #include <linux/module.h>
21c1117afbSManjunath Goudar #include <linux/pci.h>
22c1117afbSManjunath Goudar #include <linux/usb.h>
23c1117afbSManjunath Goudar #include <linux/usb/hcd.h>
24c1117afbSManjunath Goudar
25c1117afbSManjunath Goudar #include "ohci.h"
26c1117afbSManjunath Goudar #include "pci-quirks.h"
27c1117afbSManjunath Goudar
28c1117afbSManjunath Goudar #define DRIVER_DESC "OHCI PCI platform driver"
29c1117afbSManjunath Goudar
30c1117afbSManjunath Goudar static const char hcd_name[] = "ohci-pci";
31ab1666c1SLibin Yang
32ab1666c1SLibin Yang
331da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/
341da177e4SLinus Torvalds
broken_suspend(struct usb_hcd * hcd)35931384fbSDavid Brownell static int broken_suspend(struct usb_hcd *hcd)
36931384fbSDavid Brownell {
37931384fbSDavid Brownell device_init_wakeup(&hcd->self.root_hub->dev, 0);
38931384fbSDavid Brownell return 0;
39931384fbSDavid Brownell }
40931384fbSDavid Brownell
411da177e4SLinus Torvalds /* AMD 756, for most chips (early revs), corrupts register
421da177e4SLinus Torvalds * values on read ... so enable the vendor workaround.
431da177e4SLinus Torvalds */
ohci_quirk_amd756(struct usb_hcd * hcd)44931384fbSDavid Brownell static int ohci_quirk_amd756(struct usb_hcd *hcd)
454302a595SBenjamin Herrenschmidt {
464302a595SBenjamin Herrenschmidt struct ohci_hcd *ohci = hcd_to_ohci (hcd);
474302a595SBenjamin Herrenschmidt
481da177e4SLinus Torvalds ohci->flags = OHCI_QUIRK_AMD756;
490e498763SDavid Brownell ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
504302a595SBenjamin Herrenschmidt
516a9062f3SDavid Brownell /* also erratum 10 (suspend/resume issues) */
52931384fbSDavid Brownell return broken_suspend(hcd);
534302a595SBenjamin Herrenschmidt }
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds /* Apple's OHCI driver has a lot of bizarre workarounds
561da177e4SLinus Torvalds * for this chip. Evidently control and bulk lists
571da177e4SLinus Torvalds * can get confused. (B&W G3 models, and ...)
581da177e4SLinus Torvalds */
ohci_quirk_opti(struct usb_hcd * hcd)59931384fbSDavid Brownell static int ohci_quirk_opti(struct usb_hcd *hcd)
604302a595SBenjamin Herrenschmidt {
614302a595SBenjamin Herrenschmidt struct ohci_hcd *ohci = hcd_to_ohci (hcd);
624302a595SBenjamin Herrenschmidt
634302a595SBenjamin Herrenschmidt ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n");
644302a595SBenjamin Herrenschmidt
654302a595SBenjamin Herrenschmidt return 0;
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds
681da177e4SLinus Torvalds /* Check for NSC87560. We have to look at the bridge (fn1) to
691da177e4SLinus Torvalds * identify the USB (fn2). This quirk might apply to more or
701da177e4SLinus Torvalds * even all NSC stuff.
711da177e4SLinus Torvalds */
ohci_quirk_ns(struct usb_hcd * hcd)72931384fbSDavid Brownell static int ohci_quirk_ns(struct usb_hcd *hcd)
734302a595SBenjamin Herrenschmidt {
744302a595SBenjamin Herrenschmidt struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
751da177e4SLinus Torvalds struct pci_dev *b;
761da177e4SLinus Torvalds
774302a595SBenjamin Herrenschmidt b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
781da177e4SLinus Torvalds if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
791da177e4SLinus Torvalds && b->vendor == PCI_VENDOR_ID_NS) {
804302a595SBenjamin Herrenschmidt struct ohci_hcd *ohci = hcd_to_ohci (hcd);
814302a595SBenjamin Herrenschmidt
821da177e4SLinus Torvalds ohci->flags |= OHCI_QUIRK_SUPERIO;
830e498763SDavid Brownell ohci_dbg (ohci, "Using NSC SuperIO setup\n");
841da177e4SLinus Torvalds }
852e3a43f0SAlan Cox pci_dev_put(b);
864302a595SBenjamin Herrenschmidt
874302a595SBenjamin Herrenschmidt return 0;
881da177e4SLinus Torvalds }
890e498763SDavid Brownell
900e498763SDavid Brownell /* Check for Compaq's ZFMicro chipset, which needs short
910e498763SDavid Brownell * delays before control or bulk queues get re-activated
920e498763SDavid Brownell * in finish_unlinks()
930e498763SDavid Brownell */
ohci_quirk_zfmicro(struct usb_hcd * hcd)94931384fbSDavid Brownell static int ohci_quirk_zfmicro(struct usb_hcd *hcd)
954302a595SBenjamin Herrenschmidt {
964302a595SBenjamin Herrenschmidt struct ohci_hcd *ohci = hcd_to_ohci (hcd);
974302a595SBenjamin Herrenschmidt
980e498763SDavid Brownell ohci->flags |= OHCI_QUIRK_ZFMICRO;
9989a0fd18SMike Nuss ohci_dbg(ohci, "enabled Compaq ZFMicro chipset quirks\n");
1004302a595SBenjamin Herrenschmidt
1014302a595SBenjamin Herrenschmidt return 0;
1020e498763SDavid Brownell }
1036a9062f3SDavid Brownell
10411d1a4aaSBenjamin Herrenschmidt /* Check for Toshiba SCC OHCI which has big endian registers
10511d1a4aaSBenjamin Herrenschmidt * and little endian in memory data structures
10611d1a4aaSBenjamin Herrenschmidt */
ohci_quirk_toshiba_scc(struct usb_hcd * hcd)107931384fbSDavid Brownell static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
10811d1a4aaSBenjamin Herrenschmidt {
10911d1a4aaSBenjamin Herrenschmidt struct ohci_hcd *ohci = hcd_to_ohci (hcd);
11011d1a4aaSBenjamin Herrenschmidt
11111d1a4aaSBenjamin Herrenschmidt /* That chip is only present in the southbridge of some
11211d1a4aaSBenjamin Herrenschmidt * cell based platforms which are supposed to select
11311d1a4aaSBenjamin Herrenschmidt * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if
11411d1a4aaSBenjamin Herrenschmidt * that was the case though.
11511d1a4aaSBenjamin Herrenschmidt */
11611d1a4aaSBenjamin Herrenschmidt #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
11711d1a4aaSBenjamin Herrenschmidt ohci->flags |= OHCI_QUIRK_BE_MMIO;
11811d1a4aaSBenjamin Herrenschmidt ohci_dbg (ohci, "enabled big endian Toshiba quirk\n");
11911d1a4aaSBenjamin Herrenschmidt return 0;
12011d1a4aaSBenjamin Herrenschmidt #else
12111d1a4aaSBenjamin Herrenschmidt ohci_err (ohci, "unsupported big endian Toshiba quirk\n");
12211d1a4aaSBenjamin Herrenschmidt return -ENXIO;
12311d1a4aaSBenjamin Herrenschmidt #endif
12411d1a4aaSBenjamin Herrenschmidt }
1254302a595SBenjamin Herrenschmidt
126d576bb9fSMichael Hanselmann /* Check for NEC chip and apply quirk for allegedly lost interrupts.
127d576bb9fSMichael Hanselmann */
12889a0fd18SMike Nuss
ohci_quirk_nec_worker(struct work_struct * work)12989a0fd18SMike Nuss static void ohci_quirk_nec_worker(struct work_struct *work)
13089a0fd18SMike Nuss {
13189a0fd18SMike Nuss struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work);
13289a0fd18SMike Nuss int status;
13389a0fd18SMike Nuss
13489a0fd18SMike Nuss status = ohci_restart(ohci);
13589a0fd18SMike Nuss if (status != 0)
13689a0fd18SMike Nuss ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
13789a0fd18SMike Nuss "ohci_restart", status);
13889a0fd18SMike Nuss }
13989a0fd18SMike Nuss
ohci_quirk_nec(struct usb_hcd * hcd)140d576bb9fSMichael Hanselmann static int ohci_quirk_nec(struct usb_hcd *hcd)
141d576bb9fSMichael Hanselmann {
142d576bb9fSMichael Hanselmann struct ohci_hcd *ohci = hcd_to_ohci (hcd);
143d576bb9fSMichael Hanselmann
144d576bb9fSMichael Hanselmann ohci->flags |= OHCI_QUIRK_NEC;
14589a0fd18SMike Nuss INIT_WORK(&ohci->nec_work, ohci_quirk_nec_worker);
146d576bb9fSMichael Hanselmann ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n");
147d576bb9fSMichael Hanselmann
148d576bb9fSMichael Hanselmann return 0;
149d576bb9fSMichael Hanselmann }
150d576bb9fSMichael Hanselmann
ohci_quirk_amd700(struct usb_hcd * hcd)151ab1666c1SLibin Yang static int ohci_quirk_amd700(struct usb_hcd *hcd)
152ab1666c1SLibin Yang {
153ab1666c1SLibin Yang struct ohci_hcd *ohci = hcd_to_ohci(hcd);
154ab1666c1SLibin Yang
1554fbb8aa7SRyan Kennedy if (usb_amd_quirk_pll_check())
156ad93562bSAndiry Xu ohci->flags |= OHCI_QUIRK_AMD_PLL;
157ad93562bSAndiry Xu
158a1f17a87SLibin Yang /* SB800 needs pre-fetch fix */
15902c123eeSHuang Rui if (usb_amd_prefetch_quirk()) {
160a1f17a87SLibin Yang ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;
161a1f17a87SLibin Yang ohci_dbg(ohci, "enabled AMD prefetch quirk\n");
162a1f17a87SLibin Yang }
163a1f17a87SLibin Yang
164c1db30a2SAlan Stern ohci->flags |= OHCI_QUIRK_GLOBAL_SUSPEND;
165ab1666c1SLibin Yang return 0;
166ab1666c1SLibin Yang }
167ab1666c1SLibin Yang
ohci_quirk_qemu(struct usb_hcd * hcd)16821a60f6eSGerd Hoffmann static int ohci_quirk_qemu(struct usb_hcd *hcd)
16921a60f6eSGerd Hoffmann {
17021a60f6eSGerd Hoffmann struct ohci_hcd *ohci = hcd_to_ohci(hcd);
17121a60f6eSGerd Hoffmann
17221a60f6eSGerd Hoffmann ohci->flags |= OHCI_QUIRK_QEMU;
17321a60f6eSGerd Hoffmann ohci_dbg(ohci, "enabled qemu quirk\n");
17421a60f6eSGerd Hoffmann return 0;
17521a60f6eSGerd Hoffmann }
17621a60f6eSGerd Hoffmann
1774302a595SBenjamin Herrenschmidt /* List of quirks for OHCI */
1784302a595SBenjamin Herrenschmidt static const struct pci_device_id ohci_pci_quirks[] = {
1794302a595SBenjamin Herrenschmidt {
1804302a595SBenjamin Herrenschmidt PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c),
1814302a595SBenjamin Herrenschmidt .driver_data = (unsigned long)ohci_quirk_amd756,
1824302a595SBenjamin Herrenschmidt },
1834302a595SBenjamin Herrenschmidt {
1844302a595SBenjamin Herrenschmidt PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861),
1854302a595SBenjamin Herrenschmidt .driver_data = (unsigned long)ohci_quirk_opti,
1864302a595SBenjamin Herrenschmidt },
1874302a595SBenjamin Herrenschmidt {
1884302a595SBenjamin Herrenschmidt PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID),
1894302a595SBenjamin Herrenschmidt .driver_data = (unsigned long)ohci_quirk_ns,
1904302a595SBenjamin Herrenschmidt },
1914302a595SBenjamin Herrenschmidt {
1924302a595SBenjamin Herrenschmidt PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8),
1934302a595SBenjamin Herrenschmidt .driver_data = (unsigned long)ohci_quirk_zfmicro,
1944302a595SBenjamin Herrenschmidt },
19511d1a4aaSBenjamin Herrenschmidt {
19611d1a4aaSBenjamin Herrenschmidt PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6),
19711d1a4aaSBenjamin Herrenschmidt .driver_data = (unsigned long)ohci_quirk_toshiba_scc,
19811d1a4aaSBenjamin Herrenschmidt },
199931384fbSDavid Brownell {
200d576bb9fSMichael Hanselmann PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB),
201d576bb9fSMichael Hanselmann .driver_data = (unsigned long)ohci_quirk_nec,
202d576bb9fSMichael Hanselmann },
203d576bb9fSMichael Hanselmann {
204931384fbSDavid Brownell /* Toshiba portege 4000 */
205931384fbSDavid Brownell .vendor = PCI_VENDOR_ID_AL,
206931384fbSDavid Brownell .device = 0x5237,
2078ab5e8c0SAndrey Borzenkov .subvendor = PCI_VENDOR_ID_TOSHIBA,
208931384fbSDavid Brownell .subdevice = 0x0004,
209931384fbSDavid Brownell .driver_data = (unsigned long) broken_suspend,
210931384fbSDavid Brownell },
21133f73e56SRaphael Assenat {
21233f73e56SRaphael Assenat PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152),
21333f73e56SRaphael Assenat .driver_data = (unsigned long) broken_suspend,
21433f73e56SRaphael Assenat },
215ab1666c1SLibin Yang {
216ab1666c1SLibin Yang PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4397),
217ab1666c1SLibin Yang .driver_data = (unsigned long)ohci_quirk_amd700,
218ab1666c1SLibin Yang },
219ab1666c1SLibin Yang {
220ab1666c1SLibin Yang PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4398),
221ab1666c1SLibin Yang .driver_data = (unsigned long)ohci_quirk_amd700,
222ab1666c1SLibin Yang },
223ab1666c1SLibin Yang {
224ab1666c1SLibin Yang PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
225ab1666c1SLibin Yang .driver_data = (unsigned long)ohci_quirk_amd700,
226ab1666c1SLibin Yang },
22721a60f6eSGerd Hoffmann {
22821a60f6eSGerd Hoffmann .vendor = PCI_VENDOR_ID_APPLE,
22921a60f6eSGerd Hoffmann .device = 0x003f,
23021a60f6eSGerd Hoffmann .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET,
23121a60f6eSGerd Hoffmann .subdevice = PCI_SUBDEVICE_ID_QEMU,
23221a60f6eSGerd Hoffmann .driver_data = (unsigned long)ohci_quirk_qemu,
23321a60f6eSGerd Hoffmann },
234ab1666c1SLibin Yang
2354302a595SBenjamin Herrenschmidt {},
2364302a595SBenjamin Herrenschmidt };
2374302a595SBenjamin Herrenschmidt
ohci_pci_reset(struct usb_hcd * hcd)2384302a595SBenjamin Herrenschmidt static int ohci_pci_reset (struct usb_hcd *hcd)
2394302a595SBenjamin Herrenschmidt {
2404302a595SBenjamin Herrenschmidt struct ohci_hcd *ohci = hcd_to_ohci (hcd);
241c1117afbSManjunath Goudar struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
2424302a595SBenjamin Herrenschmidt int ret = 0;
2434302a595SBenjamin Herrenschmidt
2444302a595SBenjamin Herrenschmidt if (hcd->self.controller) {
2454302a595SBenjamin Herrenschmidt const struct pci_device_id *quirk_id;
2464302a595SBenjamin Herrenschmidt
2474302a595SBenjamin Herrenschmidt quirk_id = pci_match_id(ohci_pci_quirks, pdev);
2484302a595SBenjamin Herrenschmidt if (quirk_id != NULL) {
2494302a595SBenjamin Herrenschmidt int (*quirk)(struct usb_hcd *ohci);
2504302a595SBenjamin Herrenschmidt quirk = (void *)quirk_id->driver_data;
2514302a595SBenjamin Herrenschmidt ret = quirk(hcd);
2524302a595SBenjamin Herrenschmidt }
2534302a595SBenjamin Herrenschmidt }
2544302a595SBenjamin Herrenschmidt
255c1117afbSManjunath Goudar if (ret == 0)
256c1117afbSManjunath Goudar ret = ohci_setup(hcd);
257c1117afbSManjunath Goudar /*
258c1117afbSManjunath Goudar * After ohci setup RWC may not be set for add-in PCI cards.
259c1117afbSManjunath Goudar * This transfers PCI PM wakeup capabilities.
2606a9062f3SDavid Brownell */
2616fd9086aSAlan Stern if (device_can_wakeup(&pdev->dev))
2626a9062f3SDavid Brownell ohci->hc_control |= OHCI_CTRL_RWC;
2634302a595SBenjamin Herrenschmidt return ret;
2641da177e4SLinus Torvalds }
2651da177e4SLinus Torvalds
266c1117afbSManjunath Goudar static struct hc_driver __read_mostly ohci_pci_hc_driver;
2671da177e4SLinus Torvalds
268c1117afbSManjunath Goudar static const struct ohci_driver_overrides pci_overrides __initconst = {
269c1117afbSManjunath Goudar .product_desc = "OHCI PCI host controller",
2701da177e4SLinus Torvalds .reset = ohci_pci_reset,
2711da177e4SLinus Torvalds };
2721da177e4SLinus Torvalds
2731da177e4SLinus Torvalds static const struct pci_device_id pci_ids[] = { {
2741da177e4SLinus Torvalds /* handle any USB OHCI controller */
275c67808eeSJean Delvare PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0),
2763a0bac06SAlessandro Rubini }, {
2773a0bac06SAlessandro Rubini /* The device in the ConneXT I/O hub has no class reg */
2783a0bac06SAlessandro Rubini PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_OHCI),
2791da177e4SLinus Torvalds }, { /* end: all zeroes */ }
2801da177e4SLinus Torvalds };
2811da177e4SLinus Torvalds MODULE_DEVICE_TABLE (pci, pci_ids);
2821da177e4SLinus Torvalds
ohci_pci_probe(struct pci_dev * dev,const struct pci_device_id * id)283ff4c65caSVinod Koul static int ohci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
284ff4c65caSVinod Koul {
2854e55e22dSHeikki Krogerus return usb_hcd_pci_probe(dev, &ohci_pci_hc_driver);
286ff4c65caSVinod Koul }
287ff4c65caSVinod Koul
2881da177e4SLinus Torvalds /* pci driver glue; this is a "new style" PCI driver module */
2891da177e4SLinus Torvalds static struct pci_driver ohci_pci_driver = {
290cd3d8cfcSCorentin Labbe .name = hcd_name,
2911da177e4SLinus Torvalds .id_table = pci_ids,
2921da177e4SLinus Torvalds
293ff4c65caSVinod Koul .probe = ohci_pci_probe,
2941da177e4SLinus Torvalds .remove = usb_hcd_pci_remove,
29564a21d02SAleksey Gorelov .shutdown = usb_hcd_pci_shutdown,
2961da177e4SLinus Torvalds
29769820e01SAlan Stern #ifdef CONFIG_PM
298abb30641SAlan Stern .driver = {
299abb30641SAlan Stern .pm = &usb_hcd_pci_pm_ops
300abb30641SAlan Stern },
301abb30641SAlan Stern #endif
302abb30641SAlan Stern };
303c1117afbSManjunath Goudar
304*1f7d5520SBasavaraj Natikar #ifdef CONFIG_PM
ohci_pci_resume(struct usb_hcd * hcd,pm_message_t msg)305*1f7d5520SBasavaraj Natikar static int ohci_pci_resume(struct usb_hcd *hcd, pm_message_t msg)
306*1f7d5520SBasavaraj Natikar {
307*1f7d5520SBasavaraj Natikar return ohci_resume(hcd, msg.event == PM_EVENT_RESTORE);
308*1f7d5520SBasavaraj Natikar }
309*1f7d5520SBasavaraj Natikar #endif
ohci_pci_init(void)310c1117afbSManjunath Goudar static int __init ohci_pci_init(void)
311c1117afbSManjunath Goudar {
312c1117afbSManjunath Goudar if (usb_disabled())
313c1117afbSManjunath Goudar return -ENODEV;
314c1117afbSManjunath Goudar
315c1117afbSManjunath Goudar ohci_init_driver(&ohci_pci_hc_driver, &pci_overrides);
3169a11899cSAlan Stern
317d3474049SAlan Stern #ifdef CONFIG_PM
3189a11899cSAlan Stern /* Entries for the PCI suspend/resume callbacks are special */
3199a11899cSAlan Stern ohci_pci_hc_driver.pci_suspend = ohci_suspend;
320*1f7d5520SBasavaraj Natikar ohci_pci_hc_driver.pci_resume = ohci_pci_resume;
321d3474049SAlan Stern #endif
3229a11899cSAlan Stern
323c1117afbSManjunath Goudar return pci_register_driver(&ohci_pci_driver);
324c1117afbSManjunath Goudar }
325c1117afbSManjunath Goudar module_init(ohci_pci_init);
326c1117afbSManjunath Goudar
ohci_pci_cleanup(void)327c1117afbSManjunath Goudar static void __exit ohci_pci_cleanup(void)
328c1117afbSManjunath Goudar {
329c1117afbSManjunath Goudar pci_unregister_driver(&ohci_pci_driver);
330c1117afbSManjunath Goudar }
331c1117afbSManjunath Goudar module_exit(ohci_pci_cleanup);
332c1117afbSManjunath Goudar
333c1117afbSManjunath Goudar MODULE_DESCRIPTION(DRIVER_DESC);
334c1117afbSManjunath Goudar MODULE_LICENSE("GPL");
33505c92da0STom Gundersen MODULE_SOFTDEP("pre: ehci_pci");
336