usb: ehci-msm-hsic: Add support in device tree to MSM HSIC host
Add support in device tree to MSM HSIC host including support in
GDSC (Global Distributed Switch Controller) for new platforms.
Change-Id: I6b0df0eabb03278b97b2b69f9fcdc2ef3806ba0b
Signed-off-by: Ofir Cohen <ofirc@codeaurora.org>
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 2d69a98..d7c8dad 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -76,6 +76,7 @@
struct clk *phy_clk;
struct clk *cal_clk;
struct regulator *hsic_vddcx;
+ struct regulator *hsic_gdsc;
bool async_int;
atomic_t in_lpm;
struct wake_lock wlock;
@@ -103,6 +104,8 @@
struct msm_hsic_hcd *__mehci;
static bool debug_bus_voting_enabled = true;
+static u64 ehci_msm_hsic_dma_mask = DMA_BIT_MASK(32);
+
static unsigned int enable_payload_log = 1;
module_param(enable_payload_log, uint, S_IRUGO | S_IWUSR);
@@ -393,6 +396,35 @@
}
+/* Global Distributed Switch Controller (GDSC) init */
+static int msm_hsic_init_gdsc(struct msm_hsic_hcd *mehci, int init)
+{
+ int ret = 0;
+
+ if (IS_ERR(mehci->hsic_gdsc))
+ return 0;
+
+ if (!mehci->hsic_gdsc) {
+ mehci->hsic_gdsc = devm_regulator_get(mehci->dev,
+ "HSIC_GDSC");
+ if (IS_ERR(mehci->hsic_gdsc))
+ return 0;
+ }
+
+ if (init) {
+ ret = regulator_enable(mehci->hsic_gdsc);
+ if (ret) {
+ dev_err(mehci->dev, "unable to enable hsic gdsc\n");
+ return ret;
+ }
+ } else {
+ regulator_disable(mehci->hsic_gdsc);
+ }
+
+ return 0;
+
+}
+
static int ulpi_read(struct msm_hsic_hcd *mehci, u32 reg)
{
struct usb_hcd *hcd = hsic_to_hcd(mehci);
@@ -1534,6 +1566,11 @@
dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &ehci_msm_hsic_dma_mask;
+ if (!pdev->dev.coherent_dma_mask)
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
/* After parent device's probe is executed, it will be put in suspend
* mode. When child device's probe is called, driver core is not
* resuming parent device due to which parent will be in suspend even
@@ -1588,6 +1625,13 @@
if (pdata)
mehci->ehci.log2_irq_thresh = pdata->log2_irq_thresh;
+ ret = msm_hsic_init_gdsc(mehci, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to initialize GDSC\n");
+ ret = -ENODEV;
+ goto put_hcd;
+ }
+
res = platform_get_resource_byname(pdev,
IORESOURCE_IRQ,
"peripheral_status_irq");
@@ -1715,6 +1759,7 @@
msm_hsic_config_gpios(mehci, 0);
deinit_vddcx:
msm_hsic_init_vddcx(mehci, 0);
+ msm_hsic_init_gdsc(mehci, 0);
deinit_clocks:
msm_hsic_init_clocks(mehci, 0);
unmap:
@@ -1763,6 +1808,7 @@
usb_remove_hcd(hcd);
msm_hsic_config_gpios(mehci, 0);
msm_hsic_init_vddcx(mehci, 0);
+ msm_hsic_init_gdsc(mehci, 0);
msm_hsic_init_clocks(mehci, 0);
wake_lock_destroy(&mehci->wlock);
@@ -1881,7 +1927,11 @@
msm_hsic_runtime_idle)
};
#endif
-
+static const struct of_device_id hsic_host_dt_match[] = {
+ { .compatible = "qcom,hsic-host",
+ },
+ {}
+};
static struct platform_driver ehci_msm_hsic_driver = {
.probe = ehci_hsic_msm_probe,
.remove = __devexit_p(ehci_hsic_msm_remove),
@@ -1890,5 +1940,6 @@
#ifdef CONFIG_PM
.pm = &msm_hsic_dev_pm_ops,
#endif
+ .of_match_table = hsic_host_dt_match,
},
};