summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Lachaud <etiennex.lachaud@intel.com>2018-07-31 16:31:10 +0200
committerTasayco Loarte, VictorX <victorx.tasayco.loarte@intel.com>2018-10-18 06:00:19 -0700
commitf12bebe15c1638565a5d32afdff7c0790123e0c6 (patch)
treeb414ccafafbfd4bd6d808617a1ae05287717faf9
parenteed7196079be4c4898850ffdb186f8d1a1d97322 (diff)
downloadx86-android-x86-robby-4.4.159-pie-wear-dr.tar.gz
dwc IRQ is registered when USB is plugged then unregistered when USB is unplugged. Due to some race condition the irq might be missed, creating a strange situation where dwc driver holds a wakelock but the charger isn't notified, thus the board is not charging and not considered "plugged" Change-Id: I8f581338259cc3914ca50b84655210ef6b352b75 Tracked-On: https://jira01.devtools.intel.com/browse/AW-8189 Signed-off-by: Etienne Lachaud <etiennex.lachaud@intel.com> Reviewed-on: https://android.intel.com/648475 Reviewed-by: Dubray, SimonX <simonx.dubray@intel.com> Reviewed-by: jenkins_ndg <jenkins_ndg@intel.com> Reviewed-by: Tasayco Loarte, VictorX <victorx.tasayco.loarte@intel.com>
-rw-r--r--drivers/usb/dwc3/dwc3-device-intel.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/drivers/usb/dwc3/dwc3-device-intel.c b/drivers/usb/dwc3/dwc3-device-intel.c
index 3b896b72a63e..7dfe4edcfda9 100644
--- a/drivers/usb/dwc3/dwc3-device-intel.c
+++ b/drivers/usb/dwc3/dwc3-device-intel.c
@@ -249,7 +249,6 @@ int dwc3_start_peripheral(struct usb_gadget *g)
{
struct dwc3 *dwc = gadget_to_dwc(g);
unsigned long flags;
- int irq;
int ret = 0;
wake_lock(&_dev_data->wake_lock);
@@ -269,7 +268,7 @@ int dwc3_start_peripheral(struct usb_gadget *g)
dwc3_event_buffers_setup(dwc);
ret = dwc3_init_for_enumeration(dwc);
if (ret)
- goto err1;
+ goto err0;
if (dwc->soft_connected)
dwc3_gadget_run_stop(dwc, 1, false);
@@ -277,28 +276,8 @@ int dwc3_start_peripheral(struct usb_gadget *g)
dwc->pm_state = PM_ACTIVE;
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- irq = platform_get_irq(to_platform_device(dwc->dev), 0);
- if (dwc->quirks_disable_irqthread)
- ret = request_irq(irq, dwc3_quirks_interrupt,
- IRQF_SHARED, "dwc3", dwc);
- else
- ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
- IRQF_SHARED, "dwc3", dwc);
- if (ret) {
- dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
- irq, ret);
- goto err0;
- }
- mutex_unlock(&_dev_data->mutex);
-
- return 0;
-
-err1:
- spin_unlock_irqrestore(&dwc->lock, flags);
-
err0:
+ spin_unlock_irqrestore(&dwc->lock, flags);
mutex_unlock(&_dev_data->mutex);
return ret;
@@ -309,7 +288,6 @@ int dwc3_stop_peripheral(struct usb_gadget *g)
struct dwc3 *dwc = gadget_to_dwc(g);
unsigned long flags;
u8 epnum;
- int irq;
mutex_lock(&_dev_data->mutex);
spin_lock_irqsave(&dwc->lock, flags);
@@ -353,9 +331,6 @@ int dwc3_stop_peripheral(struct usb_gadget *g)
dwc->pm_state = PM_DISCONNECTED;
spin_unlock_irqrestore(&dwc->lock, flags);
- irq = platform_get_irq(to_platform_device(dwc->dev), 0);
- free_irq(irq, dwc);
-
mutex_unlock(&_dev_data->mutex);
cancel_delayed_work_sync(&dwc->link_work);
@@ -473,6 +448,7 @@ static int dwc3_device_intel_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int ret = -ENOMEM;
void *mem;
+ int irq;
struct dwc_device_par *pdata;
struct usb_phy *usb_phy;
@@ -616,11 +592,27 @@ static int dwc3_device_intel_probe(struct platform_device *pdev)
goto err1;
}
+ irq = platform_get_irq(to_platform_device(dwc->dev), 0);
+ if (dwc->quirks_disable_irqthread)
+ ret = request_irq(irq, dwc3_quirks_interrupt,
+ IRQF_SHARED, "dwc3", dwc);
+ else
+ ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
+ IRQF_SHARED, "dwc3", dwc);
+ if (ret) {
+ dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
+ irq, ret);
+ goto err2;
+ }
+
pm_runtime_allow(dev);
pm_runtime_put(dev);
return 0;
+err2:
+ dwc3_debugfs_exit(dwc);
+
err1:
dwc3_gadget_exit(dwc);
@@ -632,10 +624,15 @@ err0:
static int dwc3_device_intel_remove(struct platform_device *pdev)
{
+ int irq;
+
iounmap(_dev_data->flis_reg);
wake_lock_destroy(&_dev_data->wake_lock);
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq, _dev_data->dwc);
+
dwc3_remove(pdev);
kfree(_dev_data);