[04/11] usb: dwc3: gadget: implement dwc3_gadget_get_link_state

Message ID 1393357243-2958-5-git-send-email-balbi@ti.com
State New
Headers show

Commit Message

Felipe Balbi Feb. 25, 2014, 7:40 p.m.
From: Paul Zimmerman <Paul.Zimmerman@synopsys.com>

This function will be used during hibernation to get
the current link state. It will be needed at least
for Hibernation support.

Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/gadget.c | 36 ++++++++++++++++++++++++++++++++++++
 drivers/usb/dwc3/gadget.h |  1 +
 2 files changed, 37 insertions(+)

Comments

Felipe Balbi Feb. 25, 2014, 8:50 p.m. | #1
On Wed, Feb 26, 2014 at 12:10:09AM +0300, Sergei Shtylyov wrote:
> Hello.
> 
> On 02/25/2014 10:40 PM, Felipe Balbi wrote:
> 
> >From: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
> 
> >This function will be used during hibernation to get
> >the current link state. It will be needed at least
> >for Hibernation support.
> 
> >Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
> >Signed-off-by: Felipe Balbi <balbi@ti.com>
> >---
> >  drivers/usb/dwc3/gadget.c | 36 ++++++++++++++++++++++++++++++++++++
> >  drivers/usb/dwc3/gadget.h |  1 +
> >  2 files changed, 37 insertions(+)
> 
> >diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> >index 31b13c2..ff10161 100644
> >--- a/drivers/usb/dwc3/gadget.c
> >+++ b/drivers/usb/dwc3/gadget.c
> >@@ -68,6 +68,42 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
> >  }
> >
> >  /**
> >+ * dwc3_gadget_get_lik_state - Gets current state of USB Link
> >+ * @dwc: pointer to our context structure
> >+ *
> >+ * Caller should take care of locking. This function will
> >+ * return the link state on success (>= 0) or -ETIMEDOUT.
> >+ */
> >+int dwc3_gadget_get_link_state(struct dwc3 *dwc)
> >+{
> >+	u32		reg;
> >+
> >+	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
> >+
> >+	/*
> >+	 * Wait until device controller is ready.
> >+	 * (This only applied to 1.94a and later
> >+	 * RTL releases)
> >+	 */
> >+	if (dwc->revision >= DWC3_REVISION_194A) {
> >+		int	retries = 10000;
> >+
> >+		do {
> >+			reg = dwc3_readl(dwc->regs, DWC3_DSTS);
> >+			if (!(reg & DWC3_DSTS_DCNRD))
> >+				break;
> >+
> >+			if (!retries)
> 
>    Hm, I doubt this will ever be true. This check would be meaningful
> after the loop...

good catch, I'll update the patch.
Felipe Balbi Feb. 26, 2014, 3:43 p.m. | #2
Hi,

On Wed, Feb 26, 2014 at 03:34:43PM +0530, Pratyush Anand wrote:
> On Wed, Feb 26, 2014 at 03:40:36AM +0800, Felipe Balbi wrote:
> > From: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
> > 
> > This function will be used during hibernation to get
> > the current link state. It will be needed at least
> > for Hibernation support.
> > 
> 
> Since we do receive linksts_change_interrupt, where we already update
> dwc->link_state. So, do we really need it.

I'll let Paul comment on this one.
Felipe Balbi Feb. 27, 2014, 4:50 p.m. | #3
Hi,


On Wed, Feb 26, 2014 at 11:00:33PM +0000, Paul Zimmerman wrote:
> Hi Felipe,
> 
> Can you drop the part that checks the DCNRD bit, please? I made a
> mistake when I originally submitted this. It is not necessary to check
> the DCNRD bit every time before reading the link state, it should only
> be checked the first time after coming out of hibernation. Doing it
> every time is unnecessary overhead, and can even cause problems with a
> hibernation-enabled controller.
> 
> So for now maybe just drop the entire patch, and instead call
> DWC3_DSTS_USBLNKST() directly?

I removed the DCNRD check but kept the function around. updated patch
pushed to dwc3-hibernation

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 31b13c2..ff10161 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -68,6 +68,42 @@  int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode)
 }
 
 /**
+ * dwc3_gadget_get_lik_state - Gets current state of USB Link
+ * @dwc: pointer to our context structure
+ *
+ * Caller should take care of locking. This function will
+ * return the link state on success (>= 0) or -ETIMEDOUT.
+ */
+int dwc3_gadget_get_link_state(struct dwc3 *dwc)
+{
+	u32		reg;
+
+	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+
+	/*
+	 * Wait until device controller is ready.
+	 * (This only applied to 1.94a and later
+	 * RTL releases)
+	 */
+	if (dwc->revision >= DWC3_REVISION_194A) {
+		int	retries = 10000;
+
+		do {
+			reg = dwc3_readl(dwc->regs, DWC3_DSTS);
+			if (!(reg & DWC3_DSTS_DCNRD))
+				break;
+
+			if (!retries)
+				return -ETIMEDOUT;
+
+			udelay(5);
+		} while (--retries);
+	}
+
+	return DWC3_DSTS_USBLNKST(reg);
+}
+
+/**
  * dwc3_gadget_set_link_state - Sets USB Link to a particular State
  * @dwc: pointer to our context structure
  * @state: the state to put link into
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index febe1aa..d101244 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -86,6 +86,7 @@  void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 		int status);
 
 int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode);
+int dwc3_gadget_get_link_state(struct dwc3 *dwc);
 int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
 
 void dwc3_ep0_interrupt(struct dwc3 *dwc,