aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/core.c
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2014-04-23 03:56:41 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-04-24 15:56:34 -0400
commit90893b90d372f9c721ab8cd64b66230670deded3 (patch)
tree30276d209812d4e9ddbaf4fa97ff098b6e71b935 /drivers/usb/chipidea/core.c
parentc4a8b6392a3f131259aa2392cfc6bb6d0ca549f9 (diff)
usb: chipidea: add proper delay for waiting correct PHY status
After the PHY has powered and initialized, it needs some delay for controller to reflect PHY's status. Some status and values for id, vbus, dp/dm are only stable after this delay. The current code tries to clear id/vbus status without enough delay, it causes the status are not cleared properly. This patch add 2ms delay after phy has initialized, and clear the unexpected status after that. Signed-off-by: Peter Chen <peter.chen@freescale.com> Tested-by: Li Jun <b47624@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.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index ff38cf367464..d506f342d013 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -199,11 +199,10 @@ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
199 hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm), 199 hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
200 0); 200 0);
201 /* 201 /*
202 * The controller needs at least 1ms to reflect 202 * the PHY needs some time (less
203 * PHY's status, the PHY also needs some time (less
204 * than 1ms) to leave low power mode. 203 * than 1ms) to leave low power mode.
205 */ 204 */
206 usleep_range(1500, 2000); 205 usleep_range(1000, 1100);
207 } 206 }
208} 207}
209 208
@@ -555,12 +554,8 @@ static void ci_get_otg_capable(struct ci_hdrc *ci)
555 ci->is_otg = (hw_read(ci, CAP_DCCPARAMS, 554 ci->is_otg = (hw_read(ci, CAP_DCCPARAMS,
556 DCCPARAMS_DC | DCCPARAMS_HC) 555 DCCPARAMS_DC | DCCPARAMS_HC)
557 == (DCCPARAMS_DC | DCCPARAMS_HC)); 556 == (DCCPARAMS_DC | DCCPARAMS_HC));
558 if (ci->is_otg) { 557 if (ci->is_otg)
559 dev_dbg(ci->dev, "It is OTG capable controller\n"); 558 dev_dbg(ci->dev, "It is OTG capable controller\n");
560 /* Disable and clear all OTG irq */
561 hw_write_otgsc(ci, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS,
562 OTGSC_INT_STATUS_BITS);
563 }
564} 559}
565 560
566static int ci_hdrc_probe(struct platform_device *pdev) 561static int ci_hdrc_probe(struct platform_device *pdev)
@@ -622,6 +617,13 @@ static int ci_hdrc_probe(struct platform_device *pdev)
622 if (ret) { 617 if (ret) {
623 dev_err(dev, "unable to init phy: %d\n", ret); 618 dev_err(dev, "unable to init phy: %d\n", ret);
624 return ret; 619 return ret;
620 } else {
621 /*
622 * The delay to sync PHY's status, the maximum delay is
623 * 2ms since the otgsc uses 1ms timer to debounce the
624 * PHY's input
625 */
626 usleep_range(2000, 2500);
625 } 627 }
626 628
627 ci->hw_bank.phys = res->start; 629 ci->hw_bank.phys = res->start;
@@ -656,6 +658,9 @@ static int ci_hdrc_probe(struct platform_device *pdev)
656 } 658 }
657 659
658 if (ci->is_otg) { 660 if (ci->is_otg) {
661 /* Disable and clear all OTG irq */
662 hw_write_otgsc(ci, OTGSC_INT_EN_BITS | OTGSC_INT_STATUS_BITS,
663 OTGSC_INT_STATUS_BITS);
659 ret = ci_hdrc_otg_init(ci); 664 ret = ci_hdrc_otg_init(ci);
660 if (ret) { 665 if (ret) {
661 dev_err(dev, "init otg fails, ret = %d\n", ret); 666 dev_err(dev, "init otg fails, ret = %d\n", ret);
@@ -665,11 +670,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
665 670
666 if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) { 671 if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
667 if (ci->is_otg) { 672 if (ci->is_otg) {
668 /*
669 * ID pin needs 1ms debouce time,
670 * we delay 2ms for safe.
671 */
672 mdelay(2);
673 ci->role = ci_otg_role(ci); 673 ci->role = ci_otg_role(ci);
674 /* Enable ID change irq */ 674 /* Enable ID change irq */
675 hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE); 675 hw_write_otgsc(ci, OTGSC_IDIE, OTGSC_IDIE);