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

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

usbpd: Add mutex lock to manipulate svid_handler list



svid_handler is registered by different client driver (e.g. Linux
DP driver). Client driver may unregister in some error case which
may race against accessing svid_handler list. Hence add mutext lock
to guard svid_handler list manipulation.

CRs-Fixed: 2102703
Change-Id: I6653a31e3fa1f27e0cdd7a32f752df57f8b6c718
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent bafb98e9
Loading
Loading
Loading
Loading
+20 −4
Original line number Original line Diff line number Diff line
@@ -430,6 +430,7 @@ struct usbpd {
	int			num_svids;
	int			num_svids;
	struct vdm_tx		*vdm_tx;
	struct vdm_tx		*vdm_tx;
	struct vdm_tx		*vdm_tx_retry;
	struct vdm_tx		*vdm_tx_retry;
	struct mutex		svid_handler_lock;
	struct list_head	svid_handlers;
	struct list_head	svid_handlers;


	struct list_head	instance;
	struct list_head	instance;
@@ -581,10 +582,15 @@ static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid)
{
{
	struct usbpd_svid_handler *handler;
	struct usbpd_svid_handler *handler;


	list_for_each_entry(handler, &pd->svid_handlers, entry)
	mutex_lock(&pd->svid_handler_lock);
		if (svid == handler->svid)
	list_for_each_entry(handler, &pd->svid_handlers, entry) {
		if (svid == handler->svid) {
			mutex_unlock(&pd->svid_handler_lock);
			return handler;
			return handler;
		}
	}


	mutex_unlock(&pd->svid_handler_lock);
	return NULL;
	return NULL;
}
}


@@ -1412,9 +1418,11 @@ int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
		return -EINVAL;
		return -EINVAL;
	}
	}


	usbpd_dbg(&pd->dev, "registered handler for SVID 0x%04x\n", hdlr->svid);
	usbpd_dbg(&pd->dev, "registered handler(%pK) for SVID 0x%04x\n",

							hdlr, hdlr->svid);
	mutex_lock(&pd->svid_handler_lock);
	list_add_tail(&hdlr->entry, &pd->svid_handlers);
	list_add_tail(&hdlr->entry, &pd->svid_handlers);
	mutex_unlock(&pd->svid_handler_lock);
	hdlr->request_usb_ss_lane = usbpd_release_ss_lane;
	hdlr->request_usb_ss_lane = usbpd_release_ss_lane;


	/* already connected with this SVID discovered? */
	/* already connected with this SVID discovered? */
@@ -1436,7 +1444,12 @@ EXPORT_SYMBOL(usbpd_register_svid);


void usbpd_unregister_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
void usbpd_unregister_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
{
{

	usbpd_dbg(&pd->dev, "unregistered handler(%pK) for SVID 0x%04x\n",
							hdlr, hdlr->svid);
	mutex_lock(&pd->svid_handler_lock);
	list_del_init(&hdlr->entry);
	list_del_init(&hdlr->entry);
	mutex_unlock(&pd->svid_handler_lock);
}
}
EXPORT_SYMBOL(usbpd_unregister_svid);
EXPORT_SYMBOL(usbpd_unregister_svid);


@@ -1747,6 +1760,7 @@ static void reset_vdm_state(struct usbpd *pd)
{
{
	struct usbpd_svid_handler *handler;
	struct usbpd_svid_handler *handler;


	mutex_lock(&pd->svid_handler_lock);
	list_for_each_entry(handler, &pd->svid_handlers, entry) {
	list_for_each_entry(handler, &pd->svid_handlers, entry) {
		if (handler->discovered) {
		if (handler->discovered) {
			handler->disconnect(handler);
			handler->disconnect(handler);
@@ -1754,6 +1768,7 @@ static void reset_vdm_state(struct usbpd *pd)
		}
		}
	}
	}


	mutex_unlock(&pd->svid_handler_lock);
	pd->vdm_state = VDM_NONE;
	pd->vdm_state = VDM_NONE;
	kfree(pd->vdm_tx_retry);
	kfree(pd->vdm_tx_retry);
	pd->vdm_tx_retry = NULL;
	pd->vdm_tx_retry = NULL;
@@ -3853,6 +3868,7 @@ struct usbpd *usbpd_create(struct device *parent)
	hrtimer_init(&pd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hrtimer_init(&pd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	pd->timer.function = pd_timeout;
	pd->timer.function = pd_timeout;
	mutex_init(&pd->swap_lock);
	mutex_init(&pd->swap_lock);
	mutex_init(&pd->svid_handler_lock);


	pd->usb_psy = power_supply_get_by_name("usb");
	pd->usb_psy = power_supply_get_by_name("usb");
	if (!pd->usb_psy) {
	if (!pd->usb_psy) {