linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pavankumar Kondeti <pkondeti@codeaurora.org>
To: greg@kroah.com
Cc: linux-usb@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	Pavankumar Kondeti <pkondeti@codeaurora.org>,
	Vamsi Krishna <vskrishn@codeaurora.org>
Subject: [PATCH v2] USB: msm72k_udc: Add Remote wakeup support
Date: Tue,  9 Nov 2010 16:48:12 +0530	[thread overview]
Message-ID: <1289301494-26150-4-git-send-email-pkondeti@codeaurora.org> (raw)
In-Reply-To: <1289301494-26150-1-git-send-email-pkondeti@codeaurora.org>

Process device remote wakeup set/clear feature requests and implement
wakeup method of usb_gadget_ops.  This patch also provides a sysfs file
to initiate remote wakeup from user space.  Remote wakeup can be generated
by poking into /sys/devices/platform/msm_hsusb/gadget/wakeup file.

Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Vamsi Krishna <vskrishn@codeaurora.org>
---
 drivers/usb/gadget/msm72k_udc.c  |   62 ++++++++++++++++++++++++++++++++++++++
 include/linux/usb/msm_hsusb_hw.h |    3 ++
 2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 6ec1a32..51e9f2e 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -179,6 +179,7 @@ static void usb_do_work(struct work_struct *w);
  * @clk: clock struct of usb_hs_clk.
  * @pclk: clock struct of usb_hs_pclk.
  * @ep0_dir: direction of ep0 setup data transfer.
+ * @remote_wakeup: indicates remote wakeup capability enabled by host
  *
  */
 struct usb_info {
@@ -221,6 +222,7 @@ struct usb_info {
 	struct clk *pclk;
 
 	unsigned int ep0_dir;
+	u8 remote_wakeup;
 };
 
 static const struct usb_ep_ops msm72k_ep_ops;
@@ -647,6 +649,8 @@ static void handle_setup(struct usb_info *ui)
 				u16 temp = 0;
 
 				temp = 1 << USB_DEVICE_SELF_POWERED;
+				temp |= (ui->remote_wakeup <<
+						USB_DEVICE_REMOTE_WAKEUP);
 				memcpy(req->buf, &temp, 2);
 				break;
 			}
@@ -695,6 +699,16 @@ static void handle_setup(struct usb_info *ui)
 			*/
 			writel((ctl.wValue << 25) | (1 << 24), USB_DEVICEADDR);
 			goto ack;
+		} else if (ctl.bRequest == USB_REQ_SET_FEATURE) {
+			switch (ctl.wValue) {
+			case USB_DEVICE_REMOTE_WAKEUP:
+				ui->remote_wakeup = 1;
+				goto ack;
+			}
+		} else if ((ctl.bRequest == USB_REQ_CLEAR_FEATURE) &&
+				(ctl.wValue == USB_DEVICE_REMOTE_WAKEUP)) {
+			ui->remote_wakeup = 0;
+			goto ack;
 		}
 	}
 
@@ -900,6 +914,7 @@ static irqreturn_t usb_interrupt(int irq, void *data)
 		writel(readl(USB_ENDPTCOMPLETE), USB_ENDPTCOMPLETE);
 		writel(0xffffffff, USB_ENDPTFLUSH);
 		writel(0, USB_ENDPTCTRL(1));
