diff options
author | Peter Chen <peter.chen@freescale.com> | 2014-02-19 00:41:40 -0500 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:58:01 -0400 |
commit | 7cdfed037192bf9adf8bb80cd427883c77f84435 (patch) | |
tree | 21a7c9c6dc53391b9e7409e7791d27ae37fe2c97 | |
parent | 582ecdb29d528a965656f81ed357190a98373480 (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>
-rw-r--r-- | drivers/usb/chipidea/ci.h | 2 | ||||
-rw-r--r-- | drivers/usb/chipidea/core.c | 76 | ||||
-rw-r--r-- | drivers/usb/chipidea/udc.c | 6 |
3 files changed, 27 insertions, 57 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index a37255edc503..dee75c33c08b 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h | |||
@@ -171,8 +171,6 @@ struct ci_hdrc { | |||
171 | 171 | ||
172 | struct ci_hdrc_platform_data *platdata; | 172 | struct ci_hdrc_platform_data *platdata; |
173 | int vbus_active; | 173 | int vbus_active; |
174 | /* FIXME: some day, we'll not use global phy */ | ||
175 | bool global_phy; | ||
176 | struct usb_phy *transceiver; | 174 | struct usb_phy *transceiver; |
177 | struct usb_hcd *hcd; | 175 | struct usb_hcd *hcd; |
178 | struct dentry *debugfs; | 176 | struct dentry *debugfs; |
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index fb38df9356d4..75e23f550736 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -542,38 +542,6 @@ static void ci_get_otg_capable(struct ci_hdrc *ci) | |||
542 | } | 542 | } |
543 | } | 543 | } |
544 | 544 | ||
545 | static int ci_usb_phy_init(struct ci_hdrc *ci) | ||
546 | { | ||
547 | int ret; | ||
548 | |||
549 | if (ci->platdata->phy) { | ||
550 | ci->transceiver = ci->platdata->phy; | ||
551 | ret = usb_phy_init(ci->transceiver); | ||
552 | if (!ret) | ||
553 | hw_wait_phy_stable(); | ||
554 | return ret; | ||
555 | } else { | ||
556 | ci->global_phy = true; | ||
557 | ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | ||
558 | if (IS_ERR(ci->transceiver)) | ||
559 | ci->transceiver = NULL; | ||
560 | |||
561 | return 0; | ||
562 | } | ||
563 | } | ||
564 | |||
565 | static void ci_usb_phy_destroy(struct ci_hdrc *ci) | ||
566 | { | ||
567 | if (!ci->transceiver) | ||
568 | return; | ||
569 | |||
570 | otg_set_peripheral(ci->transceiver->otg, NULL); | ||
571 | if (ci->global_phy) | ||
572 | usb_put_phy(ci->transceiver); | ||
573 | else | ||
574 | usb_phy_shutdown(ci->transceiver); | ||
575 | } | ||
576 | |||
577 | static int ci_hdrc_probe(struct platform_device *pdev) | 545 | static int ci_hdrc_probe(struct platform_device *pdev) |
578 | { | 546 | { |
579 | struct device *dev = &pdev->dev; | 547 | struct device *dev = &pdev->dev; |
@@ -612,10 +580,31 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
612 | 580 | ||
613 | hw_phymode_configure(ci); | 581 | hw_phymode_configure(ci); |
614 | 582 | ||
615 | ret = ci_usb_phy_init(ci); | 583 | if (ci->platdata->phy) |
584 | ci->transceiver = ci->platdata->phy; | ||
585 | else | ||
586 | ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | ||
587 | |||
588 | if (IS_ERR(ci->transceiver)) { | ||
589 | ret = PTR_ERR(ci->transceiver); | ||
590 | /* | ||
591 | * if -ENXIO is returned, it means PHY layer wasn't | ||
592 | * enabled, so it makes no sense to return -EPROBE_DEFER | ||
593 | * in that case, since no PHY driver will ever probe. | ||
594 | */ | ||
595 | if (ret == -ENXIO) | ||
596 | return ret; | ||
597 | |||
598 | dev_err(dev, "no usb2 phy configured\n"); | ||
599 | return -EPROBE_DEFER; | ||
600 | } | ||
601 | |||
602 | ret = usb_phy_init(ci->transceiver); | ||
616 | if (ret) { | 603 | if (ret) { |
617 | dev_err(dev, "unable to init phy: %d\n", ret); | 604 | dev_err(dev, "unable to init phy: %d\n", ret); |
618 | return ret; | 605 | return ret; |
606 | } else { | ||
607 | hw_wait_phy_stable(); | ||
619 | } | 608 | } |
620 | 609 | ||
621 | ci->hw_bank.phys = res->start; | 610 | ci->hw_bank.phys = res->start; |
@@ -624,7 +613,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
624 | if (ci->irq < 0) { | 613 | if (ci->irq < 0) { |
625 | dev_err(dev, "missing IRQ\n"); | 614 | dev_err(dev, "missing IRQ\n"); |
626 | ret = -ENODEV; | 615 | ret = -ENODEV; |
627 | goto destroy_phy; | 616 | goto deinit_phy; |
628 | } | 617 | } |
629 | 618 | ||
630 | ci_get_otg_capable(ci); | 619 | ci_get_otg_capable(ci); |
@@ -645,23 +634,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
645 | ret = ci_hdrc_gadget_init(ci); | 634 | ret = ci_hdrc_gadget_init(ci); |
646 | if (ret) | 635 | if (ret) |
647 | dev_info(dev, "doesn't support gadget\n"); | 636 | dev_info(dev, "doesn't support gadget\n"); |
648 | if (!ret && ci->transceiver) { | ||
649 | ret = otg_set_peripheral(ci->transceiver->otg, | ||
650 | &ci->gadget); | ||
651 | /* | ||
652 | * If we implement all USB functions using chipidea drivers, | ||
653 | * it doesn't need to call above API, meanwhile, if we only | ||
654 | * use gadget function, calling above API is useless. | ||
655 | */ | ||
656 | if (ret && ret != -ENOTSUPP) | ||
657 | goto destroy_phy; | ||
658 | } | ||
659 | } | 637 | } |
660 | 638 | ||
661 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { | 639 | if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { |
662 | dev_err(dev, "no supported roles\n"); | 640 | dev_err(dev, "no supported roles\n"); |
663 | ret = -ENODEV; | 641 | ret = -ENODEV; |
664 | goto destroy_phy; | 642 | goto deinit_phy; |
665 | } | 643 | } |
666 | 644 | ||
667 | if (ci->is_otg) { | 645 | if (ci->is_otg) { |
@@ -722,8 +700,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
722 | free_irq(ci->irq, ci); | 700 | free_irq(ci->irq, ci); |
723 | stop: | 701 | stop: |
724 | ci_role_destroy(ci); | 702 | ci_role_destroy(ci); |
725 | destroy_phy: | 703 | deinit_phy: |
726 | ci_usb_phy_destroy(ci); | 704 | usb_phy_shutdown(ci->transceiver); |
727 | 705 | ||
728 | return ret; | 706 | return ret; |
729 | } | 707 | } |
@@ -741,7 +719,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) | |||
741 | free_irq(ci->irq, ci); | 719 | free_irq(ci->irq, ci); |
742 | ci_role_destroy(ci); | 720 | ci_role_destroy(ci); |
743 | ci_hdrc_enter_lpm(ci, true); | 721 | ci_hdrc_enter_lpm(ci, true); |
744 | ci_usb_phy_destroy(ci); | 722 | usb_phy_shutdown(ci->transceiver); |
745 | kfree(ci->hw_bank.regmap); | 723 | kfree(ci->hw_bank.regmap); |
746 | 724 | ||
747 | return 0; | 725 | return 0; |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c318e66cc575..7ec2b54926a0 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -1885,12 +1885,6 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci) | |||
1885 | 1885 | ||
1886 | dma_pool_destroy(ci->td_pool); | 1886 | dma_pool_destroy(ci->td_pool); |
1887 | dma_pool_destroy(ci->qh_pool); | 1887 | dma_pool_destroy(ci->qh_pool); |
1888 | |||
1889 | if (ci->transceiver) { | ||
1890 | otg_set_peripheral(ci->transceiver->otg, NULL); | ||
1891 | if (ci->global_phy) | ||
1892 | usb_put_phy(ci->transceiver); | ||
1893 | } | ||
1894 | } | 1888 | } |
1895 | 1889 | ||
1896 | static int udc_id_switch_for_device(struct ci_hdrc *ci) | 1890 | static int udc_id_switch_for_device(struct ci_hdrc *ci) |