From patchwork Tue Jan 15 06:19:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Xie X-Patchwork-Id: 1975211 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 90C003FE1B for ; Tue, 15 Jan 2013 06:36:04 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Tv03t-0001Lb-Ol; Tue, 15 Jan 2013 06:31:54 +0000 Received: from na3sys009aog107.obsmtp.com ([74.125.149.197]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1Tuzt6-00021Y-Rg for linux-arm-kernel@lists.infradead.org; Tue, 15 Jan 2013 06:20:46 +0000 Received: from MSI-MTA.marvell.com ([65.219.4.132]) (using TLSv1) by na3sys009aob107.postini.com ([74.125.148.12]) with SMTP ID DSNKUPT1LH16xPo7WpUS63PmxbxKZJoROWeG@postini.com; Mon, 14 Jan 2013 22:20:44 PST Received: from maili.marvell.com ([10.68.76.210]) by MSI-MTA.marvell.com with Microsoft SMTPSVC(6.0.3790.4675); Mon, 14 Jan 2013 22:19:50 -0800 Received: from localhost (unknown [10.38.36.239]) by maili.marvell.com (Postfix) with ESMTP id 99A1B4E510; Mon, 14 Jan 2013 22:19:50 -0800 (PST) From: Chao Xie To: linux-usb@vger.kernel.org, linux-arm-kernel@lists.infradead.org, haojian.zhuang@gmail.com, stern@rowland.harvard.edu, balbi@ti.com, gregkh@linuxfoundation.org, xiechao.mail@gmail.com Subject: [V3 PATCH 23/25] usb: gadget: mv_udc: add device tree support Date: Tue, 15 Jan 2013 01:19:16 -0500 Message-Id: <1358230758-10176-24-git-send-email-chao.xie@marvell.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1358230758-10176-1-git-send-email-chao.xie@marvell.com> References: <1358230758-10176-1-git-send-email-chao.xie@marvell.com> X-OriginalArrivalTime: 15 Jan 2013 06:19:50.0880 (UTC) FILETIME=[5360CE00:01CDF2E8] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130115_012045_176546_AC813361 X-CRM114-Status: GOOD ( 20.89 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [74.125.149.197 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Chao Xie X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org In original driver, we have callbacks in platform data, and some dynamically allocations variables in platform data. Now, these blocks are removed, the device tree support is easier now. Signed-off-by: Chao Xie --- drivers/usb/gadget/mv_udc.h | 5 +- drivers/usb/gadget/mv_udc_core.c | 105 ++++++++++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 25 deletions(-) diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h index 50ae7c7..de84722 100644 --- a/drivers/usb/gadget/mv_udc.h +++ b/drivers/usb/gadget/mv_udc.h @@ -179,6 +179,7 @@ struct mv_udc { int irq; unsigned int extern_attr; + unsigned int mode; struct notifier_block notifier; struct mv_cap_regs __iomem *cap_regs; @@ -222,11 +223,9 @@ struct mv_udc { struct mv_usb2_phy *phy; struct usb_phy *transceiver; - struct mv_usb_platform_data *pdata; - /* some SOC has mutiple clock sources for USB*/ unsigned int clknum; - struct clk *clk[0]; + struct clk **clk; }; /* endpoint data structure */ diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 4b50334..edac3ef 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -2153,21 +2154,57 @@ static int mv_udc_remove(struct platform_device *pdev) return 0; } +static int mv_udc_parse_dt(struct platform_device *pdev, + struct mv_udc *udc) +{ + struct device_node *np = pdev->dev.of_node; + unsigned int clks_num; + int i, ret; + const char *clk_name; + + if (!np) + return 1; + + clks_num = of_property_count_strings(np, "clocks"); + if (clks_num < 0) + return clks_num; + + udc->clk = devm_kzalloc(&pdev->dev, + sizeof(struct clk *) * clks_num, GFP_KERNEL); + if (udc->clk == NULL) + return -ENOMEM; + + for (i = 0; i < clks_num; i++) { + ret = of_property_read_string_index(np, "clocks", i, + &clk_name); + if (ret) + return ret; + udc->clk[i] = devm_clk_get(&pdev->dev, clk_name); + if (IS_ERR(udc->clk[i])) + return PTR_ERR(udc->clk[i]); + } + + udc->clknum = clks_num; + + ret = of_property_read_u32(np, "extern_attr", &udc->extern_attr); + if (ret) + return ret; + + ret = of_property_read_u32(np, "mode", &udc->mode); + if (ret) + return ret; + + return 0; +} + static int mv_udc_probe(struct platform_device *pdev) { - struct mv_usb_platform_data *pdata = pdev->dev.platform_data; struct mv_udc *udc; int retval = 0; - int clk_i = 0; struct resource *r; size_t size; - if (pdata == NULL) { - dev_err(&pdev->dev, "missing platform_data\n"); - return -ENODEV; - } - - size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; + size = sizeof(*udc); udc = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (udc == NULL) { dev_err(&pdev->dev, "failed to allocate memory for udc\n"); @@ -2175,14 +2212,43 @@ static int mv_udc_probe(struct platform_device *pdev) } udc->done = &release_done; - udc->extern_attr = pdata->extern_attr; - udc->pdata = pdev->dev.platform_data; spin_lock_init(&udc->lock); udc->dev = pdev; + retval = mv_udc_parse_dt(pdev, udc); + if (retval > 0) { + /* no CONFIG_OF */ + struct mv_usb_platform_data *pdata = pdev->dev.platform_data; + int clk_i = 0; + + if (pdata == NULL) { + dev_err(&pdev->dev, "missing platform_data\n"); + return -ENODEV; + } + udc->extern_attr = pdata->extern_attr; + udc->mode = pdata->mode; + udc->clknum = pdata->clknum; + + size = sizeof(struct clk *) * udc->clknum; + udc->clk = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (udc->clk == NULL) + return -ENOMEM; + for (clk_i = 0; clk_i < udc->clknum; clk_i++) { + udc->clk[clk_i] = devm_clk_get(&pdev->dev, + pdata->clkname[clk_i]); + if (IS_ERR(udc->clk[clk_i])) { + retval = PTR_ERR(udc->clk[clk_i]); + return retval; + } + } + } else if (retval < 0) { + dev_err(&pdev->dev, "error parse dt\n"); + return retval; + } + #ifdef CONFIG_USB_OTG_UTILS - if (pdata->mode == MV_USB_MODE_OTG) { + if (udc->mode == MV_USB_MODE_OTG) { udc->transceiver = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(udc->transceiver)) { @@ -2191,17 +2257,6 @@ static int mv_udc_probe(struct platform_device *pdev) } } #endif - - udc->clknum = pdata->clknum; - for (clk_i = 0; clk_i < udc->clknum; clk_i++) { - udc->clk[clk_i] = devm_clk_get(&pdev->dev, - pdata->clkname[clk_i]); - if (IS_ERR(udc->clk[clk_i])) { - retval = PTR_ERR(udc->clk[clk_i]); - return retval; - } - } - r = platform_get_resource(udc->dev, IORESOURCE_MEM, 0); if (r == NULL) { dev_err(&pdev->dev, "no I/O memory resource defined\n"); @@ -2466,6 +2521,11 @@ static void mv_udc_shutdown(struct platform_device *pdev) mv_udc_disable(udc); } +static struct of_device_id mv_udc_dt_ids[] = { + { .compatible = "mrvl,mv-udc" }, +}; +MODULE_DEVICE_TABLE(of, mv_udc_dt_ids); + static struct platform_driver udc_driver = { .probe = mv_udc_probe, .remove = mv_udc_remove, @@ -2476,6 +2536,7 @@ static struct platform_driver udc_driver = { #ifdef CONFIG_PM .pm = &mv_udc_pm_ops, #endif + .of_match_table = mv_udc_dt_ids, }, };