All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Chen <peter.chen@nxp.com>
To: "linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>
Cc: dl-linux-imx <linux-imx@nxp.com>,
	"robh+dt@kernel.org" <robh+dt@kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"frieder.schrempf@exceet.de" <frieder.schrempf@exceet.de>,
	"festevam@gmail.com" <festevam@gmail.com>,
	PETER CHEN <peter.chen@nxp.com>
Subject: [v3,3/4] usb: chipidea: host: override ehci->hub_control
Date: Tue, 27 Nov 2018 09:30:59 +0000	[thread overview]
Message-ID: <20181127092824.22756-4-peter.chen@nxp.com> (raw)

The chipidea controller has some special requirements during
suspend/resume, override common ehci->hub_control to implement
it.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
---
 drivers/usb/chipidea/host.c | 76 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 028a3574266a..aa4756dab487 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -220,6 +220,81 @@ void ci_hdrc_host_destroy(struct ci_hdrc *ci)
 		host_stop(ci);
 }
 
+/* The below code is based on tegra ehci driver */
+static int ci_ehci_hub_control(
+	struct usb_hcd	*hcd,
+	u16		typeReq,
+	u16		wValue,
+	u16		wIndex,
+	char		*buf,
+	u16		wLength
+)
+{
+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
+	u32 __iomem	*status_reg;
+	u32		temp;
+	unsigned long	flags;
+	int		retval = 0;
+	struct device *dev = hcd->self.controller;
+	struct ci_hdrc *ci = dev_get_drvdata(dev);
+
+	status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+
+	spin_lock_irqsave(&ehci->lock, flags);
+
+	if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
+		temp = ehci_readl(ehci, status_reg);
+		if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
+			retval = -EPIPE;
+			goto done;
+		}
+
+		temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
+		temp |= PORT_WKDISC_E | PORT_WKOC_E;
+		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+
+		/*
+		 * If a transaction is in progress, there may be a delay in
+		 * suspending the port. Poll until the port is suspended.
+		 */
+		if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
+						PORT_SUSPEND, 5000))
+			ehci_err(ehci, "timeout waiting for SUSPEND\n");
+
+		if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
+			if (ci->platdata->notify_event)
+				ci->platdata->notify_event
+					(ci, CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
+
+			temp = ehci_readl(ehci, status_reg);
+			temp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
+			ehci_writel(ehci, temp, status_reg);
+		}
+
+		set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
+		goto done;
+	}
+
+	/*
+	 * After resume has finished, it needs do some post resume
+	 * operation for some SoCs.
+	 */
+	else if (typeReq == ClearPortFeature &&
+					wValue == USB_PORT_FEAT_C_SUSPEND) {
+
+		/* Make sure the resume has finished, it should be finished */
+		if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
+			ehci_err(ehci, "timeout waiting for resume\n");
+	}
+
+	spin_unlock_irqrestore(&ehci->lock, flags);
+
+	/* Handle the hub control events here */
+	return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+done:
+	spin_unlock_irqrestore(&ehci->lock, flags);
+	return retval;
+}
 static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
 {
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -298,4 +373,5 @@ void ci_hdrc_host_driver_init(void)
 	ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
 	orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
 	ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
+	ci_ehci_hc_driver.hub_control = ci_ehci_hub_control;
 }

WARNING: multiple messages have this Message-ID (diff)
From: PETER CHEN <peter.chen@nxp.com>
To: "linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>
Cc: dl-linux-imx <linux-imx@nxp.com>,
	"robh+dt@kernel.org" <robh+dt@kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"frieder.schrempf@exceet.de" <frieder.schrempf@exceet.de>,
	"festevam@gmail.com" <festevam@gmail.com>,
	PETER CHEN <peter.chen@nxp.com>
Subject: [PATCH v3 3/4] usb: chipidea: host: override ehci->hub_control
Date: Tue, 27 Nov 2018 09:30:59 +0000	[thread overview]
Message-ID: <20181127092824.22756-4-peter.chen@nxp.com> (raw)
In-Reply-To: <20181127092824.22756-1-peter.chen@nxp.com>

The chipidea controller has some special requirements during
suspend/resume, override common ehci->hub_control to implement
it.

Signed-off-by: Peter Chen <peter.chen@nxp.com>
---
 drivers/usb/chipidea/host.c | 76 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 028a3574266a..aa4756dab487 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -220,6 +220,81 @@ void ci_hdrc_host_destroy(struct ci_hdrc *ci)
 		host_stop(ci);
 }
 
