diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/Kconfig | 8 | ||||
-rw-r--r-- | drivers/usb/musb/Makefile | 16 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.c | 104 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 4 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 222 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 12 | ||||
-rw-r--r-- | drivers/usb/musb/musb_debug.h | 13 | ||||
-rw-r--r-- | drivers/usb/musb/musb_debugfs.c | 294 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget_ep0.c | 25 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 1 | ||||
-rw-r--r-- | drivers/usb/musb/musb_regs.h | 10 | ||||
-rw-r--r-- | drivers/usb/musb/musb_virthub.c | 4 | ||||
-rw-r--r-- | drivers/usb/musb/musbhsdma.h | 16 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 32 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 15 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010_omap.c | 22 |
16 files changed, 643 insertions, 155 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index b4c783c284ba..cfd38edfcf9e 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -38,11 +38,12 @@ config USB_MUSB_SOC | |||
38 | default y if ARCH_DAVINCI | 38 | default y if ARCH_DAVINCI |
39 | default y if ARCH_OMAP2430 | 39 | default y if ARCH_OMAP2430 |
40 | default y if ARCH_OMAP3 | 40 | default y if ARCH_OMAP3 |
41 | default y if ARCH_OMAP4 | ||
41 | default y if (BF54x && !BF544) | 42 | default y if (BF54x && !BF544) |
42 | default y if (BF52x && !BF522 && !BF523) | 43 | default y if (BF52x && !BF522 && !BF523) |
43 | 44 | ||
44 | comment "DaVinci 35x and 644x USB support" | 45 | comment "DaVinci 35x and 644x USB support" |
45 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 46 | depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx |
46 | 47 | ||
47 | comment "OMAP 243x high speed USB support" | 48 | comment "OMAP 243x high speed USB support" |
48 | depends on USB_MUSB_HDRC && ARCH_OMAP2430 | 49 | depends on USB_MUSB_HDRC && ARCH_OMAP2430 |
@@ -50,6 +51,9 @@ comment "OMAP 243x high speed USB support" | |||
50 | comment "OMAP 343x high speed USB support" | 51 | comment "OMAP 343x high speed USB support" |
51 | depends on USB_MUSB_HDRC && ARCH_OMAP3 | 52 | depends on USB_MUSB_HDRC && ARCH_OMAP3 |
52 | 53 | ||
54 | comment "OMAP 44xx high speed USB support" | ||
55 | depends on USB_MUSB_HDRC && ARCH_OMAP4 | ||
56 | |||
53 | comment "Blackfin high speed USB Support" | 57 | comment "Blackfin high speed USB Support" |
54 | depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) | 58 | depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) |
55 | 59 | ||
@@ -153,7 +157,7 @@ config MUSB_PIO_ONLY | |||
153 | config USB_INVENTRA_DMA | 157 | config USB_INVENTRA_DMA |
154 | bool | 158 | bool |
155 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY | 159 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY |
156 | default ARCH_OMAP2430 || ARCH_OMAP3 || BLACKFIN | 160 | default ARCH_OMAP2430 || ARCH_OMAP3 || BLACKFIN || ARCH_OMAP4 |
157 | help | 161 | help |
158 | Enable DMA transfers using Mentor's engine. | 162 | Enable DMA transfers using Mentor's engine. |
159 | 163 | ||
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index 85710ccc1887..9705f716386e 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile | |||
@@ -6,7 +6,7 @@ musb_hdrc-objs := musb_core.o | |||
6 | 6 | ||
7 | obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o | 7 | obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o |
8 | 8 | ||
9 | ifeq ($(CONFIG_ARCH_DAVINCI),y) | 9 | ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y) |
10 | musb_hdrc-objs += davinci.o | 10 | musb_hdrc-objs += davinci.o |
11 | endif | 11 | endif |
12 | 12 | ||
@@ -22,6 +22,10 @@ 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_ARCH_OMAP4),y) | ||
26 | musb_hdrc-objs += omap2430.o | ||
27 | endif | ||
28 | |||
25 | ifeq ($(CONFIG_BF54x),y) | 29 | ifeq ($(CONFIG_BF54x),y) |
26 | musb_hdrc-objs += blackfin.o | 30 | musb_hdrc-objs += blackfin.o |
27 | endif | 31 | endif |
@@ -38,6 +42,10 @@ ifeq ($(CONFIG_USB_MUSB_HDRC_HCD),y) | |||
38 | musb_hdrc-objs += musb_virthub.o musb_host.o | 42 | musb_hdrc-objs += musb_virthub.o musb_host.o |
39 | endif | 43 | endif |
40 | 44 | ||
45 | ifeq ($(CONFIG_DEBUG_FS),y) | ||
46 | musb_hdrc-objs += musb_debugfs.o | ||
47 | endif | ||
48 | |||
41 | # the kconfig must guarantee that only one of the | 49 | # the kconfig must guarantee that only one of the |
42 | # possible I/O schemes will be enabled at a time ... | 50 | # possible I/O schemes will be enabled at a time ... |
43 | # PIO only, or DMA (several potential schemes). | 51 | # PIO only, or DMA (several potential schemes). |
@@ -64,12 +72,6 @@ endif | |||
64 | 72 | ||
65 | ################################################################################ | 73 | ################################################################################ |
66 | 74 | ||
67 | # FIXME remove all these extra "-DMUSB_* things, stick to CONFIG_* | ||
68 | |||
69 | ifeq ($(CONFIG_USB_INVENTRA_MUSB_HAS_AHB_ID),y) | ||
70 | EXTRA_CFLAGS += -DMUSB_AHB_ID | ||
71 | endif | ||
72 | |||
73 | # Debugging | 75 | # Debugging |
74 | 76 | ||
75 | ifeq ($(CONFIG_USB_MUSB_DEBUG),y) | 77 | ifeq ($(CONFIG_USB_MUSB_DEBUG),y) |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 719a22d664ef..b611420a8050 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -170,15 +170,16 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci) | |||
170 | retval = musb_interrupt(musb); | 170 | retval = musb_interrupt(musb); |
171 | } | 171 | } |
172 | 172 | ||
173 | spin_unlock_irqrestore(&musb->lock, flags); | 173 | /* Start sampling ID pin, when plug is removed from MUSB */ |
174 | if (is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE | ||
175 | || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { | ||
176 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
177 | musb->a_wait_bcon = TIMER_DELAY; | ||
178 | } | ||
174 | 179 | ||
175 | /* REVISIT we sometimes get spurious IRQs on g_ep0 | 180 | spin_unlock_irqrestore(&musb->lock, flags); |
176 | * not clear why... fall in BF54x too. | ||
177 | */ | ||
178 | if (retval != IRQ_HANDLED) | ||
179 | DBG(5, "spurious?\n"); | ||
180 | 181 | ||
181 | return IRQ_HANDLED; | 182 | return retval; |
182 | } | 183 | } |
183 | 184 | ||
184 | static void musb_conn_timer_handler(unsigned long _musb) | 185 | static void musb_conn_timer_handler(unsigned long _musb) |
@@ -186,6 +187,7 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
186 | struct musb *musb = (void *)_musb; | 187 | struct musb *musb = (void *)_musb; |
187 | unsigned long flags; | 188 | unsigned long flags; |
188 | u16 val; | 189 | u16 val; |
190 | static u8 toggle; | ||
189 | 191 | ||
190 | spin_lock_irqsave(&musb->lock, flags); | 192 | spin_lock_irqsave(&musb->lock, flags); |
191 | switch (musb->xceiv->state) { | 193 | switch (musb->xceiv->state) { |
@@ -193,10 +195,44 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
193 | case OTG_STATE_A_WAIT_BCON: | 195 | case OTG_STATE_A_WAIT_BCON: |
194 | /* Start a new session */ | 196 | /* Start a new session */ |
195 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | 197 | val = musb_readw(musb->mregs, MUSB_DEVCTL); |
198 | val &= ~MUSB_DEVCTL_SESSION; | ||
199 | musb_writew(musb->mregs, MUSB_DEVCTL, val); | ||
196 | val |= MUSB_DEVCTL_SESSION; | 200 | val |= MUSB_DEVCTL_SESSION; |
197 | musb_writew(musb->mregs, MUSB_DEVCTL, val); | 201 | musb_writew(musb->mregs, MUSB_DEVCTL, val); |
202 | /* Check if musb is host or peripheral. */ | ||
203 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
198 | 204 | ||
205 | if (!(val & MUSB_DEVCTL_BDEVICE)) { | ||
206 | gpio_set_value(musb->config->gpio_vrsel, 1); | ||
207 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
208 | } else { | ||
209 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
210 | /* Ignore VBUSERROR and SUSPEND IRQ */ | ||
211 | val = musb_readb(musb->mregs, MUSB_INTRUSBE); | ||
212 | val &= ~MUSB_INTR_VBUSERROR; | ||
213 | musb_writeb(musb->mregs, MUSB_INTRUSBE, val); | ||
214 | |||
215 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; | ||
216 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); | ||
217 | if (is_otg_enabled(musb)) | ||
218 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
219 | else | ||
220 | musb_writeb(musb->mregs, MUSB_POWER, MUSB_POWER_HSENAB); | ||
221 | } | ||
222 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
223 | break; | ||
224 | case OTG_STATE_B_IDLE: | ||
225 | |||
226 | if (!is_peripheral_enabled(musb)) | ||
227 | break; | ||
228 | /* Start a new session. It seems that MUSB needs taking | ||
229 | * some time to recognize the type of the plug inserted? | ||
230 | */ | ||
231 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | ||
232 | val |= MUSB_DEVCTL_SESSION; | ||
233 | musb_writew(musb->mregs, MUSB_DEVCTL, val); | ||
199 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | 234 | val = musb_readw(musb->mregs, MUSB_DEVCTL); |
235 | |||
200 | if (!(val & MUSB_DEVCTL_BDEVICE)) { | 236 | if (!(val & MUSB_DEVCTL_BDEVICE)) { |
201 | gpio_set_value(musb->config->gpio_vrsel, 1); | 237 | gpio_set_value(musb->config->gpio_vrsel, 1); |
202 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | 238 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; |
@@ -211,12 +247,27 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
211 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; | 247 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; |
212 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); | 248 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); |
213 | 249 | ||
214 | val = MUSB_POWER_HSENAB; | 250 | /* Toggle the Soft Conn bit, so that we can response to |
215 | musb_writeb(musb->mregs, MUSB_POWER, val); | 251 | * the inserting of either A-plug or B-plug. |
252 | */ | ||
253 | if (toggle) { | ||
254 | val = musb_readb(musb->mregs, MUSB_POWER); | ||
255 | val &= ~MUSB_POWER_SOFTCONN; | ||
256 | musb_writeb(musb->mregs, MUSB_POWER, val); | ||
257 | toggle = 0; | ||
258 | } else { | ||
259 | val = musb_readb(musb->mregs, MUSB_POWER); | ||
260 | val |= MUSB_POWER_SOFTCONN; | ||
261 | musb_writeb(musb->mregs, MUSB_POWER, val); | ||
262 | toggle = 1; | ||
263 | } | ||
264 | /* The delay time is set to 1/4 second by default, | ||
265 | * shortening it, if accelerating A-plug detection | ||
266 | * is needed in OTG mode. | ||
267 | */ | ||
268 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY / 4); | ||
216 | } | 269 | } |
217 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
218 | break; | 270 | break; |
219 | |||
220 | default: | 271 | default: |
221 | DBG(1, "%s state not handled\n", otg_state_string(musb)); | 272 | DBG(1, "%s state not handled\n", otg_state_string(musb)); |
222 | break; | 273 | break; |
@@ -228,7 +279,7 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
228 | 279 | ||
229 | void musb_platform_enable(struct musb *musb) | 280 | void musb_platform_enable(struct musb *musb) |
230 | { | 281 | { |
231 | if (is_host_enabled(musb)) { | 282 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) { |
232 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 283 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
233 | musb->a_wait_bcon = TIMER_DELAY; | 284 | musb->a_wait_bcon = TIMER_DELAY; |
234 | } | 285 | } |
@@ -238,16 +289,12 @@ void musb_platform_disable(struct musb *musb) | |||
238 | { | 289 | { |
239 | } | 290 | } |
240 | 291 | ||
241 | static void bfin_vbus_power(struct musb *musb, int is_on, int sleeping) | ||
242 | { | ||
243 | } | ||
244 | |||
245 | static void bfin_set_vbus(struct musb *musb, int is_on) | 292 | static void bfin_set_vbus(struct musb *musb, int is_on) |
246 | { | 293 | { |
247 | if (is_on) | 294 | int value = musb->config->gpio_vrsel_active; |
248 | gpio_set_value(musb->config->gpio_vrsel, 1); | 295 | if (!is_on) |
249 | else | 296 | value = !value; |
250 | gpio_set_value(musb->config->gpio_vrsel, 0); | 297 | gpio_set_value(musb->config->gpio_vrsel, value); |
251 | 298 | ||
252 | DBG(1, "VBUS %s, devctl %02x " | 299 | DBG(1, "VBUS %s, devctl %02x " |
253 | /* otg %3x conf %08x prcm %08x */ "\n", | 300 | /* otg %3x conf %08x prcm %08x */ "\n", |
@@ -262,7 +309,7 @@ static int bfin_set_power(struct otg_transceiver *x, unsigned mA) | |||
262 | 309 | ||
263 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 310 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) |
264 | { | 311 | { |
265 | if (is_host_enabled(musb)) | 312 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) |
266 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 313 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
267 | } | 314 | } |
268 | 315 | ||
@@ -276,7 +323,7 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
276 | return -EIO; | 323 | return -EIO; |
277 | } | 324 | } |
278 | 325 | ||
279 | int __init musb_platform_init(struct musb *musb) | 326 | int __init musb_platform_init(struct musb *musb, void *board_data) |
280 | { | 327 | { |
281 | 328 | ||
282 | /* | 329 | /* |
@@ -345,23 +392,10 @@ int __init musb_platform_init(struct musb *musb) | |||
345 | return 0; | 392 | return 0; |
346 | } | 393 | } |
347 | 394 | ||
348 | int musb_platform_suspend(struct musb *musb) | ||
349 | { | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | int musb_platform_resume(struct musb *musb) | ||
354 | { | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | |||
359 | int musb_platform_exit(struct musb *musb) | 395 | int musb_platform_exit(struct musb *musb) |
360 | { | 396 | { |
361 | 397 | ||
362 | bfin_vbus_power(musb, 0 /*off*/, 1); | ||
363 | gpio_free(musb->config->gpio_vrsel); | 398 | gpio_free(musb->config->gpio_vrsel); |
364 | musb_platform_suspend(musb); | ||
365 | 399 | ||
366 | return 0; | 400 | return 0; |
367 | } | 401 | } |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 29bce5c0fd10..57624361c1de 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -376,7 +376,7 @@ int musb_platform_set_mode(struct musb *musb, u8 mode) | |||
376 | return -EIO; | 376 | return -EIO; |
377 | } | 377 | } |
378 | 378 | ||
379 | int __init musb_platform_init(struct musb *musb) | 379 | int __init musb_platform_init(struct musb *musb, void *board_data) |
380 | { | 380 | { |
381 | void __iomem *tibase = musb->ctrl_base; | 381 | void __iomem *tibase = musb->ctrl_base; |
382 | u32 revision; | 382 | u32 revision; |
@@ -444,6 +444,8 @@ int __init musb_platform_init(struct musb *musb) | |||
444 | return 0; | 444 | return 0; |
445 | 445 | ||
446 | fail: | 446 | fail: |
447 | clk_disable(musb->clock); | ||
448 | |||
447 | usb_nop_xceiv_unregister(); | 449 | usb_nop_xceiv_unregister(); |
448 | return -ENODEV; | 450 | return -ENODEV; |
449 | } | 451 | } |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 0e8b8ab1d168..fad70bc83555 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -149,6 +149,87 @@ static inline struct musb *dev_to_musb(struct device *dev) | |||
149 | 149 | ||
150 | /*-------------------------------------------------------------------------*/ | 150 | /*-------------------------------------------------------------------------*/ |
151 | 151 | ||
152 | #ifndef CONFIG_BLACKFIN | ||
153 | static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset) | ||
154 | { | ||
155 | void __iomem *addr = otg->io_priv; | ||
156 | int i = 0; | ||
157 | u8 r; | ||
158 | u8 power; | ||
159 | |||
160 | /* Make sure the transceiver is not in low power mode */ | ||
161 | power = musb_readb(addr, MUSB_POWER); | ||
162 | power &= ~MUSB_POWER_SUSPENDM; | ||
163 | musb_writeb(addr, MUSB_POWER, power); | ||
164 | |||
165 | /* REVISIT: musbhdrc_ulpi_an.pdf recommends setting the | ||
166 | * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM. | ||
167 | */ | ||
168 | |||
169 | musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset); | ||
170 | musb_writeb(addr, MUSB_ULPI_REG_CONTROL, | ||
171 | MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR); | ||
172 | |||
173 | while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) | ||
174 | & MUSB_ULPI_REG_CMPLT)) { | ||
175 | i++; | ||
176 | if (i == 10000) { | ||
177 | DBG(3, "ULPI read timed out\n"); | ||
178 | return -ETIMEDOUT; | ||
179 | } | ||
180 | |||
181 | } | ||
182 | r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); | ||
183 | r &= ~MUSB_ULPI_REG_CMPLT; | ||
184 | musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); | ||
185 | |||
186 | return musb_readb(addr, MUSB_ULPI_REG_DATA); | ||
187 | } | ||
188 | |||
189 | static int musb_ulpi_write(struct otg_transceiver *otg, | ||
190 | u32 offset, u32 data) | ||
191 | { | ||
192 | void __iomem *addr = otg->io_priv; | ||
193 | int i = 0; | ||
194 | u8 r = 0; | ||
195 | u8 power; | ||
196 | |||
197 | /* Make sure the transceiver is not in low power mode */ | ||
198 | power = musb_readb(addr, MUSB_POWER); | ||
199 | power &= ~MUSB_POWER_SUSPENDM; | ||
200 | musb_writeb(addr, MUSB_POWER, power); | ||
201 | |||
202 | musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset); | ||
203 | musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data); | ||
204 | musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ); | ||
205 | |||
206 | while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) | ||
207 | & MUSB_ULPI_REG_CMPLT)) { | ||
208 | i++; | ||
209 | if (i == 10000) { | ||
210 | DBG(3, "ULPI write timed out\n"); | ||
211 | return -ETIMEDOUT; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); | ||
216 | r &= ~MUSB_ULPI_REG_CMPLT; | ||
217 | musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | #else | ||
222 | #define musb_ulpi_read(a, b) NULL | ||
223 | #define musb_ulpi_write(a, b, c) NULL | ||
224 | #endif | ||
225 | |||
226 | static struct otg_io_access_ops musb_ulpi_access = { | ||
227 | .read = musb_ulpi_read, | ||
228 | .write = musb_ulpi_write, | ||
229 | }; | ||
230 | |||
231 | /*-------------------------------------------------------------------------*/ | ||
232 | |||
152 | #if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN) | 233 | #if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN) |
153 | 234 | ||
154 | /* | 235 | /* |
@@ -353,8 +434,7 @@ void musb_hnp_stop(struct musb *musb) | |||
353 | * which cause occasional OPT A "Did not receive reset after connect" | 434 | * which cause occasional OPT A "Did not receive reset after connect" |
354 | * errors. | 435 | * errors. |
355 | */ | 436 | */ |
356 | musb->port1_status &= | 437 | musb->port1_status &= ~(USB_PORT_STAT_C_CONNECTION << 16); |
357 | ~(1 << USB_PORT_FEAT_C_CONNECTION); | ||
358 | } | 438 | } |
359 | 439 | ||
360 | #endif | 440 | #endif |
@@ -530,8 +610,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
530 | musb_writeb(mbase, MUSB_DEVCTL, devctl); | 610 | musb_writeb(mbase, MUSB_DEVCTL, devctl); |
531 | } else { | 611 | } else { |
532 | musb->port1_status |= | 612 | musb->port1_status |= |
533 | (1 << USB_PORT_FEAT_OVER_CURRENT) | 613 | USB_PORT_STAT_OVERCURRENT |
534 | | (1 << USB_PORT_FEAT_C_OVER_CURRENT); | 614 | | (USB_PORT_STAT_C_OVERCURRENT << 16); |
535 | } | 615 | } |
536 | break; | 616 | break; |
537 | default: | 617 | default: |
@@ -965,10 +1045,8 @@ static void musb_shutdown(struct platform_device *pdev) | |||
965 | spin_lock_irqsave(&musb->lock, flags); | 1045 | spin_lock_irqsave(&musb->lock, flags); |
966 | musb_platform_disable(musb); | 1046 | musb_platform_disable(musb); |
967 | musb_generic_disable(musb); | 1047 | musb_generic_disable(musb); |
968 | if (musb->clock) { | 1048 | if (musb->clock) |
969 | clk_put(musb->clock); | 1049 | clk_put(musb->clock); |
970 | musb->clock = NULL; | ||
971 | } | ||
972 | spin_unlock_irqrestore(&musb->lock, flags); | 1050 | spin_unlock_irqrestore(&musb->lock, flags); |
973 | 1051 | ||
974 | /* FIXME power down */ | 1052 | /* FIXME power down */ |
@@ -988,7 +1066,8 @@ static void musb_shutdown(struct platform_device *pdev) | |||
988 | * more than selecting one of a bunch of predefined configurations. | 1066 | * more than selecting one of a bunch of predefined configurations. |
989 | */ | 1067 | */ |
990 | #if defined(CONFIG_USB_TUSB6010) || \ | 1068 | #if defined(CONFIG_USB_TUSB6010) || \ |
991 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 1069 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ |
1070 | || defined(CONFIG_ARCH_OMAP4) | ||
992 | static ushort __initdata fifo_mode = 4; | 1071 | static ushort __initdata fifo_mode = 4; |
993 | #else | 1072 | #else |
994 | static ushort __initdata fifo_mode = 2; | 1073 | static ushort __initdata fifo_mode = 2; |
@@ -998,24 +1077,13 @@ static ushort __initdata fifo_mode = 2; | |||
998 | module_param(fifo_mode, ushort, 0); | 1077 | module_param(fifo_mode, ushort, 0); |
999 | MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration"); | 1078 | MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration"); |
1000 | 1079 | ||
1001 | |||
1002 | enum fifo_style { FIFO_RXTX, FIFO_TX, FIFO_RX } __attribute__ ((packed)); | ||
1003 | enum buf_mode { BUF_SINGLE, BUF_DOUBLE } __attribute__ ((packed)); | ||
1004 | |||
1005 | struct fifo_cfg { | ||
1006 | u8 hw_ep_num; | ||
1007 | enum fifo_style style; | ||
1008 | enum buf_mode mode; | ||
1009 | u16 maxpacket; | ||
1010 | }; | ||
1011 | |||
1012 | /* | 1080 | /* |
1013 | * tables defining fifo_mode values. define more if you like. | 1081 | * tables defining fifo_mode values. define more if you like. |
1014 | * for host side, make sure both halves of ep1 are set up. | 1082 | * for host side, make sure both halves of ep1 are set up. |
1015 | */ | 1083 | */ |
1016 | 1084 | ||
1017 | /* mode 0 - fits in 2KB */ | 1085 | /* mode 0 - fits in 2KB */ |
1018 | static struct fifo_cfg __initdata mode_0_cfg[] = { | 1086 | static struct musb_fifo_cfg __initdata mode_0_cfg[] = { |
1019 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | 1087 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, |
1020 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | 1088 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, |
1021 | { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, }, | 1089 | { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, }, |
@@ -1024,7 +1092,7 @@ static struct fifo_cfg __initdata mode_0_cfg[] = { | |||
1024 | }; | 1092 | }; |
1025 | 1093 | ||
1026 | /* mode 1 - fits in 4KB */ | 1094 | /* mode 1 - fits in 4KB */ |
1027 | static struct fifo_cfg __initdata mode_1_cfg[] = { | 1095 | static struct musb_fifo_cfg __initdata mode_1_cfg[] = { |
1028 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, | 1096 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, |
1029 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, | 1097 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, |
1030 | { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, }, | 1098 | { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, }, |
@@ -1033,7 +1101,7 @@ static struct fifo_cfg __initdata mode_1_cfg[] = { | |||
1033 | }; | 1101 | }; |
1034 | 1102 | ||
1035 | /* mode 2 - fits in 4KB */ | 1103 | /* mode 2 - fits in 4KB */ |
1036 | static struct fifo_cfg __initdata mode_2_cfg[] = { | 1104 | static struct musb_fifo_cfg __initdata mode_2_cfg[] = { |
1037 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | 1105 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, |
1038 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | 1106 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, |
1039 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, | 1107 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, |
@@ -1043,7 +1111,7 @@ static struct fifo_cfg __initdata mode_2_cfg[] = { | |||
1043 | }; | 1111 | }; |
1044 | 1112 | ||
1045 | /* mode 3 - fits in 4KB */ | 1113 | /* mode 3 - fits in 4KB */ |
1046 | static struct fifo_cfg __initdata mode_3_cfg[] = { | 1114 | static struct musb_fifo_cfg __initdata mode_3_cfg[] = { |
1047 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, | 1115 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, |
1048 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, | 1116 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, |
1049 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, | 1117 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, |
@@ -1053,7 +1121,7 @@ static struct fifo_cfg __initdata mode_3_cfg[] = { | |||
1053 | }; | 1121 | }; |
1054 | 1122 | ||
1055 | /* mode 4 - fits in 16KB */ | 1123 | /* mode 4 - fits in 16KB */ |
1056 | static struct fifo_cfg __initdata mode_4_cfg[] = { | 1124 | static struct musb_fifo_cfg __initdata mode_4_cfg[] = { |
1057 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | 1125 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, |
1058 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | 1126 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, |
1059 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, | 1127 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, |
@@ -1084,7 +1152,7 @@ static struct fifo_cfg __initdata mode_4_cfg[] = { | |||
1084 | }; | 1152 | }; |
1085 | 1153 | ||
1086 | /* mode 5 - fits in 8KB */ | 1154 | /* mode 5 - fits in 8KB */ |
1087 | static struct fifo_cfg __initdata mode_5_cfg[] = { | 1155 | static struct musb_fifo_cfg __initdata mode_5_cfg[] = { |
1088 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, | 1156 | { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, |
1089 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, | 1157 | { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, |
1090 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, | 1158 | { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, |
@@ -1122,7 +1190,7 @@ static struct fifo_cfg __initdata mode_5_cfg[] = { | |||
1122 | */ | 1190 | */ |
1123 | static int __init | 1191 | static int __init |
1124 | fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, | 1192 | fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, |
1125 | const struct fifo_cfg *cfg, u16 offset) | 1193 | const struct musb_fifo_cfg *cfg, u16 offset) |
1126 | { | 1194 | { |
1127 | void __iomem *mbase = musb->mregs; | 1195 | void __iomem *mbase = musb->mregs; |
1128 | int size = 0; | 1196 | int size = 0; |
@@ -1193,17 +1261,23 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, | |||
1193 | return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0)); | 1261 | return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0)); |
1194 | } | 1262 | } |
1195 | 1263 | ||
1196 | static struct fifo_cfg __initdata ep0_cfg = { | 1264 | static struct musb_fifo_cfg __initdata ep0_cfg = { |
1197 | .style = FIFO_RXTX, .maxpacket = 64, | 1265 | .style = FIFO_RXTX, .maxpacket = 64, |
1198 | }; | 1266 | }; |
1199 | 1267 | ||
1200 | static int __init ep_config_from_table(struct musb *musb) | 1268 | static int __init ep_config_from_table(struct musb *musb) |
1201 | { | 1269 | { |
1202 | const struct fifo_cfg *cfg; | 1270 | const struct musb_fifo_cfg *cfg; |
1203 | unsigned i, n; | 1271 | unsigned i, n; |
1204 | int offset; | 1272 | int offset; |
1205 | struct musb_hw_ep *hw_ep = musb->endpoints; | 1273 | struct musb_hw_ep *hw_ep = musb->endpoints; |
1206 | 1274 | ||
1275 | if (musb->config->fifo_cfg) { | ||
1276 | cfg = musb->config->fifo_cfg; | ||
1277 | n = musb->config->fifo_cfg_size; | ||
1278 | goto done; | ||
1279 | } | ||
1280 | |||
1207 | switch (fifo_mode) { | 1281 | switch (fifo_mode) { |
1208 | default: | 1282 | default: |
1209 | fifo_mode = 0; | 1283 | fifo_mode = 0; |
@@ -1238,6 +1312,7 @@ static int __init ep_config_from_table(struct musb *musb) | |||
1238 | musb_driver_name, fifo_mode); | 1312 | musb_driver_name, fifo_mode); |
1239 | 1313 | ||
1240 | 1314 | ||
1315 | done: | ||
1241 | offset = fifo_setup(musb, hw_ep, &ep0_cfg, 0); | 1316 | offset = fifo_setup(musb, hw_ep, &ep0_cfg, 0); |
1242 | /* assert(offset > 0) */ | 1317 | /* assert(offset > 0) */ |
1243 | 1318 | ||
@@ -1463,7 +1538,8 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
1463 | 1538 | ||
1464 | /*-------------------------------------------------------------------------*/ | 1539 | /*-------------------------------------------------------------------------*/ |
1465 | 1540 | ||
1466 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) | 1541 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || \ |
1542 | defined(CONFIG_ARCH_OMAP4) | ||
1467 | 1543 | ||
1468 | static irqreturn_t generic_interrupt(int irq, void *__hci) | 1544 | static irqreturn_t generic_interrupt(int irq, void *__hci) |
1469 | { | 1545 | { |
@@ -1853,15 +1929,6 @@ static void musb_free(struct musb *musb) | |||
1853 | put_device(musb->xceiv->dev); | 1929 | put_device(musb->xceiv->dev); |
1854 | #endif | 1930 | #endif |
1855 | 1931 | ||
1856 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
1857 | musb_platform_exit(musb); | ||
1858 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
1859 | |||
1860 | if (musb->clock) { | ||
1861 | clk_disable(musb->clock); | ||
1862 | clk_put(musb->clock); | ||
1863 | } | ||
1864 | |||
1865 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1932 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
1866 | usb_put_hcd(musb_to_hcd(musb)); | 1933 | usb_put_hcd(musb_to_hcd(musb)); |
1867 | #else | 1934 | #else |
@@ -1889,8 +1956,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
1889 | */ | 1956 | */ |
1890 | if (!plat) { | 1957 | if (!plat) { |
1891 | dev_dbg(dev, "no platform_data?\n"); | 1958 | dev_dbg(dev, "no platform_data?\n"); |
1892 | return -ENODEV; | 1959 | status = -ENODEV; |
1960 | goto fail0; | ||
1893 | } | 1961 | } |
1962 | |||
1894 | switch (plat->mode) { | 1963 | switch (plat->mode) { |
1895 | case MUSB_HOST: | 1964 | case MUSB_HOST: |
1896 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 1965 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
@@ -1912,13 +1981,16 @@ bad_config: | |||
1912 | #endif | 1981 | #endif |
1913 | default: | 1982 | default: |
1914 | dev_err(dev, "incompatible Kconfig role setting\n"); | 1983 | dev_err(dev, "incompatible Kconfig role setting\n"); |
1915 | return -EINVAL; | 1984 | status = -EINVAL; |
1985 | goto fail0; | ||
1916 | } | 1986 | } |
1917 | 1987 | ||
1918 | /* allocate */ | 1988 | /* allocate */ |
1919 | musb = allocate_instance(dev, plat->config, ctrl); | 1989 | musb = allocate_instance(dev, plat->config, ctrl); |
1920 | if (!musb) | 1990 | if (!musb) { |
1921 | return -ENOMEM; | 1991 | status = -ENOMEM; |
1992 | goto fail0; | ||
1993 | } | ||
1922 | 1994 | ||
1923 | spin_lock_init(&musb->lock); | 1995 | spin_lock_init(&musb->lock); |
1924 | musb->board_mode = plat->mode; | 1996 | musb->board_mode = plat->mode; |
@@ -1936,7 +2008,7 @@ bad_config: | |||
1936 | if (IS_ERR(musb->clock)) { | 2008 | if (IS_ERR(musb->clock)) { |
1937 | status = PTR_ERR(musb->clock); | 2009 | status = PTR_ERR(musb->clock); |
1938 | musb->clock = NULL; | 2010 | musb->clock = NULL; |
1939 | goto fail; | 2011 | goto fail1; |
1940 | } | 2012 | } |
1941 | } | 2013 | } |
1942 | 2014 | ||
@@ -1954,13 +2026,18 @@ bad_config: | |||
1954 | * isp1504, non-OTG, etc) mostly hooking up through ULPI. | 2026 | * isp1504, non-OTG, etc) mostly hooking up through ULPI. |
1955 | */ | 2027 | */ |
1956 | musb->isr = generic_interrupt; | 2028 | musb->isr = generic_interrupt; |
1957 | status = musb_platform_init(musb); | 2029 | status = musb_platform_init(musb, plat->board_data); |
1958 | |||
1959 | if (status < 0) | 2030 | if (status < 0) |
1960 | goto fail; | 2031 | goto fail2; |
2032 | |||
1961 | if (!musb->isr) { | 2033 | if (!musb->isr) { |
1962 | status = -ENODEV; | 2034 | status = -ENODEV; |
1963 | goto fail2; | 2035 | goto fail3; |
2036 | } | ||
2037 | |||
2038 | if (!musb->xceiv->io_ops) { | ||
2039 | musb->xceiv->io_priv = musb->mregs; | ||
2040 | musb->xceiv->io_ops = &musb_ulpi_access; | ||
1964 | } | 2041 | } |
1965 | 2042 | ||
1966 | #ifndef CONFIG_MUSB_PIO_ONLY | 2043 | #ifndef CONFIG_MUSB_PIO_ONLY |
@@ -1986,7 +2063,7 @@ bad_config: | |||
1986 | ? MUSB_CONTROLLER_MHDRC | 2063 | ? MUSB_CONTROLLER_MHDRC |
1987 | : MUSB_CONTROLLER_HDRC, musb); | 2064 | : MUSB_CONTROLLER_HDRC, musb); |
1988 | if (status < 0) | 2065 | if (status < 0) |
1989 | goto fail2; | 2066 | goto fail3; |
1990 | 2067 | ||
1991 | #ifdef CONFIG_USB_MUSB_OTG | 2068 | #ifdef CONFIG_USB_MUSB_OTG |
1992 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); | 2069 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); |
@@ -1999,7 +2076,7 @@ bad_config: | |||
1999 | if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { | 2076 | if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { |
2000 | dev_err(dev, "request_irq %d failed!\n", nIrq); | 2077 | dev_err(dev, "request_irq %d failed!\n", nIrq); |
2001 | status = -ENODEV; | 2078 | status = -ENODEV; |
2002 | goto fail2; | 2079 | goto fail3; |
2003 | } | 2080 | } |
2004 | musb->nIrq = nIrq; | 2081 | musb->nIrq = nIrq; |
2005 | /* FIXME this handles wakeup irqs wrong */ | 2082 | /* FIXME this handles wakeup irqs wrong */ |
@@ -2039,8 +2116,6 @@ bad_config: | |||
2039 | musb->xceiv->state = OTG_STATE_A_IDLE; | 2116 | musb->xceiv->state = OTG_STATE_A_IDLE; |
2040 | 2117 | ||
2041 | status = usb_add_hcd(musb_to_hcd(musb), -1, 0); | 2118 | status = usb_add_hcd(musb_to_hcd(musb), -1, 0); |
2042 | if (status) | ||
2043 | goto fail; | ||
2044 | 2119 | ||
2045 | DBG(1, "%s mode, status %d, devctl %02x %c\n", | 2120 | DBG(1, "%s mode, status %d, devctl %02x %c\n", |
2046 | "HOST", status, | 2121 | "HOST", status, |
@@ -2055,8 +2130,6 @@ bad_config: | |||
2055 | musb->xceiv->state = OTG_STATE_B_IDLE; | 2130 | musb->xceiv->state = OTG_STATE_B_IDLE; |
2056 | 2131 | ||
2057 | status = musb_gadget_setup(musb); | 2132 | status = musb_gadget_setup(musb); |
2058 | if (status) | ||
2059 | goto fail; | ||
2060 | 2133 | ||
2061 | DBG(1, "%s mode, status %d, dev%02x\n", | 2134 | DBG(1, "%s mode, status %d, dev%02x\n", |
2062 | is_otg_enabled(musb) ? "OTG" : "PERIPHERAL", | 2135 | is_otg_enabled(musb) ? "OTG" : "PERIPHERAL", |
@@ -2064,12 +2137,18 @@ bad_config: | |||
2064 | musb_readb(musb->mregs, MUSB_DEVCTL)); | 2137 | musb_readb(musb->mregs, MUSB_DEVCTL)); |
2065 | 2138 | ||
2066 | } | 2139 | } |
2140 | if (status < 0) | ||
2141 | goto fail3; | ||
2142 | |||
2143 | status = musb_init_debugfs(musb); | ||
2144 | if (status < 0) | ||
2145 | goto fail4; | ||
2067 | 2146 | ||
2068 | #ifdef CONFIG_SYSFS | 2147 | #ifdef CONFIG_SYSFS |
2069 | status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); | 2148 | status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); |
2070 | #endif | ||
2071 | if (status) | 2149 | if (status) |
2072 | goto fail2; | 2150 | goto fail5; |
2151 | #endif | ||
2073 | 2152 | ||
2074 | dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", | 2153 | dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", |
2075 | ({char *s; | 2154 | ({char *s; |
@@ -2085,17 +2164,32 @@ bad_config: | |||
2085 | 2164 | ||
2086 | return 0; | 2165 | return 0; |
2087 | 2166 | ||
2088 | fail2: | 2167 | fail5: |
2168 | musb_exit_debugfs(musb); | ||
2169 | |||
2170 | fail4: | ||
2171 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) | ||
2172 | usb_remove_hcd(musb_to_hcd(musb)); | ||
2173 | else | ||
2174 | musb_gadget_cleanup(musb); | ||
2175 | |||
2176 | fail3: | ||
2177 | if (musb->irq_wake) | ||
2178 | device_init_wakeup(dev, 0); | ||
2089 | musb_platform_exit(musb); | 2179 | musb_platform_exit(musb); |
2090 | fail: | ||
2091 | dev_err(musb->controller, | ||
2092 | "musb_init_controller failed with status %d\n", status); | ||
2093 | 2180 | ||
2181 | fail2: | ||
2094 | if (musb->clock) | 2182 | if (musb->clock) |
2095 | clk_put(musb->clock); | 2183 | clk_put(musb->clock); |
2096 | device_init_wakeup(dev, 0); | 2184 | |
2185 | fail1: | ||
2186 | dev_err(musb->controller, | ||
2187 | "musb_init_controller failed with status %d\n", status); | ||
2188 | |||
2097 | musb_free(musb); | 2189 | musb_free(musb); |
2098 | 2190 | ||
2191 | fail0: | ||
2192 | |||
2099 | return status; | 2193 | return status; |
2100 | 2194 | ||
2101 | } | 2195 | } |
@@ -2132,7 +2226,6 @@ static int __init musb_probe(struct platform_device *pdev) | |||
2132 | /* clobbered by use_dma=n */ | 2226 | /* clobbered by use_dma=n */ |
2133 | orig_dma_mask = dev->dma_mask; | 2227 | orig_dma_mask = dev->dma_mask; |
2134 | #endif | 2228 | #endif |
2135 | |||
2136 | status = musb_init_controller(dev, irq, base); | 2229 | status = musb_init_controller(dev, irq, base); |
2137 | if (status < 0) | 2230 | if (status < 0) |
2138 | iounmap(base); | 2231 | iounmap(base); |
@@ -2150,11 +2243,16 @@ static int __exit musb_remove(struct platform_device *pdev) | |||
2150 | * - Peripheral mode: peripheral is deactivated (or never-activated) | 2243 | * - Peripheral mode: peripheral is deactivated (or never-activated) |
2151 | * - OTG mode: both roles are deactivated (or never-activated) | 2244 | * - OTG mode: both roles are deactivated (or never-activated) |
2152 | */ | 2245 | */ |
2246 | musb_exit_debugfs(musb); | ||
2153 | musb_shutdown(pdev); | 2247 | musb_shutdown(pdev); |
2154 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 2248 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
2155 | if (musb->board_mode == MUSB_HOST) | 2249 | if (musb->board_mode == MUSB_HOST) |
2156 | usb_remove_hcd(musb_to_hcd(musb)); | 2250 | usb_remove_hcd(musb_to_hcd(musb)); |
2157 | #endif | 2251 | #endif |
2252 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
2253 | musb_platform_exit(musb); | ||
2254 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
2255 | |||
2158 | musb_free(musb); | 2256 | musb_free(musb); |
2159 | iounmap(ctrl_base); | 2257 | iounmap(ctrl_base); |
2160 | device_init_wakeup(&pdev->dev, 0); | 2258 | device_init_wakeup(&pdev->dev, 0); |
@@ -2176,6 +2274,7 @@ void musb_save_context(struct musb *musb) | |||
2176 | if (is_host_enabled(musb)) { | 2274 | if (is_host_enabled(musb)) { |
2177 | musb_context.frame = musb_readw(musb_base, MUSB_FRAME); | 2275 | musb_context.frame = musb_readw(musb_base, MUSB_FRAME); |
2178 | musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); | 2276 | musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); |
2277 | musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs); | ||
2179 | } | 2278 | } |
2180 | musb_context.power = musb_readb(musb_base, MUSB_POWER); | 2279 | musb_context.power = musb_readb(musb_base, MUSB_POWER); |
2181 | musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); | 2280 | musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); |
@@ -2247,6 +2346,7 @@ void musb_restore_context(struct musb *musb) | |||
2247 | if (is_host_enabled(musb)) { | 2346 | if (is_host_enabled(musb)) { |
2248 | musb_writew(musb_base, MUSB_FRAME, musb_context.frame); | 2347 | musb_writew(musb_base, MUSB_FRAME, musb_context.frame); |
2249 | musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode); | 2348 | musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode); |
2349 | musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl); | ||
2250 | } | 2350 | } |
2251 | musb_writeb(musb_base, MUSB_POWER, musb_context.power); | 2351 | musb_writeb(musb_base, MUSB_POWER, musb_context.power); |
2252 | musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); | 2352 | musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index cd9f4a9a06c6..b22d02dea7d3 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -69,7 +69,7 @@ struct musb_ep; | |||
69 | #include "musb_regs.h" | 69 | #include "musb_regs.h" |
70 | 70 | ||
71 | #include "musb_gadget.h" | 71 | #include "musb_gadget.h" |
72 | #include "../core/hcd.h" | 72 | #include <linux/usb/hcd.h> |
73 | #include "musb_host.h" | 73 | #include "musb_host.h" |
74 | 74 | ||
75 | 75 | ||
@@ -213,7 +213,8 @@ enum musb_g_ep0_state { | |||
213 | */ | 213 | */ |
214 | 214 | ||
215 | #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ | 215 | #if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ |
216 | || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_BLACKFIN) | 216 | || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_BLACKFIN) \ |
217 | || defined(CONFIG_ARCH_OMAP4) | ||
217 | /* REVISIT indexed access seemed to | 218 | /* REVISIT indexed access seemed to |
218 | * misbehave (on DaVinci) for at least peripheral IN ... | 219 | * misbehave (on DaVinci) for at least peripheral IN ... |
219 | */ | 220 | */ |
@@ -478,7 +479,7 @@ struct musb_context_registers { | |||
478 | u16 frame; | 479 | u16 frame; |
479 | u8 index, testmode; | 480 | u8 index, testmode; |
480 | 481 | ||
481 | u8 devctl, misc; | 482 | u8 devctl, busctl, misc; |
482 | 483 | ||
483 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; | 484 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; |
484 | }; | 485 | }; |
@@ -596,7 +597,8 @@ extern void musb_hnp_stop(struct musb *musb); | |||
596 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); | 597 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); |
597 | 598 | ||
598 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ | 599 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ |
599 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 600 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ |
601 | defined(CONFIG_ARCH_OMAP4) | ||
600 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); | 602 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); |
601 | #else | 603 | #else |
602 | #define musb_platform_try_idle(x, y) do {} while (0) | 604 | #define musb_platform_try_idle(x, y) do {} while (0) |
@@ -608,7 +610,7 @@ extern int musb_platform_get_vbus_status(struct musb *musb); | |||
608 | #define musb_platform_get_vbus_status(x) 0 | 610 | #define musb_platform_get_vbus_status(x) 0 |
609 | #endif | 611 | #endif |
610 | 612 | ||
611 | extern int __init musb_platform_init(struct musb *musb); | 613 | extern int __init musb_platform_init(struct musb *musb, void *board_data); |
612 | extern int musb_platform_exit(struct musb *musb); | 614 | extern int musb_platform_exit(struct musb *musb); |
613 | 615 | ||
614 | #endif /* __MUSB_CORE_H__ */ | 616 | #endif /* __MUSB_CORE_H__ */ |
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h index 9fc1db44c72c..d73afdbde3ee 100644 --- a/drivers/usb/musb/musb_debug.h +++ b/drivers/usb/musb/musb_debug.h | |||
@@ -59,4 +59,17 @@ static inline int _dbg_level(unsigned l) | |||
59 | 59 | ||
60 | extern const char *otg_state_string(struct musb *); | 60 | extern const char *otg_state_string(struct musb *); |
61 | 61 | ||
62 | #ifdef CONFIG_DEBUG_FS | ||
63 | extern int musb_init_debugfs(struct musb *musb); | ||
64 | extern void musb_exit_debugfs(struct musb *musb); | ||
65 | #else | ||
66 | static inline int musb_init_debugfs(struct musb *musb) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | static inline void musb_exit_debugfs(struct musb *musb) | ||
71 | { | ||
72 | } | ||
73 | #endif | ||
74 | |||
62 | #endif /* __MUSB_LINUX_DEBUG_H__ */ | 75 | #endif /* __MUSB_LINUX_DEBUG_H__ */ |
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c new file mode 100644 index 000000000000..bba76af0c0c6 --- /dev/null +++ b/drivers/usb/musb/musb_debugfs.c | |||
@@ -0,0 +1,294 @@ | |||
1 | /* | ||
2 | * MUSB OTG driver debugfs support | ||
3 | * | ||
4 | * Copyright 2010 Nokia Corporation | ||
5 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> | ||
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 | #include <linux/module.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/sched.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/list.h> | ||
39 | #include <linux/kobject.h> | ||
40 | #include <linux/platform_device.h> | ||
41 | #include <linux/io.h> | ||
42 | #include <linux/debugfs.h> | ||
43 | #include <linux/seq_file.h> | ||
44 | |||
45 | #ifdef CONFIG_ARM | ||
46 | #include <mach/hardware.h> | ||
47 | #include <mach/memory.h> | ||
48 | #include <asm/mach-types.h> | ||
49 | #endif | ||
50 | |||
51 | #include <asm/uaccess.h> | ||
52 | |||
53 | #include "musb_core.h" | ||
54 | #include "musb_debug.h" | ||
55 | |||
56 | #ifdef CONFIG_ARCH_DAVINCI | ||
57 | #include "davinci.h" | ||
58 | #endif | ||
59 | |||
60 | struct musb_register_map { | ||
61 | char *name; | ||
62 | unsigned offset; | ||
63 | unsigned size; | ||
64 | }; | ||
65 | |||
66 | static const struct musb_register_map musb_regmap[] = { | ||
67 | { "FAddr", 0x00, 8 }, | ||
68 | { "Power", 0x01, 8 }, | ||
69 | { "Frame", 0x0c, 16 }, | ||
70 | { "Index", 0x0e, 8 }, | ||
71 | { "Testmode", 0x0f, 8 }, | ||
72 | { "TxMaxPp", 0x10, 16 }, | ||
73 | { "TxCSRp", 0x12, 16 }, | ||
74 | { "RxMaxPp", 0x14, 16 }, | ||
75 | { "RxCSR", 0x16, 16 }, | ||
76 | { "RxCount", 0x18, 16 }, | ||
77 | { "ConfigData", 0x1f, 8 }, | ||
78 | { "DevCtl", 0x60, 8 }, | ||
79 | { "MISC", 0x61, 8 }, | ||
80 | { "TxFIFOsz", 0x62, 8 }, | ||
81 | { "RxFIFOsz", 0x63, 8 }, | ||
82 | { "TxFIFOadd", 0x64, 16 }, | ||
83 | { "RxFIFOadd", 0x66, 16 }, | ||
84 | { "VControl", 0x68, 32 }, | ||
85 | { "HWVers", 0x6C, 16 }, | ||
86 | { "EPInfo", 0x78, 8 }, | ||
87 | { "RAMInfo", 0x79, 8 }, | ||
88 | { "LinkInfo", 0x7A, 8 }, | ||
89 | { "VPLen", 0x7B, 8 }, | ||
90 | { "HS_EOF1", 0x7C, 8 }, | ||
91 | { "FS_EOF1", 0x7D, 8 }, | ||
92 | { "LS_EOF1", 0x7E, 8 }, | ||
93 | { "SOFT_RST", 0x7F, 8 }, | ||
94 | { "DMA_CNTLch0", 0x204, 16 }, | ||
95 | { "DMA_ADDRch0", 0x208, 16 }, | ||
96 | { "DMA_COUNTch0", 0x20C, 16 }, | ||
97 | { "DMA_CNTLch1", 0x214, 16 }, | ||
98 | { "DMA_ADDRch1", 0x218, 16 }, | ||
99 | { "DMA_COUNTch1", 0x21C, 16 }, | ||
100 | { "DMA_CNTLch2", 0x224, 16 }, | ||
101 | { "DMA_ADDRch2", 0x228, 16 }, | ||
102 | { "DMA_COUNTch2", 0x22C, 16 }, | ||
103 | { "DMA_CNTLch3", 0x234, 16 }, | ||
104 | { "DMA_ADDRch3", 0x238, 16 }, | ||
105 | { "DMA_COUNTch3", 0x23C, 16 }, | ||
106 | { "DMA_CNTLch4", 0x244, 16 }, | ||
107 | { "DMA_ADDRch4", 0x248, 16 }, | ||
108 | { "DMA_COUNTch4", 0x24C, 16 }, | ||
109 | { "DMA_CNTLch5", 0x254, 16 }, | ||
110 | { "DMA_ADDRch5", 0x258, 16 }, | ||
111 | { "DMA_COUNTch5", 0x25C, 16 }, | ||
112 | { "DMA_CNTLch6", 0x264, 16 }, | ||
113 | { "DMA_ADDRch6", 0x268, 16 }, | ||
114 | { "DMA_COUNTch6", 0x26C, 16 }, | ||
115 | { "DMA_CNTLch7", 0x274, 16 }, | ||
116 | { "DMA_ADDRch7", 0x278, 16 }, | ||
117 | { "DMA_COUNTch7", 0x27C, 16 }, | ||
118 | { } /* Terminating Entry */ | ||
119 | }; | ||
120 | |||
121 | static struct dentry *musb_debugfs_root; | ||
122 | |||
123 | static int musb_regdump_show(struct seq_file *s, void *unused) | ||
124 | { | ||
125 | struct musb *musb = s->private; | ||
126 | unsigned i; | ||
127 | |||
128 | seq_printf(s, "MUSB (M)HDRC Register Dump\n"); | ||
129 | |||
130 | for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) { | ||
131 | switch (musb_regmap[i].size) { | ||
132 | case 8: | ||
133 | seq_printf(s, "%-12s: %02x\n", musb_regmap[i].name, | ||
134 | musb_readb(musb->mregs, musb_regmap[i].offset)); | ||
135 | break; | ||
136 | case 16: | ||
137 | seq_printf(s, "%-12s: %04x\n", musb_regmap[i].name, | ||
138 | musb_readw(musb->mregs, musb_regmap[i].offset)); | ||
139 | break; | ||
140 | case 32: | ||
141 | seq_printf(s, "%-12s: %08x\n", musb_regmap[i].name, | ||
142 | musb_readl(musb->mregs, musb_regmap[i].offset)); | ||
143 | break; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int musb_regdump_open(struct inode *inode, struct file *file) | ||
151 | { | ||
152 | return single_open(file, musb_regdump_show, inode->i_private); | ||
153 | } | ||
154 | |||
155 | static int musb_test_mode_show(struct seq_file *s, void *unused) | ||
156 | { | ||
157 | struct musb *musb = s->private; | ||
158 | unsigned test; | ||
159 | |||
160 | test = musb_readb(musb->mregs, MUSB_TESTMODE); | ||
161 | |||
162 | if (test & MUSB_TEST_FORCE_HOST) | ||
163 | seq_printf(s, "force host\n"); | ||
164 | |||
165 | if (test & MUSB_TEST_FIFO_ACCESS) | ||
166 | seq_printf(s, "fifo access\n"); | ||
167 | |||
168 | if (test & MUSB_TEST_FORCE_FS) | ||
169 | seq_printf(s, "force full-speed\n"); | ||
170 | |||
171 | if (test & MUSB_TEST_FORCE_HS) | ||
172 | seq_printf(s, "force high-speed\n"); | ||
173 | |||
174 | if (test & MUSB_TEST_PACKET) | ||
175 | seq_printf(s, "test packet\n"); | ||
176 | |||
177 | if (test & MUSB_TEST_K) | ||
178 | seq_printf(s, "test K\n"); | ||
179 | |||
180 | if (test & MUSB_TEST_J) | ||
181 | seq_printf(s, "test J\n"); | ||
182 | |||
183 | if (test & MUSB_TEST_SE0_NAK) | ||
184 | seq_printf(s, "test SE0 NAK\n"); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static const struct file_operations musb_regdump_fops = { | ||
190 | .open = musb_regdump_open, | ||
191 | .read = seq_read, | ||
192 | .llseek = seq_lseek, | ||
193 | .release = single_release, | ||
194 | }; | ||
195 | |||
196 | static int musb_test_mode_open(struct inode *inode, struct file *file) | ||
197 | { | ||
198 | file->private_data = inode->i_private; | ||
199 | |||
200 | return single_open(file, musb_test_mode_show, inode->i_private); | ||
201 | } | ||
202 | |||
203 | static ssize_t musb_test_mode_write(struct file *file, | ||
204 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
205 | { | ||
206 | struct musb *musb = file->private_data; | ||
207 | u8 test = 0; | ||
208 | char buf[18]; | ||
209 | |||
210 | memset(buf, 0x00, sizeof(buf)); | ||
211 | |||
212 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
213 | return -EFAULT; | ||
214 | |||
215 | if (!strncmp(buf, "force host", 9)) | ||
216 | test = MUSB_TEST_FORCE_HOST; | ||
217 | |||
218 | if (!strncmp(buf, "fifo access", 11)) | ||
219 | test = MUSB_TEST_FIFO_ACCESS; | ||
220 | |||
221 | if (!strncmp(buf, "force full-speed", 15)) | ||
222 | test = MUSB_TEST_FORCE_FS; | ||
223 | |||
224 | if (!strncmp(buf, "force high-speed", 15)) | ||
225 | test = MUSB_TEST_FORCE_HS; | ||
226 | |||
227 | if (!strncmp(buf, "test packet", 10)) { | ||
228 | test = MUSB_TEST_PACKET; | ||
229 | musb_load_testpacket(musb); | ||
230 | } | ||
231 | |||
232 | if (!strncmp(buf, "test K", 6)) | ||
233 | test = MUSB_TEST_K; | ||
234 | |||
235 | if (!strncmp(buf, "test J", 6)) | ||
236 | test = MUSB_TEST_J; | ||
237 | |||
238 | if (!strncmp(buf, "test SE0 NAK", 12)) | ||
239 | test = MUSB_TEST_SE0_NAK; | ||
240 | |||
241 | musb_writeb(musb->mregs, MUSB_TESTMODE, test); | ||
242 | |||
243 | return count; | ||
244 | } | ||
245 | |||
246 | static const struct file_operations musb_test_mode_fops = { | ||
247 | .open = musb_test_mode_open, | ||
248 | .write = musb_test_mode_write, | ||
249 | .read = seq_read, | ||
250 | .llseek = seq_lseek, | ||
251 | .release = single_release, | ||
252 | }; | ||
253 | |||
254 | int __init musb_init_debugfs(struct musb *musb) | ||
255 | { | ||
256 | struct dentry *root; | ||
257 | struct dentry *file; | ||
258 | int ret; | ||
259 | |||
260 | root = debugfs_create_dir("musb", NULL); | ||
261 | if (IS_ERR(root)) { | ||
262 | ret = PTR_ERR(root); | ||
263 | goto err0; | ||
264 | } | ||
265 | |||
266 | file = debugfs_create_file("regdump", S_IRUGO, root, musb, | ||
267 | &musb_regdump_fops); | ||
268 | if (IS_ERR(file)) { | ||
269 | ret = PTR_ERR(file); | ||
270 | goto err1; | ||
271 | } | ||
272 | |||
273 | file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, | ||
274 | root, musb, &musb_test_mode_fops); | ||
275 | if (IS_ERR(file)) { | ||
276 | ret = PTR_ERR(file); | ||
277 | goto err1; | ||
278 | } | ||
279 | |||
280 | musb_debugfs_root = root; | ||
281 | |||
282 | return 0; | ||
283 | |||
284 | err1: | ||
285 | debugfs_remove_recursive(root); | ||
286 | |||
287 | err0: | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | void /* __init_or_exit */ musb_exit_debugfs(struct musb *musb) | ||
292 | { | ||
293 | debugfs_remove_recursive(musb_debugfs_root); | ||
294 | } | ||
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index 53d06451f820..21b9788d0243 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c | |||
@@ -351,6 +351,31 @@ __acquires(musb->lock) | |||
351 | musb->test_mode_nr = | 351 | musb->test_mode_nr = |
352 | MUSB_TEST_PACKET; | 352 | MUSB_TEST_PACKET; |
353 | break; | 353 | break; |
354 | |||
355 | case 0xc0: | ||
356 | /* TEST_FORCE_HS */ | ||
357 | pr_debug("TEST_FORCE_HS\n"); | ||
358 | musb->test_mode_nr = | ||
359 | MUSB_TEST_FORCE_HS; | ||
360 | break; | ||
361 | case 0xc1: | ||
362 | /* TEST_FORCE_FS */ | ||
363 | pr_debug("TEST_FORCE_FS\n"); | ||
364 | musb->test_mode_nr = | ||
365 | MUSB_TEST_FORCE_FS; | ||
366 | break; | ||
367 | case 0xc2: | ||
368 | /* TEST_FIFO_ACCESS */ | ||
369 | pr_debug("TEST_FIFO_ACCESS\n"); | ||
370 | musb->test_mode_nr = | ||
371 | MUSB_TEST_FIFO_ACCESS; | ||
372 | break; | ||
373 | case 0xc3: | ||
374 | /* TEST_FORCE_HOST */ | ||
375 | pr_debug("TEST_FORCE_HOST\n"); | ||
376 | musb->test_mode_nr = | ||
377 | MUSB_TEST_FORCE_HOST; | ||
378 | break; | ||
354 | default: | 379 | default: |
355 | goto stall; | 380 | goto stall; |
356 | } | 381 | } |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index dec896e888db..877d20b1dff9 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -2042,6 +2042,7 @@ static int musb_urb_enqueue( | |||
2042 | * odd, rare, error prone, but legal. | 2042 | * odd, rare, error prone, but legal. |
2043 | */ | 2043 | */ |
2044 | kfree(qh); | 2044 | kfree(qh); |
2045 | qh = NULL; | ||
2045 | ret = 0; | 2046 | ret = 0; |
2046 | } else | 2047 | } else |
2047 | ret = musb_schedule(musb, qh, | 2048 | ret = musb_schedule(musb, qh, |
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index fa55aacc385d..244267527a60 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
@@ -75,6 +75,10 @@ | |||
75 | /* MUSB ULPI VBUSCONTROL */ | 75 | /* MUSB ULPI VBUSCONTROL */ |
76 | #define MUSB_ULPI_USE_EXTVBUS 0x01 | 76 | #define MUSB_ULPI_USE_EXTVBUS 0x01 |
77 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 | 77 | #define MUSB_ULPI_USE_EXTVBUSIND 0x02 |
78 | /* ULPI_REG_CONTROL */ | ||
79 | #define MUSB_ULPI_REG_REQ (1 << 0) | ||
80 | #define MUSB_ULPI_REG_CMPLT (1 << 1) | ||
81 | #define MUSB_ULPI_RDN_WR (1 << 2) | ||
78 | 82 | ||
79 | /* TESTMODE */ | 83 | /* TESTMODE */ |
80 | #define MUSB_TEST_FORCE_HOST 0x80 | 84 | #define MUSB_TEST_FORCE_HOST 0x80 |
@@ -251,6 +255,12 @@ | |||
251 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ | 255 | /* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ |
252 | #define MUSB_HWVERS 0x6C /* 8 bit */ | 256 | #define MUSB_HWVERS 0x6C /* 8 bit */ |
253 | #define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */ | 257 | #define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */ |
258 | #define MUSB_ULPI_INT_MASK 0x72 /* 8 bit */ | ||
259 | #define MUSB_ULPI_INT_SRC 0x73 /* 8 bit */ | ||
260 | #define MUSB_ULPI_REG_DATA 0x74 /* 8 bit */ | ||
261 | #define MUSB_ULPI_REG_ADDR 0x75 /* 8 bit */ | ||
262 | #define MUSB_ULPI_REG_CONTROL 0x76 /* 8 bit */ | ||
263 | #define MUSB_ULPI_RAW_DATA 0x77 /* 8 bit */ | ||
254 | 264 | ||
255 | #define MUSB_EPINFO 0x78 /* 8 bit */ | 265 | #define MUSB_EPINFO 0x78 /* 8 bit */ |
256 | #define MUSB_RAMINFO 0x79 /* 8 bit */ | 266 | #define MUSB_RAMINFO 0x79 /* 8 bit */ |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 7775e1c0a215..92e85e027cfb 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -183,8 +183,8 @@ static void musb_port_reset(struct musb *musb, bool do_reset) | |||
183 | 183 | ||
184 | void musb_root_disconnect(struct musb *musb) | 184 | void musb_root_disconnect(struct musb *musb) |
185 | { | 185 | { |
186 | musb->port1_status = (1 << USB_PORT_FEAT_POWER) | 186 | musb->port1_status = USB_PORT_STAT_POWER |
187 | | (1 << USB_PORT_FEAT_C_CONNECTION); | 187 | | (USB_PORT_STAT_C_CONNECTION << 16); |
188 | 188 | ||
189 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); | 189 | usb_hcd_poll_rh_status(musb_to_hcd(musb)); |
190 | musb->is_active = 0; | 190 | musb->is_active = 0; |
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index 613f95a058f7..f763d62f151c 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h | |||
@@ -102,26 +102,16 @@ static inline void musb_write_hsdma_addr(void __iomem *mbase, | |||
102 | 102 | ||
103 | static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel) | 103 | static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel) |
104 | { | 104 | { |
105 | u32 count = musb_readw(mbase, | 105 | return musb_readl(mbase, |
106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH)); | 106 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH)); |
107 | |||
108 | count = count << 16; | ||
109 | |||
110 | count |= musb_readw(mbase, | ||
111 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW)); | ||
112 | |||
113 | return count; | ||
114 | } | 107 | } |
115 | 108 | ||
116 | static inline void musb_write_hsdma_count(void __iomem *mbase, | 109 | static inline void musb_write_hsdma_count(void __iomem *mbase, |
117 | u8 bchannel, u32 len) | 110 | u8 bchannel, u32 len) |
118 | { | 111 | { |
119 | musb_writew(mbase, | 112 | musb_writel(mbase, |
120 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW), | ||
121 | ((u16)((u32) len & 0xFFFF))); | ||
122 | musb_writew(mbase, | ||
123 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), | 113 | MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH), |
124 | ((u16)(((u32) len >> 16) & 0xFFFF))); | 114 | len); |
125 | } | 115 | } |
126 | 116 | ||
127 | #endif /* CONFIG_BLACKFIN */ | 117 | #endif /* CONFIG_BLACKFIN */ |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 490cdf15ccb6..e06d65e36bf7 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -32,17 +32,11 @@ | |||
32 | #include <linux/clk.h> | 32 | #include <linux/clk.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | 34 | ||
35 | #include <asm/mach-types.h> | ||
36 | #include <mach/hardware.h> | ||
37 | #include <plat/mux.h> | 35 | #include <plat/mux.h> |
38 | 36 | ||
39 | #include "musb_core.h" | 37 | #include "musb_core.h" |
40 | #include "omap2430.h" | 38 | #include "omap2430.h" |
41 | 39 | ||
42 | #ifdef CONFIG_ARCH_OMAP3430 | ||
43 | #define get_cpu_rev() 2 | ||
44 | #endif | ||
45 | |||
46 | 40 | ||
47 | static struct timer_list musb_idle_timer; | 41 | static struct timer_list musb_idle_timer; |
48 | 42 | ||
@@ -145,10 +139,6 @@ void musb_platform_enable(struct musb *musb) | |||
145 | void musb_platform_disable(struct musb *musb) | 139 | void musb_platform_disable(struct musb *musb) |
146 | { | 140 | { |
147 | } | 141 | } |
148 | static void omap_vbus_power(struct musb *musb, int is_on, int sleeping) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | static void omap_set_vbus(struct musb *musb, int is_on) | 142 | static void omap_set_vbus(struct musb *musb, int is_on) |
153 | { | 143 | { |
154 | u8 devctl; | 144 | u8 devctl; |
@@ -199,9 +189,10 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
199 | return 0; | 189 | return 0; |
200 | } | 190 | } |
201 | 191 | ||
202 | int __init musb_platform_init(struct musb *musb) | 192 | int __init musb_platform_init(struct musb *musb, void *board_data) |
203 | { | 193 | { |
204 | u32 l; | 194 | u32 l; |
195 | struct omap_musb_board_data *data = board_data; | ||
205 | 196 | ||
206 | #if defined(CONFIG_ARCH_OMAP2430) | 197 | #if defined(CONFIG_ARCH_OMAP2430) |
207 | omap_cfg_reg(AE5_2430_USB0HS_STP); | 198 | omap_cfg_reg(AE5_2430_USB0HS_STP); |
@@ -235,7 +226,15 @@ int __init musb_platform_init(struct musb *musb) | |||
235 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); | 226 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); |
236 | 227 | ||
237 | l = musb_readl(musb->mregs, OTG_INTERFSEL); | 228 | l = musb_readl(musb->mregs, OTG_INTERFSEL); |
238 | l |= ULPI_12PIN; | 229 | |
230 | if (data->interface_type == MUSB_INTERFACE_UTMI) { | ||
231 | /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ | ||
232 | l &= ~ULPI_12PIN; /* Disable ULPI */ | ||
233 | l |= UTMI_8BIT; /* Enable UTMI */ | ||
234 | } else { | ||
235 | l |= ULPI_12PIN; | ||
236 | } | ||
237 | |||
239 | musb_writel(musb->mregs, OTG_INTERFSEL, l); | 238 | musb_writel(musb->mregs, OTG_INTERFSEL, l); |
240 | 239 | ||
241 | pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " | 240 | pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " |
@@ -246,8 +245,6 @@ int __init musb_platform_init(struct musb *musb) | |||
246 | musb_readl(musb->mregs, OTG_INTERFSEL), | 245 | musb_readl(musb->mregs, OTG_INTERFSEL), |
247 | musb_readl(musb->mregs, OTG_SIMENABLE)); | 246 | musb_readl(musb->mregs, OTG_SIMENABLE)); |
248 | 247 | ||
249 | omap_vbus_power(musb, musb->board_mode == MUSB_HOST, 1); | ||
250 | |||
251 | if (is_host_enabled(musb)) | 248 | if (is_host_enabled(musb)) |
252 | musb->board_set_vbus = omap_set_vbus; | 249 | musb->board_set_vbus = omap_set_vbus; |
253 | 250 | ||
@@ -272,7 +269,7 @@ void musb_platform_restore_context(struct musb *musb, | |||
272 | } | 269 | } |
273 | #endif | 270 | #endif |
274 | 271 | ||
275 | int musb_platform_suspend(struct musb *musb) | 272 | static int musb_platform_suspend(struct musb *musb) |
276 | { | 273 | { |
277 | u32 l; | 274 | u32 l; |
278 | 275 | ||
@@ -327,12 +324,7 @@ static int musb_platform_resume(struct musb *musb) | |||
327 | int musb_platform_exit(struct musb *musb) | 324 | int musb_platform_exit(struct musb *musb) |
328 | { | 325 | { |
329 | 326 | ||
330 | omap_vbus_power(musb, 0 /*off*/, 1); | ||
331 | |||
332 | musb_platform_suspend(musb); | 327 | musb_platform_suspend(musb); |
333 | 328 | ||
334 | clk_put(musb->clock); | ||
335 | musb->clock = NULL; | ||
336 | |||
337 | return 0; | 329 | return 0; |
338 | } | 330 | } |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index ab776a8d98ca..05c077f8f9ac 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -29,6 +29,19 @@ static void tusb_source_power(struct musb *musb, int is_on); | |||
29 | #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf) | 29 | #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf) |
30 | #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf) | 30 | #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf) |
31 | 31 | ||
32 | #ifdef CONFIG_PM | ||
33 | /* REVISIT: These should be only needed if somebody implements off idle */ | ||
34 | void musb_platform_save_context(struct musb *musb, | ||
35 | struct musb_context_registers *musb_context) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | void musb_platform_restore_context(struct musb *musb, | ||
40 | struct musb_context_registers *musb_context) | ||
41 | { | ||
42 | } | ||
43 | #endif | ||
44 | |||
32 | /* | 45 | /* |
33 | * Checks the revision. We need to use the DMA register as 3.0 does not | 46 | * Checks the revision. We need to use the DMA register as 3.0 does not |
34 | * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV. | 47 | * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV. |
@@ -1091,7 +1104,7 @@ err: | |||
1091 | return -ENODEV; | 1104 | return -ENODEV; |
1092 | } | 1105 | } |
1093 | 1106 | ||
1094 | int __init musb_platform_init(struct musb *musb) | 1107 | int __init musb_platform_init(struct musb *musb, void *board_data) |
1095 | { | 1108 | { |
1096 | struct platform_device *pdev; | 1109 | struct platform_device *pdev; |
1097 | struct resource *mem; | 1110 | struct resource *mem; |
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 5afa070d7dc9..c061a88f2b0f 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c | |||
@@ -39,7 +39,7 @@ struct tusb_omap_dma_ch { | |||
39 | 39 | ||
40 | struct tusb_omap_dma *tusb_dma; | 40 | struct tusb_omap_dma *tusb_dma; |
41 | 41 | ||
42 | void __iomem *dma_addr; | 42 | dma_addr_t dma_addr; |
43 | 43 | ||
44 | u32 len; | 44 | u32 len; |
45 | u16 packet_sz; | 45 | u16 packet_sz; |
@@ -126,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) | |||
126 | struct tusb_omap_dma_ch *chdat = to_chdat(channel); | 126 | struct tusb_omap_dma_ch *chdat = to_chdat(channel); |
127 | struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; | 127 | struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; |
128 | struct musb *musb = chdat->musb; | 128 | struct musb *musb = chdat->musb; |
129 | struct device *dev = musb->controller; | ||
129 | struct musb_hw_ep *hw_ep = chdat->hw_ep; | 130 | struct musb_hw_ep *hw_ep = chdat->hw_ep; |
130 | void __iomem *ep_conf = hw_ep->conf; | 131 | void __iomem *ep_conf = hw_ep->conf; |
131 | void __iomem *mbase = musb->mregs; | 132 | void __iomem *mbase = musb->mregs; |
@@ -173,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) | |||
173 | DBG(3, "Using PIO for remaining %lu bytes\n", pio); | 174 | DBG(3, "Using PIO for remaining %lu bytes\n", pio); |
174 | buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len; | 175 | buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len; |
175 | if (chdat->tx) { | 176 | if (chdat->tx) { |
176 | dma_cache_maint(phys_to_virt((u32)chdat->dma_addr), | 177 | dma_unmap_single(dev, chdat->dma_addr, |
177 | chdat->transfer_len, DMA_TO_DEVICE); | 178 | chdat->transfer_len, |
179 | DMA_TO_DEVICE); | ||
178 | musb_write_fifo(hw_ep, pio, buf); | 180 | musb_write_fifo(hw_ep, pio, buf); |
179 | } else { | 181 | } else { |
182 | dma_unmap_single(dev, chdat->dma_addr, | ||
183 | chdat->transfer_len, | ||
184 | DMA_FROM_DEVICE); | ||
180 | musb_read_fifo(hw_ep, pio, buf); | 185 | musb_read_fifo(hw_ep, pio, buf); |
181 | dma_cache_maint(phys_to_virt((u32)chdat->dma_addr), | ||
182 | chdat->transfer_len, DMA_FROM_DEVICE); | ||
183 | } | 186 | } |
184 | channel->actual_len += pio; | 187 | channel->actual_len += pio; |
185 | } | 188 | } |
@@ -224,6 +227,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, | |||
224 | struct tusb_omap_dma_ch *chdat = to_chdat(channel); | 227 | struct tusb_omap_dma_ch *chdat = to_chdat(channel); |
225 | struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; | 228 | struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; |
226 | struct musb *musb = chdat->musb; | 229 | struct musb *musb = chdat->musb; |
230 | struct device *dev = musb->controller; | ||
227 | struct musb_hw_ep *hw_ep = chdat->hw_ep; | 231 | struct musb_hw_ep *hw_ep = chdat->hw_ep; |
228 | void __iomem *mbase = musb->mregs; | 232 | void __iomem *mbase = musb->mregs; |
229 | void __iomem *ep_conf = hw_ep->conf; | 233 | void __iomem *ep_conf = hw_ep->conf; |
@@ -299,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, | |||
299 | chdat->packet_sz = packet_sz; | 303 | chdat->packet_sz = packet_sz; |
300 | chdat->len = len; | 304 | chdat->len = len; |
301 | channel->actual_len = 0; | 305 | channel->actual_len = 0; |
302 | chdat->dma_addr = (void __iomem *)dma_addr; | 306 | chdat->dma_addr = dma_addr; |
303 | channel->status = MUSB_DMA_STATUS_BUSY; | 307 | channel->status = MUSB_DMA_STATUS_BUSY; |
304 | 308 | ||
305 | /* Since we're recycling dma areas, we need to clean or invalidate */ | 309 | /* Since we're recycling dma areas, we need to clean or invalidate */ |
306 | if (chdat->tx) | 310 | if (chdat->tx) |
307 | dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE); | 311 | dma_map_single(dev, phys_to_virt(dma_addr), len, |
312 | DMA_TO_DEVICE); | ||
308 | else | 313 | else |
309 | dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE); | 314 | dma_map_single(dev, phys_to_virt(dma_addr), len, |
315 | DMA_FROM_DEVICE); | ||
310 | 316 | ||
311 | /* Use 16-bit transfer if dma_addr is not 32-bit aligned */ | 317 | /* Use 16-bit transfer if dma_addr is not 32-bit aligned */ |
312 | if ((dma_addr & 0x3) == 0) { | 318 | if ((dma_addr & 0x3) == 0) { |