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

Commit 0ed723e6 authored by Mayank Rana's avatar Mayank Rana Committed by Gerrit - the friendly Code Review server
Browse files

dwc3-msm: Add dwc3_msm_release_ss_lane() API



DP driver needs to use both USB SS lane in some use case. Hence
to release USB SS lane, add dwc3_msm_release_ss_lane() API which
performs below operations:
i. Stop USB host mode
ii. Start USB host mode into high speed mode if USB host mode
was active.

dwc3_msm_release_ss_lane() API is blocking call, and will comeback
once above both operations are performed.

Change-Id: I56df606914a613bfe4b76298b0041a66fc74878d
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent e1007d06
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -150,6 +150,9 @@
#define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n)	(n << 16)
#define DWC3_GEVENT_TYPE_GSI			0x3

/* BAM pipe mask */
#define MSM_PIPE_ID_MASK	(0x1F)

enum dbm_reg {
	DBM_EP_CFG,
	DBM_DATA_FIFO,
@@ -3738,6 +3741,63 @@ static void dwc3_init_dbm(struct dwc3_msm *mdwc)
			"qcom,reset-ep-after-lpm-resume");
}

static void dwc3_start_stop_host(struct dwc3_msm *mdwc, bool start)
{
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	if (start) {
		dbg_log_string("start host mode");
		mdwc->id_state = DWC3_ID_GROUND;
		mdwc->vbus_active = false;
	} else {
		dbg_log_string("stop_host_mode started");
		mdwc->id_state = DWC3_ID_FLOAT;
		mdwc->vbus_active = false;
	}

	dwc3_ext_event_notify(mdwc);
	dbg_event(0xFF, "flush_work", 0);
	flush_work(&mdwc->resume_work);
	drain_workqueue(mdwc->sm_usb_wq);
	if (start)
		dbg_log_string("host mode started");
	else
		dbg_log_string("stop_host_mode completed");
}

int dwc3_msm_release_ss_lane(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = NULL;

	if (mdwc == NULL) {
		dev_err(dev, "dwc3-msm is not initialized yet.\n");
		return -EAGAIN;
	}

	dwc = platform_get_drvdata(mdwc->dwc3);
	if (dwc == NULL) {
		dev_err(dev, "dwc3 controller is not initialized yet.\n");
		return -EAGAIN;
	}

	dbg_event(0xFF, "ss_lane_release", 0);
	if (mdwc->id_state != DWC3_ID_GROUND) {
		dbg_log_string("USB host mode is not active");
		return 0;
	}

	/* stop USB host mode */
	dwc3_start_stop_host(mdwc, false);

	/* restart USB host mode into high speed */
	dwc->maximum_speed = USB_SPEED_HIGH;
	dwc3_start_stop_host(mdwc, true);

	return 0;
}
EXPORT_SYMBOL(dwc3_msm_release_ss_lane);

static int dwc3_msm_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node, *dwc3_node;
+3 −1
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
 * These bit fields are set by function drivers that wish to queue
 * usb_requests with sps/bam parameters.
 */
#define MSM_PIPE_ID_MASK		(0x1F)
#define MSM_TX_PIPE_ID_OFS		(16)
#define MSM_SPS_MODE			BIT(5)
#define MSM_IS_FINITE_TRANSFER		BIT(6)
@@ -121,6 +120,7 @@ int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size,
	u8 dst_pipe_idx);
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);
#else
static inline struct usb_ep *usb_ep_autoconfig_by_name(
		struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc,
@@ -146,6 +146,8 @@ static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget)
{ return false; }
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; }
#endif

#endif /* __LINUX_USB_DWC3_MSM_H */