+		ui->remote_wakeup = 0;
 
 		if (ui->online != 0) {
 			/* marking us offline will cause ept queue attempts
@@ -1660,12 +1675,52 @@ static int msm72k_pullup(struct usb_gadget *_gadget, int is_active)
 	return 0;
 }
 
+static int msm72k_wakeup(struct usb_gadget *_gadget)
+{
+	struct usb_info *ui = container_of(_gadget, struct usb_info, gadget);
+	unsigned long flags;
+
+	if (!ui->remote_wakeup) {
+		dev_err(&ui->pdev->dev, "%s: remote wakeup not supported\n",
+				__func__);
+		return -ENOTSUPP;
+	}
+
+	if (!ui->online) {
+		dev_err(&ui->pdev->dev, "%s: device is not configured\n",
+				__func__);
+		return -ENODEV;
+	}
+
+	spin_lock_irqsave(&ui->lock, flags);
+	if ((readl(USB_PORTSC) & PORTSC_SUSP) == PORTSC_SUSP) {
+		dev_info(&ui->pdev->dev, "%s: enabling force resume\n",
+				__func__);
+		writel(readl(USB_PORTSC) | PORTSC_FPR, USB_PORTSC);
+	}
+	spin_unlock_irqrestore(&ui->lock, flags);
+
+	return 0;
+}
+
 static const struct usb_gadget_ops msm72k_ops = {
 	.get_frame	= msm72k_get_frame,
 	.vbus_session	= msm72k_udc_vbus_session,
 	.pullup		= msm72k_pullup,
+	.wakeup		= msm72k_wakeup,
 };
 
+static ssize_t usb_remote_wakeup(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct usb_info *ui = the_usb_info;
+
+	msm72k_wakeup(&ui->gadget);
+
+	return count;
+}
+static DEVICE_ATTR(wakeup, S_IWUSR, 0, usb_remote_wakeup);
+
 static int msm72k_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -1795,6 +1850,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 	dev_info(&ui->pdev->dev, "registered gadget driver '%s'\n",
 			driver->driver.name);
 
+	/* create sysfs node for remote wakeup */
+	retval = device_create_file(&ui->gadget.dev, &dev_attr_wakeup);
+	if (retval != 0)
+		dev_info(&ui->pdev->dev, "failed to create sysfs entry:"
+				"(wakeup) error: (%d)\n", retval);
+
 	usb_start(ui);
 
 	return 0;
@@ -1815,6 +1876,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 	if (!driver || driver != dev->driver || !driver->unbind)
 		return -EINVAL;
 
+	device_remove_file(&dev->gadget.dev, &dev_attr_wakeup);
 	driver->unbind(&dev->gadget);
 	dev->gadget.dev.driver = NULL;
 	dev->driver = NULL;
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index cfbd0aa..6f54268 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -171,6 +171,9 @@ struct ept_queue_item {
 #define PORTSC_PSPD_LS        (1 << 26)
 #define PORTSC_PSPD_HS        (2 << 26)
 #define PORTSC_PSPD_MASK      (3 << 26)
+/* suspend and remote wakeup */
+#define PORTSC_FPR             (1 << 6)
+#define PORTSC_SUSP            (1 << 7)
 
 #define PORTSC_PTS_MASK       (3 << 30)
 #define PORTSC_PTS_ULPI       (2 << 30)
-- 
1.7.1

--
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

  parent reply	other threads:[~2010-11-09 11:18 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-09 11:18 [PATCH v2] Add MSM USB Device Controller support Pavankumar Kondeti
2010-11-09 11:18 ` [PATCH v2] USB: Add MSM USB Device Controller driver Pavankumar Kondeti
2010-11-09 11:40   ` Matthieu CASTET
2010-11-09 12:16     ` Pavan Kondeti
2010-11-09 13:36       ` Matthieu CASTET
2010-11-10  2:12         ` Pavan Kondeti
2010-11-10  2:54           ` David Brownell
2010-11-10  6:22             ` Brian Swetland
2010-11-19 17:16               ` Matthieu CASTET
2010-11-27 14:00                 ` Pavan Kondeti
2010-11-28  6:30                   ` David Brownell
2010-11-28 12:09                     ` Pavan Kondeti
2010-12-07 12:44                 ` Pavan Kondeti
2010-11-09 13:25   ` Heikki Krogerus
2010-11-09 13:52   ` Matthieu CASTET
2010-11-09 15:36     ` Igor Grinberg
2010-11-10  2:19       ` Pavan Kondeti
2010-11-10  6:47         ` Igor Grinberg
2010-11-11  2:10           ` Pavan Kondeti
2010-11-19  5:50             ` Pavan Kondeti
2010-11-21  8:09               ` Igor Grinberg
2010-11-10  2:17     ` Pavan Kondeti
2010-11-09 11:18 ` [PATCH v2] USB: msm72k_udc: Add debugfs support Pavankumar Kondeti
2010-11-09 11:18 ` Pavankumar Kondeti [this message]
2010-11-09 11:18 ` [PATCH v2] USB: msm72k_udc: Add Test Mode support Pavankumar Kondeti
2010-11-09 11:18 ` [PATCH] USB: msm72k_udc: Add charging notification support Pavankumar Kondeti

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=1289301494-26150-4-git-send-email-pkondeti@codeaurora.org \
    --to=pkondeti@codeaurora.org \
    --cc=greg@kroah.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=vskrishn@codeaurora.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).