omap iommu: Fix Memory leak
[linux-2.6-block.git] / arch / arm / mach-omap2 / usb-ehci.c
CommitLineData
58a5491c
FB
1/*
2 * linux/arch/arm/mach-omap2/usb-ehci.c
3 *
4 * This file will contain the board specific details for the
5 * Synopsys EHCI host controller on OMAP3430
6 *
7 * Copyright (C) 2007 Texas Instruments
8 * Author: Vikram Pandita <vikram.pandita@ti.com>
9 *
10 * Generalization by:
11 * Felipe Balbi <felipe.balbi@nokia.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/types.h>
19#include <linux/errno.h>
20#include <linux/delay.h>
21#include <linux/platform_device.h>
22#include <linux/clk.h>
23#include <asm/io.h>
24#include <plat/mux.h>
25
26#include <mach/hardware.h>
27#include <mach/irqs.h>
28#include <plat/usb.h>
29
4896e394
TL
30#include "mux.h"
31
58a5491c
FB
32#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
33
34static struct resource ehci_resources[] = {
35 {
36 .start = OMAP34XX_EHCI_BASE,
37 .end = OMAP34XX_EHCI_BASE + SZ_1K - 1,
38 .flags = IORESOURCE_MEM,
39 },
40 {
41 .start = OMAP34XX_UHH_CONFIG_BASE,
42 .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
43 .flags = IORESOURCE_MEM,
44 },
45 {
46 .start = OMAP34XX_USBTLL_BASE,
47 .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1,
48 .flags = IORESOURCE_MEM,
49 },
50 { /* general IRQ */
51 .start = INT_34XX_EHCI_IRQ,
52 .flags = IORESOURCE_IRQ,
53 }
54};
55
56static u64 ehci_dmamask = ~(u32)0;
57static struct platform_device ehci_device = {
58 .name = "ehci-omap",
59 .id = 0,
60 .dev = {
61 .dma_mask = &ehci_dmamask,
62 .coherent_dma_mask = 0xffffffff,
63 .platform_data = NULL,
64 },
65 .num_resources = ARRAY_SIZE(ehci_resources),
66 .resource = ehci_resources,
67};
68
69/* MUX settings for EHCI pins */
70/*
71 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
72 */
6f69a181 73static void setup_ehci_io_mux(const enum ehci_hcd_omap_mode *port_mode)
58a5491c
FB
74{
75 switch (port_mode[0]) {
76 case EHCI_HCD_OMAP_MODE_PHY:
4896e394
TL
77 omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
78 omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
79 omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
80 omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
81 omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
82 omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
83 omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
84 omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
85 omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
86 omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
87 omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
88 omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
58a5491c
FB
89 break;
90 case EHCI_HCD_OMAP_MODE_TLL:
4896e394
TL
91 omap_mux_init_signal("hsusb1_tll_stp",
92 OMAP_PIN_INPUT_PULLUP);
93 omap_mux_init_signal("hsusb1_tll_clk",
94 OMAP_PIN_INPUT_PULLDOWN);
95 omap_mux_init_signal("hsusb1_tll_dir",
96 OMAP_PIN_INPUT_PULLDOWN);
97 omap_mux_init_signal("hsusb1_tll_nxt",
98 OMAP_PIN_INPUT_PULLDOWN);
99 omap_mux_init_signal("hsusb1_tll_data0",
100 OMAP_PIN_INPUT_PULLDOWN);
101 omap_mux_init_signal("hsusb1_tll_data1",
102 OMAP_PIN_INPUT_PULLDOWN);
103 omap_mux_init_signal("hsusb1_tll_data2",
104 OMAP_PIN_INPUT_PULLDOWN);
105 omap_mux_init_signal("hsusb1_tll_data3",
106 OMAP_PIN_INPUT_PULLDOWN);
107 omap_mux_init_signal("hsusb1_tll_data4",
108 OMAP_PIN_INPUT_PULLDOWN);
109 omap_mux_init_signal("hsusb1_tll_data5",
110 OMAP_PIN_INPUT_PULLDOWN);
111 omap_mux_init_signal("hsusb1_tll_data6",
112 OMAP_PIN_INPUT_PULLDOWN);
113 omap_mux_init_signal("hsusb1_tll_data7",
114 OMAP_PIN_INPUT_PULLDOWN);
58a5491c
FB
115 break;
116 case EHCI_HCD_OMAP_MODE_UNKNOWN:
117 /* FALLTHROUGH */
118 default:
119 break;
120 }
121
122 switch (port_mode[1]) {
123 case EHCI_HCD_OMAP_MODE_PHY:
4896e394
TL
124 omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
125 omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
126 omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
127 omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
128 omap_mux_init_signal("hsusb2_data0",
129 OMAP_PIN_INPUT_PULLDOWN);
130 omap_mux_init_signal("hsusb2_data1",
131 OMAP_PIN_INPUT_PULLDOWN);
132 omap_mux_init_signal("hsusb2_data2",
133 OMAP_PIN_INPUT_PULLDOWN);
134 omap_mux_init_signal("hsusb2_data3",
135 OMAP_PIN_INPUT_PULLDOWN);
136 omap_mux_init_signal("hsusb2_data4",
137 OMAP_PIN_INPUT_PULLDOWN);
138 omap_mux_init_signal("hsusb2_data5",
139 OMAP_PIN_INPUT_PULLDOWN);
140 omap_mux_init_signal("hsusb2_data6",
141 OMAP_PIN_INPUT_PULLDOWN);
142 omap_mux_init_signal("hsusb2_data7",
143 OMAP_PIN_INPUT_PULLDOWN);
58a5491c
FB
144 break;
145 case EHCI_HCD_OMAP_MODE_TLL:
4896e394
TL
146 omap_mux_init_signal("hsusb2_tll_stp",
147 OMAP_PIN_INPUT_PULLUP);
148 omap_mux_init_signal("hsusb2_tll_clk",
149 OMAP_PIN_INPUT_PULLDOWN);
150 omap_mux_init_signal("hsusb2_tll_dir",
151 OMAP_PIN_INPUT_PULLDOWN);
152 omap_mux_init_signal("hsusb2_tll_nxt",
153 OMAP_PIN_INPUT_PULLDOWN);
154 omap_mux_init_signal("hsusb2_tll_data0",
155 OMAP_PIN_INPUT_PULLDOWN);
156 omap_mux_init_signal("hsusb2_tll_data1",
157 OMAP_PIN_INPUT_PULLDOWN);
158 omap_mux_init_signal("hsusb2_tll_data2",
159 OMAP_PIN_INPUT_PULLDOWN);
160 omap_mux_init_signal("hsusb2_tll_data3",
161 OMAP_PIN_INPUT_PULLDOWN);
162 omap_mux_init_signal("hsusb2_tll_data4",
163 OMAP_PIN_INPUT_PULLDOWN);
164 omap_mux_init_signal("hsusb2_tll_data5",
165 OMAP_PIN_INPUT_PULLDOWN);
166 omap_mux_init_signal("hsusb2_tll_data6",
167 OMAP_PIN_INPUT_PULLDOWN);
168 omap_mux_init_signal("hsusb2_tll_data7",
169 OMAP_PIN_INPUT_PULLDOWN);
58a5491c
FB
170 break;
171 case EHCI_HCD_OMAP_MODE_UNKNOWN:
172 /* FALLTHROUGH */
173 default:
174 break;
175 }
176
177 switch (port_mode[2]) {
178 case EHCI_HCD_OMAP_MODE_PHY:
179 printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
180 break;
181 case EHCI_HCD_OMAP_MODE_TLL:
4896e394
TL
182 omap_mux_init_signal("hsusb3_tll_stp",
183 OMAP_PIN_INPUT_PULLUP);
184 omap_mux_init_signal("hsusb3_tll_clk",
185 OMAP_PIN_INPUT_PULLDOWN);
186 omap_mux_init_signal("hsusb3_tll_dir",
187 OMAP_PIN_INPUT_PULLDOWN);
188 omap_mux_init_signal("hsusb3_tll_nxt",
189 OMAP_PIN_INPUT_PULLDOWN);
190 omap_mux_init_signal("hsusb3_tll_data0",
191 OMAP_PIN_INPUT_PULLDOWN);
192 omap_mux_init_signal("hsusb3_tll_data1",
193 OMAP_PIN_INPUT_PULLDOWN);
194 omap_mux_init_signal("hsusb3_tll_data2",
195 OMAP_PIN_INPUT_PULLDOWN);
196 omap_mux_init_signal("hsusb3_tll_data3",
197 OMAP_PIN_INPUT_PULLDOWN);
198 omap_mux_init_signal("hsusb3_tll_data4",
199 OMAP_PIN_INPUT_PULLDOWN);
200 omap_mux_init_signal("hsusb3_tll_data5",
201 OMAP_PIN_INPUT_PULLDOWN);
202 omap_mux_init_signal("hsusb3_tll_data6",
203 OMAP_PIN_INPUT_PULLDOWN);
204 omap_mux_init_signal("hsusb3_tll_data7",
205 OMAP_PIN_INPUT_PULLDOWN);
58a5491c
FB
206 break;
207 case EHCI_HCD_OMAP_MODE_UNKNOWN:
208 /* FALLTHROUGH */
209 default:
210 break;
211 }
212
213 return;
214}
215
6f69a181 216void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
58a5491c
FB
217{
218 platform_device_add_data(&ehci_device, pdata, sizeof(*pdata));
219
220 /* Setup Pin IO MUX for EHCI */
221 if (cpu_is_omap34xx())
222 setup_ehci_io_mux(pdata->port_mode);
223
224 if (platform_device_register(&ehci_device) < 0) {
225 printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
226 return;
227 }
228}
229
230#else
231
6f69a181 232void __init usb_ehci_init(const struct ehci_hcd_omap_platform_data *pdata)
58a5491c
FB
233
234{
235}
236
237#endif /* CONFIG_USB_EHCI_HCD */
238
95344fcc
AG
239#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
240
241static struct resource ohci_resources[] = {
242 {
243 .start = OMAP34XX_OHCI_BASE,
244 .end = OMAP34XX_OHCI_BASE + SZ_1K - 1,
245 .flags = IORESOURCE_MEM,
246 },
247 {
248 .start = OMAP34XX_UHH_CONFIG_BASE,
249 .end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1,
250 .flags = IORESOURCE_MEM,
251 },
252 {
253 .start = OMAP34XX_USBTLL_BASE,
254 .end = OMAP34XX_USBTLL_BASE + SZ_4K - 1,
255 .flags = IORESOURCE_MEM,
256 },
257 { /* general IRQ */
258 .start = INT_34XX_OHCI_IRQ,
259 .flags = IORESOURCE_IRQ,
260 }
261};
262
263static u64 ohci_dmamask = DMA_BIT_MASK(32);
264
265static struct platform_device ohci_device = {
266 .name = "ohci-omap3",
267 .id = 0,
268 .dev = {
269 .dma_mask = &ohci_dmamask,
270 .coherent_dma_mask = 0xffffffff,
271 },
272 .num_resources = ARRAY_SIZE(ohci_resources),
273 .resource = ohci_resources,
274};
275
276static void setup_ohci_io_mux(const enum ohci_omap3_port_mode *port_mode)
277{
278 switch (port_mode[0]) {
279 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
280 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
281 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
282 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
283 omap_mux_init_signal("mm1_rxdp",
284 OMAP_PIN_INPUT_PULLDOWN);
285 omap_mux_init_signal("mm1_rxdm",
286 OMAP_PIN_INPUT_PULLDOWN);
287 /* FALLTHROUGH */
288 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
289 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
290 omap_mux_init_signal("mm1_rxrcv",
291 OMAP_PIN_INPUT_PULLDOWN);
292 /* FALLTHROUGH */
293 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
294 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
295 omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
296 /* FALLTHROUGH */
297 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
298 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
299 omap_mux_init_signal("mm1_txse0",
300 OMAP_PIN_INPUT_PULLDOWN);
301 omap_mux_init_signal("mm1_txdat",
302 OMAP_PIN_INPUT_PULLDOWN);
303 break;
304 case OMAP_OHCI_PORT_MODE_UNUSED:
305 /* FALLTHROUGH */
306 default:
307 break;
308 }
309 switch (port_mode[1]) {
310 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
311 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
312 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
313 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
314 omap_mux_init_signal("mm2_rxdp",
315 OMAP_PIN_INPUT_PULLDOWN);
316 omap_mux_init_signal("mm2_rxdm",
317 OMAP_PIN_INPUT_PULLDOWN);
318 /* FALLTHROUGH */
319 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
320 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
321 omap_mux_init_signal("mm2_rxrcv",
322 OMAP_PIN_INPUT_PULLDOWN);
323 /* FALLTHROUGH */
324 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
325 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
326 omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
327 /* FALLTHROUGH */
328 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
329 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
330 omap_mux_init_signal("mm2_txse0",
331 OMAP_PIN_INPUT_PULLDOWN);
332 omap_mux_init_signal("mm2_txdat",
333 OMAP_PIN_INPUT_PULLDOWN);
334 break;
335 case OMAP_OHCI_PORT_MODE_UNUSED:
336 /* FALLTHROUGH */
337 default:
338 break;
339 }
340 switch (port_mode[2]) {
341 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
342 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
343 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
344 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
345 omap_mux_init_signal("mm3_rxdp",
346 OMAP_PIN_INPUT_PULLDOWN);
347 omap_mux_init_signal("mm3_rxdm",
348 OMAP_PIN_INPUT_PULLDOWN);
349 /* FALLTHROUGH */
350 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
351 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
352 omap_mux_init_signal("mm3_rxrcv",
353 OMAP_PIN_INPUT_PULLDOWN);
354 /* FALLTHROUGH */
355 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
356 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
357 omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
358 /* FALLTHROUGH */
359 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
360 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
361 omap_mux_init_signal("mm3_txse0",
362 OMAP_PIN_INPUT_PULLDOWN);
363 omap_mux_init_signal("mm3_txdat",
364 OMAP_PIN_INPUT_PULLDOWN);
365 break;
366 case OMAP_OHCI_PORT_MODE_UNUSED:
367 /* FALLTHROUGH */
368 default:
369 break;
370 }
371}
372
373void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata)
374{
375 platform_device_add_data(&ohci_device, pdata, sizeof(*pdata));
376
377 /* Setup Pin IO MUX for OHCI */
378 if (cpu_is_omap34xx())
379 setup_ohci_io_mux(pdata->port_mode);
380
381 if (platform_device_register(&ohci_device) < 0) {
382 pr_err("Unable to register FS-USB (OHCI) device\n");
383 return;
384 }
385}
386
387#else
388
389void __init usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata)
390{
391}
392
393#endif /* CONFIG_USB_OHCI_HCD */