From patchwork Mon Nov 26 04:43:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Xie X-Patchwork-Id: 1800071 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 50C3B3FC54 for ; Mon, 26 Nov 2012 04:47:55 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TcqYU-0006lL-4h; Mon, 26 Nov 2012 04:44:26 +0000 Received: from na3sys009aog122.obsmtp.com ([74.125.149.147]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1TcqXr-0006Z8-K4 for linux-arm-kernel@lists.infradead.org; Mon, 26 Nov 2012 04:43:50 +0000 Received: from MSI-MTA.marvell.com ([65.219.4.132]) (using TLSv1) by na3sys009aob122.postini.com ([74.125.148.12]) with SMTP ID DSNKULLzfw6ueYhZqiFYtalRHyKW6ZCdHQna@postini.com; Sun, 25 Nov 2012 20:43:47 PST Received: from maili.marvell.com ([10.68.76.210]) by MSI-MTA.marvell.com with Microsoft SMTPSVC(6.0.3790.3959); Sun, 25 Nov 2012 20:43:36 -0800 Received: from localhost (unknown [10.38.36.205]) by maili.marvell.com (Postfix) with ESMTP id 22BAC4E510; Sun, 25 Nov 2012 20:43:36 -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, chao.xie@marvell.com Subject: [PATCH 02/27] usb: gadget: mv_udc: use devm_xxx for probe Date: Sun, 25 Nov 2012 23:43:15 -0500 Message-Id: <1353905020-29372-3-git-send-email-xiechao.mail@gmail.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1353905020-29372-1-git-send-email-xiechao.mail@gmail.com> References: <1353905020-29372-1-git-send-email-xiechao.mail@gmail.com> X-OriginalArrivalTime: 26 Nov 2012 04:43:36.0134 (UTC) FILETIME=[98B4FE60:01CDCB90] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121125_234348_028279_292A924D X-CRM114-Status: GOOD ( 17.39 ) X-Spam-Score: -3.3 (---) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-3.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [74.125.149.147 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (xiechao.mail[at]gmail.com) 0.0 DKIM_ADSP_CUSTOM_MED No valid author signature, adsp_override is CUSTOM_MED -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.9 NML_ADSP_CUSTOM_MED ADSP custom_med hit, and not from a mailing list 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 From: Chao Xie use devm_xxx for udc driver probe. So we do need care about the resources release in driver remove or failure handling in driver probe. Signed-off-by: Chao Xie --- drivers/usb/gadget/mv_udc_core.c | 156 ++++++++++++++------------------------ 1 files changed, 56 insertions(+), 100 deletions(-) diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index fa4950a..1104327 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2115,12 +2115,11 @@ static void gadget_release(struct device *dev) complete(udc->done); } -static int __devexit mv_udc_remove(struct platform_device *dev) +static int __devexit mv_udc_remove(struct platform_device *pdev) { struct mv_udc *udc; - int clk_i; - udc = platform_get_drvdata(dev); + udc = platform_get_drvdata(pdev); usb_del_gadget_udc(&udc->gadget); @@ -2129,55 +2128,27 @@ static int __devexit mv_udc_remove(struct platform_device *dev) destroy_workqueue(udc->qwork); } - /* - * If we have transceiver inited, - * then vbus irq will not be requested in udc driver. - */ - if (udc->pdata && udc->pdata->vbus - && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver)) - free_irq(udc->pdata->vbus->irq, &dev->dev); - /* free memory allocated in probe */ if (udc->dtd_pool) dma_pool_destroy(udc->dtd_pool); if (udc->ep_dqh) - dma_free_coherent(&dev->dev, udc->ep_dqh_size, + dma_free_coherent(&pdev->dev, udc->ep_dqh_size, udc->ep_dqh, udc->ep_dqh_dma); - kfree(udc->eps); - - if (udc->irq) - free_irq(udc->irq, &dev->dev); - mv_udc_disable(udc); - if (udc->cap_regs) - iounmap(udc->cap_regs); - - if (udc->phy_regs) - iounmap(udc->phy_regs); - - if (udc->status_req) { - kfree(udc->status_req->req.buf); - kfree(udc->status_req); - } - - for (clk_i = 0; clk_i <= udc->clknum; clk_i++) - clk_put(udc->clk[clk_i]); - device_unregister(&udc->gadget.dev); /* free dev, wait for the release() finished */ wait_for_completion(udc->done); - kfree(udc); return 0; } -static int __devinit mv_udc_probe(struct platform_device *dev) +static int __devinit mv_udc_probe(struct platform_device *pdev) { - struct mv_usb_platform_data *pdata = dev->dev.platform_data; + struct mv_usb_platform_data *pdata = pdev->dev.platform_data; struct mv_udc *udc; int retval = 0; int clk_i = 0; @@ -2185,70 +2156,68 @@ static int __devinit mv_udc_probe(struct platform_device *dev) size_t size; if (pdata == NULL) { - dev_err(&dev->dev, "missing platform_data\n"); + dev_err(&pdev->dev, "missing platform_data\n"); return -ENODEV; } size = sizeof(*udc) + sizeof(struct clk *) * pdata->clknum; - udc = kzalloc(size, GFP_KERNEL); + udc = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (udc == NULL) { - dev_err(&dev->dev, "failed to allocate memory for udc\n"); + dev_err(&pdev->dev, "failed to allocate memory for udc\n"); return -ENOMEM; } udc->done = &release_done; - udc->pdata = dev->dev.platform_data; + udc->pdata = pdev->dev.platform_data; spin_lock_init(&udc->lock); - udc->dev = dev; + udc->dev = pdev; #ifdef CONFIG_USB_OTG_UTILS if (pdata->mode == MV_USB_MODE_OTG) - udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); + udc->transceiver = devm_usb_get_phy(&pdev->dev, + USB_PHY_TYPE_USB2); #endif udc->clknum = pdata->clknum; for (clk_i = 0; clk_i < udc->clknum; clk_i++) { - udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[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]); - goto err_put_clk; + return retval; } } r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "capregs"); if (r == NULL) { - dev_err(&dev->dev, "no I/O memory resource defined\n"); - retval = -ENODEV; - goto err_put_clk; + dev_err(&pdev->dev, "no I/O memory resource defined\n"); + return -ENODEV; } udc->cap_regs = (struct mv_cap_regs __iomem *) - ioremap(r->start, resource_size(r)); + devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (udc->cap_regs == NULL) { - dev_err(&dev->dev, "failed to map I/O memory\n"); - retval = -EBUSY; - goto err_put_clk; + dev_err(&pdev->dev, "failed to map I/O memory\n"); + return -EBUSY; } r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "phyregs"); if (r == NULL) { - dev_err(&dev->dev, "no phy I/O memory resource defined\n"); - retval = -ENODEV; - goto err_iounmap_capreg; + dev_err(&pdev->dev, "no phy I/O memory resource defined\n"); + return -ENODEV; } udc->phy_regs = ioremap(r->start, resource_size(r)); if (udc->phy_regs == NULL) { - dev_err(&dev->dev, "failed to map phy I/O memory\n"); - retval = -EBUSY; - goto err_iounmap_capreg; + dev_err(&pdev->dev, "failed to map phy I/O memory\n"); + return -EBUSY; } /* we will acces controller register, so enable the clk */ retval = mv_udc_enable_internal(udc); if (retval) - goto err_iounmap_phyreg; + return retval; udc->op_regs = (struct mv_op_regs __iomem *)((unsigned long)udc->cap_regs @@ -2265,11 +2234,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev) size = udc->max_eps * sizeof(struct mv_dqh) *2; size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); - udc->ep_dqh = dma_alloc_coherent(&dev->dev, size, + udc->ep_dqh = dma_alloc_coherent(&pdev->dev, size, &udc->ep_dqh_dma, GFP_KERNEL); if (udc->ep_dqh == NULL) { - dev_err(&dev->dev, "allocate dQH memory failed\n"); + dev_err(&pdev->dev, "allocate dQH memory failed\n"); retval = -ENOMEM; goto err_disable_clock; } @@ -2277,7 +2246,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev) /* create dTD dma_pool resource */ udc->dtd_pool = dma_pool_create("mv_dtd", - &dev->dev, + &pdev->dev, sizeof(struct mv_dtd), DTD_ALIGNMENT, DMA_BOUNDARY); @@ -2288,19 +2257,20 @@ static int __devinit mv_udc_probe(struct platform_device *dev) } size = udc->max_eps * sizeof(struct mv_ep) *2; - udc->eps = kzalloc(size, GFP_KERNEL); + udc->eps = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (udc->eps == NULL) { - dev_err(&dev->dev, "allocate ep memory failed\n"); + dev_err(&pdev->dev, "allocate ep memory failed\n"); retval = -ENOMEM; goto err_destroy_dma; } /* initialize ep0 status request structure */ - udc->status_req = kzalloc(sizeof(struct mv_req), GFP_KERNEL); + udc->status_req = devm_kzalloc(&pdev->dev, sizeof(struct mv_req), + GFP_KERNEL); if (!udc->status_req) { - dev_err(&dev->dev, "allocate status_req memory failed\n"); + dev_err(&pdev->dev, "allocate status_req memory failed\n"); retval = -ENOMEM; - goto err_free_eps; + goto err_destroy_dma; } INIT_LIST_HEAD(&udc->status_req->queue); @@ -2315,17 +2285,17 @@ static int __devinit mv_udc_probe(struct platform_device *dev) r = platform_get_resource(udc->dev, IORESOURCE_IRQ, 0); if (r == NULL) { - dev_err(&dev->dev, "no IRQ resource defined\n"); + dev_err(&pdev->dev, "no IRQ resource defined\n"); retval = -ENODEV; - goto err_free_status_req; + goto err_destroy_dma; } udc->irq = r->start; - if (request_irq(udc->irq, mv_udc_irq, + if (devm_request_irq(&pdev->dev, udc->irq, mv_udc_irq, IRQF_SHARED, driver_name, udc)) { - dev_err(&dev->dev, "Request irq %d for UDC failed\n", + dev_err(&pdev->dev, "Request irq %d for UDC failed\n", udc->irq); retval = -ENODEV; - goto err_free_status_req; + goto err_destroy_dma; } /* initialize gadget structure */ @@ -2337,14 +2307,14 @@ static int __devinit mv_udc_probe(struct platform_device *dev) /* the "gadget" abstracts/virtualizes the controller */ dev_set_name(&udc->gadget.dev, "gadget"); - udc->gadget.dev.parent = &dev->dev; - udc->gadget.dev.dma_mask = dev->dev.dma_mask; + udc->gadget.dev.parent = &pdev->dev; + udc->gadget.dev.dma_mask = pdev->dev.dma_mask; udc->gadget.dev.release = gadget_release; udc->gadget.name = driver_name; /* gadget name */ retval = device_register(&udc->gadget.dev); if (retval) - goto err_free_irq; + goto err_destroy_dma; eps_init(udc); @@ -2353,10 +2323,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev) udc->clock_gating = 1; else if (pdata->vbus) { udc->clock_gating = 1; - retval = request_threaded_irq(pdata->vbus->irq, NULL, + retval = devm_request_threaded_irq(&pdev->dev, + pdata->vbus->irq, NULL, mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); if (retval) { - dev_info(&dev->dev, + dev_info(&pdev->dev, "Can not request irq for VBUS, " "disable clock gating\n"); udc->clock_gating = 0; @@ -2364,7 +2335,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev) udc->qwork = create_singlethread_workqueue("mv_udc_queue"); if (!udc->qwork) { - dev_err(&dev->dev, "cannot create workqueue\n"); + dev_err(&pdev->dev, "cannot create workqueue\n"); retval = -ENOMEM; goto err_unregister; } @@ -2382,43 +2353,28 @@ static int __devinit mv_udc_probe(struct platform_device *dev) else udc->vbus_active = 1; - retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); + retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); if (retval) - goto err_unregister; + goto err_create_workqueue; - platform_set_drvdata(dev, udc); - dev_info(&dev->dev, "successful probe UDC device %s clock gating.\n", + platform_set_drvdata(pdev, udc); + dev_info(&pdev->dev, "successful probe UDC device %s clock gating.\n", udc->clock_gating ? "with" : "without"); return 0; +err_create_workqueue: + destroy_workqueue(udc->qwork); err_unregister: - if (udc->pdata && udc->pdata->vbus - && udc->clock_gating && IS_ERR_OR_NULL(udc->transceiver)) - free_irq(pdata->vbus->irq, &dev->dev); device_unregister(&udc->gadget.dev); -err_free_irq: - free_irq(udc->irq, &dev->dev); -err_free_status_req: - kfree(udc->status_req->req.buf); - kfree(udc->status_req); -err_free_eps: - kfree(udc->eps); err_destroy_dma: dma_pool_destroy(udc->dtd_pool); err_free_dma: - dma_free_coherent(&dev->dev, udc->ep_dqh_size, + dma_free_coherent(&pdev->dev, udc->ep_dqh_size, udc->ep_dqh, udc->ep_dqh_dma); err_disable_clock: mv_udc_disable_internal(udc); -err_iounmap_phyreg: - iounmap(udc->phy_regs); -err_iounmap_capreg: - iounmap(udc->cap_regs); -err_put_clk: - for (clk_i--; clk_i >= 0; clk_i--) - clk_put(udc->clk[clk_i]); - kfree(udc); + return retval; } @@ -2489,12 +2445,12 @@ static const struct dev_pm_ops mv_udc_pm_ops = { }; #endif -static void mv_udc_shutdown(struct platform_device *dev) +static void mv_udc_shutdown(struct platform_device *pdev) { struct mv_udc *udc; u32 mode; - udc = platform_get_drvdata(dev); + udc = platform_get_drvdata(pdev); /* reset controller mode to IDLE */ mv_udc_enable(udc); mode = readl(&udc->op_regs->usbmode);