diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/Kconfig | 12 | ||||
-rw-r--r-- | drivers/usb/musb/Makefile | 8 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.c | 320 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.h | 52 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 18 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 84 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 73 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 45 | ||||
-rw-r--r-- | drivers/usb/musb/musb_io.h | 26 | ||||
-rw-r--r-- | drivers/usb/musb/musb_regs.h | 397 | ||||
-rw-r--r-- | drivers/usb/musb/musbhsdma.c | 84 | ||||
-rw-r--r-- | drivers/usb/musb/musbhsdma.h | 149 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 15 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 7 |
15 files changed, 1043 insertions, 249 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 4b9542bbb35c..5af7379cd9a3 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -11,7 +11,7 @@ config USB_MUSB_HDRC | |||
11 | depends on (USB || USB_GADGET) && HAVE_CLK | 11 | depends on (USB || USB_GADGET) && HAVE_CLK |
12 | depends on !SUPERH | 12 | depends on !SUPERH |
13 | select TWL4030_USB if MACH_OMAP_3430SDP | 13 | select TWL4030_USB if MACH_OMAP_3430SDP |
14 | tristate 'Inventra Highspeed Dual Role Controller (TI, ...)' | 14 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
15 | help | 15 | help |
16 | Say Y here if your system has a dual role high speed USB | 16 | Say Y here if your system has a dual role high speed USB |
17 | controller based on the Mentor Graphics silicon IP. Then | 17 | controller based on the Mentor Graphics silicon IP. Then |
@@ -22,6 +22,9 @@ config USB_MUSB_HDRC | |||
22 | Texas Instruments parts using this IP include DaVinci 644x, | 22 | Texas Instruments parts using this IP include DaVinci 644x, |
23 | OMAP 243x, OMAP 343x, and TUSB 6010. | 23 | OMAP 243x, OMAP 343x, and TUSB 6010. |
24 | 24 | ||
25 | Analog Devices parts using this IP include Blackfin BF54x, | ||
26 | BF525 and BF527. | ||
27 | |||
25 | If you do not know what this is, please say N. | 28 | If you do not know what this is, please say N. |
26 | 29 | ||
27 | To compile this driver as a module, choose M here; the | 30 | To compile this driver as a module, choose M here; the |
@@ -33,6 +36,8 @@ config USB_MUSB_SOC | |||
33 | default y if ARCH_DAVINCI | 36 | default y if ARCH_DAVINCI |
34 | default y if ARCH_OMAP2430 | 37 | default y if ARCH_OMAP2430 |
35 | default y if ARCH_OMAP34XX | 38 | default y if ARCH_OMAP34XX |
39 | default y if (BF54x && !BF544) | ||
40 | default y if (BF52x && !BF522 && !BF523) | ||
36 | 41 | ||
37 | comment "DaVinci 644x USB support" | 42 | comment "DaVinci 644x USB support" |
38 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 43 | depends on USB_MUSB_HDRC && ARCH_DAVINCI |
@@ -43,6 +48,9 @@ comment "OMAP 243x high speed USB support" | |||
43 | comment "OMAP 343x high speed USB support" | 48 | comment "OMAP 343x high speed USB support" |
44 | depends on USB_MUSB_HDRC && ARCH_OMAP34XX | 49 | depends on USB_MUSB_HDRC && ARCH_OMAP34XX |
45 | 50 | ||
51 | comment "Blackfin high speed USB Support" | ||
52 | depends on USB_MUSB_HDRC && (BF54x && !BF544) || (BF52x && !BF522 && !BF523) | ||
53 | |||
46 | config USB_TUSB6010 | 54 | config USB_TUSB6010 |
47 | boolean "TUSB 6010 support" | 55 | boolean "TUSB 6010 support" |
48 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC | 56 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC |
@@ -142,7 +150,7 @@ config MUSB_PIO_ONLY | |||
142 | config USB_INVENTRA_DMA | 150 | config USB_INVENTRA_DMA |
143 | bool | 151 | bool |
144 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY | 152 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY |
145 | default ARCH_OMAP2430 || ARCH_OMAP34XX | 153 | default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN |
146 | help | 154 | help |
147 | Enable DMA transfers using Mentor's engine. | 155 | Enable DMA transfers using Mentor's engine. |
148 | 156 | ||
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index b6af0d687a73..85710ccc1887 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile | |||
@@ -22,6 +22,14 @@ ifeq ($(CONFIG_ARCH_OMAP3430),y) | |||
22 | musb_hdrc-objs += omap2430.o | 22 | musb_hdrc-objs += omap2430.o |
23 | endif | 23 | endif |
24 | 24 | ||
25 | ifeq ($(CONFIG_BF54x),y) | ||
26 | musb_hdrc-objs += blackfin.o | ||
27 | endif | ||
28 | |||
29 | ifeq ($(CONFIG_BF52x),y) | ||
30 | musb_hdrc-objs += blackfin.o | ||
31 | endif | ||
32 | |||
25 | ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y) | 33 | ifeq ($(CONFIG_USB_GADGET_MUSB_HDRC),y) |
26 | musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o | 34 | musb_hdrc-objs += musb_gadget_ep0.o musb_gadget.o |
27 | endif | 35 | endif |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c new file mode 100644 index 000000000000..786134852092 --- /dev/null +++ b/drivers/usb/musb/blackfin.c | |||
@@ -0,0 +1,320 @@ | |||
1 | /* | ||
2 | * MUSB OTG controller driver for Blackfin Processors | ||
3 | * | ||
4 | * Copyright 2006-2008 Analog Devices Inc. | ||
5 | * | ||
6 | * Enter bugs at http://blackfin.uclinux.org/ | ||
7 | * | ||
8 | * Licensed under the GPL-2 or later. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include <asm/cacheflush.h> | ||
22 | |||
23 | #include "musb_core.h" | ||
24 | #include "blackfin.h" | ||
25 | |||
26 | /* | ||
27 | * Load an endpoint's FIFO | ||
28 | */ | ||
29 | void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | ||
30 | { | ||
31 | void __iomem *fifo = hw_ep->fifo; | ||
32 | void __iomem *epio = hw_ep->regs; | ||
33 | |||
34 | prefetch((u8 *)src); | ||
35 | |||
36 | musb_writew(epio, MUSB_TXCOUNT, len); | ||
37 | |||
38 | DBG(4, "TX ep%d fifo %p count %d buf %p, epio %p\n", | ||
39 | hw_ep->epnum, fifo, len, src, epio); | ||
40 | |||
41 | dump_fifo_data(src, len); | ||
42 | |||
43 | if (unlikely((unsigned long)src & 0x01)) | ||
44 | outsw_8((unsigned long)fifo, src, | ||
45 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
46 | else | ||
47 | outsw((unsigned long)fifo, src, | ||
48 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Unload an endpoint's FIFO | ||
53 | */ | ||
54 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | ||
55 | { | ||
56 | void __iomem *fifo = hw_ep->fifo; | ||
57 | u8 epnum = hw_ep->epnum; | ||
58 | u16 dma_reg = 0; | ||
59 | |||
60 | DBG(4, "%cX ep%d fifo %p count %d buf %p\n", | ||
61 | 'R', hw_ep->epnum, fifo, len, dst); | ||
62 | |||
63 | #ifdef CONFIG_BF52x | ||
64 | invalidate_dcache_range((unsigned int)dst, | ||
65 | (unsigned int)(dst + len)); | ||
66 | |||
67 | /* Setup DMA address register */ | ||
68 | dma_reg = (u16) ((u32) dst & 0xFFFF); | ||
69 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); | ||
70 | SSYNC(); | ||
71 | |||
72 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); | ||
73 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | ||
74 | SSYNC(); | ||
75 | |||
76 | /* Setup DMA count register */ | ||
77 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); | ||
78 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); | ||
79 | SSYNC(); | ||
80 | |||
81 | /* Enable the DMA */ | ||
82 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; | ||
83 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); | ||
84 | SSYNC(); | ||
85 | |||
86 | /* Wait for compelete */ | ||
87 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) | ||
88 | cpu_relax(); | ||
89 | |||
90 | /* acknowledge dma interrupt */ | ||
91 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); | ||
92 | SSYNC(); | ||
93 | |||
94 | /* Reset DMA */ | ||
95 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | ||
96 | SSYNC(); | ||
97 | #else | ||
98 | if (unlikely((unsigned long)dst & 0x01)) | ||
99 | insw_8((unsigned long)fifo, dst, | ||
100 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
101 | else | ||
102 | insw((unsigned long)fifo, dst, | ||
103 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
104 | #endif | ||
105 | |||
106 | dump_fifo_data(dst, len); | ||
107 | } | ||
108 | |||
109 | static irqreturn_t blackfin_interrupt(int irq, void *__hci) | ||
110 | { | ||
111 | unsigned long flags; | ||
112 | irqreturn_t retval = IRQ_NONE; | ||
113 | struct musb *musb = __hci; | ||
114 | |||
115 | spin_lock_irqsave(&musb->lock, flags); | ||
116 | |||
117 | musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); | ||
118 | musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); | ||
119 | musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); | ||
120 | |||
121 | if (musb->int_usb || musb->int_tx || musb->int_rx) { | ||
122 | musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb); | ||
123 | musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx); | ||
124 | musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx); | ||
125 | retval = musb_interrupt(musb); | ||
126 | } | ||
127 | |||
128 | spin_unlock_irqrestore(&musb->lock, flags); | ||
129 | |||
130 | /* REVISIT we sometimes get spurious IRQs on g_ep0 | ||
131 | * not clear why... fall in BF54x too. | ||
132 | */ | ||
133 | if (retval != IRQ_HANDLED) | ||
134 | DBG(5, "spurious?\n"); | ||
135 | |||
136 | return IRQ_HANDLED; | ||
137 | } | ||
138 | |||
139 | static void musb_conn_timer_handler(unsigned long _musb) | ||
140 | { | ||
141 | struct musb *musb = (void *)_musb; | ||
142 | unsigned long flags; | ||
143 | u16 val; | ||
144 | |||
145 | spin_lock_irqsave(&musb->lock, flags); | ||
146 | switch (musb->xceiv.state) { | ||
147 | case OTG_STATE_A_IDLE: | ||
148 | case OTG_STATE_A_WAIT_BCON: | ||
149 | /* Start a new session */ | ||
150 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
151 | val |= MUSB_DEVCTL_SESSION; | ||
152 | musb_writew(musb->mregs, MUSB_DEVCTL, val); | ||
153 | |||
154 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
155 | if (!(val & MUSB_DEVCTL_BDEVICE)) { | ||
156 | gpio_set_value(musb->config->gpio_vrsel, 1); | ||
157 | musb->xceiv.state = OTG_STATE_A_WAIT_BCON; | ||
158 | } else { | ||
159 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
160 | |||
161 | /* Ignore VBUSERROR and SUSPEND IRQ */ | ||
162 | val = musb_readb(musb->mregs, MUSB_INTRUSBE); | ||
163 | val &= ~MUSB_INTR_VBUSERROR; | ||
164 | musb_writeb(musb->mregs, MUSB_INTRUSBE, val); | ||
165 | |||
166 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; | ||
167 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); | ||
168 | |||
169 | val = MUSB_POWER_HSENAB; | ||
170 | musb_writeb(musb->mregs, MUSB_POWER, val); | ||
171 | } | ||
172 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
173 | break; | ||
174 | |||
175 | default: | ||
176 | DBG(1, "%s state not handled\n", otg_state_string(musb)); | ||
177 | break; | ||
178 | } | ||
179 | spin_unlock_irqrestore(&musb->lock, flags); | ||
180 | |||
181 | DBG(4, "state is %s\n", otg_state_string(musb)); | ||
182 | } | ||
183 | |||
184 | void musb_platform_enable(struct musb *musb) | ||
185 | { | ||
186 | if (is_host_enabled(musb)) { | ||
187 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
188 | musb->a_wait_bcon = TIMER_DELAY; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | void musb_platform_disable(struct musb *musb) | ||
193 | { | ||
194 | } | ||
195 | |||
196 | static void bfin_vbus_power(struct musb *musb, int is_on, int sleeping) | ||
197 | { | ||
198 | } | ||
199 | |||
200 | static void bfin_set_vbus(struct musb *musb, int is_on) | ||
201 | { | ||
202 | if (is_on) | ||
203 | gpio_set_value(musb->config->gpio_vrsel, 1); | ||
204 | else | ||
205 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
206 | |||
207 | DBG(1, "VBUS %s, devctl %02x " | ||
208 | /* otg %3x conf %08x prcm %08x */ "\n", | ||
209 | otg_state_string(musb), | ||
210 | musb_readb(musb->mregs, MUSB_DEVCTL)); | ||
211 | } | ||
212 | |||
213 | static int bfin_set_power(struct otg_transceiver *x, unsigned mA) | ||
214 | { | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | ||
219 | { | ||
220 | if (is_host_enabled(musb)) | ||
221 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
222 | } | ||
223 | |||
224 | int musb_platform_get_vbus_status(struct musb *musb) | ||
225 | { | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | ||
230 | { | ||
231 | } | ||
232 | |||
233 | int __init musb_platform_init(struct musb *musb) | ||
234 | { | ||
235 | |||
236 | /* | ||
237 | * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE | ||
238 | * and OTG HOST modes, while rev 1.1 and greater require PE7 to | ||
239 | * be low for DEVICE mode and high for HOST mode. We set it high | ||
240 | * here because we are in host mode | ||
241 | */ | ||
242 | |||
243 | if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { | ||
244 | printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n", | ||
245 | musb->config->gpio_vrsel); | ||
246 | return -ENODEV; | ||
247 | } | ||
248 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
249 | |||
250 | if (ANOMALY_05000346) { | ||
251 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); | ||
252 | SSYNC(); | ||
253 | } | ||
254 | |||
255 | if (ANOMALY_05000347) { | ||
256 | bfin_write_USB_APHY_CNTRL(0x0); | ||
257 | SSYNC(); | ||
258 | } | ||
259 | |||
260 | /* TODO | ||
261 | * Set SIC-IVG register | ||
262 | */ | ||
263 | |||
264 | /* Configure PLL oscillator register */ | ||
265 | bfin_write_USB_PLLOSC_CTRL(0x30a8); | ||
266 | SSYNC(); | ||
267 | |||
268 | bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1); | ||
269 | SSYNC(); | ||
270 | |||
271 | bfin_write_USB_EP_NI0_RXMAXP(64); | ||
272 | SSYNC(); | ||
273 | |||
274 | bfin_write_USB_EP_NI0_TXMAXP(64); | ||
275 | SSYNC(); | ||
276 | |||
277 | /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/ | ||
278 | bfin_write_USB_GLOBINTR(0x7); | ||
279 | SSYNC(); | ||
280 | |||
281 | bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA | | ||
282 | EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA | | ||
283 | EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA | | ||
284 | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | | ||
285 | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); | ||
286 | SSYNC(); | ||
287 | |||
288 | if (is_host_enabled(musb)) { | ||
289 | musb->board_set_vbus = bfin_set_vbus; | ||
290 | setup_timer(&musb_conn_timer, | ||
291 | musb_conn_timer_handler, (unsigned long) musb); | ||
292 | } | ||
293 | if (is_peripheral_enabled(musb)) | ||
294 | musb->xceiv.set_power = bfin_set_power; | ||
295 | |||
296 | musb->isr = blackfin_interrupt; | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | int musb_platform_suspend(struct musb *musb) | ||
302 | { | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | int musb_platform_resume(struct musb *musb) | ||
307 | { | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | |||
312 | int musb_platform_exit(struct musb *musb) | ||
313 | { | ||
314 | |||
315 | bfin_vbus_power(musb, 0 /*off*/, 1); | ||
316 | gpio_free(musb->config->gpio_vrsel); | ||
317 | musb_platform_suspend(musb); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h new file mode 100644 index 000000000000..a240c1e53d16 --- /dev/null +++ b/drivers/usb/musb/blackfin.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 by Analog Devices, Inc. | ||
3 | * | ||
4 | * The Inventra Controller Driver for Linux is free software; you | ||
5 | * can redistribute it and/or modify it under the terms of the GNU | ||
6 | * General Public License version 2 as published by the Free Software | ||
7 | * Foundation. | ||
8 | */ | ||
9 | |||
10 | #ifndef __MUSB_BLACKFIN_H__ | ||
11 | #define __MUSB_BLACKFIN_H__ | ||
12 | |||
13 | /* | ||
14 | * Blackfin specific definitions | ||
15 | */ | ||
16 | |||
17 | #undef DUMP_FIFO_DATA | ||
18 | #ifdef DUMP_FIFO_DATA | ||
19 | static void dump_fifo_data(u8 *buf, u16 len) | ||
20 | { | ||
21 | u8 *tmp = buf; | ||
22 | int i; | ||
23 | |||
24 | for (i = 0; i < len; i++) { | ||
25 | if (!(i % 16) && i) | ||
26 | pr_debug("\n"); | ||
27 | pr_debug("%02x ", *tmp++); | ||
28 | } | ||
29 | pr_debug("\n"); | ||
30 | } | ||
31 | #else | ||
32 | #define dump_fifo_data(buf, len) do {} while (0) | ||
33 | #endif | ||
34 | |||
35 | #ifdef CONFIG_BF52x | ||
36 | |||
37 | #define USB_DMA_BASE USB_DMA_INTERRUPT | ||
38 | #define USB_DMAx_CTRL 0x04 | ||
39 | #define USB_DMAx_ADDR_LOW 0x08 | ||
40 | #define USB_DMAx_ADDR_HIGH 0x0C | ||
41 | #define USB_DMAx_COUNT_LOW 0x10 | ||
42 | #define USB_DMAx_COUNT_HIGH 0x14 | ||
43 | |||
44 | #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) | ||
45 | #endif | ||
46 | |||
47 | /* Almost 1 second */ | ||
48 | #define TIMER_DELAY (1 * HZ) | ||
49 | |||
50 | static struct timer_list musb_conn_timer; | ||
51 | |||
52 | #endif /* __MUSB_BLACKFIN_H__ */ | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index dfb3bcbe00fc..0d566dc5ce06 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -32,9 +32,9 @@ | |||
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
34 | 34 | ||
35 | #include <asm/arch/hardware.h> | 35 | #include <mach/arch/hardware.h> |
36 | #include <asm/arch/memory.h> | 36 | #include <mach/arch/memory.h> |
37 | #include <asm/arch/gpio.h> | 37 | #include <mach/arch/gpio.h> |
38 | #include <asm/mach-types.h> | 38 | #include <asm/mach-types.h> |
39 | 39 | ||
40 | #include "musb_core.h" | 40 | #include "musb_core.h" |
@@ -364,6 +364,18 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
364 | return IRQ_HANDLED; | 364 | return IRQ_HANDLED; |
365 | } | 365 | } |
366 | 366 | ||
367 | int musb_platform_set_mode(struct musb *musb, u8 mode) | ||
368 | { | ||
369 | /* EVM can't do this (right?) */ | ||
370 | return -EIO; | ||
371 | } | ||
372 | |||
373 | int musb_platform_set_mode(struct musb *musb, u8 mode) | ||
374 | { | ||
375 | /* EVM can't do this (right?) */ | ||
376 | return -EIO; | ||
377 | } | ||
378 | |||
367 | int __init musb_platform_init(struct musb *musb) | 379 | int __init musb_platform_init(struct musb *musb) |
368 | { | 380 | { |
369 | void __iomem *tibase = musb->ctrl_base; | 381 | void __iomem *tibase = musb->ctrl_base; |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 5280dba9b1fb..6c7faacfb535 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -148,7 +148,8 @@ static inline struct musb *dev_to_musb(struct device *dev) | |||
148 | 148 | ||
149 | /*-------------------------------------------------------------------------*/ | 149 | /*-------------------------------------------------------------------------*/ |
150 | 150 | ||
151 | #ifndef CONFIG_USB_TUSB6010 | 151 | #if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN) |
152 | |||
152 | /* | 153 | /* |
153 | * Load an endpoint's FIFO | 154 | * Load an endpoint's FIFO |
154 | */ | 155 | */ |
@@ -1124,25 +1125,25 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, | |||
1124 | #endif | 1125 | #endif |
1125 | switch (cfg->style) { | 1126 | switch (cfg->style) { |
1126 | case FIFO_TX: | 1127 | case FIFO_TX: |
1127 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | 1128 | musb_write_txfifosz(mbase, c_size); |
1128 | musb_writew(mbase, MUSB_TXFIFOADD, c_off); | 1129 | musb_write_txfifoadd(mbase, c_off); |
1129 | hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); | 1130 | hw_ep->tx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); |
1130 | hw_ep->max_packet_sz_tx = maxpacket; | 1131 | hw_ep->max_packet_sz_tx = maxpacket; |
1131 | break; | 1132 | break; |
1132 | case FIFO_RX: | 1133 | case FIFO_RX: |
1133 | musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); | 1134 | musb_write_rxfifosz(mbase, c_size); |
1134 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 1135 | musb_write_rxfifoadd(mbase, c_off); |
1135 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); | 1136 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); |
1136 | hw_ep->max_packet_sz_rx = maxpacket; | 1137 | hw_ep->max_packet_sz_rx = maxpacket; |
1137 | break; | 1138 | break; |
1138 | case FIFO_RXTX: | 1139 | case FIFO_RXTX: |
1139 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | 1140 | musb_write_txfifosz(mbase, c_size); |
1140 | musb_writew(mbase, MUSB_TXFIFOADD, c_off); | 1141 | musb_write_txfifoadd(mbase, c_off); |
1141 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); | 1142 | hw_ep->rx_double_buffered = !!(c_size & MUSB_FIFOSZ_DPB); |
1142 | hw_ep->max_packet_sz_rx = maxpacket; | 1143 | hw_ep->max_packet_sz_rx = maxpacket; |
1143 | 1144 | ||
1144 | musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); | 1145 | musb_write_rxfifosz(mbase, c_size); |
1145 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | 1146 | musb_write_rxfifoadd(mbase, c_off); |
1146 | hw_ep->tx_double_buffered = hw_ep->rx_double_buffered; | 1147 | hw_ep->tx_double_buffered = hw_ep->rx_double_buffered; |
1147 | hw_ep->max_packet_sz_tx = maxpacket; | 1148 | hw_ep->max_packet_sz_tx = maxpacket; |
1148 | 1149 | ||
@@ -1212,7 +1213,7 @@ static int __init ep_config_from_table(struct musb *musb) | |||
1212 | if (epn >= musb->config->num_eps) { | 1213 | if (epn >= musb->config->num_eps) { |
1213 | pr_debug("%s: invalid ep %d\n", | 1214 | pr_debug("%s: invalid ep %d\n", |
1214 | musb_driver_name, epn); | 1215 | musb_driver_name, epn); |
1215 | continue; | 1216 | return -EINVAL; |
1216 | } | 1217 | } |
1217 | offset = fifo_setup(musb, hw_ep + epn, cfg++, offset); | 1218 | offset = fifo_setup(musb, hw_ep + epn, cfg++, offset); |
1218 | if (offset < 0) { | 1219 | if (offset < 0) { |
@@ -1246,9 +1247,10 @@ static int __init ep_config_from_table(struct musb *musb) | |||
1246 | */ | 1247 | */ |
1247 | static int __init ep_config_from_hw(struct musb *musb) | 1248 | static int __init ep_config_from_hw(struct musb *musb) |
1248 | { | 1249 | { |
1249 | u8 epnum = 0, reg; | 1250 | u8 epnum = 0; |
1250 | struct musb_hw_ep *hw_ep; | 1251 | struct musb_hw_ep *hw_ep; |
1251 | void *mbase = musb->mregs; | 1252 | void *mbase = musb->mregs; |
1253 | int ret = 0; | ||
1252 | 1254 | ||
1253 | DBG(2, "<== static silicon ep config\n"); | 1255 | DBG(2, "<== static silicon ep config\n"); |
1254 | 1256 | ||
@@ -1258,26 +1260,9 @@ static int __init ep_config_from_hw(struct musb *musb) | |||
1258 | musb_ep_select(mbase, epnum); | 1260 | musb_ep_select(mbase, epnum); |
1259 | hw_ep = musb->endpoints + epnum; | 1261 | hw_ep = musb->endpoints + epnum; |
1260 | 1262 | ||
1261 | /* read from core using indexed model */ | 1263 | ret = musb_read_fifosize(musb, hw_ep, epnum); |
1262 | reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); | 1264 | if (ret < 0) |
1263 | if (!reg) { | ||
1264 | /* 0's returned when no more endpoints */ | ||
1265 | break; | 1265 | break; |
1266 | } | ||
1267 | musb->nr_endpoints++; | ||
1268 | musb->epmask |= (1 << epnum); | ||
1269 | |||
1270 | hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f); | ||
1271 | |||
1272 | /* shared TX/RX FIFO? */ | ||
1273 | if ((reg & 0xf0) == 0xf0) { | ||
1274 | hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx; | ||
1275 | hw_ep->is_shared_fifo = true; | ||
1276 | continue; | ||
1277 | } else { | ||
1278 | hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4); | ||
1279 | hw_ep->is_shared_fifo = false; | ||
1280 | } | ||
1281 | 1266 | ||
1282 | /* FIXME set up hw_ep->{rx,tx}_double_buffered */ | 1267 | /* FIXME set up hw_ep->{rx,tx}_double_buffered */ |
1283 | 1268 | ||
@@ -1326,7 +1311,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1326 | 1311 | ||
1327 | /* log core options (read using indexed model) */ | 1312 | /* log core options (read using indexed model) */ |
1328 | musb_ep_select(mbase, 0); | 1313 | musb_ep_select(mbase, 0); |
1329 | reg = musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); | 1314 | reg = musb_read_configdata(mbase); |
1330 | 1315 | ||
1331 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); | 1316 | strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); |
1332 | if (reg & MUSB_CONFIGDATA_DYNFIFO) | 1317 | if (reg & MUSB_CONFIGDATA_DYNFIFO) |
@@ -1391,7 +1376,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1391 | } | 1376 | } |
1392 | 1377 | ||
1393 | /* log release info */ | 1378 | /* log release info */ |
1394 | hwvers = musb_readw(mbase, MUSB_HWVERS); | 1379 | hwvers = musb_read_hwvers(mbase); |
1395 | rev_major = (hwvers >> 10) & 0x1f; | 1380 | rev_major = (hwvers >> 10) & 0x1f; |
1396 | rev_minor = hwvers & 0x3ff; | 1381 | rev_minor = hwvers & 0x3ff; |
1397 | snprintf(aRevision, 32, "%d.%d%s", rev_major, | 1382 | snprintf(aRevision, 32, "%d.%d%s", rev_major, |
@@ -1400,8 +1385,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1400 | musb_driver_name, type, aRevision, aDate); | 1385 | musb_driver_name, type, aRevision, aDate); |
1401 | 1386 | ||
1402 | /* configure ep0 */ | 1387 | /* configure ep0 */ |
1403 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | 1388 | musb_configure_ep0(musb); |
1404 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | ||
1405 | 1389 | ||
1406 | /* discover endpoint configuration */ | 1390 | /* discover endpoint configuration */ |
1407 | musb->nr_endpoints = 1; | 1391 | musb->nr_endpoints = 1; |
@@ -1445,7 +1429,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1445 | 1429 | ||
1446 | hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase; | 1430 | hw_ep->regs = MUSB_EP_OFFSET(i, 0) + mbase; |
1447 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1431 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
1448 | hw_ep->target_regs = MUSB_BUSCTL_OFFSET(i, 0) + mbase; | 1432 | hw_ep->target_regs = musb_read_target_reg_base(i, mbase); |
1449 | hw_ep->rx_reinit = 1; | 1433 | hw_ep->rx_reinit = 1; |
1450 | hw_ep->tx_reinit = 1; | 1434 | hw_ep->tx_reinit = 1; |
1451 | #endif | 1435 | #endif |
@@ -1671,17 +1655,20 @@ musb_mode_store(struct device *dev, struct device_attribute *attr, | |||
1671 | { | 1655 | { |
1672 | struct musb *musb = dev_to_musb(dev); | 1656 | struct musb *musb = dev_to_musb(dev); |
1673 | unsigned long flags; | 1657 | unsigned long flags; |
1658 | int status; | ||
1674 | 1659 | ||
1675 | spin_lock_irqsave(&musb->lock, flags); | 1660 | spin_lock_irqsave(&musb->lock, flags); |
1676 | if (!strncmp(buf, "host", 4)) | 1661 | if (sysfs_streq(buf, "host")) |
1677 | musb_platform_set_mode(musb, MUSB_HOST); | 1662 | status = musb_platform_set_mode(musb, MUSB_HOST); |
1678 | if (!strncmp(buf, "peripheral", 10)) | 1663 | else if (sysfs_streq(buf, "peripheral")) |
1679 | musb_platform_set_mode(musb, MUSB_PERIPHERAL); | 1664 | status = musb_platform_set_mode(musb, MUSB_PERIPHERAL); |
1680 | if (!strncmp(buf, "otg", 3)) | 1665 | else if (sysfs_streq(buf, "otg")) |
1681 | musb_platform_set_mode(musb, MUSB_OTG); | 1666 | status = musb_platform_set_mode(musb, MUSB_OTG); |
1667 | else | ||
1668 | status = -EINVAL; | ||
1682 | spin_unlock_irqrestore(&musb->lock, flags); | 1669 | spin_unlock_irqrestore(&musb->lock, flags); |
1683 | 1670 | ||
1684 | return n; | 1671 | return (status == 0) ? n : status; |
1685 | } | 1672 | } |
1686 | static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store); | 1673 | static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store); |
1687 | 1674 | ||
@@ -1781,7 +1768,7 @@ allocate_instance(struct device *dev, | |||
1781 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1768 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
1782 | struct usb_hcd *hcd; | 1769 | struct usb_hcd *hcd; |
1783 | 1770 | ||
1784 | hcd = usb_create_hcd(&musb_hc_driver, dev, dev->bus_id); | 1771 | hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev)); |
1785 | if (!hcd) | 1772 | if (!hcd) |
1786 | return NULL; | 1773 | return NULL; |
1787 | /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */ | 1774 | /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */ |
@@ -1810,7 +1797,6 @@ allocate_instance(struct device *dev, | |||
1810 | for (epnum = 0, ep = musb->endpoints; | 1797 | for (epnum = 0, ep = musb->endpoints; |
1811 | epnum < musb->config->num_eps; | 1798 | epnum < musb->config->num_eps; |
1812 | epnum++, ep++) { | 1799 | epnum++, ep++) { |
1813 | |||
1814 | ep->musb = musb; | 1800 | ep->musb = musb; |
1815 | ep->epnum = epnum; | 1801 | ep->epnum = epnum; |
1816 | } | 1802 | } |
@@ -1838,7 +1824,7 @@ static void musb_free(struct musb *musb) | |||
1838 | musb_gadget_cleanup(musb); | 1824 | musb_gadget_cleanup(musb); |
1839 | #endif | 1825 | #endif |
1840 | 1826 | ||
1841 | if (musb->nIrq >= 0) { | 1827 | if (musb->nIrq >= 0 && musb->irq_wake) { |
1842 | disable_irq_wake(musb->nIrq); | 1828 | disable_irq_wake(musb->nIrq); |
1843 | free_irq(musb->nIrq, musb); | 1829 | free_irq(musb->nIrq, musb); |
1844 | } | 1830 | } |
@@ -1984,15 +1970,19 @@ bad_config: | |||
1984 | INIT_WORK(&musb->irq_work, musb_irq_work); | 1970 | INIT_WORK(&musb->irq_work, musb_irq_work); |
1985 | 1971 | ||
1986 | /* attach to the IRQ */ | 1972 | /* attach to the IRQ */ |
1987 | if (request_irq(nIrq, musb->isr, 0, dev->bus_id, musb)) { | 1973 | if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { |
1988 | dev_err(dev, "request_irq %d failed!\n", nIrq); | 1974 | dev_err(dev, "request_irq %d failed!\n", nIrq); |
1989 | status = -ENODEV; | 1975 | status = -ENODEV; |
1990 | goto fail2; | 1976 | goto fail2; |
1991 | } | 1977 | } |
1992 | musb->nIrq = nIrq; | 1978 | musb->nIrq = nIrq; |
1993 | /* FIXME this handles wakeup irqs wrong */ | 1979 | /* FIXME this handles wakeup irqs wrong */ |
1994 | if (enable_irq_wake(nIrq) == 0) | 1980 | if (enable_irq_wake(nIrq) == 0) { |
1981 | musb->irq_wake = 1; | ||
1995 | device_init_wakeup(dev, 1); | 1982 | device_init_wakeup(dev, 1); |
1983 | } else { | ||
1984 | musb->irq_wake = 0; | ||
1985 | } | ||
1996 | 1986 | ||
1997 | pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", | 1987 | pr_info("%s: USB %s mode controller at %p using %s, IRQ %d\n", |
1998 | musb_driver_name, | 1988 | musb_driver_name, |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 82227251931b..630946a2d9fc 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -191,7 +191,7 @@ enum musb_g_ep0_state { | |||
191 | */ | 191 | */ |
192 | 192 | ||
193 | #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ | 193 | #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ |
194 | || defined(CONFIG_ARCH_OMAP3430) | 194 | || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_BLACKFIN) |
195 | /* REVISIT indexed access seemed to | 195 | /* REVISIT indexed access seemed to |
196 | * misbehave (on DaVinci) for at least peripheral IN ... | 196 | * misbehave (on DaVinci) for at least peripheral IN ... |
197 | */ | 197 | */ |
@@ -359,6 +359,7 @@ struct musb { | |||
359 | struct otg_transceiver xceiv; | 359 | struct otg_transceiver xceiv; |
360 | 360 | ||
361 | int nIrq; | 361 | int nIrq; |
362 | unsigned irq_wake:1; | ||
362 | 363 | ||
363 | struct musb_hw_ep endpoints[MUSB_C_NUM_EPS]; | 364 | struct musb_hw_ep endpoints[MUSB_C_NUM_EPS]; |
364 | #define control_ep endpoints | 365 | #define control_ep endpoints |
@@ -447,6 +448,70 @@ static inline struct musb *gadget_to_musb(struct usb_gadget *g) | |||
447 | } | 448 | } |
448 | #endif | 449 | #endif |
449 | 450 | ||
451 | #ifdef CONFIG_BLACKFIN | ||
452 | static inline int musb_read_fifosize(struct musb *musb, | ||
453 | struct musb_hw_ep *hw_ep, u8 epnum) | ||
454 | { | ||
455 | musb->nr_endpoints++; | ||
456 | musb->epmask |= (1 << epnum); | ||
457 | |||
458 | if (epnum < 5) { | ||
459 | hw_ep->max_packet_sz_tx = 128; | ||
460 | hw_ep->max_packet_sz_rx = 128; | ||
461 | } else { | ||
462 | hw_ep->max_packet_sz_tx = 1024; | ||
463 | hw_ep->max_packet_sz_rx = 1024; | ||
464 | } | ||
465 | hw_ep->is_shared_fifo = false; | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static inline void musb_configure_ep0(struct musb *musb) | ||
471 | { | ||
472 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | ||
473 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | ||
474 | musb->endpoints[0].is_shared_fifo = true; | ||
475 | } | ||
476 | |||
477 | #else | ||
478 | |||
479 | static inline int musb_read_fifosize(struct musb *musb, | ||
480 | struct musb_hw_ep *hw_ep, u8 epnum) | ||
481 | { | ||
482 | u8 reg = 0; | ||
483 | |||
484 | /* read from core using indexed model */ | ||
485 | reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); | ||
486 | /* 0's returned when no more endpoints */ | ||
487 | if (!reg) | ||
488 | return -ENODEV; | ||
489 | |||
490 | musb->nr_endpoints++; | ||
491 | musb->epmask |= (1 << epnum); | ||
492 | |||
493 | hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f); | ||
494 | |||
495 | /* shared TX/RX FIFO? */ | ||
496 | if ((reg & 0xf0) == 0xf0) { | ||
497 | hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx; | ||
498 | hw_ep->is_shared_fifo = true; | ||
499 | return 0; | ||
500 | } else { | ||
501 | hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4); | ||
502 | hw_ep->is_shared_fifo = false; | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static inline void musb_configure_ep0(struct musb *musb) | ||
509 | { | ||
510 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | ||
511 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | ||
512 | } | ||
513 | #endif /* CONFIG_BLACKFIN */ | ||
514 | |||
450 | 515 | ||
451 | /***************************** Glue it together *****************************/ | 516 | /***************************** Glue it together *****************************/ |
452 | 517 | ||
@@ -467,16 +532,16 @@ extern void musb_platform_disable(struct musb *musb); | |||
467 | 532 | ||
468 | extern void musb_hnp_stop(struct musb *musb); | 533 | extern void musb_hnp_stop(struct musb *musb); |
469 | 534 | ||
470 | extern void musb_platform_set_mode(struct musb *musb, u8 musb_mode); | 535 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); |
471 | 536 | ||
472 | #if defined(CONFIG_USB_TUSB6010) || \ | 537 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ |
473 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) | 538 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) |
474 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); | 539 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); |
475 | #else | 540 | #else |
476 | #define musb_platform_try_idle(x, y) do {} while (0) | 541 | #define musb_platform_try_idle(x, y) do {} while (0) |
477 | #endif | 542 | #endif |
478 | 543 | ||
479 | #ifdef CONFIG_USB_TUSB6010 | 544 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) |
480 | extern int musb_platform_get_vbus_status(struct musb *musb); | 545 | extern int musb_platform_get_vbus_status(struct musb *musb); |
481 | #else | 546 | #else |
482 | #define musb_platform_get_vbus_status(x) 0 | 547 | #define musb_platform_get_vbus_status(x) 0 |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d6a802c224fa..6197daeab8f9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1633,7 +1633,7 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1633 | musb->g.speed = USB_SPEED_UNKNOWN; | 1633 | musb->g.speed = USB_SPEED_UNKNOWN; |
1634 | 1634 | ||
1635 | /* this "gadget" abstracts/virtualizes the controller */ | 1635 | /* this "gadget" abstracts/virtualizes the controller */ |
1636 | strcpy(musb->g.dev.bus_id, "gadget"); | 1636 | dev_set_name(&musb->g.dev, "gadget"); |
1637 | musb->g.dev.parent = musb->controller; | 1637 | musb->g.dev.parent = musb->controller; |
1638 | musb->g.dev.dma_mask = musb->controller->dma_mask; | 1638 | musb->g.dev.dma_mask = musb->controller->dma_mask; |
1639 | musb->g.dev.release = musb_gadget_release; | 1639 | musb->g.dev.release = musb_gadget_release; |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index cc64462d4c4e..99fa61234876 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -112,18 +112,21 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) | |||
112 | { | 112 | { |
113 | void __iomem *epio = ep->regs; | 113 | void __iomem *epio = ep->regs; |
114 | u16 csr; | 114 | u16 csr; |
115 | u16 lastcsr = 0; | ||
115 | int retries = 1000; | 116 | int retries = 1000; |
116 | 117 | ||
117 | csr = musb_readw(epio, MUSB_TXCSR); | 118 | csr = musb_readw(epio, MUSB_TXCSR); |
118 | while (csr & MUSB_TXCSR_FIFONOTEMPTY) { | 119 | while (csr & MUSB_TXCSR_FIFONOTEMPTY) { |
119 | DBG(5, "Host TX FIFONOTEMPTY csr: %02x\n", csr); | 120 | if (csr != lastcsr) |
121 | DBG(3, "Host TX FIFONOTEMPTY csr: %02x\n", csr); | ||
122 | lastcsr = csr; | ||
120 | csr |= MUSB_TXCSR_FLUSHFIFO; | 123 | csr |= MUSB_TXCSR_FLUSHFIFO; |
121 | musb_writew(epio, MUSB_TXCSR, csr); | 124 | musb_writew(epio, MUSB_TXCSR, csr); |
122 | csr = musb_readw(epio, MUSB_TXCSR); | 125 | csr = musb_readw(epio, MUSB_TXCSR); |
123 | if (retries-- < 1) { | 126 | if (WARN(retries-- < 1, |
124 | ERR("Could not flush host TX fifo: csr: %04x\n", csr); | 127 | "Could not flush host TX%d fifo: csr: %04x\n", |
128 | ep->epnum, csr)) | ||
125 | return; | 129 | return; |
126 | } | ||
127 | mdelay(1); | 130 | mdelay(1); |
128 | } | 131 | } |
129 | } | 132 | } |
@@ -268,7 +271,7 @@ __musb_giveback(struct musb *musb, struct urb *urb, int status) | |||
268 | __releases(musb->lock) | 271 | __releases(musb->lock) |
269 | __acquires(musb->lock) | 272 | __acquires(musb->lock) |
270 | { | 273 | { |
271 | DBG(({ int level; switch (urb->status) { | 274 | DBG(({ int level; switch (status) { |
272 | case 0: | 275 | case 0: |
273 | level = 4; | 276 | level = 4; |
274 | break; | 277 | break; |
@@ -283,8 +286,8 @@ __acquires(musb->lock) | |||
283 | level = 2; | 286 | level = 2; |
284 | break; | 287 | break; |
285 | }; level; }), | 288 | }; level; }), |
286 | "complete %p (%d), dev%d ep%d%s, %d/%d\n", | 289 | "complete %p %pF (%d), dev%d ep%d%s, %d/%d\n", |
287 | urb, urb->status, | 290 | urb, urb->complete, status, |
288 | usb_pipedevice(urb->pipe), | 291 | usb_pipedevice(urb->pipe), |
289 | usb_pipeendpoint(urb->pipe), | 292 | usb_pipeendpoint(urb->pipe), |
290 | usb_pipein(urb->pipe) ? "in" : "out", | 293 | usb_pipein(urb->pipe) ? "in" : "out", |
@@ -593,12 +596,10 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) | |||
593 | 596 | ||
594 | /* target addr and (for multipoint) hub addr/port */ | 597 | /* target addr and (for multipoint) hub addr/port */ |
595 | if (musb->is_multipoint) { | 598 | if (musb->is_multipoint) { |
596 | musb_writeb(ep->target_regs, MUSB_RXFUNCADDR, | 599 | musb_write_rxfunaddr(ep->target_regs, qh->addr_reg); |
597 | qh->addr_reg); | 600 | musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg); |
598 | musb_writeb(ep->target_regs, MUSB_RXHUBADDR, | 601 | musb_write_rxhubport(ep->target_regs, qh->h_port_reg); |
599 | qh->h_addr_reg); | 602 | |
600 | musb_writeb(ep->target_regs, MUSB_RXHUBPORT, | ||
601 | qh->h_port_reg); | ||
602 | } else | 603 | } else |
603 | musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); | 604 | musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); |
604 | 605 | ||
@@ -712,15 +713,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
712 | 713 | ||
713 | /* target addr and (for multipoint) hub addr/port */ | 714 | /* target addr and (for multipoint) hub addr/port */ |
714 | if (musb->is_multipoint) { | 715 | if (musb->is_multipoint) { |
715 | musb_writeb(mbase, | 716 | musb_write_txfunaddr(mbase, epnum, qh->addr_reg); |
716 | MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), | 717 | musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg); |
717 | qh->addr_reg); | 718 | musb_write_txhubport(mbase, epnum, qh->h_port_reg); |
718 | musb_writeb(mbase, | ||
719 | MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), | ||
720 | qh->h_addr_reg); | ||
721 | musb_writeb(mbase, | ||
722 | MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), | ||
723 | qh->h_port_reg); | ||
724 | /* FIXME if !epnum, do the same for RX ... */ | 719 | /* FIXME if !epnum, do the same for RX ... */ |
725 | } else | 720 | } else |
726 | musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); | 721 | musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); |
@@ -988,8 +983,10 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
988 | if (fifo_count) { | 983 | if (fifo_count) { |
989 | fifo_dest = (u8 *) (urb->transfer_buffer | 984 | fifo_dest = (u8 *) (urb->transfer_buffer |
990 | + urb->actual_length); | 985 | + urb->actual_length); |
991 | DBG(3, "Sending %d bytes to %p\n", | 986 | DBG(3, "Sending %d byte%s to ep0 fifo %p\n", |
992 | fifo_count, fifo_dest); | 987 | fifo_count, |
988 | (fifo_count == 1) ? "" : "s", | ||
989 | fifo_dest); | ||
993 | musb_write_fifo(hw_ep, fifo_count, fifo_dest); | 990 | musb_write_fifo(hw_ep, fifo_count, fifo_dest); |
994 | 991 | ||
995 | urb->actual_length += fifo_count; | 992 | urb->actual_length += fifo_count; |
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index 223f0a514094..b06e9ef00cfc 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ | 40 | #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ |
41 | && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ | 41 | && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ |
42 | && !defined(CONFIG_PPC64) | 42 | && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) |
43 | static inline void readsl(const void __iomem *addr, void *buf, int len) | 43 | static inline void readsl(const void __iomem *addr, void *buf, int len) |
44 | { insl((unsigned long)addr, buf, len); } | 44 | { insl((unsigned long)addr, buf, len); } |
45 | static inline void readsw(const void __iomem *addr, void *buf, int len) | 45 | static inline void readsw(const void __iomem *addr, void *buf, int len) |
@@ -56,6 +56,8 @@ static inline void writesb(const void __iomem *addr, const void *buf, int len) | |||
56 | 56 | ||
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #ifndef CONFIG_BLACKFIN | ||
60 | |||
59 | /* NOTE: these offsets are all in bytes */ | 61 | /* NOTE: these offsets are all in bytes */ |
60 | 62 | ||
61 | static inline u16 musb_readw(const void __iomem *addr, unsigned offset) | 63 | static inline u16 musb_readw(const void __iomem *addr, unsigned offset) |
@@ -114,4 +116,26 @@ static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) | |||
114 | 116 | ||
115 | #endif /* CONFIG_USB_TUSB6010 */ | 117 | #endif /* CONFIG_USB_TUSB6010 */ |
116 | 118 | ||
119 | #else | ||
120 | |||
121 | static inline u8 musb_readb(const void __iomem *addr, unsigned offset) | ||
122 | { return (u8) (bfin_read16(addr + offset)); } | ||
123 | |||
124 | static inline u16 musb_readw(const void __iomem *addr, unsigned offset) | ||
125 | { return bfin_read16(addr + offset); } | ||
126 | |||
127 | static inline u32 musb_readl(const void __iomem *addr, unsigned offset) | ||
128 | { return (u32) (bfin_read16(addr + offset)); } | ||
129 | |||
130 | static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) | ||
131 | { bfin_write16(addr + offset, (u16) data); } | ||
132 | |||
133 | static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data) | ||
134 | { bfin_write16(addr + offset, data); } | ||
135 | |||
136 | static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) | ||
137 | { bfin_write16(addr + offset, (u16) data); } | ||
138 | |||
139 | #endif /* CONFIG_BLACKFIN */ | ||
140 | |||
117 | #endif | 141 | #endif |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 9c228661aa5a..de3b2f18db44 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -38,97 +38,6 @@ | |||
38 | #define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */ | 38 | #define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */ |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Common USB registers | ||
42 | */ | ||
43 | |||
44 | #define MUSB_FADDR 0x00 /* 8-bit */ | ||
45 | #define MUSB_POWER 0x01 /* 8-bit */ | ||
46 | |||
47 | #define MUSB_INTRTX 0x02 /* 16-bit */ | ||
48 | #define MUSB_INTRRX 0x04 | ||
49 | #define MUSB_INTRTXE 0x06 | ||
50 | #define MUSB_INTRRXE 0x08 | ||
51 | #define MUSB_INTRUSB 0x0A /* 8 bit */ | ||
52 | #define MUSB_INTRUSBE 0x0B /* 8 bit */ | ||
53 | #define MUSB_FRAME 0x0C | ||
54 | #define MUSB_INDEX 0x0E /* 8 bit */ | ||
55 | #define MUSB_TESTMODE 0x0F /* 8 bit */ | ||
56 | |||
57 | /* Get offset for a given FIFO from musb->mregs */ | ||
58 | #ifdef CONFIG_USB_TUSB6010 | ||
59 | #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) | ||
60 | #else | ||
61 | #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) | ||
62 | #endif | ||
63 | |||
64 | /* | ||
65 | * Additional Control Registers | ||
66 | */ | ||
67 | |||
68 | #define MUSB_DEVCTL 0x60 /* 8 bit */ | ||
69 | |||
70 | /* These are always controlled through the INDEX register */ | ||
71 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ | ||
72 | #define MUSB_RXFIFOSZ 0x63 /* 8-bit (see masks) */ | ||
73 | #define MUSB_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ | ||
74 | #define MUSB_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ | ||
75 | |||
76 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ | ||
77 | #define MUSB_HWVERS 0x6C /* 8 bit */ | ||
78 | |||
79 | #define MUSB_EPINFO 0x78 /* 8 bit */ | ||
80 | #define MUSB_RAMINFO 0x79 /* 8 bit */ | ||
81 | #define MUSB_LINKINFO 0x7a /* 8 bit */ | ||
82 | #define MUSB_VPLEN 0x7b /* 8 bit */ | ||
83 | #define MUSB_HS_EOF1 0x7c /* 8 bit */ | ||
84 | #define MUSB_FS_EOF1 0x7d /* 8 bit */ | ||
85 | #define MUSB_LS_EOF1 0x7e /* 8 bit */ | ||
86 | |||
87 | /* Offsets to endpoint registers */ | ||
88 | #define MUSB_TXMAXP 0x00 | ||
89 | #define MUSB_TXCSR 0x02 | ||
90 | #define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ | ||
91 | #define MUSB_RXMAXP 0x04 | ||
92 | #define MUSB_RXCSR 0x06 | ||
93 | #define MUSB_RXCOUNT 0x08 | ||
94 | #define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ | ||
95 | #define MUSB_TXTYPE 0x0A | ||
96 | #define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ | ||
97 | #define MUSB_TXINTERVAL 0x0B | ||
98 | #define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ | ||
99 | #define MUSB_RXTYPE 0x0C | ||
100 | #define MUSB_RXINTERVAL 0x0D | ||
101 | #define MUSB_FIFOSIZE 0x0F | ||
102 | #define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ | ||
103 | |||
104 | /* Offsets to endpoint registers in indexed model (using INDEX register) */ | ||
105 | #define MUSB_INDEXED_OFFSET(_epnum, _offset) \ | ||
106 | (0x10 + (_offset)) | ||
107 | |||
108 | /* Offsets to endpoint registers in flat models */ | ||
109 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | ||
110 | (0x100 + (0x10*(_epnum)) + (_offset)) | ||
111 | |||
112 | #ifdef CONFIG_USB_TUSB6010 | ||
113 | /* TUSB6010 EP0 configuration register is special */ | ||
114 | #define MUSB_TUSB_OFFSET(_epnum, _offset) \ | ||
115 | (0x10 + _offset) | ||
116 | #include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ | ||
117 | #endif | ||
118 | |||
119 | /* "bus control"/target registers, for host side multipoint (external hubs) */ | ||
120 | #define MUSB_TXFUNCADDR 0x00 | ||
121 | #define MUSB_TXHUBADDR 0x02 | ||
122 | #define MUSB_TXHUBPORT 0x03 | ||
123 | |||
124 | #define MUSB_RXFUNCADDR 0x04 | ||
125 | #define MUSB_RXHUBADDR 0x06 | ||
126 | #define MUSB_RXHUBPORT 0x07 | ||
127 | |||
128 | #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ | ||
129 | (0x80 + (8*(_epnum)) + (_offset)) | ||
130 | |||
131 | /* | ||
132 | * MUSB Register bits | 41 | * MUSB Register bits |
133 | */ | 42 | */ |
134 | 43 | ||
@@ -228,7 +137,6 @@ | |||
228 | 137 | ||
229 | /* TXCSR in Peripheral and Host mode */ | 138 | /* TXCSR in Peripheral and Host mode */ |
230 | #define MUSB_TXCSR_AUTOSET 0x8000 | 139 | #define MUSB_TXCSR_AUTOSET 0x8000 |
231 | #define MUSB_TXCSR_MODE 0x2000 | ||
232 | #define MUSB_TXCSR_DMAENAB 0x1000 | 140 | #define MUSB_TXCSR_DMAENAB 0x1000 |
233 | #define MUSB_TXCSR_FRCDATATOG 0x0800 | 141 | #define MUSB_TXCSR_FRCDATATOG 0x0800 |
234 | #define MUSB_TXCSR_DMAMODE 0x0400 | 142 | #define MUSB_TXCSR_DMAMODE 0x0400 |
@@ -297,4 +205,309 @@ | |||
297 | /* HUBADDR */ | 205 | /* HUBADDR */ |
298 | #define MUSB_HUBADDR_MULTI_TT 0x80 | 206 | #define MUSB_HUBADDR_MULTI_TT 0x80 |
299 | 207 | ||
208 | |||
209 | #ifndef CONFIG_BLACKFIN | ||
210 | |||
211 | /* | ||
212 | * Common USB registers | ||
213 | */ | ||
214 | |||
215 | #define MUSB_FADDR 0x00 /* 8-bit */ | ||
216 | #define MUSB_POWER 0x01 /* 8-bit */ | ||
217 | |||
218 | #define MUSB_INTRTX 0x02 /* 16-bit */ | ||
219 | #define MUSB_INTRRX 0x04 | ||
220 | #define MUSB_INTRTXE 0x06 | ||
221 | #define MUSB_INTRRXE 0x08 | ||
222 | #define MUSB_INTRUSB 0x0A /* 8 bit */ | ||
223 | #define MUSB_INTRUSBE 0x0B /* 8 bit */ | ||
224 | #define MUSB_FRAME 0x0C | ||
225 | #define MUSB_INDEX 0x0E /* 8 bit */ | ||
226 | #define MUSB_TESTMODE 0x0F /* 8 bit */ | ||
227 | |||
228 | /* Get offset for a given FIFO from musb->mregs */ | ||
229 | #ifdef CONFIG_USB_TUSB6010 | ||
230 | #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) | ||
231 | #else | ||
232 | #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) | ||
233 | #endif | ||
234 | |||
235 | /* | ||
236 | * Additional Control Registers | ||
237 | */ | ||
238 | |||
239 | #define MUSB_DEVCTL 0x60 /* 8 bit */ | ||
240 | |||
241 | /* These are always controlled through the INDEX register */ | ||
242 | #define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ | ||
243 | #define MUSB_RXFIFOSZ 0x63 /* 8-bit (see masks) */ | ||
244 | #define MUSB_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ | ||
245 | #define MUSB_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ | ||
246 | |||
247 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ | ||
248 | #define MUSB_HWVERS 0x6C /* 8 bit */ | ||
249 | |||
250 | #define MUSB_EPINFO 0x78 /* 8 bit */ | ||
251 | #define MUSB_RAMINFO 0x79 /* 8 bit */ | ||
252 | #define MUSB_LINKINFO 0x7a /* 8 bit */ | ||
253 | #define MUSB_VPLEN 0x7b /* 8 bit */ | ||
254 | #define MUSB_HS_EOF1 0x7c /* 8 bit */ | ||
255 | #define MUSB_FS_EOF1 0x7d /* 8 bit */ | ||
256 | #define MUSB_LS_EOF1 0x7e /* 8 bit */ | ||
257 | |||
258 | /* Offsets to endpoint registers */ | ||
259 | #define MUSB_TXMAXP 0x00 | ||
260 | #define MUSB_TXCSR 0x02 | ||
261 | #define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ | ||
262 | #define MUSB_RXMAXP 0x04 | ||
263 | #define MUSB_RXCSR 0x06 | ||
264 | #define MUSB_RXCOUNT 0x08 | ||
265 | #define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ | ||
266 | #define MUSB_TXTYPE 0x0A | ||
267 | #define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ | ||
268 | #define MUSB_TXINTERVAL 0x0B | ||
269 | #define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ | ||
270 | #define MUSB_RXTYPE 0x0C | ||
271 | #define MUSB_RXINTERVAL 0x0D | ||
272 | #define MUSB_FIFOSIZE 0x0F | ||
273 | #define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ | ||
274 | |||
275 | /* Offsets to endpoint registers in indexed model (using INDEX register) */ | ||
276 | #define MUSB_INDEXED_OFFSET(_epnum, _offset) \ | ||
277 | (0x10 + (_offset)) | ||
278 | |||
279 | /* Offsets to endpoint registers in flat models */ | ||
280 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | ||
281 | (0x100 + (0x10*(_epnum)) + (_offset)) | ||
282 | |||
283 | #ifdef CONFIG_USB_TUSB6010 | ||
284 | /* TUSB6010 EP0 configuration register is special */ | ||
285 | #define MUSB_TUSB_OFFSET(_epnum, _offset) \ | ||
286 | (0x10 + _offset) | ||
287 | #include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ | ||
288 | #endif | ||
289 | |||
290 | #define MUSB_TXCSR_MODE 0x2000 | ||
291 | |||
292 | /* "bus control"/target registers, for host side multipoint (external hubs) */ | ||
293 | #define MUSB_TXFUNCADDR 0x00 | ||
294 | #define MUSB_TXHUBADDR 0x02 | ||
295 | #define MUSB_TXHUBPORT 0x03 | ||
296 | |||
297 | #define MUSB_RXFUNCADDR 0x04 | ||
298 | #define MUSB_RXHUBADDR 0x06 | ||
299 | #define MUSB_RXHUBPORT 0x07 | ||
300 | |||
301 | #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ | ||
302 | (0x80 + (8*(_epnum)) + (_offset)) | ||
303 | |||
304 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) | ||
305 | { | ||
306 | musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); | ||
307 | } | ||
308 | |||
309 | static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off) | ||
310 | { | ||
311 | musb_writew(mbase, MUSB_TXFIFOADD, c_off); | ||
312 | } | ||
313 | |||
314 | static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size) | ||
315 | { | ||
316 | musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); | ||
317 | } | ||
318 | |||
319 | static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | ||
320 | { | ||
321 | musb_writew(mbase, MUSB_RXFIFOADD, c_off); | ||
322 | } | ||
323 | |||
324 | static inline u8 musb_read_configdata(void __iomem *mbase) | ||
325 | { | ||
326 | return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); | ||
327 | } | ||
328 | |||
329 | static inline u16 musb_read_hwvers(void __iomem *mbase) | ||
330 | { | ||
331 | return musb_readw(mbase, MUSB_HWVERS); | ||
332 | } | ||
333 | |||
334 | static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) | ||
335 | { | ||
336 | return (MUSB_BUSCTL_OFFSET(i, 0) + mbase); | ||
337 | } | ||
338 | |||
339 | static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, | ||
340 | u8 qh_addr_reg) | ||
341 | { | ||
342 | musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg); | ||
343 | } | ||
344 | |||
345 | static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, | ||
346 | u8 qh_h_addr_reg) | ||
347 | { | ||
348 | musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg); | ||
349 | } | ||
350 | |||
351 | static inline void musb_write_rxhubport(void __iomem *ep_target_regs, | ||
352 | u8 qh_h_port_reg) | ||
353 | { | ||
354 | musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg); | ||
355 | } | ||
356 | |||
357 | static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, | ||
358 | u8 qh_addr_reg) | ||
359 | { | ||
360 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), | ||
361 | qh_addr_reg); | ||
362 | } | ||
363 | |||
364 | static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, | ||
365 | u8 qh_addr_reg) | ||
366 | { | ||
367 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), | ||
368 | qh_addr_reg); | ||
369 | } | ||
370 | |||
371 | static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | ||
372 | u8 qh_h_port_reg) | ||
373 | { | ||
374 | musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), | ||
375 | qh_h_port_reg); | ||
376 | } | ||
377 | |||
378 | #else /* CONFIG_BLACKFIN */ | ||
379 | |||
380 | #define USB_BASE USB_FADDR | ||
381 | #define USB_OFFSET(reg) (reg - USB_BASE) | ||
382 | |||
383 | /* | ||
384 | * Common USB registers | ||
385 | */ | ||
386 | #define MUSB_FADDR USB_OFFSET(USB_FADDR) /* 8-bit */ | ||
387 | #define MUSB_POWER USB_OFFSET(USB_POWER) /* 8-bit */ | ||
388 | #define MUSB_INTRTX USB_OFFSET(USB_INTRTX) /* 16-bit */ | ||
389 | #define MUSB_INTRRX USB_OFFSET(USB_INTRRX) | ||
390 | #define MUSB_INTRTXE USB_OFFSET(USB_INTRTXE) | ||
391 | #define MUSB_INTRRXE USB_OFFSET(USB_INTRRXE) | ||
392 | #define MUSB_INTRUSB USB_OFFSET(USB_INTRUSB) /* 8 bit */ | ||
393 | #define MUSB_INTRUSBE USB_OFFSET(USB_INTRUSBE)/* 8 bit */ | ||
394 | #define MUSB_FRAME USB_OFFSET(USB_FRAME) | ||
395 | #define MUSB_INDEX USB_OFFSET(USB_INDEX) /* 8 bit */ | ||
396 | #define MUSB_TESTMODE USB_OFFSET(USB_TESTMODE)/* 8 bit */ | ||
397 | |||
398 | /* Get offset for a given FIFO from musb->mregs */ | ||
399 | #define MUSB_FIFO_OFFSET(epnum) \ | ||
400 | (USB_OFFSET(USB_EP0_FIFO) + ((epnum) * 8)) | ||
401 | |||
402 | /* | ||
403 | * Additional Control Registers | ||
404 | */ | ||
405 | |||
406 | #define MUSB_DEVCTL USB_OFFSET(USB_OTG_DEV_CTL) /* 8 bit */ | ||
407 | |||
408 | #define MUSB_LINKINFO USB_OFFSET(USB_LINKINFO)/* 8 bit */ | ||
409 | #define MUSB_VPLEN USB_OFFSET(USB_VPLEN) /* 8 bit */ | ||
410 | #define MUSB_HS_EOF1 USB_OFFSET(USB_HS_EOF1) /* 8 bit */ | ||
411 | #define MUSB_FS_EOF1 USB_OFFSET(USB_FS_EOF1) /* 8 bit */ | ||
412 | #define MUSB_LS_EOF1 USB_OFFSET(USB_LS_EOF1) /* 8 bit */ | ||
413 | |||
414 | /* Offsets to endpoint registers */ | ||
415 | #define MUSB_TXMAXP 0x00 | ||
416 | #define MUSB_TXCSR 0x04 | ||
417 | #define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ | ||
418 | #define MUSB_RXMAXP 0x08 | ||
419 | #define MUSB_RXCSR 0x0C | ||
420 | #define MUSB_RXCOUNT 0x10 | ||
421 | #define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ | ||
422 | #define MUSB_TXTYPE 0x14 | ||
423 | #define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ | ||
424 | #define MUSB_TXINTERVAL 0x18 | ||
425 | #define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ | ||
426 | #define MUSB_RXTYPE 0x1C | ||
427 | #define MUSB_RXINTERVAL 0x20 | ||
428 | #define MUSB_TXCOUNT 0x28 | ||
429 | |||
430 | /* Offsets to endpoint registers in indexed model (using INDEX register) */ | ||
431 | #define MUSB_INDEXED_OFFSET(_epnum, _offset) \ | ||
432 | (0x40 + (_offset)) | ||
433 | |||
434 | /* Offsets to endpoint registers in flat models */ | ||
435 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | ||
436 | (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset)) | ||
437 | |||
438 | /* Not implemented - HW has seperate Tx/Rx FIFO */ | ||
439 | #define MUSB_TXCSR_MODE 0x0000 | ||
440 | |||
441 | /* | ||
442 | * Dummy stub for clk framework, it will be removed | ||
443 | * until Blackfin supports clk framework | ||
444 | */ | ||
445 | #define clk_get(dev, id) NULL | ||
446 | #define clk_put(clock) do {} while (0) | ||
447 | #define clk_enable(clock) do {} while (0) | ||
448 | #define clk_disable(clock) do {} while (0) | ||
449 | |||
450 | static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) | ||
451 | { | ||
452 | } | ||
453 | |||
454 | static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off) | ||
455 | { | ||
456 | } | ||
457 | |||
458 | static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size) | ||
459 | { | ||
460 | } | ||
461 | |||
462 | static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) | ||
463 | { | ||
464 | } | ||
465 | |||
466 | static inline u8 musb_read_configdata(void __iomem *mbase) | ||
467 | { | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | static inline u16 musb_read_hwvers(void __iomem *mbase) | ||
472 | { | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static inline u16 musb_read_target_reg_base(u8 i, void __iomem *mbase) | ||
477 | { | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, | ||
482 | u8 qh_addr_req) | ||
483 | { | ||
484 | } | ||
485 | |||
486 | static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, | ||
487 | u8 qh_h_addr_reg) | ||
488 | { | ||
489 | } | ||
490 | |||
491 | static inline void musb_write_rxhubport(void __iomem *ep_target_regs, | ||
492 | u8 qh_h_port_reg) | ||
493 | { | ||
494 | } | ||
495 | |||
496 | static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, | ||
497 | u8 qh_addr_reg) | ||
498 | { | ||
499 | } | ||
500 | |||
501 | static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, | ||
502 | u8 qh_addr_reg) | ||
503 | { | ||
504 | } | ||
505 | |||
506 | static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, | ||
507 | u8 qh_h_port_reg) | ||
508 | { | ||
509 | } | ||
510 | |||
511 | #endif /* CONFIG_BLACKFIN */ | ||
512 | |||
300 | #endif /* __MUSB_REGS_H__ */ | 513 | #endif /* __MUSB_REGS_H__ */ |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 8c734ef2c1ed..8662e9e159c3 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -34,58 +34,7 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include "musb_core.h" | 36 | #include "musb_core.h" |
37 | 37 | #include "musbhsdma.h" | |
38 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | ||
39 | #include "omap2430.h" | ||
40 | #endif | ||
41 | |||
42 | #define MUSB_HSDMA_BASE 0x200 | ||
43 | #define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0) | ||
44 | #define MUSB_HSDMA_CONTROL 0x4 | ||
45 | #define MUSB_HSDMA_ADDRESS 0x8 | ||
46 | #define MUSB_HSDMA_COUNT 0xc | ||
47 | |||
48 | #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ | ||
49 | (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset) | ||
50 | |||
51 | /* control register (16-bit): */ | ||
52 | #define MUSB_HSDMA_ENABLE_SHIFT 0 | ||
53 | #define MUSB_HSDMA_TRANSMIT_SHIFT 1 | ||
54 | #define MUSB_HSDMA_MODE1_SHIFT 2 | ||
55 | #define MUSB_HSDMA_IRQENABLE_SHIFT 3 | ||
56 | #define MUSB_HSDMA_ENDPOINT_SHIFT 4 | ||
57 | #define MUSB_HSDMA_BUSERROR_SHIFT 8 | ||
58 | #define MUSB_HSDMA_BURSTMODE_SHIFT 9 | ||
59 | #define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT) | ||
60 | #define MUSB_HSDMA_BURSTMODE_UNSPEC 0 | ||
61 | #define MUSB_HSDMA_BURSTMODE_INCR4 1 | ||
62 | #define MUSB_HSDMA_BURSTMODE_INCR8 2 | ||
63 | #define MUSB_HSDMA_BURSTMODE_INCR16 3 | ||
64 | |||
65 | #define MUSB_HSDMA_CHANNELS 8 | ||
66 | |||
67 | struct musb_dma_controller; | ||
68 | |||
69 | struct musb_dma_channel { | ||
70 | struct dma_channel channel; | ||
71 | struct musb_dma_controller *controller; | ||
72 | u32 start_addr; | ||
73 | u32 len; | ||
74 | u16 max_packet_sz; | ||
75 | u8 idx; | ||
76 | u8 epnum; | ||
77 | u8 transmit; | ||
78 | }; | ||
79 | |||
80 | struct musb_dma_controller { | ||
81 | struct dma_controller controller; | ||
82 | struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS]; | ||
83 | void *private_data; | ||
84 | void __iomem *base; | ||
85 | u8 channel_count; | ||
86 | u8 used_channels; | ||
87 | u8 irq; | ||
88 | }; | ||
89 | 38 | ||
90 | static int dma_controller_start(struct dma_controller *c) | 39 | static int dma_controller_start(struct dma_controller *c) |
91 | { | 40 | { |
@@ -203,12 +152,8 @@ static void configure_channel(struct dma_channel *channel, | |||
203 | : 0); | 152 | : 0); |
204 | 153 | ||
205 | /* address/count */ | 154 | /* address/count */ |
206 | musb_writel(mbase, | 155 | musb_write_hsdma_addr(mbase, bchannel, dma_addr); |
207 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), | 156 | musb_write_hsdma_count(mbase, bchannel, len); |
208 | dma_addr); | ||
209 | musb_writel(mbase, | ||
210 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), | ||
211 | len); | ||
212 | 157 | ||
213 | /* control (this should start things) */ | 158 | /* control (this should start things) */ |
214 | musb_writew(mbase, | 159 | musb_writew(mbase, |
@@ -279,13 +224,8 @@ static int dma_channel_abort(struct dma_channel *channel) | |||
279 | musb_writew(mbase, | 224 | musb_writew(mbase, |
280 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), | 225 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL), |
281 | 0); | 226 | 0); |
282 | musb_writel(mbase, | 227 | musb_write_hsdma_addr(mbase, bchannel, 0); |
283 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), | 228 | musb_write_hsdma_count(mbase, bchannel, 0); |
284 | 0); | ||
285 | musb_writel(mbase, | ||
286 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), | ||
287 | 0); | ||
288 | |||
289 | channel->status = MUSB_DMA_STATUS_FREE; | 229 | channel->status = MUSB_DMA_STATUS_FREE; |
290 | } | 230 | } |
291 | 231 | ||
@@ -333,10 +273,8 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
333 | } else { | 273 | } else { |
334 | u8 devctl; | 274 | u8 devctl; |
335 | 275 | ||
336 | addr = musb_readl(mbase, | 276 | addr = musb_read_hsdma_addr(mbase, |
337 | MUSB_HSDMA_CHANNEL_OFFSET( | 277 | bchannel); |
338 | bchannel, | ||
339 | MUSB_HSDMA_ADDRESS)); | ||
340 | channel->actual_len = addr | 278 | channel->actual_len = addr |
341 | - musb_channel->start_addr; | 279 | - musb_channel->start_addr; |
342 | 280 | ||
@@ -375,6 +313,12 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
375 | } | 313 | } |
376 | } | 314 | } |
377 | } | 315 | } |
316 | |||
317 | #ifdef CONFIG_BLACKFIN | ||
318 | /* Clear DMA interrup flags */ | ||
319 | musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); | ||
320 | #endif | ||
321 | |||
378 | retval = IRQ_HANDLED; | 322 | retval = IRQ_HANDLED; |
379 | done: | 323 | done: |
380 | spin_unlock_irqrestore(&musb->lock, flags); | 324 | spin_unlock_irqrestore(&musb->lock, flags); |
@@ -424,7 +368,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) | |||
424 | controller->controller.channel_abort = dma_channel_abort; | 368 | controller->controller.channel_abort = dma_channel_abort; |
425 | 369 | ||
426 | if (request_irq(irq, dma_controller_irq, IRQF_DISABLED, | 370 | if (request_irq(irq, dma_controller_irq, IRQF_DISABLED, |
427 | musb->controller->bus_id, &controller->controller)) { | 371 | dev_name(musb->controller), &controller->controller)) { |
428 | dev_err(dev, "request_irq %d failed!\n", irq); | 372 | dev_err(dev, "request_irq %d failed!\n", irq); |
429 | dma_controller_destroy(&controller->controller); | 373 | dma_controller_destroy(&controller->controller); |
430 | 374 | ||
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h new file mode 100644 index 000000000000..1299d92dc83f --- /dev/null +++ b/drivers/usb/musb/musbhsdma.h | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * MUSB OTG driver - support for Mentor's DMA controller | ||
3 | * | ||
4 | * Copyright 2005 Mentor Graphics Corporation | ||
5 | * Copyright (C) 2005-2007 by Texas Instruments | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
22 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
23 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
24 | * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
27 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
28 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | ||
35 | #include "omap2430.h" | ||
36 | #endif | ||
37 | |||
38 | #ifndef CONFIG_BLACKFIN | ||
39 | |||
40 | #define MUSB_HSDMA_BASE 0x200 | ||
41 | #define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0) | ||
42 | #define MUSB_HSDMA_CONTROL 0x4 | ||
43 | #define MUSB_HSDMA_ADDRESS 0x8 | ||
44 | #define MUSB_HSDMA_COUNT 0xc | ||
45 | |||
46 | #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ | ||
47 | (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset) | ||
48 | |||
49 | #define musb_read_hsdma_addr(mbase, bchannel) \ | ||
50 | musb_readl(mbase, \ | ||
51 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS)) | ||
52 | |||
53 | #define musb_write_hsdma_addr(mbase, bchannel, addr) \ | ||
54 | musb_writel(mbase, \ | ||
55 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \ | ||
56 | addr) | ||
57 | |||
58 | #define musb_write_hsdma_count(mbase, bchannel, len) \ | ||
59 | musb_writel(mbase, \ | ||
60 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \ | ||
61 | len) | ||
62 | #else | ||
63 | |||
64 | #define MUSB_HSDMA_BASE 0x400 | ||
65 | #define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0) | ||
66 | #define MUSB_HSDMA_CONTROL 0x04 | ||
67 | #define MUSB_HSDMA_ADDR_LOW 0x08 | ||
68 | #define MUSB_HSDMA_ADDR_HIGH 0x0C | ||
69 | #define MUSB_HSDMA_COUNT_LOW 0x10 | ||
70 | #define MUSB_HSDMA_COUNT_HIGH 0x14 | ||
71 | |||
72 | #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ | ||
73 | (MUSB_HSDMA_BASE + (_bchannel * 0x20) + _offset) | ||
74 | |||
75 | static inline u32 musb_read_hsdma_addr(void __iomem *mbase, u8 bchannel) | ||
76 | { | ||
77 | u32 addr = musb_readw(mbase, | ||
78 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH)); | ||
79 | |||
80 | addr = addr << 16; | ||
81 | |||
82 | addr |= musb_readw(mbase, | ||
83 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW)); | ||
84 | |||
85 | return addr; | ||
86 | } | ||
87 | |||
88 | static inline void musb_write_hsdma_addr(void __iomem *mbase, | ||
89 | u8 bchannel, dma_addr_t dma_addr) | ||
90 | { | ||
91 | musb_writew(mbase, | ||
92 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW), | ||
93 | ((u16)((u32) dma_addr & 0xFFFF))); | ||
94 | musb_writew(mbase, | ||
95 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH), | ||
96 | ((u16)(((u32) dma_addr >> 16) & 0xFFFF))); | ||
97 | } | ||
98 | |||
99 | static inline void musb_write_hsdma_count(void __iomem *mbase, | ||
100 | u8 bchannel, u32 len) | ||
101 | { | ||
102 | musb_writew(mbase, | ||
103 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW), | ||
104 | ((u16)((u32) len & 0xFFFF))); | ||
105 | musb_writew(mbase, | ||
106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), | ||
107 | ((u16)(((u32) len >> 16) & 0xFFFF))); | ||
108 | } | ||
109 | |||
110 | #endif /* CONFIG_BLACKFIN */ | ||
111 | |||
112 | /* control register (16-bit): */ | ||
113 | #define MUSB_HSDMA_ENABLE_SHIFT 0 | ||
114 | #define MUSB_HSDMA_TRANSMIT_SHIFT 1 | ||
115 | #define MUSB_HSDMA_MODE1_SHIFT 2 | ||
116 | #define MUSB_HSDMA_IRQENABLE_SHIFT 3 | ||
117 | #define MUSB_HSDMA_ENDPOINT_SHIFT 4 | ||
118 | #define MUSB_HSDMA_BUSERROR_SHIFT 8 | ||
119 | #define MUSB_HSDMA_BURSTMODE_SHIFT 9 | ||
120 | #define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT) | ||
121 | #define MUSB_HSDMA_BURSTMODE_UNSPEC 0 | ||
122 | #define MUSB_HSDMA_BURSTMODE_INCR4 1 | ||
123 | #define MUSB_HSDMA_BURSTMODE_INCR8 2 | ||
124 | #define MUSB_HSDMA_BURSTMODE_INCR16 3 | ||
125 | |||
126 | #define MUSB_HSDMA_CHANNELS 8 | ||
127 | |||
128 | struct musb_dma_controller; | ||
129 | |||
130 | struct musb_dma_channel { | ||
131 | struct dma_channel channel; | ||
132 | struct musb_dma_controller *controller; | ||
133 | u32 start_addr; | ||
134 | u32 len; | ||
135 | u16 max_packet_sz; | ||
136 | u8 idx; | ||
137 | u8 epnum; | ||
138 | u8 transmit; | ||
139 | }; | ||
140 | |||
141 | struct musb_dma_controller { | ||
142 | struct dma_controller controller; | ||
143 | struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS]; | ||
144 | void *private_data; | ||
145 | void __iomem *base; | ||
146 | u8 channel_count; | ||
147 | u8 used_channels; | ||
148 | u8 irq; | ||
149 | }; | ||
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index ce6c162920f7..901dffdf23b1 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -58,10 +58,10 @@ static void musb_do_idle(unsigned long _musb) | |||
58 | #endif | 58 | #endif |
59 | u8 devctl; | 59 | u8 devctl; |
60 | 60 | ||
61 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
62 | |||
63 | spin_lock_irqsave(&musb->lock, flags); | 61 | spin_lock_irqsave(&musb->lock, flags); |
64 | 62 | ||
63 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
64 | |||
65 | switch (musb->xceiv.state) { | 65 | switch (musb->xceiv.state) { |
66 | case OTG_STATE_A_WAIT_BCON: | 66 | case OTG_STATE_A_WAIT_BCON: |
67 | devctl &= ~MUSB_DEVCTL_SESSION; | 67 | devctl &= ~MUSB_DEVCTL_SESSION; |
@@ -196,7 +196,7 @@ static int omap_set_power(struct otg_transceiver *x, unsigned mA) | |||
196 | 196 | ||
197 | static int musb_platform_resume(struct musb *musb); | 197 | static int musb_platform_resume(struct musb *musb); |
198 | 198 | ||
199 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 199 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) |
200 | { | 200 | { |
201 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 201 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
202 | 202 | ||
@@ -204,15 +204,24 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
204 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | 204 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
205 | 205 | ||
206 | switch (musb_mode) { | 206 | switch (musb_mode) { |
207 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
207 | case MUSB_HOST: | 208 | case MUSB_HOST: |
208 | otg_set_host(&musb->xceiv, musb->xceiv.host); | 209 | otg_set_host(&musb->xceiv, musb->xceiv.host); |
209 | break; | 210 | break; |
211 | #endif | ||
212 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
210 | case MUSB_PERIPHERAL: | 213 | case MUSB_PERIPHERAL: |
211 | otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); | 214 | otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget); |
212 | break; | 215 | break; |
216 | #endif | ||
217 | #ifdef CONFIG_USB_MUSB_OTG | ||
213 | case MUSB_OTG: | 218 | case MUSB_OTG: |
214 | break; | 219 | break; |
220 | #endif | ||
221 | default: | ||
222 | return -EINVAL; | ||
215 | } | 223 | } |
224 | return 0; | ||
216 | } | 225 | } |
217 | 226 | ||
218 | int __init musb_platform_init(struct musb *musb) | 227 | int __init musb_platform_init(struct musb *musb) |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index ee8fca92a4ac..9e20fd070d71 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -598,7 +598,7 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
598 | * and peripheral modes in non-OTG configurations by reconfiguring hardware | 598 | * and peripheral modes in non-OTG configurations by reconfiguring hardware |
599 | * and then setting musb->board_mode. For now, only support OTG mode. | 599 | * and then setting musb->board_mode. For now, only support OTG mode. |
600 | */ | 600 | */ |
601 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 601 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) |
602 | { | 602 | { |
603 | void __iomem *tbase = musb->ctrl_base; | 603 | void __iomem *tbase = musb->ctrl_base; |
604 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; | 604 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; |
@@ -641,7 +641,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
641 | #endif | 641 | #endif |
642 | 642 | ||
643 | default: | 643 | default: |
644 | DBG(2, "Trying to set unknown mode %i\n", musb_mode); | 644 | DBG(2, "Trying to set mode %i\n", musb_mode); |
645 | return -EINVAL; | ||
645 | } | 646 | } |
646 | 647 | ||
647 | musb_writel(tbase, TUSB_PHY_OTG_CTRL, | 648 | musb_writel(tbase, TUSB_PHY_OTG_CTRL, |
@@ -655,6 +656,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
655 | !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) | 656 | !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) |
656 | INFO("Cannot be peripheral with mini-A cable " | 657 | INFO("Cannot be peripheral with mini-A cable " |
657 | "otg_stat: %08x\n", otg_stat); | 658 | "otg_stat: %08x\n", otg_stat); |
659 | |||
660 | return 0; | ||
658 | } | 661 | } |
659 | 662 | ||
660 | static inline unsigned long | 663 | static inline unsigned long |