Merge "msm8974: mhl_sii8334: init chip on discovery"
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index c66d50d..a759e86 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -357,14 +357,20 @@
 static int mhl_sii_wait_for_rgnd(struct mhl_tx_ctrl *mhl_ctrl)
 {
 	int timeout;
-	/* let isr handle RGND interrupt */
+
 	pr_debug("%s:%u\n", __func__, __LINE__);
 	INIT_COMPLETION(mhl_ctrl->rgnd_done);
+	/*
+	 * after toggling reset line and enabling disc
+	 * tx can take a while to generate intr
+	 */
 	timeout = wait_for_completion_interruptible_timeout
-		(&mhl_ctrl->rgnd_done, HZ);
+		(&mhl_ctrl->rgnd_done, HZ * 3);
 	if (!timeout) {
-		/* most likely nothing plugged in USB */
-		/* USB HOST connected or already in USB mode */
+		/*
+		 * most likely nothing plugged in USB
+		 * USB HOST connected or already in USB mode
+		 */
 		pr_warn("%s:%u timedout\n", __func__, __LINE__);
 		return -ENODEV;
 	}
@@ -380,9 +386,25 @@
 	struct i2c_client *client = mhl_ctrl->i2c_handle;
 	unsigned long flags;
 
-	enable_irq(client->irq);
+	if (!mhl_ctrl->irq_req_done) {
+		rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL,
+					  &mhl_tx_isr,
+					  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					  client->dev.driver->name, mhl_ctrl);
+		if (rc) {
+			pr_err("request_threaded_irq failed, status: %d\n",
+			       rc);
+			return -EINVAL;
+		} else {
+			pr_debug("request_threaded_irq succeeded\n");
+			mhl_ctrl->irq_req_done = true;
+		}
+	} else {
+		enable_irq(client->irq);
+	}
+
 	/* wait for i2c interrupt line to be activated */
-	msleep(300);
+	msleep(100);
 
 	if (id) {
 		/* When MHL cable is disconnected we get a sii8334
@@ -413,8 +435,10 @@
 		/* chipset PR recommends waiting for at least 100 ms
 		 * the chipset needs longer to come out of D3 state.
 		 */
-		msleep(300);
+		msleep(100);
 		mhl_init_reg_settings(mhl_ctrl, true);
+		/* allow tx to enable dev disc after D3 state */
+		msleep(100);
 		rc = mhl_sii_wait_for_rgnd(mhl_ctrl);
 	} else {
 		if (mhl_ctrl->cur_state == POWER_STATE_D3) {
@@ -493,6 +517,10 @@
 	uint8_t i;
 	struct i2c_client *client = mhl_ctrl->i2c_handle;
 
+	/* Read the chip rev ID */
+	mhl_ctrl->chip_rev_id = MHL_SII_PAGE0_RD(0x04);
+	pr_debug("MHL: chip rev ID read=[%x]\n", mhl_ctrl->chip_rev_id);
+
 	/*
 	 * REG_SRST
 	 */
@@ -1428,40 +1456,6 @@
 	return IRQ_HANDLED;
 }
 
-static int mhl_tx_chip_init(struct mhl_tx_ctrl *mhl_ctrl)
-{
-	uint8_t chip_rev_id = 0x00;
-	struct i2c_client *client = mhl_ctrl->i2c_handle;
-	unsigned long flags;
-
-
-	spin_lock_irqsave(&mhl_ctrl->lock, flags);
-	mhl_ctrl->dwnstream_hpd = 0;
-	mhl_ctrl->tx_powered_off = false;
-	spin_unlock_irqrestore(&mhl_ctrl->lock, flags);
-
-	/* Reset the TX chip */
-	mhl_sii_reset_pin(mhl_ctrl, 0);
-	msleep(20);
-	mhl_sii_reset_pin(mhl_ctrl, 1);
-	/* TX PR-guide requires a 100 ms wait here */
-	msleep(100);
-
-	/* Read the chip rev ID */
-	chip_rev_id = MHL_SII_PAGE0_RD(0x04);
-	pr_debug("MHL: chip rev ID read=[%x]\n", chip_rev_id);
-	mhl_ctrl->chip_rev_id = chip_rev_id;
-
-	/*
-	 * Need to disable MHL discovery if
-	 * MHL-USB handshake is implemented
-	 */
-	mhl_init_reg_settings(mhl_ctrl, true);
-	switch_mode(mhl_ctrl, POWER_STATE_D3, true);
-	pr_debug("%s:%u: power_down\n", __func__, __LINE__);
-	mhl_tx_down(mhl_ctrl);
-	return 0;
-}
 
 static int mhl_sii_reg_config(struct i2c_client *client, bool enable)
 {
@@ -1791,30 +1785,12 @@
 		}
 	}
 
-	rc = mhl_tx_chip_init(mhl_ctrl);
-	if (rc) {
-		pr_err("%s: tx chip init failed [%d]\n",
-			__func__, rc);
-		goto failed_probe;
-	}
+	mhl_ctrl->dwnstream_hpd = 0;
+	mhl_ctrl->tx_powered_off = false;
+
 
 	init_completion(&mhl_ctrl->rgnd_done);
 
-	pr_debug("%s: IRQ from GPIO INTR = %d\n",
-		__func__, mhl_ctrl->i2c_handle->irq);
-	pr_debug("%s: Driver name = [%s]\n", __func__,
-		client->dev.driver->name);
-	rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL,
-				   &mhl_tx_isr,
-				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-				 client->dev.driver->name, mhl_ctrl);
-	if (rc) {
-		pr_err("request_threaded_irq failed, status: %d\n",
-		       rc);
-		goto failed_probe;
-	} else {
-		pr_debug("request_threaded_irq succeeded\n");
-	}
 
 	mhl_ctrl->mhl_psy.name = "ext-vbus";
 	mhl_ctrl->mhl_psy.type = POWER_SUPPLY_TYPE_USB_DCP;
@@ -1940,15 +1916,21 @@
 #if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP)
 static int mhl_i2c_suspend_sub(struct i2c_client *client)
 {
-	enable_irq_wake(client->irq);
-	disable_irq(client->irq);
+	struct mhl_tx_ctrl *mhl_ctrl = i2c_get_clientdata(client);
+
+	if (mhl_ctrl->irq_req_done) {
+		enable_irq_wake(client->irq);
+		disable_irq(client->irq);
+	}
 	return 0;
 }
 
 static int mhl_i2c_resume_sub(struct i2c_client *client)
 {
-	disable_irq_wake(client->irq);
-	enable_irq(client->irq);
+	struct mhl_tx_ctrl *mhl_ctrl = i2c_get_clientdata(client);
+
+	if (mhl_ctrl->irq_req_done)
+		disable_irq_wake(client->irq);
 	return 0;
 }
 #endif /* defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP) */
diff --git a/include/linux/mhl_8334.h b/include/linux/mhl_8334.h
index d1ee11c..71dec42 100644
--- a/include/linux/mhl_8334.h
+++ b/include/linux/mhl_8334.h
@@ -165,6 +165,7 @@
 	bool tx_powered_off;
 	uint8_t dwnstream_hpd;
 	bool mhl_det_discon;
+	bool irq_req_done;
 };
 
 int mhl_i2c_reg_read(struct i2c_client *client,