diff options
Diffstat (limited to 'drivers/usb/musb/davinci.c')
-rw-r--r-- | drivers/usb/musb/davinci.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 10d11ab113ab..180d7daa4099 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -215,7 +215,7 @@ static void otg_timer(unsigned long _musb) | |||
215 | DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); | 215 | DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb)); |
216 | 216 | ||
217 | spin_lock_irqsave(&musb->lock, flags); | 217 | spin_lock_irqsave(&musb->lock, flags); |
218 | switch (musb->xceiv.state) { | 218 | switch (musb->xceiv->state) { |
219 | case OTG_STATE_A_WAIT_VFALL: | 219 | case OTG_STATE_A_WAIT_VFALL: |
220 | /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL | 220 | /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL |
221 | * seems to mis-handle session "start" otherwise (or in our | 221 | * seems to mis-handle session "start" otherwise (or in our |
@@ -226,7 +226,7 @@ static void otg_timer(unsigned long _musb) | |||
226 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 226 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
227 | break; | 227 | break; |
228 | } | 228 | } |
229 | musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | 229 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
230 | musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, | 230 | musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG, |
231 | MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); | 231 | MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT); |
232 | break; | 232 | break; |
@@ -251,7 +251,7 @@ static void otg_timer(unsigned long _musb) | |||
251 | if (devctl & MUSB_DEVCTL_BDEVICE) | 251 | if (devctl & MUSB_DEVCTL_BDEVICE) |
252 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 252 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
253 | else | 253 | else |
254 | musb->xceiv.state = OTG_STATE_A_IDLE; | 254 | musb->xceiv->state = OTG_STATE_A_IDLE; |
255 | break; | 255 | break; |
256 | default: | 256 | default: |
257 | break; | 257 | break; |
@@ -265,6 +265,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
265 | irqreturn_t retval = IRQ_NONE; | 265 | irqreturn_t retval = IRQ_NONE; |
266 | struct musb *musb = __hci; | 266 | struct musb *musb = __hci; |
267 | void __iomem *tibase = musb->ctrl_base; | 267 | void __iomem *tibase = musb->ctrl_base; |
268 | struct cppi *cppi; | ||
268 | u32 tmp; | 269 | u32 tmp; |
269 | 270 | ||
270 | spin_lock_irqsave(&musb->lock, flags); | 271 | spin_lock_irqsave(&musb->lock, flags); |
@@ -281,16 +282,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
281 | /* CPPI interrupts share the same IRQ line, but have their own | 282 | /* CPPI interrupts share the same IRQ line, but have their own |
282 | * mask, state, "vector", and EOI registers. | 283 | * mask, state, "vector", and EOI registers. |
283 | */ | 284 | */ |
284 | if (is_cppi_enabled()) { | 285 | cppi = container_of(musb->dma_controller, struct cppi, controller); |
285 | u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); | 286 | if (is_cppi_enabled() && musb->dma_controller && !cppi->irq) |
286 | u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); | 287 | retval = cppi_interrupt(irq, __hci); |
287 | |||
288 | if (cppi_tx || cppi_rx) { | ||
289 | DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx); | ||
290 | cppi_completion(musb, cppi_rx, cppi_tx); | ||
291 | retval = IRQ_HANDLED; | ||
292 | } | ||
293 | } | ||
294 | 288 | ||
295 | /* ack and handle non-CPPI interrupts */ | 289 | /* ack and handle non-CPPI interrupts */ |
296 | tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); | 290 | tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG); |
@@ -331,21 +325,21 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
331 | * to stop registering in devctl. | 325 | * to stop registering in devctl. |
332 | */ | 326 | */ |
333 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; | 327 | musb->int_usb &= ~MUSB_INTR_VBUSERROR; |
334 | musb->xceiv.state = OTG_STATE_A_WAIT_VFALL; | 328 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; |
335 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 329 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
336 | WARNING("VBUS error workaround (delay coming)\n"); | 330 | WARNING("VBUS error workaround (delay coming)\n"); |
337 | } else if (is_host_enabled(musb) && drvvbus) { | 331 | } else if (is_host_enabled(musb) && drvvbus) { |
338 | musb->is_active = 1; | 332 | musb->is_active = 1; |
339 | MUSB_HST_MODE(musb); | 333 | MUSB_HST_MODE(musb); |
340 | musb->xceiv.default_a = 1; | 334 | musb->xceiv->default_a = 1; |
341 | musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; | 335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
342 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); | 336 | portstate(musb->port1_status |= USB_PORT_STAT_POWER); |
343 | del_timer(&otg_workaround); | 337 | del_timer(&otg_workaround); |
344 | } else { | 338 | } else { |
345 | musb->is_active = 0; | 339 | musb->is_active = 0; |
346 | MUSB_DEV_MODE(musb); | 340 | MUSB_DEV_MODE(musb); |
347 | musb->xceiv.default_a = 0; | 341 | musb->xceiv->default_a = 0; |
348 | musb->xceiv.state = OTG_STATE_B_IDLE; | 342 | musb->xceiv->state = OTG_STATE_B_IDLE; |
349 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | 343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); |
350 | } | 344 | } |
351 | 345 | ||
@@ -367,17 +361,12 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
367 | 361 | ||
368 | /* poll for ID change */ | 362 | /* poll for ID change */ |
369 | if (is_otg_enabled(musb) | 363 | if (is_otg_enabled(musb) |
370 | && musb->xceiv.state == OTG_STATE_B_IDLE) | 364 | && musb->xceiv->state == OTG_STATE_B_IDLE) |
371 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 365 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
372 | 366 | ||
373 | spin_unlock_irqrestore(&musb->lock, flags); | 367 | spin_unlock_irqrestore(&musb->lock, flags); |
374 | 368 | ||
375 | /* REVISIT we sometimes get unhandled IRQs | 369 | return retval; |
376 | * (e.g. ep0). not clear why... | ||
377 | */ | ||
378 | if (retval != IRQ_HANDLED) | ||
379 | DBG(5, "unhandled? %08x\n", tmp); | ||
380 | return IRQ_HANDLED; | ||
381 | } | 370 | } |
382 | 371 | ||
383 | int musb_platform_set_mode(struct musb *musb, u8 mode) | 372 | int musb_platform_set_mode(struct musb *musb, u8 mode) |
@@ -391,6 +380,11 @@ int __init musb_platform_init(struct musb *musb) | |||
391 | void __iomem *tibase = musb->ctrl_base; | 380 | void __iomem *tibase = musb->ctrl_base; |
392 | u32 revision; | 381 | u32 revision; |
393 | 382 | ||
383 | usb_nop_xceiv_register(); | ||
384 | musb->xceiv = otg_get_transceiver(); | ||
385 | if (!musb->xceiv) | ||
386 | return -ENODEV; | ||
387 | |||
394 | musb->mregs += DAVINCI_BASE_OFFSET; | 388 | musb->mregs += DAVINCI_BASE_OFFSET; |
395 | 389 | ||
396 | clk_enable(musb->clock); | 390 | clk_enable(musb->clock); |
@@ -398,7 +392,7 @@ int __init musb_platform_init(struct musb *musb) | |||
398 | /* returns zero if e.g. not clocked */ | 392 | /* returns zero if e.g. not clocked */ |
399 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); | 393 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); |
400 | if (revision == 0) | 394 | if (revision == 0) |
401 | return -ENODEV; | 395 | goto fail; |
402 | 396 | ||
403 | if (is_host_enabled(musb)) | 397 | if (is_host_enabled(musb)) |
404 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); | 398 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); |
@@ -432,6 +426,10 @@ int __init musb_platform_init(struct musb *musb) | |||
432 | 426 | ||
433 | musb->isr = davinci_interrupt; | 427 | musb->isr = davinci_interrupt; |
434 | return 0; | 428 | return 0; |
429 | |||
430 | fail: | ||
431 | usb_nop_xceiv_unregister(); | ||
432 | return -ENODEV; | ||
435 | } | 433 | } |
436 | 434 | ||
437 | int musb_platform_exit(struct musb *musb) | 435 | int musb_platform_exit(struct musb *musb) |
@@ -442,7 +440,7 @@ int musb_platform_exit(struct musb *musb) | |||
442 | davinci_source_power(musb, 0 /*off*/, 1); | 440 | davinci_source_power(musb, 0 /*off*/, 1); |
443 | 441 | ||
444 | /* delay, to avoid problems with module reload */ | 442 | /* delay, to avoid problems with module reload */ |
445 | if (is_host_enabled(musb) && musb->xceiv.default_a) { | 443 | if (is_host_enabled(musb) && musb->xceiv->default_a) { |
446 | int maxdelay = 30; | 444 | int maxdelay = 30; |
447 | u8 devctl, warn = 0; | 445 | u8 devctl, warn = 0; |
448 | 446 | ||
@@ -471,5 +469,7 @@ int musb_platform_exit(struct musb *musb) | |||
471 | 469 | ||
472 | clk_disable(musb->clock); | 470 | clk_disable(musb->clock); |
473 | 471 | ||
472 | usb_nop_xceiv_unregister(); | ||
473 | |||
474 | return 0; | 474 | return 0; |
475 | } | 475 | } |