From a7d090b908c846b44cfed2bc6cfaf2f076e0767a Mon Sep 17 00:00:00 2001
From: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Date: Wed, 19 Mar 2014 16:37:49 +0530
Subject: [PATCH] USB: ehci-msm2: Add module parameter to activate driver for
 uicc card

On some platforms, host only port is used for connecting peripherals
like uicc card. Userspace will come to know uicc card insertion and
use sysfs interface to activate driver and binds driver. Hence fail
probe for uicc card till userspace activates this driver through
sysfs.

Userspace has to run following commands to activate driver:
    1. echo Y > /sys/module/ehci_msm2/parameters/uicc_card_present
    2. echo msm_ehci_host > /sys/bus/platform/mdrivers/msm_ehci_host/bind

Also external vbus is not required for uicc card and hence don't fail
probe if no external vbus.

CRs-Fixed: 616098
Change-Id: I821bb2cabf4b5ba46fef71ac48a7df0b7aa74bf6
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
---
 .../devicetree/bindings/usb/msm-hsusb.txt     |  2 ++
 drivers/usb/host/ehci-msm2.c                  | 23 +++++++++++++++++++
 include/linux/usb/msm_hsusb.h                 |  1 +
 3 files changed, 26 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 3bd4ff54e799..ccc7d1ca8061 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -193,6 +193,7 @@ Optional properties :
 - qcom,ext-hub-reset-gpio: If present then an external HUB is connected to
   the USB host controller and its RESET_N signal is connected to this
   ext-hub-reset-gpio GPIO. It should be driven LOW to RESET the HUB.
+- qcom,usb2-enable-uicc: If present, usb2 port will be used for uicc card connection.
 
 Example MSM HSUSB EHCI controller device node :
 	ehci: qcom,ehci-host@f9a55000 {
@@ -212,6 +213,7 @@ Example MSM HSUSB EHCI controller device node :
 		qcom,usb2-enable-hsphy2;
 		qcom,usb2-power-budget = <500>;
 		qcom,vdd-voltage-level = <1 2 3 5 7>;
+		qcom,usb2-enable-uicc;
 	};
 
 ANDROID USB:
diff --git a/drivers/usb/host/ehci-msm2.c b/drivers/usb/host/ehci-msm2.c
index 0e603292173a..f8ccfb5a145e 100644
--- a/drivers/usb/host/ehci-msm2.c
+++ b/drivers/usb/host/ehci-msm2.c
@@ -57,6 +57,10 @@ static const char hcd_name[] = "ehci-msm2";
 
 #define PDEV_NAME_LEN 20
 
+static bool uicc_card_present;
+module_param(uicc_card_present, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(uicc_card_present, "UICC card inserted");
+
 struct msm_hcd {
 	struct ehci_hcd				ehci;
 	spinlock_t				wakeup_lock;
@@ -291,6 +295,11 @@ static int msm_ehci_config_vddcx(struct msm_hcd *mhcd, int high)
 static void msm_ehci_vbus_power(struct msm_hcd *mhcd, bool on)
 {
 	int ret;
+	const struct msm_usb_host_platform_data *pdata;
+
+	pdata = mhcd->dev->platform_data;
+	if (pdata && pdata->is_uicc)
+		return;
 
 	if (!mhcd->vbus) {
 		pr_err("vbus is NULL.");
@@ -348,6 +357,10 @@ static int msm_ehci_init_vbus(struct msm_hcd *mhcd, int init)
 
 	pdata = mhcd->dev->platform_data;
 
+	/* For uicc card connection, external vbus is not required */
+	if (pdata && pdata->is_uicc)
+		return 0;
+
 	if (!init) {
 		if (pdata && pdata->dock_connect_irq)
 			free_irq(pdata->dock_connect_irq, mhcd);
@@ -1275,6 +1288,8 @@ struct msm_usb_host_platform_data *ehci_msm2_dt_to_pdata(
 
 	pdata->ext_hub_reset_gpio = of_get_named_gpio(node,
 					"qcom,ext-hub-reset-gpio", 0);
+	pdata->is_uicc = of_property_read_bool(node,
+					"qcom,usb2-enable-uicc");
 
 	return pdata;
 }
@@ -1292,6 +1307,14 @@ static int ehci_msm2_probe(struct platform_device *pdev)
 
 	dev_dbg(&pdev->dev, "ehci_msm2 probe\n");
 
+	/*
+	 * Fail probe in case of uicc till userspace activates driver through
+	 * sysfs entry.
+	 */
+	if (!uicc_card_present && pdev->dev.of_node && of_property_read_bool(
+				pdev->dev.of_node, "qcom,usb2-enable-uicc"))
+		return -ENODEV;
+
 	hcd = usb_create_hcd(&ehci_msm2_hc_driver, &pdev->dev,
 				dev_name(&pdev->dev));
 	if (!hcd) {
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 73e5ef764c8f..0ea5b99bcc3f 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -556,6 +556,7 @@ struct msm_usb_host_platform_data {
 	bool no_selective_suspend;
 	int resume_gpio;
 	int ext_hub_reset_gpio;
+	bool is_uicc;
 };
 
 /**
-- 
GitLab