From 1eeb4b1093e4f5f24a26524a8c08940a7fce0aef Mon Sep 17 00:00:00 2001 From: Jeng-Hung Chen Date: Thu, 28 Sep 2017 12:11:09 +0800 Subject: usb: fix race hazard in usb clock switching Description: fix unpaired clock control of usb_enable_clock Bug: 67076117 Change-Id: I8cf450b79de33fb44cd15440bf2904cfc6215593 --- drivers/misc/mediatek/usb20/mt2601/usb20.c | 33 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/misc/mediatek/usb20/mt2601/usb20.c b/drivers/misc/mediatek/usb20/mt2601/usb20.c index 709e3b5d4361..b33e3b552f63 100644 --- a/drivers/misc/mediatek/usb20/mt2601/usb20.c +++ b/drivers/misc/mediatek/usb20/mt2601/usb20.c @@ -167,39 +167,38 @@ static void mt_usb_enable(struct musb *musb) unsigned long flags; DBG(0, "%d, %d\n", mtk_usb_power, musb->power); - if (musb->power == true) { return; } - + musb->power = true; flags = musb_readl(mtk_musb->mregs, USB_L1INTM); - - mdelay(10); - + /* mask ID pin, so "open clock" and "set flag" won't be interrupted. ISR may call clock_disable. */ + musb_writel(mtk_musb->mregs, USB_L1INTM, (~IDDIG_INT_STATUS)&flags); + if (down_interruptible(&power_clock_lock)) + { + xlog_printk(ANDROID_LOG_ERROR, "USB20", "%s: busy, Couldn't get power_clock_lock\n", __func__); + return; + } usb_phy_recover(); - mtk_usb_power = true; - musb->power = true; - - if (in_interrupt()) { - DBG(0, "in interrupt !!!!!!!!!!!!!!!\n"); - } - + up(&power_clock_lock); musb_writel(mtk_musb->mregs, USB_L1INTM, flags); } static void mt_usb_disable(struct musb *musb) { - pr_debug("%s, %d, %d\n", __func__, mtk_usb_power, musb->power); - if (musb->power == false) { return; } - + musb->power = false; + if (down_interruptible(&power_clock_lock)) + { + xlog_printk(ANDROID_LOG_ERROR, "USB20", "%s: busy, Couldn't get power_clock_lock\n", __func__); + return; + } usb_phy_savecurrent(); - mtk_usb_power = false; - musb->power = false; + up(&power_clock_lock); } /* ================================ */ -- cgit v1.2.3