From 95f620eb0645bab75bd90d404375610d7deab1da Mon Sep 17 00:00:00 2001 From: "Wu, Hao" Date: Mon, 12 Mar 2012 16:36:03 +0800 Subject: [PATCH] usb/penwell_otg: stop ULPI polling when in test mode BZ: 26716 ULPI Polling will fail and cause HW/SW reset once entered test mode, so when it entered test mode, then notify penwell_otg to stop ULPI polling. Change-Id: I477b39ac9cd01a4baf8f848c323f703a3c6a114a Signed-off-by: Wu, Hao Reviewed-on: http://android.intel.com:8080/38322 Reviewed-by: Tang, Richard Reviewed-by: Zhuang, Jin Can Reviewed-by: Li, Wenji Reviewed-by: Meng, Zhe Tested-by: Meng, Zhe Reviewed-by: Saripalli, Ramakrishna Reviewed-by: buildbot Tested-by: buildbot --- drivers/usb/gadget/langwell_udc.c | 5 +++++ drivers/usb/otg/penwell_otg.c | 18 +++++++++++++++++- include/linux/usb/intel_mid_otg.h | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 6241337..cc46a8f 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c @@ -1677,6 +1677,9 @@ static void langwell_udc_stop_testmode(struct langwell_udc *dev) writel(portsc1, &dev->op_regs->portsc1); } + langwell_udc_notify_otg( + MID_OTG_NOTIFY_TEST_MODE_STOP); + dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return; } @@ -2251,6 +2254,8 @@ static void test_mode_complete(struct usb_ep *ep, struct usb_request *_req) langwell_vbus_draw(&dev->gadget, 0); case TEST_PACKET: case TEST_FORCE_EN: + langwell_udc_notify_otg( + MID_OTG_NOTIFY_TEST_MODE_START); portsc1 = readl(&dev->op_regs->portsc1); portsc1 |= req->test_mode << 16; writel(portsc1, &dev->op_regs->portsc1); diff --git a/drivers/usb/otg/penwell_otg.c b/drivers/usb/otg/penwell_otg.c index 5885b31..8a7e5af 100644 --- a/drivers/usb/otg/penwell_otg.c +++ b/drivers/usb/otg/penwell_otg.c @@ -2217,6 +2217,16 @@ static int penwell_otg_iotg_notify(struct notifier_block *nb, flag = 1; break; /* Test mode support */ + case MID_OTG_NOTIFY_TEST_MODE_START: + dev_dbg(pnw->dev, "PNW OTG Notfiy Client Testmode Start\n"); + iotg->hsm.in_test_mode = 1; + flag = 0; + break; + case MID_OTG_NOTIFY_TEST_MODE_STOP: + dev_dbg(pnw->dev, "PNW OTG Notfiy Client Testmode Stop\n"); + iotg->hsm.in_test_mode = 0; + flag = 0; + break; case MID_OTG_NOTIFY_TEST_SRP_REQD: dev_dbg(pnw->dev, "PNW OTG Notfiy Client SRP REQD\n"); iotg->hsm.otg_srp_reqd = 1; @@ -2324,6 +2334,9 @@ static void penwell_otg_ulpi_poll_work(struct work_struct *work) if (iotg->otg.state != OTG_STATE_B_PERIPHERAL) return; + if (iotg->hsm.in_test_mode) + return; + if (penwell_otg_ulpi_read(iotg, 0x16, &data)) { dev_err(pnw->dev, "ulpi read time out by polling\n"); iotg->hsm.ulpi_error = 1; @@ -2571,6 +2584,9 @@ static void penwell_otg_work(struct work_struct *work) penwell_otg_eye_diagram_optimize(); /* MFLD WA for PHY issue */ + iotg->hsm.in_test_mode = 0; + iotg->hsm.ulpi_error = 0; + if (!is_clovertrail(pdev)) penwell_otg_start_ulpi_poll(); @@ -2654,7 +2670,7 @@ static void penwell_otg_work(struct work_struct *work) iotg->otg.state = OTG_STATE_A_IDLE; penwell_update_transceiver(); - } else if (hsm->ulpi_error) { + } else if (hsm->ulpi_error && !hsm->in_test_mode) { /* WA: try to recover once detected PHY issue */ hsm->ulpi_error = 0; diff --git a/include/linux/usb/intel_mid_otg.h b/include/linux/usb/intel_mid_otg.h index eb25a3a..3695594 100644 --- a/include/linux/usb/intel_mid_otg.h +++ b/include/linux/usb/intel_mid_otg.h @@ -98,6 +98,7 @@ struct otg_hsm { int otg_srp_reqd; int otg_hnp_reqd; int otg_vbus_off; + int in_test_mode; }; /* must provide ULPI access function to read/write registers implemented in @@ -190,6 +191,8 @@ struct intel_mid_otg_xceiv *otg_to_mid_xceiv(struct otg_transceiver *otg) #define MID_OTG_NOTIFY_TEST_SRP_REQD 0x0101 #define MID_OTG_NOTIFY_TEST_VBUS_OFF 0x0102 #define MID_OTG_NOTIFY_TEST 0x0103 +#define MID_OTG_NOTIFY_TEST_MODE_START 0x0104 +#define MID_OTG_NOTIFY_TEST_MODE_STOP 0x0105 static inline int intel_mid_otg_register_notifier(struct intel_mid_otg_xceiv *iotg, -- 2.7.4