From 643cc4dee1ee804b46f8d288babca046cca7e099 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Fri, 30 Jan 2015 09:09:32 +0100 Subject: usb: dwc2: gadget: add reset flag in init function Add a flag to request physical reset of the controller when s3c_hsotg_core_init_disconnected is called. During the usb reset, controller must not be fully reconfigured and resetted. Else this leads to shorter chirp-k duration during enumeration. Tested-by: Robert Baldyga Acked-by: John Youn Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 6 ++++-- drivers/usb/dwc2/gadget.c | 33 +++++++++++++++++++++------------ drivers/usb/dwc2/hcd.c | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 485b195126e..f74304b1265 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -999,7 +999,8 @@ extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); -extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2); +extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, + bool reset); extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); #else @@ -1011,7 +1012,8 @@ static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } -static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2) {} +static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, + bool reset) {} static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} #endif diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 5e91cf154bb..3cf9c6a5e2c 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2271,9 +2271,13 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) * * Issue a soft reset to the core, and await the core finishing it. */ -void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) +void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, + bool is_usb_reset) { - s3c_hsotg_corereset(hsotg); + u32 val; + + if (!is_usb_reset) + s3c_hsotg_corereset(hsotg); /* * we must now enable ep0 ready for host detection and then @@ -2286,7 +2290,8 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) s3c_hsotg_init_fifo(hsotg); - __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); + if (!is_usb_reset) + __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); writel(1 << 18 | DCFG_DEVSPD_HS, hsotg->regs + DCFG); @@ -2357,9 +2362,11 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); - __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); - udelay(10); /* see openiboot */ - __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); + if (!is_usb_reset) { + __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); + udelay(10); /* see openiboot */ + __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); + } dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL)); @@ -2388,8 +2395,10 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg) readl(hsotg->regs + DOEPCTL0)); /* clear global NAKs */ - writel(DCTL_CGOUTNAK | DCTL_CGNPINNAK | DCTL_SFTDISCON, - hsotg->regs + DCTL); + val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; + if (!is_usb_reset) + val |= DCTL_SFTDISCON; + __orr32(hsotg->regs + DCTL, val); /* must be at-least 3ms to allow bus to see disconnect */ mdelay(3); @@ -2482,7 +2491,7 @@ irq_retry: kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); - s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_init_disconnected(hsotg, true); s3c_hsotg_core_connect(hsotg); } } @@ -3052,7 +3061,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, spin_lock_irqsave(&hsotg->lock, flags); s3c_hsotg_init(hsotg); - s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_init_disconnected(hsotg, false); hsotg->enabled = 0; spin_unlock_irqrestore(&hsotg->lock, flags); @@ -3171,7 +3180,7 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) if (is_active) { /* Kill any ep0 requests as controller will be reinitialized */ kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); - s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) s3c_hsotg_core_connect(hsotg); } else { @@ -4097,7 +4106,7 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) s3c_hsotg_phy_enable(hsotg); spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) s3c_hsotg_core_connect(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 4a9bcdd5cb2..c78c8740db1 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1373,7 +1373,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); - s3c_hsotg_core_init_disconnected(hsotg); + s3c_hsotg_core_init_disconnected(hsotg, false); s3c_hsotg_core_connect(hsotg); } else { /* A-Device connector (Host Mode) */ -- cgit v1.2.3-70-g09d2