From patchwork Mon Nov 19 10:04:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 1763811 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 1F6C33FCDE for ; Mon, 19 Nov 2012 10:10:53 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TaOGi-0007lr-Go; Mon, 19 Nov 2012 10:07:57 +0000 Received: from mail.free-electrons.com ([88.190.12.23]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TaOET-0006qm-12 for linux-arm-kernel@lists.infradead.org; Mon, 19 Nov 2012 10:05:43 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 863C2180; Mon, 19 Nov 2012 11:05:28 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham version=3.3.1 Received: from localhost (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 21A0B17D; Mon, 19 Nov 2012 11:05:09 +0100 (CET) From: Thomas Petazzoni To: Jason Cooper Subject: [PATCH 03/30] dma: mv_xor: split initialization/cleanup of XOR channels Date: Mon, 19 Nov 2012 11:04:41 +0100 Message-Id: <1353319508-30566-4-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1353319508-30566-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1353319508-30566-1-git-send-email-thomas.petazzoni@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121119_050539_786649_344C0882 X-CRM114-Status: GOOD ( 16.13 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Gregory Clement , Andrew Lunn , Lior Amsalem , linux-arm-kernel@lists.infradead.org, Maen Suleiman 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 Instead of doing the initialization/cleanup of the XOR channels directly in the ->probe() and ->remove() hooks, we create separate utility functions mv_xor_channel_add() and mv_xor_channel_remove(). This will allow to easily introduce in a future patch a different way of registering XOR channels: instead of having one platform_device per channel, we'll trigger the registration of all XOR channels of a given XOR engine directly from the XOR engine ->probe() function. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 75 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 7042772..f7b9919 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1077,19 +1077,18 @@ out: return err; } -static int __devexit mv_xor_remove(struct platform_device *dev) +static int mv_xor_channel_remove(struct mv_xor_device *device) { - struct mv_xor_device *device = platform_get_drvdata(dev); struct dma_chan *chan, *_chan; struct mv_xor_chan *mv_chan; dma_async_device_unregister(&device->common); - dma_free_coherent(&dev->dev, device->pool_size, - device->dma_desc_pool_virt, device->dma_desc_pool); + dma_free_coherent(&device->pdev->dev, device->pool_size, + device->dma_desc_pool_virt, device->dma_desc_pool); list_for_each_entry_safe(chan, _chan, &device->common.channels, - device_node) { + device_node) { mv_chan = to_mv_xor_chan(chan); list_del(&chan->device_node); } @@ -1097,19 +1096,20 @@ static int __devexit mv_xor_remove(struct platform_device *dev) return 0; } -static int __devinit mv_xor_probe(struct platform_device *pdev) +static struct mv_xor_device * +mv_xor_channel_add(struct mv_xor_shared_private *msp, + struct platform_device *pdev, + int hw_id, dma_cap_mask_t cap_mask, + size_t pool_size, int irq) { int ret = 0; - int irq; struct mv_xor_device *adev; struct mv_xor_chan *mv_chan; struct dma_device *dma_dev; - struct mv_xor_platform_data *plat_data = pdev->dev.platform_data; - adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL); if (!adev) - return -ENOMEM; + return ERR_PTR(-ENOMEM); dma_dev = &adev->common; @@ -1117,22 +1117,20 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) * note: writecombine gives slightly better performance, but * requires that we explicitly flush the writes */ - adev->pool_size = plat_data->pool_size; + adev->pool_size = pool_size; adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev, adev->pool_size, &adev->dma_desc_pool, GFP_KERNEL); if (!adev->dma_desc_pool_virt) - return -ENOMEM; + return ERR_PTR(-ENOMEM); - adev->id = plat_data->hw_id; + adev->id = hw_id; /* discover transaction capabilites from the platform data */ - dma_dev->cap_mask = plat_data->cap_mask; + dma_dev->cap_mask = cap_mask; adev->pdev = pdev; - platform_set_drvdata(pdev, adev); - - adev->shared = platform_get_drvdata(plat_data->shared); + adev->shared = msp; INIT_LIST_HEAD(&dma_dev->channels); @@ -1159,7 +1157,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) goto err_free_dma; } mv_chan->device = adev; - mv_chan->idx = plat_data->hw_id; + mv_chan->idx = hw_id; mv_chan->mmr_base = adev->shared->xor_base; if (!mv_chan->mmr_base) { @@ -1172,11 +1170,6 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) /* clear errors before enabling interrupts */ mv_xor_device_clear_err_status(mv_chan); - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto err_free_dma; - } ret = devm_request_irq(&pdev->dev, irq, mv_xor_interrupt_handler, 0, dev_name(&pdev->dev), mv_chan); @@ -1218,13 +1211,41 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : ""); dma_async_device_register(dma_dev); - goto out; + return adev; err_free_dma: - dma_free_coherent(&adev->pdev->dev, plat_data->pool_size, + dma_free_coherent(&adev->pdev->dev, pool_size, adev->dma_desc_pool_virt, adev->dma_desc_pool); - out: - return ret; + return ERR_PTR(ret); +} + +static int __devexit mv_xor_remove(struct platform_device *pdev) +{ + struct mv_xor_device *device = platform_get_drvdata(pdev); + return mv_xor_channel_remove(device); +} + +static int __devinit mv_xor_probe(struct platform_device *pdev) +{ + struct mv_xor_platform_data *plat_data = pdev->dev.platform_data; + struct mv_xor_shared_private *msp = + platform_get_drvdata(plat_data->shared); + struct mv_xor_device *mv_xor_device; + int irq; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + mv_xor_device = mv_xor_channel_add(msp, pdev, plat_data->hw_id, + plat_data->cap_mask, + plat_data->pool_size, irq); + if (IS_ERR(mv_xor_device)) + return PTR_ERR(mv_xor_device); + + platform_set_drvdata(pdev, mv_xor_device); + + return 0; } static void