diff options
author | Peter Chen <peter.chen@freescale.com> | 2014-02-19 00:41:40 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-24 20:07:52 -0500 |
commit | c859aa65a7ec40c02f435f14fa71de2a87c64513 (patch) | |
tree | e3537338526d1b40612cf0434e7ec87553b869e4 /drivers/usb/chipidea/core.c | |
parent | 3c701651c8c5f35e846512070cdbf2f5980db62c (diff) |
usb: chipidea: refine PHY operation
- Delete global_phy due to we can get the phy from phy layer now
- using devm_usb_get_phy to instead of usb_get_phy
- delete the otg_set_peripheral, which should be handled by otg layer
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r-- | drivers/usb/chipidea/core.c | 70 |
1 files changed, 26 insertions, 44 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 33f22bc6ad7f..75aaa9c3cc4a 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -496,33 +496,6 @@ static void ci_get_otg_capable(struct ci_hdrc *ci) | |||
496 | } | 496 | } |
497 | } | 497 | } |
498 | 498 | ||
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) | 499 | static int ci_hdrc_probe(struct platform_device *pdev) |
527 | { | 500 | { |
528 | struct device *dev = &pdev->dev; | 501 | struct device *dev = &pdev->dev; |
@@ -561,7 +534,26 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
561 | 534 | ||
562 | hw_phymode_configure(ci); | 535 | hw_phymode_configure(ci); |
563 | 536 | ||
564 | ret = ci_usb_phy_init(ci); | 537 | if (ci->platdata->phy) |
538 | ci->transceiver = ci->platdata->phy; | ||
539 | else | ||
540 | ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
541 | |||
542 | if (IS_ERR(ci->transceiver)) { | ||
543 | ret = PTR_ERR(ci->transceiver); | ||
544 | /* | ||
545 | * if -ENXIO is returned, it means PHY layer wasn't | ||
546 | * enabled, so it makes no sense to return -EPROBE_DEFER | ||
547 | * in that case, since no PHY driver will ever probe. | ||
548 | */ | ||
549 | if (ret == -ENXIO) | ||
550 | return ret; | ||
551 | |||
552 | dev_err(dev, "no usb2 phy configured\n"); | ||
553 | return -EPROBE_DEFER; | ||
554 | } | ||
555 | |||
556 | ret = usb_phy_init(ci->transceiver); | ||
565 | if (ret) { | 557 | if (ret) { |
566 | dev_err(dev, "unable to init phy: %d\n", ret); | 558 | dev_err(dev, "unable to init phy: %d\n", ret); |
567 | return ret; | 559 | return ret; |
@@ -573,7 +565,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
573 | if (ci->irq < 0) { | 565 | if (ci->irq < 0) { |
574 | dev_err(dev, "missing IRQ\n"); | 566 | dev_err(dev, "missing IRQ\n"); |
575 | ret = -ENODEV; | 567 | ret = -ENODEV; |
576 | goto destroy_phy; | 568 | goto deinit_phy; |
577 | } | 569 | } |
578 | 570 | ||
579 | ci_get_otg_capable(ci); | 571 | ci_get_otg_capable(ci); |
@@ -590,23 +582,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
590 | ret = ci_hdrc_gadget_init(ci); | 582 | ret = ci_hdrc_gadget_init(ci); |
591 | if (ret) | 583 | if (ret) |
592 | dev_info(dev, "doesn't support gadget\n"); | 584 | 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 | } | 585 | } |
605 | 586 | ||
606 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { | 587 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { |
607 | dev_err(dev, "no supported roles\n"); | 588 | dev_err(dev, "no supported roles\n"); |
608 | ret = -ENODEV; | 589 | ret = -ENODEV; |
609 | goto destroy_phy; | 590 | goto deinit_phy; |
610 | } | 591 | } |
611 | 592 | ||
612 | if (ci->is_otg) { | 593 | if (ci->is_otg) { |
@@ -663,8 +644,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
663 | free_irq(ci->irq, ci); | 644 | free_irq(ci->irq, ci); |
664 | stop: | 645 | stop: |
665 | ci_role_destroy(ci); | 646 | ci_role_destroy(ci); |
666 | destroy_phy: | 647 | deinit_phy: |
667 | ci_usb_phy_destroy(ci); | 648 | usb_phy_shutdown(ci->transceiver); |
668 | 649 | ||
669 | return ret; | 650 | return ret; |
670 | } | 651 | } |
@@ -677,7 +658,8 @@ static int ci_hdrc_remove(struct platform_device *pdev) | |||
677 | free_irq(ci->irq, ci); | 658 | free_irq(ci->irq, ci); |
678 | ci_role_destroy(ci); | 659 | ci_role_destroy(ci); |
679 | ci_hdrc_enter_lpm(ci, true); | 660 | ci_hdrc_enter_lpm(ci, true); |
680 | ci_usb_phy_destroy(ci); | 661 | usb_phy_shutdown(ci->transceiver); |
662 | kfree(ci->hw_bank.regmap); | ||
681 | 663 | ||
682 | return 0; | 664 | return 0; |
683 | } | 665 | } |