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

Commit 9c63b661 authored by Udipto Goswami's avatar Udipto Goswami Committed by Gerrit - the friendly Code Review server
Browse files

phy-msm-usb: Add mutex for protecting msm_otg_reset



While booting up with charger connected, there is a chance
that msm_otg_reset getting called two times from two paths,
one from apsd re-run and another as part of udc_bind. This
could create a race condition leading to clocks being not
enabled while accessing registers causing to NOC error.

Fix this by introducing mutex lock in msm_otg_reset for
protecting both the thread's execution.

Change-Id: Ie20eded91bbe37f1ed672b7b926f6e5f31fb0235
Signed-off-by: default avatarUdipto Goswami <ugoswami@codeaurora.org>
parent 1ece9bbc
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
/* Copyright (c) 2009-2019, Linux Foundation. All rights reserved.
/* Copyright (c) 2009-2020, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -890,6 +890,7 @@ static int msm_otg_reset(struct usb_phy *phy)
	u32 val = 0;
	u32 ulpi_val = 0;

	mutex_lock(&motg->lock);
	msm_otg_dbg_log_event(&motg->phy, "USB RESET", phy->otg->state,
			get_pm_runtime_counter(phy->dev));
	/*
@@ -898,10 +899,13 @@ static int msm_otg_reset(struct usb_phy *phy)
	 * USB BAM reset on other cases e.g. USB cable disconnections.
	 * If hardware reported error then it must be reset for recovery.
	 */
	if (motg->err_event_seen)
	if (motg->err_event_seen) {
		dev_info(phy->dev, "performing USB h/w reset for recovery\n");
	else if (pdata->disable_reset_on_disconnect && motg->reset_counter)
	} else if (pdata->disable_reset_on_disconnect &&
				motg->reset_counter) {
		mutex_unlock(&motg->lock);
		return 0;
	}

	motg->reset_counter++;

@@ -916,6 +920,7 @@ static int msm_otg_reset(struct usb_phy *phy)
			enable_irq(motg->phy_irq);

		enable_irq(motg->irq);
		mutex_unlock(&motg->lock);
		return ret;
	}

@@ -926,6 +931,7 @@ static int msm_otg_reset(struct usb_phy *phy)
	ret = msm_otg_link_reset(motg);
	if (ret) {
		dev_err(phy->dev, "link reset failed\n");
		mutex_unlock(&motg->lock);
		return ret;
	}

@@ -982,6 +988,7 @@ static int msm_otg_reset(struct usb_phy *phy)

	if (phy->otg->state == OTG_STATE_UNDEFINED && motg->rm_pulldown)
		msm_chg_block_on(motg);
	mutex_unlock(&motg->lock);

	return 0;
}
@@ -4171,6 +4178,7 @@ static int msm_otg_probe(struct platform_device *pdev)
	motg->pdev = pdev;
	motg->dbg_idx = 0;
	motg->dbg_lock = __RW_LOCK_UNLOCKED(lck);
	mutex_init(&motg->lock);

	if (motg->pdata->bus_scale_table) {
		motg->bus_perf_client =
+2 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 *
 * Copyright (C) 2008 Google, Inc.
 * Author: Brian Swetland <swetland@google.com>
 * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2009-2020, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -188,6 +188,7 @@ struct msm_otg {
	struct usb_phy phy;
	struct msm_otg_platform_data *pdata;
	struct platform_device *pdev;
	struct mutex lock;
	int irq;
	int async_irq;
	int phy_irq;