aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2013-09-24 00:47:53 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-30 21:54:06 -0400
commit74475ede784d4a649592751e4d85bb8ff679e1e0 (patch)
treed29b65deb7bcdcf413b51ff6814814d0597fc053 /drivers/usb/chipidea
parentdf9b17f5868bdafd46cad18b08f1e70fa22b8854 (diff)
usb: chipidea: move PHY operation to core
PHY operations are common, so move them to core. Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r--drivers/usb/chipidea/core.c57
-rw-r--r--drivers/usb/chipidea/udc.c39
2 files changed, 52 insertions, 44 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index c47a6b46dea3..b20286de1436 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -474,6 +474,33 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
474 } 474 }
475} 475}
476 476
477static int ci_usb_phy_init(struct ci_hdrc *ci)
478{
479 if (ci->platdata->phy) {
480 ci->transceiver = ci->platdata->phy;
481 return usb_phy_init(ci->transceiver);
482 } else {
483 ci->global_phy = true;
484 ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
485 if (IS_ERR(ci->transceiver))
486 ci->transceiver = NULL;
487
488 return 0;
489 }
490}
491
492static void ci_usb_phy_destroy(struct ci_hdrc *ci)
493{
494 if (!ci->transceiver)
495 return;
496
497 otg_set_peripheral(ci->transceiver->otg, NULL);
498 if (ci->global_phy)
499 usb_put_phy(ci->transceiver);
500 else
501 usb_phy_shutdown(ci->transceiver);
502}
503
477static int ci_hdrc_probe(struct platform_device *pdev) 504static int ci_hdrc_probe(struct platform_device *pdev)
478{ 505{
479 struct device *dev = &pdev->dev; 506 struct device *dev = &pdev->dev;
@@ -501,10 +528,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
501 528
502 ci->dev = dev; 529 ci->dev = dev;
503 ci->platdata = dev->platform_data; 530 ci->platdata = dev->platform_data;
504 if (ci->platdata->phy)
505 ci->transceiver = ci->platdata->phy;
506 else
507 ci->global_phy = true;
508 531
509 ret = hw_device_init(ci, base); 532 ret = hw_device_init(ci, base);
510 if (ret < 0) { 533 if (ret < 0) {
@@ -512,12 +535,19 @@ static int ci_hdrc_probe(struct platform_device *pdev)
512 return -ENODEV; 535 return -ENODEV;
513 } 536 }
514 537
538 ret = ci_usb_phy_init(ci);
539 if (ret) {
540 dev_err(dev, "unable to init phy: %d\n", ret);
541 return ret;
542 }
543
515 ci->hw_bank.phys = res->start; 544 ci->hw_bank.phys = res->start;
516 545
517 ci->irq = platform_get_irq(pdev, 0); 546 ci->irq = platform_get_irq(pdev, 0);
518 if (ci->irq < 0) { 547 if (ci->irq < 0) {
519 dev_err(dev, "missing IRQ\n"); 548 dev_err(dev, "missing IRQ\n");
520 return -ENODEV; 549 ret = -ENODEV;
550 goto destroy_phy;
521 } 551 }
522 552
523 ci_get_otg_capable(ci); 553 ci_get_otg_capable(ci);
@@ -536,11 +566,23 @@ static int ci_hdrc_probe(struct platform_device *pdev)
536 ret = ci_hdrc_gadget_init(ci); 566 ret = ci_hdrc_gadget_init(ci);
537 if (ret) 567 if (ret)
538 dev_info(dev, "doesn't support gadget\n"); 568 dev_info(dev, "doesn't support gadget\n");
569 if (!ret && ci->transceiver) {
570 ret = otg_set_peripheral(ci->transceiver->otg,
571 &ci->gadget);
572 /*
573 * If we implement all USB functions using chipidea drivers,
574 * it doesn't need to call above API, meanwhile, if we only
575 * use gadget function, calling above API is useless.
576 */
577 if (ret && ret != -ENOTSUPP)
578 goto destroy_phy;
579 }
539 } 580 }
540 581
541 if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { 582 if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
542 dev_err(dev, "no supported roles\n"); 583 dev_err(dev, "no supported roles\n");
543 return -ENODEV; 584 ret = -ENODEV;
585 goto destroy_phy;
544 } 586 }
545 587
546 if (ci->is_otg) { 588 if (ci->is_otg) {
@@ -593,6 +635,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)
593 free_irq(ci->irq, ci); 635 free_irq(ci->irq, ci);
594stop: 636stop:
595 ci_role_destroy(ci); 637 ci_role_destroy(ci);
638destroy_phy:
639 ci_usb_phy_destroy(ci);
596 640
597 return ret; 641 return ret;
598} 642}
@@ -604,6 +648,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
604 dbg_remove_files(ci); 648 dbg_remove_files(ci);
605 free_irq(ci->irq, ci); 649 free_irq(ci->irq, ci);
606 ci_role_destroy(ci); 650 ci_role_destroy(ci);
651 ci_usb_phy_destroy(ci);
607 kfree(ci->hw_bank.regmap); 652 kfree(ci->hw_bank.regmap);
608 653
609 return 0; 654 return 0;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index b157c95f7a36..2bb7d18ef2d5 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -20,7 +20,6 @@
20#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
21#include <linux/usb/ch9.h> 21#include <linux/usb/ch9.h>
22#include <linux/usb/gadget.h> 22#include <linux/usb/gadget.h>
23#include <linux/usb/otg.h>
24#include <linux/usb/chipidea.h> 23#include <linux/usb/chipidea.h>
25 24
26#include "ci.h" 25#include "ci.h"
@@ -1790,34 +1789,9 @@ static int udc_start(struct ci_hdrc *ci)
1790 1789
1791 ci->gadget.ep0 = &ci->ep0in->ep; 1790 ci->gadget.ep0 = &ci->ep0in->ep;
1792 1791
1793 if (ci->global_phy) {
1794 ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
1795 if (IS_ERR(ci->transceiver))
1796 ci->transceiver = NULL;
1797 }
1798
1799 if (ci->platdata->flags & CI_HDRC_REQUIRE_TRANSCEIVER) {
1800 if (ci->transceiver == NULL) {
1801 retval = -ENODEV;
1802 goto destroy_eps;
1803 }
1804 }
1805
1806 if (ci->transceiver) {
1807 retval = otg_set_peripheral(ci->transceiver->otg,
1808 &ci->gadget);
1809 /*
1810 * If we implement all USB functions using chipidea drivers,
1811 * it doesn't need to call above API, meanwhile, if we only
1812 * use gadget function, calling above API is useless.
1813 */
1814 if (retval && retval != -ENOTSUPP)
1815 goto put_transceiver;
1816 }
1817
1818 retval = usb_add_gadget_udc(dev, &ci->gadget); 1792 retval = usb_add_gadget_udc(dev, &ci->gadget);
1819 if (retval) 1793 if (retval)
1820 goto remove_trans; 1794 goto destroy_eps;
1821 1795
1822 pm_runtime_no_callbacks(&ci->gadget.dev); 1796 pm_runtime_no_callbacks(&ci->gadget.dev);
1823 pm_runtime_enable(&ci->gadget.dev); 1797 pm_runtime_enable(&ci->gadget.dev);
@@ -1827,17 +1801,6 @@ static int udc_start(struct ci_hdrc *ci)
1827 1801
1828 return retval; 1802 return retval;
1829 1803
1830remove_trans:
1831 if (ci->transceiver) {
1832 otg_set_peripheral(ci->transceiver->otg, NULL);
1833 if (ci->global_phy)
1834 usb_put_phy(ci->transceiver);
1835 }
1836
1837 dev_err(dev, "error = %i\n", retval);
1838put_transceiver:
1839 if (ci->transceiver && ci->global_phy)
1840 usb_put_phy(ci->transceiver);
1841destroy_eps: 1804destroy_eps:
1842 destroy_eps(ci); 1805 destroy_eps(ci);
1843free_pools: 1806free_pools: