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

Commit af11cb52 authored by Saket Saurabh's avatar Saket Saurabh
Browse files

USB: Prevent USB to enter LPM if qdss connect work is not processed



For usb cable connect in qdss composition, qdss driver will queue qdss
connect work as part of qdss_set_alt(). As part of multiple usb connect
and disonnect, USB can enter low power mode before the qdss connect work
is compeleted. This results in crash while acessing usb registers during
processing of the qdss connect work as USB clocks are off.

Fix this issue by ensuring that if qdss connect work is scheduled, then
do not allow USB to enter low power mode before qdss connect work is
completely processed. To implement this, use flag qdss_usb_active. When
usb is connected, set flag qdss_usb_active to true in qdss_set_alt().
When qdss connect work is already processed, then set the flag
qdss_usb_active to false. Further, add check in msm_bam_usb_lpm_ok()
and check if usb qdss connect work is scheduled but not completely
processed, then do not allow USB to enter low power mode.

CRs-Fixed: 718015
Change-Id: Id3d0751a01b96fb3a4f9bbb9fe3adbe25228618e
Signed-off-by: default avatarSaket Saurabh <ssaurabh@codeaurora.org>
parent 400a6b85
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -218,6 +218,7 @@ static struct usb_bam_ctx_type ctx;
static struct usb_bam_host_info host_info[MAX_BAMS];
static struct device *usb_device;
static bool probe_finished;
static bool qdss_usb_active;

static int __usb_bam_register_wake_cb(int idx, int (*callback)(void *user),
	void *param, bool trigger_cb_per_pipe);
@@ -3537,11 +3538,20 @@ bool msm_bam_device_lpm_ok(enum usb_ctrl bam_type)
	}
}

void msm_bam_set_qdss_usb_active(bool is_active)
{
	pr_debug("%s: set qdss_usb_active: %d\n", __func__, is_active);
	qdss_usb_active = is_active;
}
EXPORT_SYMBOL(msm_bam_set_qdss_usb_active);

bool msm_bam_usb_lpm_ok(enum usb_ctrl bam)
{
	pr_debug("%s: enter mode %d on %s\n",
		__func__, info[bam].cur_bam_mode, bam_enable_strings[bam]);

	if (qdss_usb_active)
		return 0;
	if (info[bam].cur_bam_mode == USB_BAM_DEVICE)
		return msm_bam_device_lpm_ok(bam);
	else /* USB_BAM_HOST */ {
+6 −4
Original line number Diff line number Diff line
@@ -586,6 +586,7 @@ static void usb_qdss_connect_work(struct work_struct *work)
	if (qdss->usb_connected == 0) {
		pr_debug("%s: discard connect_work\n", __func__);
		cancel_work_sync(&qdss->disconnect_w);
		msm_bam_set_qdss_usb_active(false);
		return;
	}

@@ -595,7 +596,7 @@ static void usb_qdss_connect_work(struct work_struct *work)
		status = init_data(qdss->port.data);
		if (status) {
			pr_err("init_data error");
			return;
			break;
		}
		status = set_qdss_data_connection(
				qdss->cdev->gadget,
@@ -604,7 +605,7 @@ static void usb_qdss_connect_work(struct work_struct *work)
				1);
		if (status) {
			pr_err("set_qdss_data_connection error");
			return;
			break;
		}
		if (qdss->ch.notify)
			qdss->ch.notify(qdss->ch.priv,
@@ -614,7 +615,7 @@ static void usb_qdss_connect_work(struct work_struct *work)
		status = send_sps_req(qdss->port.data);
		if (status) {
			pr_err("send_sps_req error\n");
			return;
			break;
		}
		break;
	case USB_GADGET_XPORT_HSIC:
@@ -633,7 +634,7 @@ static void usb_qdss_connect_work(struct work_struct *work)
				xport_to_str(dxport));
	}


	msm_bam_set_qdss_usb_active(false);

}

@@ -711,6 +712,7 @@ static int qdss_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
	if (qdss->usb_connected && (ch->app_conn ||
		(dxport == USB_GADGET_XPORT_HSIC)))
		queue_work(qdss->wq, &qdss->connect_w);
	msm_bam_set_qdss_usb_active(true);
	return 0;
fail:
	pr_err("qdss_set_alt failed\n");
+2 −0
Original line number Diff line number Diff line
@@ -625,6 +625,7 @@ bool msm_bam_hsic_lpm_ok(void);
void msm_bam_usb_host_notify_on_resume(void);
void msm_bam_hsic_host_notify_on_resume(void);
bool msm_bam_hsic_host_pipe_empty(void);
void msm_bam_set_qdss_usb_active(bool is_active);
#else
static inline bool msm_bam_usb_lpm_ok(enum usb_ctrl ctrl) { return true; }
static inline void msm_bam_notify_lpm_resume(enum usb_ctrl ctrl) {}
@@ -637,6 +638,7 @@ static inline bool msm_bam_hsic_lpm_ok(void) { return true; }
static inline void msm_bam_hsic_host_notify_on_resume(void) {}
static inline void msm_bam_usb_host_notify_on_resume(void) {}
static inline bool msm_bam_hsic_host_pipe_empty(void) { return true; }
static inline void msm_bam_set_qdss_usb_active(bool is_active) {}
#endif
#ifdef CONFIG_USB_CI13XXX_MSM
void msm_hw_bam_disable(bool bam_disable);