xref: /openbmc/linux/drivers/usb/host/ohci-pci.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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