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

Commit af88d5f8 authored by Mayank Rana's avatar Mayank Rana
Browse files

dwc3: Add usb_get_remote_wakeup_status() API()



USB composite device updates to host about its wakeup capability
using bmAttribute, and USB host may support remote wakeup
functionality using SET_FEATURE. UDC gadget ops supports wakeup()
API which can be invoked by USB function driver to resume USB bus
by signaling remote wakeup. With HW accelerated path IPA will need
to know if host has enabled remote wakeup in order to decide whether
to suspend or disconnect the GSI channels. Add an API to allow USB
GSI driver to query the current remote wakeup enabled status.

Change-Id: I09eb62714f9df90d68cce5c478dc19096477709e
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent a2839ca3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1150,6 +1150,7 @@ struct dwc3_scratchpad_array {
 * @bh_handled_evt_cnt: no. of events handled by tasklet per interrupt
 * @bh_dbg_index: index for capturing bh_completion_time and bh_handled_evt_cnt
 * @last_run_stop: timestamp denoting the last run_stop update
 * @is_remote_wakeup_enabled: remote wakeup status from host perspective
 */
struct dwc3 {
	struct work_struct	drd_work;
@@ -1395,6 +1396,7 @@ struct dwc3 {
	u32			gen2_tx_de_emph2;
	u32			gen2_tx_de_emph3;
	ktime_t			last_run_stop;
	bool			is_remote_wakeup_enabled;
};

#define INCRX_BURST_MODE 0
+15 −0
Original line number Diff line number Diff line
@@ -1838,6 +1838,21 @@ int usb_gsi_ep_op(struct usb_ep *ep, void *op_data, enum gsi_ep_op op)
}
EXPORT_SYMBOL(usb_gsi_ep_op);

/* Return true if host is supporting remote wakeup functionality. */
bool usb_get_remote_wakeup_status(struct usb_gadget *gadget)
{
	struct dwc3 *dwc = gadget_to_dwc(gadget);
	unsigned long flags;
	bool rw = false;

	spin_lock_irqsave(&dwc->lock, flags);
	rw = dwc->is_remote_wakeup_enabled ? true : false;
	spin_unlock_irqrestore(&dwc->lock, flags);

	return rw;
}
EXPORT_SYMBOL(usb_get_remote_wakeup_status);

/**
 * Configure a USB DBM ep to work in BAM mode.
 *
+6 −0
Original line number Diff line number Diff line
@@ -340,6 +340,9 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
				usb_status |= 1 << USB_DEV_STAT_U1_ENABLED;
			if (reg & DWC3_DCTL_INITU2ENA)
				usb_status |= 1 << USB_DEV_STAT_U2_ENABLED;
		} else {
			usb_status |= dwc->is_remote_wakeup_enabled <<
						USB_DEVICE_REMOTE_WAKEUP;
		}

		break;
@@ -460,6 +463,9 @@ static int dwc3_ep0_handle_device(struct dwc3 *dwc,

	switch (wValue) {
	case USB_DEVICE_REMOTE_WAKEUP:
		dbg_log_string("remote wakeup :%s",
				(set ? "enabled" : "disabled"));
		dwc->is_remote_wakeup_enabled = set;
		break;
	/*
	 * 9.4.1 says only only for SS, in AddressState only for
+9 −0
Original line number Diff line number Diff line
@@ -1993,6 +1993,12 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
	int			ret;

	spin_lock_irqsave(&dwc->lock, flags);
	if (!dwc->is_remote_wakeup_enabled) {
		spin_unlock_irqrestore(&dwc->lock, flags);
		dbg_log_string("remote wakeup not supported\n");
		return -EINVAL;
	}

	ret = __dwc3_gadget_wakeup(dwc);
	spin_unlock_irqrestore(&dwc->lock, flags);

@@ -2508,6 +2514,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
	}

	dwc->gadget_driver	= driver;
	dwc->is_remote_wakeup_enabled = false;

	/*
	 * For DRD, this might get called by gadget driver during bootup
@@ -2539,6 +2546,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)

	spin_lock_irqsave(&dwc->lock, flags);
	dwc->gadget_driver	= NULL;
	dwc->is_remote_wakeup_enabled = false;
	spin_unlock_irqrestore(&dwc->lock, flags);

	dbg_event(0xFF, "fwq_started", 0);
@@ -3362,6 +3370,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)

	dwc->gadget.speed = USB_SPEED_UNKNOWN;
	dwc->link_state = DWC3_LINK_STATE_U0;
	dwc->is_remote_wakeup_enabled = false;
}

static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+3 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size,
bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget);
int msm_dwc3_reset_dbm_ep(struct usb_ep *ep);
int dwc3_msm_release_ss_lane(struct device *dev);
bool usb_get_remote_wakeup_status(struct usb_gadget *gadget);
#else
static inline struct usb_ep *usb_ep_autoconfig_by_name(
		struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc,
@@ -163,6 +164,8 @@ static inline int msm_dwc3_reset_dbm_ep(struct usb_ep *ep)
{ return -ENODEV; }
static inline int dwc3_msm_release_ss_lane(struct device *dev)
{ return -ENODEV; }
static bool __maybe_unused usb_get_remote_wakeup_status(struct usb_gadget *gadget)
{ return false; }
#endif

#endif /* __LINUX_USB_DWC3_MSM_H */