Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 822778fa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: gadget: Add support for usb runtime pm APIs"

parents 3166e4b3 53d5dc11
Loading
Loading
Loading
Loading
+124 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <linux/workqueue.h>
#include <linux/usb/ch9.h>
#include <linux/pm_runtime.h>

#define UDC_TRACE_STR_MAX	512

@@ -847,6 +848,129 @@ extern int usb_gadget_ep_match_desc(struct usb_gadget *gadget,
/* utility to update vbus status for udc core, it may be scheduled */
extern void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status);

/**
 * usb_gadget_autopm_get - increment PM-usage counter of usb gadget's parent
 * device.
 * @gadget: usb gadget whose parent device counter is incremented
 *
 * This routine should be called by function driver when it wants to use
 * gadget's parent device and needs to guarantee that it is not suspended. In
 * addition, the routine prevents subsequent autosuspends of gadget's parent
 * device. However if the autoresume fails then the counter is re-decremented.
 *
 * This routine can run only in process context.
 */
static inline int usb_gadget_autopm_get(struct usb_gadget *gadget)
{
	int status = -ENODEV;

	if (!gadget || !gadget->dev.parent)
		return status;

	status = pm_runtime_get_sync(gadget->dev.parent);
	if (status < 0)
		pm_runtime_put_sync(gadget->dev.parent);

	if (status > 0)
		status = 0;
	return status;
}

/**
 * usb_gadget_autopm_get_async - increment PM-usage counter of usb gadget's
 * parent device.
 * @gadget: usb gadget whose parent device counter is incremented
 *
 * This routine increments @gadget parent device PM usage counter and queue an
 * autoresume request if the device is suspended. It does not autoresume device
 * directly (it only queues a request). After a successful call, the device may
 * not yet be resumed.
 *
 * This routine can run in atomic context.
 */
static inline int usb_gadget_autopm_get_async(struct usb_gadget *gadget)
{
	int status = -ENODEV;

	if (!gadget || !gadget->dev.parent)
		return status;

	status = pm_runtime_get(gadget->dev.parent);
	if (status < 0 && status != -EINPROGRESS)
		pm_runtime_put_noidle(gadget->dev.parent);

	if (status > 0 || status == -EINPROGRESS)
		status = 0;
	return status;
}

/**
 * usb_gadget_autopm_get_noresume - increment PM-usage counter of usb gadget's
 * parent device.
 * @gadget: usb gadget whose parent device counter is incremented
 *
 * This routine increments PM-usage count of @gadget parent device but does not
 * carry out an autoresume.
 *
 * This routine can run in atomic context.
 */
static inline void usb_gadget_autopm_get_noresume(struct usb_gadget *gadget)
{
	if (gadget && gadget->dev.parent)
		pm_runtime_get_noresume(gadget->dev.parent);
}

/**
 * usb_gadget_autopm_put - decrement PM-usage counter of usb gadget's parent
 * device.
 * @gadget: usb gadget whose parent device counter is decremented.
 *
 * This routine should be called by function driver when it is finished using
 * @gadget parent device and wants to allow it to autosuspend. It decrements
 * PM-usage counter of @gadget parent device, when the counter reaches 0, a
 * delayed autosuspend request is attempted.
 *
 * This routine can run only in process context.
 */
static inline void usb_gadget_autopm_put(struct usb_gadget *gadget)
{
	if (gadget && gadget->dev.parent)
		pm_runtime_put_sync(gadget->dev.parent);
}

/**
 * usb_gadget_autopm_put_async - decrement PM-usage counter of usb gadget's
 * parent device.
 * @gadget: usb gadget whose parent device counter is decremented.
 *
 * This routine decrements PM-usage counter of @gadget parent device and
 * schedules a delayed autosuspend request if the counter is <= 0.
 *
 * This routine can run in atomic context.
 */
static inline void usb_gadget_autopm_put_async(struct usb_gadget *gadget)
{
	if (gadget && gadget->dev.parent)
		pm_runtime_put(gadget->dev.parent);
}

/**
 * usb_gadget_autopm_put_no_suspend - decrement PM-usage counter of usb gadget
's
 * parent device.
 * @gadget: usb gadget whose parent device counter is decremented.
 *
 * This routine decrements PM-usage counter of @gadget parent device but does
 * not carry out an autosuspend.
 *
 * This routine can run in atomic context.
 */
static inline void usb_gadget_autopm_put_no_suspend(struct usb_gadget *gadget)
{
	if (gadget && gadget->dev.parent)
		pm_runtime_put_noidle(gadget->dev.parent);
}

/*-------------------------------------------------------------------------*/

/* utility wrapping a simple endpoint selection policy */