diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-11 16:56:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-11 16:56:29 -0400 |
commit | 1cd572fc0c5f6887ea0542e2d3ec26625e2cdfb7 (patch) | |
tree | 9b987397f34f685edbb4b1f282a32d229c15a1bd /drivers/usb/musb/blackfin.c | |
parent | e6d49d093e1076df060c18d28b8ebc36077f76e7 (diff) | |
parent | d8c3ef256f88b7c6ecd673d03073b5645be9c5e4 (diff) |
Merge tag 'musb-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
usb: musb: patches for v3.7 merge window
Here we have a bunch of miscellaneous cleanups and fixes
to the musb driver. It fixes a bunch of mistakes errors
which nobody has triggered before, so I'm not Ccing stable
tree.
We are finally improving OMAP's VBUS/ID Mailbox usage so
that we can introduce our PHY drivers properly. Also, we're
adding support for multiple instances of the MUSB IP in
the same SoC, as seen on some platforms from TI which
have 2 MUSB instances.
Other than that, we have some small fixes like not kicking
DMA for a zero byte transfer, or properly handling NAK timeout
on MUSB's host side, and the enabling of DMA Mode1 for any
transfers which are aligned to wMaxPacketSize.
All patches have been pending on mailing list for a long time
and I don't expect any big surprises with this pull request.
Diffstat (limited to 'drivers/usb/musb/blackfin.c')
-rw-r--r-- | drivers/usb/musb/blackfin.c | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index b562623a8971..e8cff9bb9d23 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -185,8 +185,8 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | /* Start sampling ID pin, when plug is removed from MUSB */ | 187 | /* Start sampling ID pin, when plug is removed from MUSB */ |
188 | if ((is_otg_enabled(musb) && (musb->xceiv->state == OTG_STATE_B_IDLE | 188 | if ((musb->xceiv->state == OTG_STATE_B_IDLE |
189 | || musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) || | 189 | || musb->xceiv->state == OTG_STATE_A_WAIT_BCON) || |
190 | (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) { | 190 | (musb->int_usb & MUSB_INTR_DISCONNECT && is_host_active(musb))) { |
191 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 191 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
192 | musb->a_wait_bcon = TIMER_DELAY; | 192 | musb->a_wait_bcon = TIMER_DELAY; |
@@ -229,18 +229,13 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
229 | 229 | ||
230 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; | 230 | val = MUSB_INTR_SUSPEND | MUSB_INTR_VBUSERROR; |
231 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); | 231 | musb_writeb(musb->mregs, MUSB_INTRUSB, val); |
232 | if (is_otg_enabled(musb)) | 232 | musb->xceiv->state = OTG_STATE_B_IDLE; |
233 | musb->xceiv->state = OTG_STATE_B_IDLE; | ||
234 | else | ||
235 | musb_writeb(musb->mregs, MUSB_POWER, MUSB_POWER_HSENAB); | ||
236 | } | 233 | } |
237 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 234 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
238 | break; | 235 | break; |
239 | case OTG_STATE_B_IDLE: | 236 | case OTG_STATE_B_IDLE: |
240 | 237 | /* | |
241 | if (!is_peripheral_enabled(musb)) | 238 | * Start a new session. It seems that MUSB needs taking |
242 | break; | ||
243 | /* Start a new session. It seems that MUSB needs taking | ||
244 | * some time to recognize the type of the plug inserted? | 239 | * some time to recognize the type of the plug inserted? |
245 | */ | 240 | */ |
246 | val = musb_readw(musb->mregs, MUSB_DEVCTL); | 241 | val = musb_readw(musb->mregs, MUSB_DEVCTL); |
@@ -296,10 +291,7 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
296 | 291 | ||
297 | static void bfin_musb_enable(struct musb *musb) | 292 | static void bfin_musb_enable(struct musb *musb) |
298 | { | 293 | { |
299 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) { | 294 | /* REVISIT is this really correct ? */ |
300 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
301 | musb->a_wait_bcon = TIMER_DELAY; | ||
302 | } | ||
303 | } | 295 | } |
304 | 296 | ||
305 | static void bfin_musb_disable(struct musb *musb) | 297 | static void bfin_musb_disable(struct musb *musb) |
@@ -324,12 +316,6 @@ static int bfin_musb_set_power(struct usb_phy *x, unsigned mA) | |||
324 | return 0; | 316 | return 0; |
325 | } | 317 | } |
326 | 318 | ||
327 | static void bfin_musb_try_idle(struct musb *musb, unsigned long timeout) | ||
328 | { | ||
329 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) | ||
330 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | ||
331 | } | ||
332 | |||
333 | static int bfin_musb_vbus_status(struct musb *musb) | 319 | static int bfin_musb_vbus_status(struct musb *musb) |
334 | { | 320 | { |
335 | return 0; | 321 | return 0; |
@@ -425,12 +411,10 @@ static int bfin_musb_init(struct musb *musb) | |||
425 | 411 | ||
426 | bfin_musb_reg_init(musb); | 412 | bfin_musb_reg_init(musb); |
427 | 413 | ||
428 | if (is_host_enabled(musb)) { | 414 | setup_timer(&musb_conn_timer, musb_conn_timer_handler, |
429 | setup_timer(&musb_conn_timer, | 415 | (unsigned long) musb); |
430 | musb_conn_timer_handler, (unsigned long) musb); | 416 | |
431 | } | 417 | musb->xceiv->set_power = bfin_musb_set_power; |
432 | if (is_peripheral_enabled(musb)) | ||
433 | musb->xceiv->set_power = bfin_musb_set_power; | ||
434 | 418 | ||
435 | musb->isr = blackfin_interrupt; | 419 | musb->isr = blackfin_interrupt; |
436 | musb->double_buffer_not_ok = true; | 420 | musb->double_buffer_not_ok = true; |
@@ -455,7 +439,6 @@ static const struct musb_platform_ops bfin_ops = { | |||
455 | .disable = bfin_musb_disable, | 439 | .disable = bfin_musb_disable, |
456 | 440 | ||
457 | .set_mode = bfin_musb_set_mode, | 441 | .set_mode = bfin_musb_set_mode, |
458 | .try_idle = bfin_musb_try_idle, | ||
459 | 442 | ||
460 | .vbus_status = bfin_musb_vbus_status, | 443 | .vbus_status = bfin_musb_vbus_status, |
461 | .set_vbus = bfin_musb_set_vbus, | 444 | .set_vbus = bfin_musb_set_vbus, |
@@ -472,6 +455,7 @@ static int __devinit bfin_probe(struct platform_device *pdev) | |||
472 | struct bfin_glue *glue; | 455 | struct bfin_glue *glue; |
473 | 456 | ||
474 | int ret = -ENOMEM; | 457 | int ret = -ENOMEM; |
458 | int musbid; | ||
475 | 459 | ||
476 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | 460 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
477 | if (!glue) { | 461 | if (!glue) { |
@@ -479,12 +463,21 @@ static int __devinit bfin_probe(struct platform_device *pdev) | |||
479 | goto err0; | 463 | goto err0; |
480 | } | 464 | } |
481 | 465 | ||
482 | musb = platform_device_alloc("musb-hdrc", -1); | 466 | /* get the musb id */ |
467 | musbid = musb_get_id(&pdev->dev, GFP_KERNEL); | ||
468 | if (musbid < 0) { | ||
469 | dev_err(&pdev->dev, "failed to allocate musb id\n"); | ||
470 | ret = -ENOMEM; | ||
471 | goto err1; | ||
472 | } | ||
473 | |||
474 | musb = platform_device_alloc("musb-hdrc", musbid); | ||
483 | if (!musb) { | 475 | if (!musb) { |
484 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | 476 | dev_err(&pdev->dev, "failed to allocate musb device\n"); |
485 | goto err1; | 477 | goto err2; |
486 | } | 478 | } |
487 | 479 | ||
480 | musb->id = musbid; | ||
488 | musb->dev.parent = &pdev->dev; | 481 | musb->dev.parent = &pdev->dev; |
489 | musb->dev.dma_mask = &bfin_dmamask; | 482 | musb->dev.dma_mask = &bfin_dmamask; |
490 | musb->dev.coherent_dma_mask = bfin_dmamask; | 483 | musb->dev.coherent_dma_mask = bfin_dmamask; |
@@ -500,26 +493,29 @@ static int __devinit bfin_probe(struct platform_device *pdev) | |||
500 | pdev->num_resources); | 493 | pdev->num_resources); |
501 | if (ret) { | 494 | if (ret) { |
502 | dev_err(&pdev->dev, "failed to add resources\n"); | 495 | dev_err(&pdev->dev, "failed to add resources\n"); |
503 | goto err2; | 496 | goto err3; |
504 | } | 497 | } |
505 | 498 | ||
506 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | 499 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); |
507 | if (ret) { | 500 | if (ret) { |
508 | dev_err(&pdev->dev, "failed to add platform_data\n"); | 501 | dev_err(&pdev->dev, "failed to add platform_data\n"); |
509 | goto err2; | 502 | goto err3; |
510 | } | 503 | } |
511 | 504 | ||
512 | ret = platform_device_add(musb); | 505 | ret = platform_device_add(musb); |
513 | if (ret) { | 506 | if (ret) { |
514 | dev_err(&pdev->dev, "failed to register musb device\n"); | 507 | dev_err(&pdev->dev, "failed to register musb device\n"); |
515 | goto err2; | 508 | goto err3; |
516 | } | 509 | } |
517 | 510 | ||
518 | return 0; | 511 | return 0; |
519 | 512 | ||
520 | err2: | 513 | err3: |
521 | platform_device_put(musb); | 514 | platform_device_put(musb); |
522 | 515 | ||
516 | err2: | ||
517 | musb_put_id(&pdev->dev, musbid); | ||
518 | |||
523 | err1: | 519 | err1: |
524 | kfree(glue); | 520 | kfree(glue); |
525 | 521 | ||
@@ -531,6 +527,7 @@ static int __devexit bfin_remove(struct platform_device *pdev) | |||
531 | { | 527 | { |
532 | struct bfin_glue *glue = platform_get_drvdata(pdev); | 528 | struct bfin_glue *glue = platform_get_drvdata(pdev); |
533 | 529 | ||
530 | musb_put_id(&pdev->dev, glue->musb->id); | ||
534 | platform_device_del(glue->musb); | 531 | platform_device_del(glue->musb); |
535 | platform_device_put(glue->musb); | 532 | platform_device_put(glue->musb); |
536 | kfree(glue); | 533 | kfree(glue); |