2 * Generic platform ohci driver
4 * Copyright 2007 Michael Buesch <m@bues.ch>
5 * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
7 * Derived from the OCHI-SSB driver
8 * Derived from the OHCI-PCI driver
9 * Copyright 1999 Roman Weissgaerber
10 * Copyright 2000-2002 David Brownell
11 * Copyright 1999 Linus Torvalds
12 * Copyright 1999 Gregory P. Smith
14 * Licensed under the GNU/GPL. See COPYING for details.
16 #include <linux/platform_device.h>
17 #include <linux/usb/ohci_pdriver.h>
19 static int ohci_platform_reset(struct usb_hcd
*hcd
)
21 struct platform_device
*pdev
= to_platform_device(hcd
->self
.controller
);
22 struct usb_ohci_pdata
*pdata
= pdev
->dev
.platform_data
;
23 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
26 if (pdata
->big_endian_desc
)
27 ohci
->flags
|= OHCI_QUIRK_BE_DESC
;
28 if (pdata
->big_endian_mmio
)
29 ohci
->flags
|= OHCI_QUIRK_BE_MMIO
;
30 if (pdata
->no_big_frame_no
)
31 ohci
->flags
|= OHCI_QUIRK_FRAME_NO
;
34 err
= ohci_init(ohci
);
39 static int ohci_platform_start(struct usb_hcd
*hcd
)
41 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
46 ohci_err(ohci
, "can't start\n");
53 static const struct hc_driver ohci_platform_hc_driver
= {
54 .description
= hcd_name
,
55 .product_desc
= "Generic Platform OHCI Controller",
56 .hcd_priv_size
= sizeof(struct ohci_hcd
),
59 .flags
= HCD_MEMORY
| HCD_USB11
,
61 .reset
= ohci_platform_reset
,
62 .start
= ohci_platform_start
,
64 .shutdown
= ohci_shutdown
,
66 .urb_enqueue
= ohci_urb_enqueue
,
67 .urb_dequeue
= ohci_urb_dequeue
,
68 .endpoint_disable
= ohci_endpoint_disable
,
70 .get_frame_number
= ohci_get_frame
,
72 .hub_status_data
= ohci_hub_status_data
,
73 .hub_control
= ohci_hub_control
,
75 .bus_suspend
= ohci_bus_suspend
,
76 .bus_resume
= ohci_bus_resume
,
79 .start_port_reset
= ohci_start_port_reset
,
82 static int __devinit
ohci_platform_probe(struct platform_device
*dev
)
85 struct resource
*res_mem
;
86 struct usb_ohci_pdata
*pdata
= dev
->dev
.platform_data
;
98 irq
= platform_get_irq(dev
, 0);
100 pr_err("no irq provided");
104 res_mem
= platform_get_resource(dev
, IORESOURCE_MEM
, 0);
106 pr_err("no memory recourse provided");
110 if (pdata
->power_on
) {
111 err
= pdata
->power_on(dev
);
116 hcd
= usb_create_hcd(&ohci_platform_hc_driver
, &dev
->dev
,
117 dev_name(&dev
->dev
));
123 hcd
->rsrc_start
= res_mem
->start
;
124 hcd
->rsrc_len
= resource_size(res_mem
);
126 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
, hcd_name
)) {
127 pr_err("controller already in use");
132 hcd
->regs
= ioremap_nocache(hcd
->rsrc_start
, hcd
->rsrc_len
);
135 goto err_release_region
;
137 err
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
141 platform_set_drvdata(dev
, hcd
);
148 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
152 if (pdata
->power_off
)
153 pdata
->power_off(dev
);
158 static int __devexit
ohci_platform_remove(struct platform_device
*dev
)
160 struct usb_hcd
*hcd
= platform_get_drvdata(dev
);
161 struct usb_ohci_pdata
*pdata
= dev
->dev
.platform_data
;
165 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
167 platform_set_drvdata(dev
, NULL
);
169 if (pdata
->power_off
)
170 pdata
->power_off(dev
);
177 static int ohci_platform_suspend(struct device
*dev
)
179 struct usb_ohci_pdata
*pdata
= dev
->platform_data
;
180 struct platform_device
*pdev
=
181 container_of(dev
, struct platform_device
, dev
);
183 if (pdata
->power_suspend
)
184 pdata
->power_suspend(pdev
);
189 static int ohci_platform_resume(struct device
*dev
)
191 struct usb_hcd
*hcd
= dev_get_drvdata(dev
);
192 struct usb_ohci_pdata
*pdata
= dev
->platform_data
;
193 struct platform_device
*pdev
=
194 container_of(dev
, struct platform_device
, dev
);
196 if (pdata
->power_on
) {
197 int err
= pdata
->power_on(pdev
);
202 ohci_finish_controller_resume(hcd
);
206 #else /* !CONFIG_PM */
207 #define ohci_platform_suspend NULL
208 #define ohci_platform_resume NULL
209 #endif /* CONFIG_PM */
211 static const struct platform_device_id ohci_platform_table
[] = {
212 { "ohci-platform", 0 },
215 MODULE_DEVICE_TABLE(platform
, ohci_platform_table
);
217 static const struct dev_pm_ops ohci_platform_pm_ops
= {
218 .suspend
= ohci_platform_suspend
,
219 .resume
= ohci_platform_resume
,
222 static struct platform_driver ohci_platform_driver
= {
223 .id_table
= ohci_platform_table
,
224 .probe
= ohci_platform_probe
,
225 .remove
= __devexit_p(ohci_platform_remove
),
226 .shutdown
= usb_hcd_platform_shutdown
,
228 .owner
= THIS_MODULE
,
229 .name
= "ohci-platform",
230 .pm
= &ohci_platform_pm_ops
,