ehci: hsic: add suspend/resume handshake with ipa resource manager

This change ensure correct sequence with the ipa resource manager
to obtain or release the producer and consumer resources upon
hsic host suspend/resume sequences which involve entering/exiting
to low power mode.

Change-Id: Iec77b9a24a3192a19de93c813b416baca26c7a77
Signed-off-by: Ido Shayevitz <idos@codeaurora.org>
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index d1d0f91..0ea9778 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -752,6 +752,19 @@
 		return -EBUSY;
 	}
 
+	if (pdata->consider_ipa_handshake) {
+		dev_dbg(mehci->dev, "%s:Wait for resources release\n",
+			__func__);
+		if (!msm_bam_hsic_lpm_ok()) {
+			dev_dbg(mehci->dev, "%s:Prod+Cons not released\n",
+			__func__);
+			enable_irq(hcd->irq);
+			return -EBUSY;
+		}
+		dev_dbg(mehci->dev, "%s:Prod+Cons resources released\n",
+			__func__);
+	}
+
 	/*
 	 * PHY may take some time or even fail to enter into low power
 	 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
@@ -829,7 +842,7 @@
 
 	wake_unlock(&mehci->wlock);
 
-	dev_dbg(mehci->dev, "HSIC-USB in low power mode\n");
+	dev_info(mehci->dev, "HSIC-USB in low power mode\n");
 
 	return 0;
 }
@@ -848,6 +861,14 @@
 		return 0;
 	}
 
+	if (pdata->consider_ipa_handshake) {
+		dev_dbg(mehci->dev, "%s:Wait for producer resource\n",
+			__func__);
+		msm_bam_wait_for_hsic_prod_granted();
+		dev_dbg(mehci->dev, "%s:Producer resource obtained\n",
+			__func__);
+	}
+
 	/* Handles race with Async interrupt */
 	disable_irq(hcd->irq);
 
@@ -933,7 +954,13 @@
 	}
 
 	enable_irq(hcd->irq);
-	dev_dbg(mehci->dev, "HSIC-USB exited from low power mode\n");
+	dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
+
+	if (pdata->consider_ipa_handshake) {
+		dev_dbg(mehci->dev, "%s:Notify usb bam on resume complete\n",
+			__func__);
+		msm_bam_hsic_notify_on_resume();
+	}
 
 	return 0;
 }
@@ -1853,6 +1880,8 @@
 				"qcom,enable-hbm");
 	pdata->disable_park_mode = (of_property_read_bool(node,
 				"qcom,disable-park-mode"));
+	pdata->consider_ipa_handshake = (of_property_read_bool(node,
+				"hsic,consider-ipa-handshake"));
 
 	return pdata;
 }
@@ -2092,6 +2121,8 @@
 	if (mehci->enable_hbm)
 		hbm_init(hcd, pdata->disable_park_mode);
 
+	msm_bam_set_hsic_host_dev(&pdev->dev);
+
 	return 0;
 
 destroy_wq:
@@ -2115,6 +2146,8 @@
 	struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
 	struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
 
+	msm_bam_set_hsic_host_dev(NULL);
+
 	/* If the device was removed no need to call pm_runtime_disable */
 	if (pdev->dev.power.power_state.event != PM_EVENT_INVALID)
 		pm_runtime_disable(&pdev->dev);