diff options
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r-- | drivers/usb/chipidea/core.c | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 33f22bc6ad7f..ca6831c5b763 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/usb/otg.h> | 64 | #include <linux/usb/otg.h> |
65 | #include <linux/usb/chipidea.h> | 65 | #include <linux/usb/chipidea.h> |
66 | #include <linux/usb/of.h> | 66 | #include <linux/usb/of.h> |
67 | #include <linux/of.h> | ||
67 | #include <linux/phy.h> | 68 | #include <linux/phy.h> |
68 | #include <linux/regulator/consumer.h> | 69 | #include <linux/regulator/consumer.h> |
69 | 70 | ||
@@ -298,6 +299,13 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode) | |||
298 | if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING) | 299 | if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING) |
299 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); | 300 | hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); |
300 | 301 | ||
302 | if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) { | ||
303 | if (ci->hw_bank.lpm) | ||
304 | hw_write(ci, OP_DEVLC, DEVLC_PFSC, DEVLC_PFSC); | ||
305 | else | ||
306 | hw_write(ci, OP_PORTSC, PORTSC_PFSC, PORTSC_PFSC); | ||
307 | } | ||
308 | |||
301 | /* USBMODE should be configured step by step */ | 309 | /* USBMODE should be configured step by step */ |
302 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | 310 | hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); |
303 | hw_write(ci, OP_USBMODE, USBMODE_CM, mode); | 311 | hw_write(ci, OP_USBMODE, USBMODE_CM, mode); |
@@ -412,6 +420,9 @@ static int ci_get_platdata(struct device *dev, | |||
412 | } | 420 | } |
413 | } | 421 | } |
414 | 422 | ||
423 | if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) | ||
424 | platdata->flags |= CI_HDRC_FORCE_FULLSPEED; | ||
425 | |||
415 | return 0; | 426 | return 0; |
416 | } | 427 | } |
417 | 428 | ||
@@ -496,33 +507,6 @@ static void ci_get_otg_capable(struct ci_hdrc *ci) | |||
496 | } | 507 | } |
497 | } | 508 | } |
498 | 509 | ||
499 | static int ci_usb_phy_init(struct ci_hdrc *ci) | ||
500 | { | ||
501 | if (ci->platdata->phy) { | ||
502 | ci->transceiver = ci->platdata->phy; | ||
503 | return usb_phy_init(ci->transceiver); | ||
504 | } else { | ||
505 | ci->global_phy = true; | ||
506 | ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | ||
507 | if (IS_ERR(ci->transceiver)) | ||
508 | ci->transceiver = NULL; | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | static void ci_usb_phy_destroy(struct ci_hdrc *ci) | ||
515 | { | ||
516 | if (!ci->transceiver) | ||
517 | return; | ||
518 | |||
519 | otg_set_peripheral(ci->transceiver->otg, NULL); | ||
520 | if (ci->global_phy) | ||
521 | usb_put_phy(ci->transceiver); | ||
522 | else | ||
523 | usb_phy_shutdown(ci->transceiver); | ||
524 | } | ||
525 | |||
526 | static int ci_hdrc_probe(struct platform_device *pdev) | 510 | static int ci_hdrc_probe(struct platform_device *pdev) |
527 | { | 511 | { |
528 | struct device *dev = &pdev->dev; | 512 | struct device *dev = &pdev->dev; |
@@ -532,7 +516,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
532 | int ret; | 516 | int ret; |
533 | enum usb_dr_mode dr_mode; | 517 | enum usb_dr_mode dr_mode; |
534 | 518 | ||
535 | if (!dev->platform_data) { | 519 | if (!dev_get_platdata(dev)) { |
536 | dev_err(dev, "platform data missing\n"); | 520 | dev_err(dev, "platform data missing\n"); |
537 | return -ENODEV; | 521 | return -ENODEV; |
538 | } | 522 | } |
@@ -549,7 +533,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
549 | } | 533 | } |
550 | 534 | ||
551 | ci->dev = dev; | 535 | ci->dev = dev; |
552 | ci->platdata = dev->platform_data; | 536 | ci->platdata = dev_get_platdata(dev); |
553 | ci->imx28_write_fix = !!(ci->platdata->flags & | 537 | ci->imx28_write_fix = !!(ci->platdata->flags & |
554 | CI_HDRC_IMX28_WRITE_FIX); | 538 | CI_HDRC_IMX28_WRITE_FIX); |
555 | 539 | ||
@@ -561,7 +545,26 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
561 | 545 | ||
562 | hw_phymode_configure(ci); | 546 | hw_phymode_configure(ci); |
563 | 547 | ||
564 | ret = ci_usb_phy_init(ci); | 548 | if (ci->platdata->phy) |
549 | ci->transceiver = ci->platdata->phy; | ||
550 | else | ||
551 | ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
552 | |||
553 | if (IS_ERR(ci->transceiver)) { | ||
554 | ret = PTR_ERR(ci->transceiver); | ||
555 | /* | ||
556 | * if -ENXIO is returned, it means PHY layer wasn't | ||
557 | * enabled, so it makes no sense to return -EPROBE_DEFER | ||
558 | * in that case, since no PHY driver will ever probe. | ||
559 | */ | ||
560 | if (ret == -ENXIO) | ||
561 | return ret; | ||
562 | |||
563 | dev_err(dev, "no usb2 phy configured\n"); | ||
564 | return -EPROBE_DEFER; | ||
565 | } | ||
566 | |||
567 | ret = usb_phy_init(ci->transceiver); | ||
565 | if (ret) { | 568 | if (ret) { |
566 | dev_err(dev, "unable to init phy: %d\n", ret); | 569 | dev_err(dev, "unable to init phy: %d\n", ret); |
567 | return ret; | 570 | return ret; |
@@ -572,8 +575,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
572 | ci->irq = platform_get_irq(pdev, 0); | 575 | ci->irq = platform_get_irq(pdev, 0); |
573 | if (ci->irq < 0) { | 576 | if (ci->irq < 0) { |
574 | dev_err(dev, "missing IRQ\n"); | 577 | dev_err(dev, "missing IRQ\n"); |
575 | ret = -ENODEV; | 578 | ret = ci->irq; |
576 | goto destroy_phy; | 579 | goto deinit_phy; |
577 | } | 580 | } |
578 | 581 | ||
579 | ci_get_otg_capable(ci); | 582 | ci_get_otg_capable(ci); |
@@ -590,23 +593,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
590 | ret = ci_hdrc_gadget_init(ci); | 593 | ret = ci_hdrc_gadget_init(ci); |
591 | if (ret) | 594 | if (ret) |
592 | dev_info(dev, "doesn't support gadget\n"); | 595 | dev_info(dev, "doesn't support gadget\n"); |
593 | if (!ret && ci->transceiver) { | ||
594 | ret = otg_set_peripheral(ci->transceiver->otg, | ||
595 | &ci->gadget); | ||
596 | /* | ||
597 | * If we implement all USB functions using chipidea drivers, | ||
598 | * it doesn't need to call above API, meanwhile, if we only | ||
599 | * use gadget function, calling above API is useless. | ||
600 | */ | ||
601 | if (ret && ret != -ENOTSUPP) | ||
602 | goto destroy_phy; | ||
603 | } | ||
604 | } | 596 | } |
605 | 597 | ||
606 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { | 598 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { |
607 | dev_err(dev, "no supported roles\n"); | 599 | dev_err(dev, "no supported roles\n"); |
608 | ret = -ENODEV; | 600 | ret = -ENODEV; |
609 | goto destroy_phy; | 601 | goto deinit_phy; |
610 | } | 602 | } |
611 | 603 | ||
612 | if (ci->is_otg) { | 604 | if (ci->is_otg) { |
@@ -663,8 +655,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
663 | free_irq(ci->irq, ci); | 655 | free_irq(ci->irq, ci); |
664 | stop: | 656 | stop: |
665 | ci_role_destroy(ci); | 657 | ci_role_destroy(ci); |
666 | destroy_phy: | 658 | deinit_phy: |
667 | ci_usb_phy_destroy(ci); | 659 | usb_phy_shutdown(ci->transceiver); |
668 | 660 | ||
669 | return ret; | 661 | return ret; |
670 | } | 662 | } |
@@ -677,7 +669,8 @@ static int ci_hdrc_remove(struct platform_device *pdev) | |||
677 | free_irq(ci->irq, ci); | 669 | free_irq(ci->irq, ci); |
678 | ci_role_destroy(ci); | 670 | ci_role_destroy(ci); |
679 | ci_hdrc_enter_lpm(ci, true); | 671 | ci_hdrc_enter_lpm(ci, true); |
680 | ci_usb_phy_destroy(ci); | 672 | usb_phy_shutdown(ci->transceiver); |
673 | kfree(ci->hw_bank.regmap); | ||
681 | 674 | ||
682 | return 0; | 675 | return 0; |
683 | } | 676 | } |