+/* The below code is based on tegra ehci driver */
+static int ci_ehci_hub_control(
+	struct usb_hcd	*hcd,
+	u16		typeReq,
+	u16		wValue,
+	u16		wIndex,
+	char		*buf,
+	u16		wLength
+)
+{
+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
+	u32 __iomem	*status_reg;
+	u32		temp;
+	unsigned long	flags;
+	int		retval = 0;
+	struct device *dev = hcd->self.controller;
+	struct ci_hdrc *ci = dev_get_drvdata(dev);
+
+	status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+
+	spin_lock_irqsave(&ehci->lock, flags);
+
+	if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
+		temp = ehci_readl(ehci, status_reg);
+		if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
+			retval = -EPIPE;
+			goto done;
+		}
+
+		temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
+		temp |= PORT_WKDISC_E | PORT_WKOC_E;
+		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+
+		/*
+		 * If a transaction is in progress, there may be a delay in
+		 * suspending the port. Poll until the port is suspended.
+		 */
+		if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
+						PORT_SUSPEND, 5000))
+			ehci_err(ehci, "timeout waiting for SUSPEND\n");
+
+		if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
+			if (ci->platdata->notify_event)
+				ci->platdata->notify_event
+					(ci, CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
+
+			temp = ehci_readl(ehci, status_reg);
+			temp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
+			ehci_writel(ehci, temp, status_reg);
+		}
+
+		set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
+		goto done;
+	}
+
+	/*
+	 * After resume has finished, it needs do some post resume
+	 * operation for some SoCs.
+	 */
+	else if (typeReq == ClearPortFeature &&
+					wValue == USB_PORT_FEAT_C_SUSPEND) {
+
+		/* Make sure the resume has finished, it should be finished */
+		if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
+			ehci_err(ehci, "timeout waiting for resume\n");
+	}
+
+	spin_unlock_irqrestore(&ehci->lock, flags);
+
+	/* Handle the hub control events here */
+	return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+done:
+	spin_unlock_irqrestore(&ehci->lock, flags);
+	return retval;
+}
 static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
 {
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -298,4 +373,5 @@ void ci_hdrc_host_driver_init(void)
 	ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
 	orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
 	ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
+	ci_ehci_hc_driver.hub_control = ci_ehci_hub_control;
 }
-- 
2.14.1

             reply	other threads:[~2018-11-27  9:30 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-27  9:30 Peter Chen [this message]
2018-11-27  9:30 ` [PATCH v3 3/4] usb: chipidea: host: override ehci->hub_control PETER CHEN
  -- strict thread matches above, loose matches on Subject: below --
2018-12-07 23:32 [v3,4/4] doc: usb: ci-hdrc-usb2: Add pinctrl properties for HSIC pin groups Rob Herring
2018-12-07 23:32 ` [PATCH v3 4/4] " Rob Herring
2018-12-05 11:10 [v3,4/4] " Fabio Estevam
2018-12-05 11:10 ` [PATCH v3 4/4] " Fabio Estevam
2018-12-05  8:00 [v3,4/4] " Frieder Schrempf
2018-12-05  8:00 ` [PATCH v3 4/4] " Schrempf Frieder
2018-12-05  7:57 [v3,4/4] " Peter Chen
2018-12-05  7:57 ` [PATCH v3 4/4] " PETER CHEN
2018-12-05  7:45 [v3,4/4] " Frieder Schrempf
2018-12-05  7:45 ` [PATCH v3 4/4] " Schrempf Frieder
2018-12-04 20:01 [v3,4/4] " Fabio Estevam
2018-12-04 20:01 ` [PATCH v3 4/4] " Fabio Estevam
2018-12-04 14:31 [v3,4/4] " Frieder Schrempf
2018-12-04 14:31 ` [PATCH v3 4/4] " Schrempf Frieder
2018-11-30  2:43 [v3,3/4] usb: chipidea: host: override ehci->hub_control Peter Chen
2018-11-30  2:43 ` [PATCH v3 3/4] " PETER CHEN
2018-11-30  2:33 [v3,4/4] doc: usb: ci-hdrc-usb2: Add pinctrl properties for HSIC pin groups Peter Chen
2018-11-30  2:33 ` [PATCH v3 4/4] " PETER CHEN
2018-11-27 13:41 [v3,2/4] usb: chipidea: imx: add HSIC support Frieder Schrempf
2018-11-27 13:41 ` [PATCH v3 2/4] " Schrempf Frieder
2018-11-27 13:41 [v3,3/4] usb: chipidea: host: override ehci->hub_control Frieder Schrempf
2018-11-27 13:41 ` [PATCH v3 3/4] " Schrempf Frieder
2018-11-27 13:40 [v3,1/4] usb: chipidea: add flag for imx hsic implementation Frieder Schrempf
2018-11-27 13:40 ` [PATCH v3 1/4] " Schrempf Frieder
2018-11-27 11:09 [v3,4/4] doc: usb: ci-hdrc-usb2: Add pinctrl properties for HSIC pin groups Fabio Estevam
2018-11-27 11:09 ` [PATCH v3 4/4] " Fabio Estevam
2018-11-27  9:31 [v3,4/4] " Peter Chen
2018-11-27  9:31 ` [PATCH v3 4/4] " PETER CHEN
2018-11-27  9:30 [v3,2/4] usb: chipidea: imx: add HSIC support Peter Chen
2018-11-27  9:30 ` [PATCH v3 2/4] " PETER CHEN
2018-11-27  9:30 [v3,1/4] usb: chipidea: add flag for imx hsic implementation Peter Chen
2018-11-27  9:30 ` [PATCH v3 1/4] " PETER CHEN
2018-11-27  9:30 [PATCH v3 0/4] usb: chipidea: imx: add HSIC support PETER CHEN

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181127092824.22756-4-peter.chen@nxp.com \
    --to=peter.chen@nxp.com \
    --cc=devicetree@vger.kernel.org \
    --cc=festevam@gmail.com \
    --cc=frieder.schrempf@exceet.de \
    --cc=linux-imx@nxp.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.