Merge "msm: camera: Fix for initial framedrop during burst mode"
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index fd866e1..4b6ba67 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -855,6 +855,7 @@
 	struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
 
 	mutex_lock(&msm_uport->clk_mutex);
+	msm_hs_write(uport, UARTDM_IMR_ADDR, 0);
 
 	/*
 	 * Disable Rx channel of UARTDM
@@ -947,7 +948,6 @@
 
 	uport->read_status_mask = (termios->c_cflag & CREAD);
 
-	msm_hs_write(uport, UARTDM_IMR_ADDR, 0);
 
 	/* Set Transmit software time out */
 	uart_update_timeout(uport, c_cflag, bps);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index d5321ff..67040e5 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -85,6 +85,8 @@
 	int			peripheral_status_irq;
 	int			wakeup_irq;
 	bool			wakeup_irq_enabled;
+	int			async_irq;
+	uint32_t		async_int_cnt;
 	atomic_t		pm_usage_cnt;
 	uint32_t		bus_perf_client;
 	uint32_t		wakeup_int_cnt;
@@ -820,9 +822,11 @@
 	atomic_set(&mehci->in_lpm, 1);
 	enable_irq(hcd->irq);
 
-	mehci->wakeup_irq_enabled = 1;
-	enable_irq_wake(mehci->wakeup_irq);
-	enable_irq(mehci->wakeup_irq);
+	if (mehci->wakeup_irq) {
+		mehci->wakeup_irq_enabled = 1;
+		enable_irq_wake(mehci->wakeup_irq);
+		enable_irq(mehci->wakeup_irq);
+	}
 
 	if (pdata && pdata->standalone_latency)
 		pm_qos_update_request(&mehci->pm_qos_req_dma,
@@ -856,13 +860,15 @@
 		pm_qos_update_request(&mehci->pm_qos_req_dma,
 			pdata->standalone_latency + 1);
 
-	spin_lock_irqsave(&mehci->wakeup_lock, flags);
-	if (mehci->wakeup_irq_enabled) {
-		disable_irq_wake(mehci->wakeup_irq);
-		disable_irq_nosync(mehci->wakeup_irq);
-		mehci->wakeup_irq_enabled = 0;
+	if (mehci->wakeup_irq) {
+		spin_lock_irqsave(&mehci->wakeup_lock, flags);
+		if (mehci->wakeup_irq_enabled) {
+			disable_irq_wake(mehci->wakeup_irq);
+			disable_irq_nosync(mehci->wakeup_irq);
+			mehci->wakeup_irq_enabled = 0;
+		}
+		spin_unlock_irqrestore(&mehci->wakeup_lock, flags);
 	}
-	spin_unlock_irqrestore(&mehci->wakeup_lock, flags);
 
 	wake_lock(&mehci->wlock);
 
@@ -1412,20 +1418,28 @@
 	struct msm_hsic_hcd *mehci = data;
 	int ret;
 
-	mehci->wakeup_int_cnt++;
-	dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
-	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt cnt: %u\n",
-			__func__, mehci->wakeup_int_cnt);
+	if (irq == mehci->async_irq) {
+		mehci->async_int_cnt++;
+		dbg_log_event(NULL, "Remote Wakeup (ASYNC) IRQ",
+							 mehci->async_int_cnt);
+	} else {
+		mehci->wakeup_int_cnt++;
+		dbg_log_event(NULL, "Remote Wakeup IRQ", mehci->wakeup_int_cnt);
+	}
+	dev_dbg(mehci->dev, "%s: hsic remote wakeup interrupt %d cnt: %u, %u\n",
+		    __func__, irq, mehci->wakeup_int_cnt, mehci->async_int_cnt);
 
 	wake_lock(&mehci->wlock);
 
-	spin_lock(&mehci->wakeup_lock);
-	if (mehci->wakeup_irq_enabled) {
-		mehci->wakeup_irq_enabled = 0;
-		disable_irq_wake(irq);
-		disable_irq_nosync(irq);
+	if (mehci->wakeup_irq) {
+		spin_lock(&mehci->wakeup_lock);
+		if (mehci->wakeup_irq_enabled) {
+			mehci->wakeup_irq_enabled = 0;
+			disable_irq_wake(irq);
+			disable_irq_nosync(irq);
+		}
+		spin_unlock(&mehci->wakeup_lock);
 	}
-	spin_unlock(&mehci->wakeup_lock);
 
 	if (!atomic_read(&mehci->pm_usage_cnt)) {
 		ret = pm_runtime_get(mehci->dev);
@@ -1843,6 +1857,21 @@
 		}
 	}
 
+	mehci->async_irq = platform_get_irq_byname(pdev, "async_irq");
+	if (mehci->async_irq < 0) {
+		dev_dbg(&pdev->dev, "platform_get_irq for async_int failed\n");
+		mehci->async_irq = 0;
+	} else {
+		ret = request_irq(mehci->async_irq, msm_hsic_wakeup_irq,
+				IRQF_TRIGGER_RISING, "msm_hsic_async", mehci);
+		if (ret) {
+			dev_err(&pdev->dev, "request irq failed (ASYNC INT)\n");
+			mehci->async_irq = 0;
+		} else {
+			enable_irq_wake(mehci->async_irq);
+		}
+	}
+
 	ret = ehci_hsic_msm_debugfs_init(mehci);
 	if (ret)
 		dev_dbg(&pdev->dev, "mode debugfs file is"
@@ -1904,6 +1933,9 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 
+	/* Remove the HCD prior to releasing our resources. */
+	usb_remove_hcd(hcd);
+
 	if (pdata && pdata->standalone_latency)
 		pm_qos_remove_request(&mehci->pm_qos_req_dma);
 
@@ -1916,6 +1948,10 @@
 		free_irq(mehci->wakeup_irq, mehci);
 	}
 
+	if (mehci->async_irq) {
+		disable_irq_wake(mehci->async_irq);
+		free_irq(mehci->async_irq, mehci);
+	}
 	/*
 	 * If the update request is called after unregister, the request will
 	 * fail. Results are undefined if unregister is called in the middle of
@@ -1933,7 +1969,6 @@
 
 	destroy_workqueue(ehci_wq);
 
-	usb_remove_hcd(hcd);
 	msm_hsic_config_gpios(mehci, 0);
 	msm_hsic_init_vddcx(mehci, 0);
 	msm_hsic_init_gdsc(mehci, 0);