11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OHCI HCD (Host Controller Driver) for USB.
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (C) Copyright 2002 Hewlett-Packard Company
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bus Glue for AMD Alchemy Au1xxx
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Written by Christopher Hoover <ch@hpl.hp.com>
11ac310bb5db057963548e067037d68c9be41d0dd0Uwe Kleine-König * Based on fragments of previous driver by Russell King et al.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified for LH7A404 from ohci-sa1111.c
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  by Durgesh Pattamatta <pattamattad@sharpsec.com>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified for AMD Alchemy Au1xxx
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  by Matt Porter <mporter@kernel.crashing.org>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is licenced under the GPL.
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21d052d1beff706920e82c5d55006b08e256b5df09Russell King#include <linux/platform_device.h>
22de25968cc87cc5b76d09de8b4cbddc8f24fcf5f7Tim Schmielau#include <linux/signal.h>
23d052d1beff706920e82c5d55006b08e256b5df09Russell King
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach-au1x00/au1000.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26d5fb7f1b5b832946eaf450b2a695ec3e7fd2d351Jordan Crouse
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int usb_disabled(void);
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Laussstatic int __devinit ohci_au1xxx_start(struct usb_hcd *hcd)
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
3253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	int ret;
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3453c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci);
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3653c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if ((ret = ohci_init(ohci)) < 0)
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if ((ret = ohci_run(ohci)) < 0) {
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err ("can't start %s", hcd->self.bus_name);
4153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		ohci_stop(hcd);
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ret;
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const struct hc_driver ohci_au1xxx_hc_driver = {
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.description =		hcd_name,
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.product_desc =		"Au1xxx OHCI",
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.hcd_priv_size =	sizeof(struct ohci_hcd),
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * generic hardware linkage
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.irq =			ohci_irq,
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags =		HCD_USB11 | HCD_MEMORY,
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * basic lifecycle operations
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.start =		ohci_au1xxx_start,
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.stop =			ohci_stop,
64dd9048af41d017f5f9ea18fb451a3b5dc89d6b83David Brownell	.shutdown =		ohci_shutdown,
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * managing i/o requests and associated device resources
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.urb_enqueue =		ohci_urb_enqueue,
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.urb_dequeue =		ohci_urb_dequeue,
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.endpoint_disable =	ohci_endpoint_disable,
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * scheduling support
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_frame_number =	ohci_get_frame,
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * root hub support
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.hub_status_data =	ohci_hub_status_data,
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.hub_control =		ohci_hub_control,
839293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell#ifdef	CONFIG_PM
840c0382e32d46f606951010b202382be14d180a17Alan Stern	.bus_suspend =		ohci_bus_suspend,
850c0382e32d46f606951010b202382be14d180a17Alan Stern	.bus_resume =		ohci_bus_resume,
869293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell#endif
879293677af3dace2645dec0d0808efa02d36bf47bDavid Brownell	.start_port_reset =	ohci_start_port_reset,
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
903ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell Kingstatic int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
92809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	int ret, unit;
9353c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	struct usb_hcd *hcd;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (usb_disabled())
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENODEV;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9853c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
9953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		pr_debug("resource[1] is not IORESOURCE_IRQ\n");
10053c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		return -ENOMEM;
10153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	}
10253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
10353c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx");
10453c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if (!hcd)
10553c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		return -ENOMEM;
10653c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
10753c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	hcd->rsrc_start = pdev->resource[0].start;
10853c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
10953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
11053c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
11153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		pr_debug("request_mem_region failed\n");
11253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		ret = -EBUSY;
11353c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		goto err1;
11453c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	}
11553c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
11653c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
11753c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if (!hcd->regs) {
11853c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		pr_debug("ioremap failed\n");
11953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		ret = -ENOMEM;
12053c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		goto err2;
12153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	}
12253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
123809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
124809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss			ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
125809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	if (alchemy_usb_control(unit, 1)) {
126ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss		printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
127ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss		ret = -ENODEV;
128ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss		goto err3;
129ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss	}
130ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss
13153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	ohci_hcd_init(hcd_to_ohci(hcd));
13253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
13353c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	ret = usb_add_hcd(hcd, pdev->resource[1].start,
134b5dd18d8747010e3f3eb1cc76a49f94291938559Yong Zhang			  IRQF_SHARED);
13553c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	if (ret == 0) {
13653c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		platform_set_drvdata(pdev, hcd);
13753c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss		return ret;
13853c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	}
13953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
140809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	alchemy_usb_control(unit, 0);
141ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lausserr3:
14253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	iounmap(hcd->regs);
14353c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lausserr2:
14453c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
14553c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lausserr1:
14653c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	usb_put_hcd(hcd);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1503ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell Kingstatic int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1523ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell King	struct usb_hcd *hcd = platform_get_drvdata(pdev);
153809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	int unit;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
155809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
156809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss			ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
15753c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	usb_remove_hcd(hcd);
158809f36c6f4a0568178c909ff1096ca83eae33f7dManuel Lauss	alchemy_usb_control(unit, 0);
15953c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	iounmap(hcd->regs);
16053c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
16153c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	usb_put_hcd(hcd);
16253c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss	platform_set_drvdata(pdev, NULL);
16353c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16653c81a348fa1d21dd042d9c9a9f91795f83fed66Manuel Lauss
16742bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss#ifdef CONFIG_PM
168807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Laussstatic int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
170807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss	struct usb_hcd *hcd = dev_get_drvdata(dev);
17142bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
17242bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	unsigned long flags;
17342bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	int rc;
17442bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
17542bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	rc = 0;
17642bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
17742bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	/* Root hub was already suspended. Disable irq emission and
17842bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	 * mark HW unaccessible, bail out if RH has been resumed. Use
17942bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	 * the spinlock to properly synchronize with possible pending
18042bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	 * RH suspend or resume activity.
18142bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	 */
18242bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	spin_lock_irqsave(&ohci->lock, flags);
183b7463c71fbbff7111d0c879d2f64fe2b08f51848Alan Stern	if (ohci->rh_state != OHCI_RH_SUSPENDED) {
18442bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss		rc = -EINVAL;
18542bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss		goto bail;
18642bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	}
18742bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
18842bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	(void)ohci_readl(ohci, &ohci->regs->intrdisable);
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19042bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
19142bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
192ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss	alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
19342bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Laussbail:
19442bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	spin_unlock_irqrestore(&ohci->lock, flags);
19542bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
19642bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	return rc;
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19842bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
199807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Laussstatic int ohci_hcd_au1xxx_drv_resume(struct device *dev)
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
201807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss	struct usb_hcd *hcd = dev_get_drvdata(dev);
20242bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
203ce6bc92285cabd0df1f154a9ef5aeb937b6de57eManuel Lauss	alchemy_usb_control(ALCHEMY_USB_OHCI0, 1);
20442bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss
20542bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
20642bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss	ohci_finish_controller_resume(hcd);
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
210807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss
211471452104b8520337ae2fb48c4e61cd4896e025dAlexey Dobriyanstatic const struct dev_pm_ops au1xxx_ohci_pmops = {
212807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss	.suspend	= ohci_hcd_au1xxx_drv_suspend,
213807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss	.resume		= ohci_hcd_au1xxx_drv_resume,
214807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss};
215807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss
216807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss#define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops
217807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss
21842bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss#else
219807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss#define AU1XXX_OHCI_PMOPS NULL
22042bfc7b44f724fb5ce838fc2f552a3eb8cd768ecManuel Lauss#endif
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2223ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell Kingstatic struct platform_driver ohci_hcd_au1xxx_driver = {
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.probe		= ohci_hcd_au1xxx_drv_probe,
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.remove		= ohci_hcd_au1xxx_drv_remove,
225dd9048af41d017f5f9ea18fb451a3b5dc89d6b83David Brownell	.shutdown	= usb_hcd_platform_shutdown,
2263ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell King	.driver		= {
2273ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell King		.name	= "au1xxx-ohci",
2283ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell King		.owner	= THIS_MODULE,
229807fcb5e19877d339a4cc56f2c6ddaf3a147457aManuel Lauss		.pm	= AU1XXX_OHCI_PMOPS,
2303ae5eaec1d2d9c0cf53745352e7d4b152810ba24Russell King	},
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
233f4fce61d410b96ae263b001c45f73df1863dad8dKay SieversMODULE_ALIAS("platform:au1xxx-ohci");
234