diff options
Diffstat (limited to 'target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch')
-rw-r--r-- | target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch b/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch new file mode 100644 index 0000000000..f8ad3cdbcb --- /dev/null +++ b/target/linux/ipq806x/patches/0156-usb-dwc3-Add-Qualcomm-DWC3-glue-layer-driver.patch @@ -0,0 +1,212 @@ +From 364532aeb9024d0ff7b88121f9a953f559b1c136 Mon Sep 17 00:00:00 2001 +From: "Ivan T. Ivanov" <iivanov@mm-sol.com> +Date: Mon, 7 Oct 2013 10:44:57 +0300 +Subject: [PATCH 156/182] usb: dwc3: Add Qualcomm DWC3 glue layer driver + +DWC3 glue layer is hardware layer around Synopsys DesignWare +USB3 core. Its purpose is to supply Synopsys IP with required +clocks, voltages and interface it with the rest of the SoC. + +Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com> +--- + drivers/usb/dwc3/Kconfig | 8 +++ + drivers/usb/dwc3/Makefile | 1 + + drivers/usb/dwc3/dwc3-qcom.c | 156 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 165 insertions(+) + create mode 100644 drivers/usb/dwc3/dwc3-qcom.c + +diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig +index e2c730f..2d01983 100644 +--- a/drivers/usb/dwc3/Kconfig ++++ b/drivers/usb/dwc3/Kconfig +@@ -59,6 +59,14 @@ config USB_DWC3_EXYNOS + Recent Exynos5 SoCs ship with one DesignWare Core USB3 IP inside, + say 'Y' or 'M' if you have one such device. + ++config USB_DWC3_QCOM ++ tristate "Qualcomm Platforms" ++ default USB_DWC3 ++ select USB_QCOM_DWC3_PHYS ++ help ++ Recent Qualcomm SoCs ship with one DesignWare Core USB3 IP inside, ++ say 'Y' or 'M' if you have one such device. ++ + config USB_DWC3_PCI + tristate "PCIe-based Platforms" + depends on PCI +diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile +index 10ac3e7..4066e4e 100644 +--- a/drivers/usb/dwc3/Makefile ++++ b/drivers/usb/dwc3/Makefile +@@ -31,5 +31,6 @@ endif + + obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o + obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o ++obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o + obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o + obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o +diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c +new file mode 100644 +index 0000000..8d17360 +--- /dev/null ++++ b/drivers/usb/dwc3/dwc3-qcom.c +@@ -0,0 +1,156 @@ ++/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 and ++ * only version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/io.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_platform.h> ++#include <linux/platform_device.h> ++#include <linux/regulator/consumer.h> ++#include <linux/usb/phy.h> ++ ++#include "core.h" ++ ++ ++struct dwc3_qcom { ++ struct device *dev; ++ ++ struct clk *core_clk; ++ struct clk *iface_clk; ++ struct clk *sleep_clk; ++ ++ struct regulator *gdsc; ++}; ++ ++static int dwc3_qcom_probe(struct platform_device *pdev) ++{ ++ struct device_node *node = pdev->dev.of_node; ++ struct dwc3_qcom *mdwc; ++ int ret = 0; ++ ++ mdwc = devm_kzalloc(&pdev->dev, sizeof(*mdwc), GFP_KERNEL); ++ if (!mdwc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, mdwc); ++ ++ mdwc->dev = &pdev->dev; ++ ++ mdwc->gdsc = devm_regulator_get(mdwc->dev, "gdsc"); ++ ++ mdwc->core_clk = devm_clk_get(mdwc->dev, "core"); ++ if (IS_ERR(mdwc->core_clk)) { ++ dev_dbg(mdwc->dev, "failed to get core clock\n"); ++ return PTR_ERR(mdwc->core_clk); ++ } ++ ++ mdwc->iface_clk = devm_clk_get(mdwc->dev, "iface"); ++ if (IS_ERR(mdwc->iface_clk)) { ++ dev_dbg(mdwc->dev, "failed to get iface clock, skipping\n"); ++ mdwc->iface_clk = NULL; ++ } ++ ++ mdwc->sleep_clk = devm_clk_get(mdwc->dev, "sleep"); ++ if (IS_ERR(mdwc->sleep_clk)) { ++ dev_dbg(mdwc->dev, "failed to get sleep clock, skipping\n"); ++ mdwc->sleep_clk = NULL; ++ } ++ ++ if (!IS_ERR(mdwc->gdsc)) { ++ ret = regulator_enable(mdwc->gdsc); ++ if (ret) ++ dev_err(mdwc->dev, "cannot enable gdsc\n"); ++ } ++ ++ clk_prepare_enable(mdwc->core_clk); ++ ++ if (mdwc->iface_clk) ++ clk_prepare_enable(mdwc->iface_clk); ++ ++ if (mdwc->sleep_clk) ++ clk_prepare_enable(mdwc->sleep_clk); ++ ++ ret = of_platform_populate(node, NULL, NULL, mdwc->dev); ++ if (ret) { ++ dev_err(mdwc->dev, "failed to register core - %d\n", ret); ++ dev_dbg(mdwc->dev, "failed to add create dwc3 core\n"); ++ goto dis_clks; ++ } ++ ++ return 0; ++ ++dis_clks: ++ ++ dev_err(mdwc->dev, "disabling clocks\n"); ++ ++ if (mdwc->sleep_clk) ++ clk_disable_unprepare(mdwc->sleep_clk); ++ ++ if (mdwc->iface_clk) ++ clk_disable_unprepare(mdwc->iface_clk); ++ ++ clk_disable_unprepare(mdwc->core_clk); ++ ++ if (!IS_ERR(mdwc->gdsc)) { ++ ret = regulator_disable(mdwc->gdsc); ++ if (ret) ++ dev_dbg(mdwc->dev, "cannot disable gdsc\n"); ++ } ++ ++ return ret; ++} ++ ++static int dwc3_qcom_remove(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ struct dwc3_qcom *mdwc = platform_get_drvdata(pdev); ++ ++ if (mdwc->sleep_clk) ++ clk_disable_unprepare(mdwc->sleep_clk); ++ ++ if (mdwc->iface_clk) ++ clk_disable_unprepare(mdwc->iface_clk); ++ ++ clk_disable_unprepare(mdwc->core_clk); ++ ++ if (!IS_ERR(mdwc->gdsc)) { ++ ret = regulator_disable(mdwc->gdsc); ++ if (ret) ++ dev_dbg(mdwc->dev, "cannot disable gdsc\n"); ++ } ++ return ret; ++} ++ ++static const struct of_device_id of_dwc3_match[] = { ++ { .compatible = "qcom,dwc3" }, ++ { /* Sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, of_dwc3_match); ++ ++static struct platform_driver dwc3_qcom_driver = { ++ .probe = dwc3_qcom_probe, ++ .remove = dwc3_qcom_remove, ++ .driver = { ++ .name = "qcom-dwc3", ++ .owner = THIS_MODULE, ++ .of_match_table = of_dwc3_match, ++ }, ++}; ++ ++module_platform_driver(dwc3_qcom_driver); ++ ++MODULE_ALIAS("platform:qcom-dwc3"); ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("DesignWare USB3 QCOM Glue Layer"); +-- +1.7.10.4 + |