diff options
author | Manjunath Goudar <manjunath.goudar@linaro.org> | 2013-04-02 12:24:02 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-08 12:40:20 -0400 |
commit | 9773696105534dd5193576adfe4a0117a6489c64 (patch) | |
tree | 3551353fdd4512391939dae7b7f54eda5918d6b6 /drivers/usb/host/ehci-atmel.c | |
parent | 7edb3daf78e5124b64a39b6eb264ec2a487e295a (diff) |
USB: EHCI: make ehci-atmel a separate driver
Separate the Atmel host controller driver from ehci-hcd host code
so that it can be built as a separate driver module.
This work is part of enabling multi-platform kernels on ARM;
however, note that other changes are still needed before Atmel can be
booted with a multi-platform kernel. This is currently planned for
Linux-3.11.
With the infrastructure added by Alan Stern in patch 3e0232039
"USB: EHCI: prepare to make ehci-hcd a library module", we can
avoid this problem by turning a bus glue into a separate
module, as we do here for the Atmel bus glue.
In V4 (arnd):
- reordered #include statements.
- removed call to ehci_shutdown and the corresponding export
In V3:
- Detailed commit message added here about why this patch is required.
- Replaced hcd_name string "ehci-atmel" to "atmel-ehci".
- Inserted blank line in the Makefile to separate the EHCI drivers from
the following non-EHCI drivers.
- Exported ehci_shutdown symbol as it is needed by the Atmel driver.
- Eliminated ehci_atmel_setup routine because hcd registers
can be directly set in the ehci_atmel_drv_probe function.
In V2:
Resolved below compiler error.
drivers/usb/host/ehci-atmel.c: In function 'ehci_atmel_drv_remove':
drivers/usb/host/ehci-atmel.c:167: error: implicit declaration of function 'ehci_shutdown'
Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Andrew Victor <linux@maxim.org.za>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-atmel.c')
-rw-r--r-- | drivers/usb/host/ehci-atmel.c | 88 |
1 files changed, 41 insertions, 47 deletions
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index f3beac4d06b8..66420097c242 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c | |||
@@ -12,9 +12,22 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/platform_device.h> | 15 | #include <linux/dma-mapping.h> |
16 | #include <linux/io.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | 19 | #include <linux/of.h> |
17 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include <linux/usb/hcd.h> | ||
24 | |||
25 | #include "ehci.h" | ||
26 | |||
27 | #define DRIVER_DESC "EHCI Atmel driver" | ||
28 | |||
29 | static const char hcd_name[] = "ehci-atmel"; | ||
30 | static struct hc_driver __read_mostly ehci_atmel_hc_driver; | ||
18 | 31 | ||
19 | /* interface and function clocks */ | 32 | /* interface and function clocks */ |
20 | static struct clk *iclk, *fclk; | 33 | static struct clk *iclk, *fclk; |
@@ -50,51 +63,6 @@ static void atmel_stop_ehci(struct platform_device *pdev) | |||
50 | 63 | ||
51 | /*-------------------------------------------------------------------------*/ | 64 | /*-------------------------------------------------------------------------*/ |
52 | 65 | ||
53 | static int ehci_atmel_setup(struct usb_hcd *hcd) | ||
54 | { | ||
55 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
56 | |||
57 | /* registers start at offset 0x0 */ | ||
58 | ehci->caps = hcd->regs; | ||
59 | |||
60 | return ehci_setup(hcd); | ||
61 | } | ||
62 | |||
63 | static const struct hc_driver ehci_atmel_hc_driver = { | ||
64 | .description = hcd_name, | ||
65 | .product_desc = "Atmel EHCI UHP HS", | ||
66 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
67 | |||
68 | /* generic hardware linkage */ | ||
69 | .irq = ehci_irq, | ||
70 | .flags = HCD_MEMORY | HCD_USB2, | ||
71 | |||
72 | /* basic lifecycle operations */ | ||
73 | .reset = ehci_atmel_setup, | ||
74 | .start = ehci_run, | ||
75 | .stop = ehci_stop, | ||
76 | .shutdown = ehci_shutdown, | ||
77 | |||
78 | /* managing i/o requests and associated device resources */ | ||
79 | .urb_enqueue = ehci_urb_enqueue, | ||
80 | .urb_dequeue = ehci_urb_dequeue, | ||
81 | .endpoint_disable = ehci_endpoint_disable, | ||
82 | .endpoint_reset = ehci_endpoint_reset, | ||
83 | |||
84 | /* scheduling support */ | ||
85 | .get_frame_number = ehci_get_frame, | ||
86 | |||
87 | /* root hub support */ | ||
88 | .hub_status_data = ehci_hub_status_data, | ||
89 | .hub_control = ehci_hub_control, | ||
90 | .bus_suspend = ehci_bus_suspend, | ||
91 | .bus_resume = ehci_bus_resume, | ||
92 | .relinquish_port = ehci_relinquish_port, | ||
93 | .port_handed_over = ehci_port_handed_over, | ||
94 | |||
95 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
96 | }; | ||
97 | |||
98 | static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32); | 66 | static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32); |
99 | 67 | ||
100 | static int ehci_atmel_drv_probe(struct platform_device *pdev) | 68 | static int ehci_atmel_drv_probe(struct platform_device *pdev) |
@@ -102,6 +70,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) | |||
102 | struct usb_hcd *hcd; | 70 | struct usb_hcd *hcd; |
103 | const struct hc_driver *driver = &ehci_atmel_hc_driver; | 71 | const struct hc_driver *driver = &ehci_atmel_hc_driver; |
104 | struct resource *res; | 72 | struct resource *res; |
73 | struct ehci_hcd *ehci; | ||
105 | int irq; | 74 | int irq; |
106 | int retval; | 75 | int retval; |
107 | 76 | ||
@@ -162,6 +131,10 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) | |||
162 | goto fail_request_resource; | 131 | goto fail_request_resource; |
163 | } | 132 | } |
164 | 133 | ||
134 | ehci = hcd_to_ehci(hcd); | ||
135 | /* registers start at offset 0x0 */ | ||
136 | ehci->caps = hcd->regs; | ||
137 | |||
165 | atmel_start_ehci(pdev); | 138 | atmel_start_ehci(pdev); |
166 | 139 | ||
167 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); | 140 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED); |
@@ -185,7 +158,6 @@ static int ehci_atmel_drv_remove(struct platform_device *pdev) | |||
185 | { | 158 | { |
186 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 159 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
187 | 160 | ||
188 | ehci_shutdown(hcd); | ||
189 | usb_remove_hcd(hcd); | 161 | usb_remove_hcd(hcd); |
190 | usb_put_hcd(hcd); | 162 | usb_put_hcd(hcd); |
191 | 163 | ||
@@ -213,3 +185,25 @@ static struct platform_driver ehci_atmel_driver = { | |||
213 | .of_match_table = of_match_ptr(atmel_ehci_dt_ids), | 185 | .of_match_table = of_match_ptr(atmel_ehci_dt_ids), |
214 | }, | 186 | }, |
215 | }; | 187 | }; |
188 | |||
189 | static int __init ehci_atmel_init(void) | ||
190 | { | ||
191 | if (usb_disabled()) | ||
192 | return -ENODEV; | ||
193 | |||
194 | pr_info("%s: " DRIVER_DESC "\n", hcd_name); | ||
195 | ehci_init_driver(&ehci_atmel_hc_driver, NULL); | ||
196 | return platform_driver_register(&ehci_atmel_driver); | ||
197 | } | ||
198 | module_init(ehci_atmel_init); | ||
199 | |||
200 | static void __exit ehci_atmel_cleanup(void) | ||
201 | { | ||
202 | platform_driver_unregister(&ehci_atmel_driver); | ||
203 | } | ||
204 | module_exit(ehci_atmel_cleanup); | ||
205 | |||
206 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
207 | MODULE_ALIAS("platform:atmel-ehci"); | ||
208 | MODULE_AUTHOR("Nicolas Ferre"); | ||
209 | MODULE_LICENSE("GPL"); | ||