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
;
89 BUG_ON(!dev
->dev
.platform_data
);
94 irq
= platform_get_irq(dev
, 0);
96 pr_err("no irq provided");
100 res_mem
= platform_get_resource(dev
, IORESOURCE_MEM
, 0);
102 pr_err("no memory recourse provided");
106 hcd
= usb_create_hcd(&ohci_platform_hc_driver
, &dev
->dev
,
107 dev_name(&dev
->dev
));
111 hcd
->rsrc_start
= res_mem
->start
;
112 hcd
->rsrc_len
= resource_size(res_mem
);
114 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
, hcd_name
)) {
115 pr_err("controller already in use");
120 hcd
->regs
= ioremap_nocache(hcd
->rsrc_start
, hcd
->rsrc_len
);
122 goto err_release_region
;
123 err
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
127 platform_set_drvdata(dev
, hcd
);
134 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
140 static int __devexit
ohci_platform_remove(struct platform_device
*dev
)
142 struct usb_hcd
*hcd
= platform_get_drvdata(dev
);
146 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
148 platform_set_drvdata(dev
, NULL
);
155 static int ohci_platform_suspend(struct device
*dev
)
160 static int ohci_platform_resume(struct device
*dev
)
162 struct usb_hcd
*hcd
= dev_get_drvdata(dev
);
164 ohci_finish_controller_resume(hcd
);
168 #else /* !CONFIG_PM */
169 #define ohci_platform_suspend NULL
170 #define ohci_platform_resume NULL
171 #endif /* CONFIG_PM */
173 static const struct platform_device_id ohci_platform_table
[] = {
174 { "ohci-platform", 0 },
177 MODULE_DEVICE_TABLE(platform
, ohci_platform_table
);
179 static const struct dev_pm_ops ohci_platform_pm_ops
= {
180 .suspend
= ohci_platform_suspend
,
181 .resume
= ohci_platform_resume
,
184 static struct platform_driver ohci_platform_driver
= {
185 .id_table
= ohci_platform_table
,
186 .probe
= ohci_platform_probe
,
187 .remove
= __devexit_p(ohci_platform_remove
),
188 .shutdown
= usb_hcd_platform_shutdown
,
190 .owner
= THIS_MODULE
,
191 .name
= "ohci-platform",
192 .pm
= &ohci_platform_pm_ops
,