From patchwork Wed Nov 18 19:25:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 56953 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp2752860lbb; Wed, 18 Nov 2015 11:25:44 -0800 (PST) X-Received: by 10.66.251.39 with SMTP id zh7mr4474152pac.6.1447874744598; Wed, 18 Nov 2015 11:25:44 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id sp3si6262165pbc.195.2015.11.18.11.25.43; Wed, 18 Nov 2015 11:25:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-usb-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755294AbbKRTZm (ORCPT + 4 others); Wed, 18 Nov 2015 14:25:42 -0500 Received: from arroyo.ext.ti.com ([192.94.94.40]:49980 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754016AbbKRTZl (ORCPT ); Wed, 18 Nov 2015 14:25:41 -0500 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id tAIJPanx008603; Wed, 18 Nov 2015 13:25:37 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id tAIJPawO026535; Wed, 18 Nov 2015 13:25:36 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.224.2; Wed, 18 Nov 2015 13:25:36 -0600 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id tAIJPZKo011667; Wed, 18 Nov 2015 13:25:36 -0600 From: Felipe Balbi To: Linux USB Mailing List CC: Subbaraya Sundeep Bhatta , "Ivan T . Ivanov" , Felipe Balbi Subject: [PATCH] usb: dwc3: add generic OF glue layer Date: Wed, 18 Nov 2015 13:25:34 -0600 Message-ID: <1447874734-3925-1-git-send-email-balbi@ti.com> X-Mailer: git-send-email 2.6.2 MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org For simple platforms which merely enable some clocks and populate its children, we can use this generic glue layer to avoid boilerplate code duplication. For now this supports Qcom and Xilinx, but if we find a way to add generic handling of regulators and optional PHYs, we can absorb exynos as well. Signed-off-by: Felipe Balbi --- Can you guys check if this works for your respective platforms ? If it does we can some code duplication going forward. drivers/usb/dwc3/Kconfig | 9 ++ drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 174 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 drivers/usb/dwc3/dwc3-of-simple.c -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 5a42c4590402..070e704829e5 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -87,6 +87,15 @@ config USB_DWC3_KEYSTONE Support of USB2/3 functionality in TI Keystone2 platforms. Say 'Y' or 'M' here if you have one such device +config USB_DWC3_OF_SIMPLE + tristate "Generic OF Simple Glue Layer" + depends on OF && COMMON_CLK + default USB_DWC3 + help + Support USB2/3 functionality in simple SoC integrations. + Currently supports Xilinx and Qualcomm DWC USB3 IP. + Say 'Y' or 'M' if you have one such device. + config USB_DWC3_ST tristate "STMicroelectronics Platforms" depends on ARCH_STI && OF diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index acc951d46c27..6491f9b474d4 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -37,5 +37,6 @@ obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o +obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c new file mode 100644 index 000000000000..00edd1195123 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -0,0 +1,174 @@ +/** + * dwc3-of-simple.c - OF glue layer for simple integrations + * + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com + * + * Author: Felipe Balbi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct dwc3_of_simple { + struct device *dev; + struct clk **clks; + int num_clocks; +}; + +static int dwc3_of_simple_probe(struct platform_device *pdev) +{ + struct dwc3_of_simple *simple; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + + int ret; + int i; + + simple = devm_kzalloc(dev, sizeof(*simple), GFP_KERNEL); + if (!simple) + return -ENOMEM; + + ret = of_clk_get_parent_count(np); + if (ret < 0) + return ret; + + simple->num_clocks = ret; + + simple->clks = devm_kcalloc(dev, simple->num_clocks, + sizeof(struct clk *), GFP_KERNEL); + if (!simple->clks) + return -ENOMEM; + + simple->dev = dev; + + for (i = 0; i < simple->num_clocks; i++) { + struct clk *clk; + + clk = of_clk_get(np, i); + if (IS_ERR(clk)) { + while (--i >= 0) + clk_put(simple->clks[i]); + return PTR_ERR(clk); + } + + ret = clk_prepare_enable(clk); + if (ret < 0) { + while (--i >= 0) { + clk_disable_unprepare(simple->clks[i]); + clk_put(simple->clks[i]); + } + clk_put(clk); + + return ret; + } + + simple->clks[i] = clk; + } + + ret = of_platform_populate(np, NULL, NULL, dev); + if (ret) { + for (i = 0; i < simple->num_clocks; i++) { + clk_disable_unprepare(simple->clks[i]); + clk_put(simple->clks[i]); + } + + return ret; + } + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + return 0; +} + +static int dwc3_of_simple_remove(struct platform_device *pdev) +{ + struct dwc3_of_simple *simple = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + int i; + + for (i = 0; i < simple->num_clocks; i++) { + clk_unprepare(simple->clks[i]); + clk_put(simple->clks[i]); + } + + of_platform_depopulate(dev); + + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + + return 0; +} + +static int dwc3_of_simple_runtime_suspend(struct device *dev) +{ + struct dwc3_of_simple *simple = dev_get_drvdata(dev); + int i; + + for (i = 0; i < simple->num_clocks; i++) + clk_disable(simple->clks[i]); + + return 0; +} + +static int dwc3_of_simple_runtime_resume(struct device *dev) +{ + struct dwc3_of_simple *simple = dev_get_drvdata(dev); + int ret; + int i; + + for (i = 0; i < simple->num_clocks; i++) { + ret = clk_enable(simple->clks[i]); + if (ret < 0) { + while (--i >= 0) + clk_disable(simple->clks[i]); + return ret; + } + } + + return 0; +} + +static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { + SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend, + dwc3_of_simple_runtime_resume, NULL) +}; + +static const struct of_device_id of_dwc3_simple_match[] = { + { .compatible = "qcom,dwc3" }, + { .compatible = "xlnx,zynqmp-dwc3" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); + +static struct platform_driver dwc3_of_simple_driver = { + .probe = dwc3_of_simple_probe, + .remove = dwc3_of_simple_remove, + .driver = { + .name = "dwc3-of-simple", + .of_match_table = of_dwc3_simple_match, + }, +}; + +module_platform_driver(dwc3_of_simple_driver); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("DesignWare USB3 OF Simple Glue Layer"); +MODULE_AUTHOR("Felipe Balbi ");