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 Original line 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
 * 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
 * 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 val = 0;
	u32 ulpi_val = 0;
	u32 ulpi_val = 0;


	mutex_lock(&motg->lock);
	msm_otg_dbg_log_event(&motg->phy, "USB RESET", phy->otg->state,
	msm_otg_dbg_log_event(&motg->phy, "USB RESET", phy->otg->state,
			get_pm_runtime_counter(phy->dev));
			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.
	 * USB BAM reset on other cases e.g. USB cable disconnections.
	 * If hardware reported error then it must be reset for recovery.
	 * 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");
		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;
		return 0;
	}


	motg->reset_counter++;
	motg->reset_counter++;


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


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


@@ -926,6 +931,7 @@ static int msm_otg_reset(struct usb_phy *phy)
	ret = msm_otg_link_reset(motg);
	ret = msm_otg_link_reset(motg);
	if (ret) {
	if (ret) {
		dev_err(phy->dev, "link reset failed\n");
		dev_err(phy->dev, "link reset failed\n");
		mutex_unlock(&motg->lock);
		return ret;
		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)
	if (phy->otg->state == OTG_STATE_UNDEFINED && motg->rm_pulldown)
		msm_chg_block_on(motg);
		msm_chg_block_on(motg);
	mutex_unlock(&motg->lock);


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


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