From: "Zhang, Yanmin" <yanmin_zhang@linux.intel.com>
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
xinhuix.pan@intel.com,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Alan Cox <alan@linux.intel.com>
Subject: [PATCH 1/3] usb: add function usb_autopm_get_interface_upgrade
Date: Tue, 26 May 2015 10:19:57 +0800 [thread overview]
Message-ID: <5563D84D.5070702@linux.intel.com> (raw)
Some usb driver has a specific requirement. Their critical functions
might be called under both atomic environment and non-atomic environment.
If it's under atomic environment, the driver can wake up the device
by calling pm_runtime_get_sync directly.
If it's under non-atomic environment, the function's caller need wake
up the device before the function accesses the device.
The patch adds usb_autopm_get_interface_upgrade, a new function to
support above capability.
Signed-off-by: Zhang Yanmin <yanmin.zhang@intel.com>
---
drivers/usb/core/driver.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/usb.h | 3 +++
2 files changed, 56 insertions(+)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 818369a..d07fd8d 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1684,6 +1684,59 @@ int usb_autopm_get_interface(struct usb_interface *intf)
EXPORT_SYMBOL_GPL(usb_autopm_get_interface);
/**
+ * usb_autopm_get_interface_retry - increment a USB interface's PM-usage counter
+ * @intf: the usb_interface whose counter should be incremented
+ *
+ * This routine should be called by an interface driver when it wants to
+ * use @intf and needs to guarantee that it is not suspended. In addition,
+ * the routine prevents @intf from being autosuspended subsequently. (Note
+ * that this will not prevent suspend events originating in the PM core.)
+ * This prevention will persist until usb_autopm_put_interface() is called
+ * or @intf is unbound. A typical example would be a character-device
+ * driver when its device file is opened.
+ *
+ * Comparing with usb_autopm_get_interface, usb_autopm_get_interface_upgrade
+ * is more careful when resuming the device.
+ * 1) The caller's caller already resumes resume the device and hold spinlocks.
+ * usb_autopm_get_interface_upgrade couldn't call pm_runtime_get_sync;
+ * 2) The caller's caller doesn't resume the device.
+ * usb_autopm_get_interface_upgrade has to resume the device before going ahead.
+ *
+ * @intf's usage counter is incremented to prevent subsequent autosuspends.
+ * However if the autoresume fails then the counter is re-decremented.
+ *
+ * This routine can run only in process context.
+ *
+ * Return: 0 on success.
+ */
+int usb_autopm_get_interface_upgrade(struct usb_interface *intf)
+{
+ int status = 0;
+
+ pm_runtime_get(&intf->dev);
+ if (!pm_runtime_active(&intf->dev)) {
+ /* If not active, next _get_sync wakes device up*/
+ status = pm_runtime_get_sync(&intf->dev);
+ /*
+ * If it's active, next _put_sync wouldn't
+ * really put it to sleep as the 1st _get
+ * keeps the device active.
+ */
+ pm_runtime_put_sync(&intf->dev);
+ if (status < 0)
+ pm_runtime_put(&intf->dev);
+ } else
+ atomic_inc(&intf->pm_usage_cnt);
+ dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
+ __func__, atomic_read(&intf->dev.power.usage_count),
+ status);
+ if (status > 0)
+ status = 0;
+ return status;
+}
+EXPORT_SYMBOL_GPL(usb_autopm_get_interface_upgrade);
+
+/**
* usb_autopm_get_interface_async - increment a USB interface's PM-usage counter
* @intf: the usb_interface whose counter should be incremented
*
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 447fe29..0a8a44a 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -663,6 +663,7 @@ extern void usb_enable_autosuspend(struct usb_device *udev);
extern void usb_disable_autosuspend(struct usb_device *udev);
extern int usb_autopm_get_interface(struct usb_interface *intf);
+extern int usb_autopm_get_interface_upgrade(struct usb_interface *intf);
extern void usb_autopm_put_interface(struct usb_interface *intf);
extern int usb_autopm_get_interface_async(struct usb_interface *intf);
extern void usb_autopm_put_interface_async(struct usb_interface *intf);
@@ -683,6 +684,8 @@ static inline int usb_disable_autosuspend(struct usb_device *udev)
static inline int usb_autopm_get_interface(struct usb_interface *intf)
{ return 0; }
+static inline int usb_autopm_get_interface_upgrade(struct usb_interface *intf)
+{ return 0; }
static inline int usb_autopm_get_interface_async(struct usb_interface *intf)
{ return 0; }
--
1.9.1
next reply other threads:[~2015-05-26 2:20 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-26 2:19 Zhang, Yanmin [this message]
2015-05-26 14:12 ` [PATCH 1/3] usb: add function usb_autopm_get_interface_upgrade Greg Kroah-Hartman
2015-05-27 0:27 ` Zhang, Yanmin
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=5563D84D.5070702@linux.intel.com \
--to=yanmin_zhang@linux.intel.com \
--cc=alan@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=xinhuix.pan@intel.com \
/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.