From a3fc74bc9bd8ffd1f2352a2053e906d1efad870d Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 12:50:27 +0100 Subject: dma: mv_xor: use dev_(err|info|notice) instead of dev_printk The usage of dev_printk() is deprecated, and the dev_err(), dev_info() and dev_notice() functions should be used instead. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index e362e2b80efb..610d0b886cd6 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -206,9 +206,9 @@ static void mv_set_mode(struct mv_xor_chan *chan, op_mode = XOR_OPERATION_MODE_MEMSET; break; default: - dev_printk(KERN_ERR, chan->device->common.dev, - "error: unsupported operation %d.\n", - type); + dev_err(chan->device->common.dev, + "error: unsupported operation %d.\n", + type); BUG(); return; } @@ -828,28 +828,28 @@ static void mv_dump_xor_regs(struct mv_xor_chan *chan) u32 val; val = __raw_readl(XOR_CONFIG(chan)); - dev_printk(KERN_ERR, chan->device->common.dev, - "config 0x%08x.\n", val); + dev_err(chan->device->common.dev, + "config 0x%08x.\n", val); val = __raw_readl(XOR_ACTIVATION(chan)); - dev_printk(KERN_ERR, chan->device->common.dev, - "activation 0x%08x.\n", val); + dev_err(chan->device->common.dev, + "activation 0x%08x.\n", val); val = __raw_readl(XOR_INTR_CAUSE(chan)); - dev_printk(KERN_ERR, chan->device->common.dev, - "intr cause 0x%08x.\n", val); + dev_err(chan->device->common.dev, + "intr cause 0x%08x.\n", val); val = __raw_readl(XOR_INTR_MASK(chan)); - dev_printk(KERN_ERR, chan->device->common.dev, - "intr mask 0x%08x.\n", val); + dev_err(chan->device->common.dev, + "intr mask 0x%08x.\n", val); val = __raw_readl(XOR_ERROR_CAUSE(chan)); - dev_printk(KERN_ERR, chan->device->common.dev, - "error cause 0x%08x.\n", val); + dev_err(chan->device->common.dev, + "error cause 0x%08x.\n", val); val = __raw_readl(XOR_ERROR_ADDR(chan)); - dev_printk(KERN_ERR, chan->device->common.dev, - "error addr 0x%08x.\n", val); + dev_err(chan->device->common.dev, + "error addr 0x%08x.\n", val); } static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan, @@ -861,9 +861,9 @@ static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan, return; } - dev_printk(KERN_ERR, chan->device->common.dev, - "error on chan %d. intr cause 0x%08x.\n", - chan->idx, intr_cause); + dev_err(chan->device->common.dev, + "error on chan %d. intr cause 0x%08x.\n", + chan->idx, intr_cause); mv_dump_xor_regs(chan); BUG(); @@ -950,8 +950,8 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { - dev_printk(KERN_ERR, dma_chan->device->dev, - "Self-test copy timed out, disabling\n"); + dev_err(dma_chan->device->dev, + "Self-test copy timed out, disabling\n"); err = -ENODEV; goto free_resources; } @@ -960,8 +960,8 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma, MV_XOR_TEST_SIZE, DMA_FROM_DEVICE); if (memcmp(src, dest, MV_XOR_TEST_SIZE)) { - dev_printk(KERN_ERR, dma_chan->device->dev, - "Self-test copy failed compare, disabling\n"); + dev_err(dma_chan->device->dev, + "Self-test copy failed compare, disabling\n"); err = -ENODEV; goto free_resources; } @@ -1048,8 +1048,8 @@ mv_xor_xor_self_test(struct mv_xor_device *device) if (mv_xor_status(dma_chan, cookie, NULL) != DMA_SUCCESS) { - dev_printk(KERN_ERR, dma_chan->device->dev, - "Self-test xor timed out, disabling\n"); + dev_err(dma_chan->device->dev, + "Self-test xor timed out, disabling\n"); err = -ENODEV; goto free_resources; } @@ -1060,10 +1060,10 @@ mv_xor_xor_self_test(struct mv_xor_device *device) for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) { u32 *ptr = page_address(dest); if (ptr[i] != cmp_word) { - dev_printk(KERN_ERR, dma_chan->device->dev, - "Self-test xor failed compare, disabling." - " index %d, data %x, expected %x\n", i, - ptr[i], cmp_word); + dev_err(dma_chan->device->dev, + "Self-test xor failed compare, disabling." + " index %d, data %x, expected %x\n", i, + ptr[i], cmp_word); err = -ENODEV; goto free_resources; } @@ -1212,7 +1212,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) goto err_free_dma; } - dev_printk(KERN_INFO, &pdev->dev, "Marvell XOR: " + dev_info(&pdev->dev, "Marvell XOR: " "( %s%s%s%s)\n", dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "", dma_has_cap(DMA_MEMSET, dma_dev->cap_mask) ? "fill " : "", @@ -1275,7 +1275,7 @@ static int mv_xor_shared_probe(struct platform_device *pdev) struct mv_xor_shared_private *msp; struct resource *res; - dev_printk(KERN_NOTICE, &pdev->dev, "Marvell shared XOR driver\n"); + dev_notice(&pdev->dev, "Marvell shared XOR driver\n"); msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL); if (!msp) -- cgit v1.2.3 From 09f2b7864ce37483f4c4ecb30b0eed599f475035 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 29 Oct 2012 16:27:34 +0100 Subject: dma: mv_xor: do not use pool_size from platform_data within the driver The driver currently pokes into the platform_data structure during its normal operation to get the pool_size value. Poking into the platform_data structure is not nice when moving to the Device Tree, so this commit adds a new pool_size field in the mv_xor_device structure, which gets initialized at ->probe() time. The driver then uses this field instead of the platform_data. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 10 ++++------ drivers/dma/mv_xor.h | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 610d0b886cd6..704277259a5b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -604,9 +604,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) int idx; struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); struct mv_xor_desc_slot *slot = NULL; - struct mv_xor_platform_data *plat_data = - mv_chan->device->pdev->dev.platform_data; - int num_descs_in_pool = plat_data->pool_size/MV_XOR_SLOT_SIZE; + int num_descs_in_pool = mv_chan->device->pool_size/MV_XOR_SLOT_SIZE; /* Allocate descriptor slots */ idx = mv_chan->slots_allocated; @@ -1084,11 +1082,10 @@ static int __devexit mv_xor_remove(struct platform_device *dev) struct mv_xor_device *device = platform_get_drvdata(dev); struct dma_chan *chan, *_chan; struct mv_xor_chan *mv_chan; - struct mv_xor_platform_data *plat_data = dev->dev.platform_data; dma_async_device_unregister(&device->common); - dma_free_coherent(&dev->dev, plat_data->pool_size, + dma_free_coherent(&dev->dev, device->pool_size, device->dma_desc_pool_virt, device->dma_desc_pool); list_for_each_entry_safe(chan, _chan, &device->common.channels, @@ -1120,8 +1117,9 @@ 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->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev, - plat_data->pool_size, + adev->pool_size, &adev->dma_desc_pool, GFP_KERNEL); if (!adev->dma_desc_pool_virt) diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index a5b422f5a8ab..a0641aebbdef 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -72,6 +72,7 @@ struct mv_xor_device { int id; dma_addr_t dma_desc_pool; void *dma_desc_pool_virt; + size_t pool_size; struct dma_device common; struct mv_xor_shared_private *shared; }; -- cgit v1.2.3 From a6b4a9d2c1063ffc52ca94b6c1b24f9b6d5b79c5 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 29 Oct 2012 16:45:46 +0100 Subject: dma: mv_xor: split initialization/cleanup of XOR channels 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(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 704277259a5b..f7b99193e884 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 -- cgit v1.2.3 From 60d151f38799d5e15845ee04b73cbf3839f1b06c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 29 Oct 2012 16:54:49 +0100 Subject: dma: mv_xor: allow channels to be registered directly from the main device Extend the XOR engine driver (currently called "mv_xor_shared") so that XOR channels can be passed in the platform_data structure, and be registered from there. This will allow the users of the driver to be converted to the single platform_driver variant of the mv_xor driver. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/mv_xor.h | 8 +++++--- 2 files changed, 50 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index f7b99193e884..6ed3162cccc9 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1292,7 +1292,9 @@ static int mv_xor_shared_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; struct mv_xor_shared_private *msp; + struct mv_xor_shared_platform_data *pdata = pdev->dev.platform_data; struct resource *res; + int i, ret; dev_notice(&pdev->dev, "Marvell shared XOR driver\n"); @@ -1334,12 +1336,55 @@ static int mv_xor_shared_probe(struct platform_device *pdev) if (!IS_ERR(msp->clk)) clk_prepare_enable(msp->clk); + if (pdata && pdata->channels) { + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { + struct mv_xor_platform_data *cd; + int irq; + + cd = &pdata->channels[i]; + if (!cd) { + ret = -ENODEV; + goto err_channel_add; + } + + irq = platform_get_irq(pdev, i); + if (irq < 0) { + ret = irq; + goto err_channel_add; + } + + msp->channels[i] = + mv_xor_channel_add(msp, pdev, cd->hw_id, + cd->cap_mask, + cd->pool_size, irq); + if (IS_ERR(msp->channels[i])) { + ret = PTR_ERR(msp->channels[i]); + goto err_channel_add; + } + } + } + return 0; + +err_channel_add: + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) + if (msp->channels[i]) + mv_xor_channel_remove(msp->channels[i]); + + clk_disable_unprepare(msp->clk); + clk_put(msp->clk); + return ret; } static int mv_xor_shared_remove(struct platform_device *pdev) { struct mv_xor_shared_private *msp = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { + if (msp->channels[i]) + mv_xor_channel_remove(msp->channels[i]); + } if (!IS_ERR(msp->clk)) { clk_disable_unprepare(msp->clk); diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index a0641aebbdef..686575f6b9f5 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -26,6 +26,7 @@ #define USE_TIMER #define MV_XOR_SLOT_SIZE 64 #define MV_XOR_THRESHOLD 1 +#define MV_XOR_MAX_CHANNELS 2 #define XOR_OPERATION_MODE_XOR 0 #define XOR_OPERATION_MODE_MEMCPY 2 @@ -53,9 +54,10 @@ #define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) struct mv_xor_shared_private { - void __iomem *xor_base; - void __iomem *xor_high_base; - struct clk *clk; + void __iomem *xor_base; + void __iomem *xor_high_base; + struct clk *clk; + struct mv_xor_device *channels[MV_XOR_MAX_CHANNELS]; }; -- cgit v1.2.3 From 18b2a02c7c8db8bb87a165d26c269968d3dd47bd Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 30 Oct 2012 11:54:34 +0100 Subject: dma: mv_xor: remove sub-driver 'mv_xor' Now that XOR channels are directly registered by the main 'mv_xor_shared' device ->probe() function and all users of the 'mv_xor' device have been removed, we can get rid of the latter. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 49 +------------------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 6ed3162cccc9..be3907bdef14 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1219,35 +1219,6 @@ mv_xor_channel_add(struct mv_xor_shared_private *msp, 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 mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp, const struct mbus_dram_target_info *dram) @@ -1279,15 +1250,6 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp, writel(win_enable, base + WINDOW_BAR_ENABLE(1)); } -static struct platform_driver mv_xor_driver = { - .probe = mv_xor_probe, - .remove = __devexit_p(mv_xor_remove), - .driver = { - .owner = THIS_MODULE, - .name = MV_XOR_NAME, - }, -}; - static int mv_xor_shared_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; @@ -1406,15 +1368,7 @@ static struct platform_driver mv_xor_shared_driver = { static int __init mv_xor_init(void) { - int rc; - - rc = platform_driver_register(&mv_xor_shared_driver); - if (!rc) { - rc = platform_driver_register(&mv_xor_driver); - if (rc) - platform_driver_unregister(&mv_xor_shared_driver); - } - return rc; + return platform_driver_register(&mv_xor_shared_driver); } module_init(mv_xor_init); @@ -1422,7 +1376,6 @@ module_init(mv_xor_init); #if 0 static void __exit mv_xor_exit(void) { - platform_driver_unregister(&mv_xor_driver); platform_driver_unregister(&mv_xor_shared_driver); return; } -- cgit v1.2.3 From e39f6ec1f9c1d6a7011adf6d95d8d80bad0586b1 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 30 Oct 2012 11:56:26 +0100 Subject: dma: mv_xor: rename mv_xor_platform_data to mv_xor_channel_data mv_xor_platform_data used to be the platform_data structure associated to the 'mv_xor' driver. This driver no longer exists, and this data structure really contains the properties of each XOR channel part of a given XOR engine. Therefore 'struct mv_xor_channel_data' is a more appropriate name. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index be3907bdef14..c7926e417281 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1300,7 +1300,7 @@ static int mv_xor_shared_probe(struct platform_device *pdev) if (pdata && pdata->channels) { for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { - struct mv_xor_platform_data *cd; + struct mv_xor_channel_data *cd; int irq; cd = &pdata->channels[i]; -- cgit v1.2.3 From 7dde453d628687c0e991cfc55c9fd299a804aee6 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 30 Oct 2012 11:58:14 +0100 Subject: dma: mv_xor: rename mv_xor_shared_platform_data to mv_xor_platform_data 'struct mv_xor_shared_platform_data' used to be the platform_data structure for the 'mv_xor_shared', but this driver is going to be renamed simply 'mv_xor', so also rename its platform_data structure accordingly. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index c7926e417281..ac598168b21f 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1254,7 +1254,7 @@ static int mv_xor_shared_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; struct mv_xor_shared_private *msp; - struct mv_xor_shared_platform_data *pdata = pdev->dev.platform_data; + struct mv_xor_platform_data *pdata = pdev->dev.platform_data; struct resource *res; int i, ret; -- cgit v1.2.3 From 0dddee7a7d42192267ebef0fe15be8b296b665c8 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 30 Oct 2012 11:59:42 +0100 Subject: dma: mv_xor: change the driver name to 'mv_xor' Since we got rid of the per-XOR channel 'mv_xor' driver, now the per-XOR engine driver that used to be called 'mv_xor_shared' can simply be named 'mv_xor'. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index ac598168b21f..0ed5183eb5a3 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1361,7 +1361,7 @@ static struct platform_driver mv_xor_shared_driver = { .remove = mv_xor_shared_remove, .driver = { .owner = THIS_MODULE, - .name = MV_XOR_SHARED_NAME, + .name = MV_XOR_NAME, }, }; -- cgit v1.2.3 From 61971656ce72ae40939abd4b23c61976270d2374 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 30 Oct 2012 12:05:40 +0100 Subject: dma: mv_xor: rename many symbols to remove the 'shared' word The 'shared' word no longer makes sense in a number of places as we renamed the 'mv_xor_shared' driver to 'mv_xor'. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 24 ++++++++++++------------ drivers/dma/mv_xor.h | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 0ed5183eb5a3..49461b6e6eb4 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1097,7 +1097,7 @@ static int mv_xor_channel_remove(struct mv_xor_device *device) } static struct mv_xor_device * -mv_xor_channel_add(struct mv_xor_shared_private *msp, +mv_xor_channel_add(struct mv_xor_private *msp, struct platform_device *pdev, int hw_id, dma_cap_mask_t cap_mask, size_t pool_size, int irq) @@ -1220,7 +1220,7 @@ mv_xor_channel_add(struct mv_xor_shared_private *msp, } static void -mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp, +mv_xor_conf_mbus_windows(struct mv_xor_private *msp, const struct mbus_dram_target_info *dram) { void __iomem *base = msp->xor_base; @@ -1250,15 +1250,15 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp, writel(win_enable, base + WINDOW_BAR_ENABLE(1)); } -static int mv_xor_shared_probe(struct platform_device *pdev) +static int mv_xor_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; - struct mv_xor_shared_private *msp; + struct mv_xor_private *msp; struct mv_xor_platform_data *pdata = pdev->dev.platform_data; struct resource *res; int i, ret; - dev_notice(&pdev->dev, "Marvell shared XOR driver\n"); + dev_notice(&pdev->dev, "Marvell XOR driver\n"); msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL); if (!msp) @@ -1338,9 +1338,9 @@ err_channel_add: return ret; } -static int mv_xor_shared_remove(struct platform_device *pdev) +static int mv_xor_remove(struct platform_device *pdev) { - struct mv_xor_shared_private *msp = platform_get_drvdata(pdev); + struct mv_xor_private *msp = platform_get_drvdata(pdev); int i; for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { @@ -1356,9 +1356,9 @@ static int mv_xor_shared_remove(struct platform_device *pdev) return 0; } -static struct platform_driver mv_xor_shared_driver = { - .probe = mv_xor_shared_probe, - .remove = mv_xor_shared_remove, +static struct platform_driver mv_xor_driver = { + .probe = mv_xor_probe, + .remove = mv_xor_remove, .driver = { .owner = THIS_MODULE, .name = MV_XOR_NAME, @@ -1368,7 +1368,7 @@ static struct platform_driver mv_xor_shared_driver = { static int __init mv_xor_init(void) { - return platform_driver_register(&mv_xor_shared_driver); + return platform_driver_register(&mv_xor_driver); } module_init(mv_xor_init); @@ -1376,7 +1376,7 @@ module_init(mv_xor_init); #if 0 static void __exit mv_xor_exit(void) { - platform_driver_unregister(&mv_xor_shared_driver); + platform_driver_unregister(&mv_xor_driver); return; } diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 686575f6b9f5..7812565b3505 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -53,7 +53,7 @@ #define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2)) #define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) -struct mv_xor_shared_private { +struct mv_xor_private { void __iomem *xor_base; void __iomem *xor_high_base; struct clk *clk; @@ -76,7 +76,7 @@ struct mv_xor_device { void *dma_desc_pool_virt; size_t pool_size; struct dma_device common; - struct mv_xor_shared_private *shared; + struct mv_xor_private *shared; }; /** -- cgit v1.2.3 From 8b5c3f6c8d8300e7825bb5ed6effe0bd35907751 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 30 Oct 2012 13:19:08 +0100 Subject: dma: mv_xor: remove unused id field in mv_xor_device structure Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 2 -- drivers/dma/mv_xor.h | 1 - 2 files changed, 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 49461b6e6eb4..3a54213c1b5f 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1125,8 +1125,6 @@ mv_xor_channel_add(struct mv_xor_private *msp, if (!adev->dma_desc_pool_virt) return ERR_PTR(-ENOMEM); - adev->id = hw_id; - /* discover transaction capabilites from the platform data */ dma_dev->cap_mask = cap_mask; adev->pdev = pdev; diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 7812565b3505..52ca6172bc6b 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -71,7 +71,6 @@ struct mv_xor_private { */ struct mv_xor_device { struct platform_device *pdev; - int id; dma_addr_t dma_desc_pool; void *dma_desc_pool_virt; size_t pool_size; -- cgit v1.2.3 From 01a9508de746bc2ae37dc63b407f2d7cdcb00386 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 13:01:34 +0100 Subject: dma: mv_xor: remove unused to_mv_xor_device() macro The to_mv_xor_device() macro is not being used by the driver, so we can get rid of it. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 3a54213c1b5f..a9994713072e 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -36,9 +36,6 @@ static void mv_xor_issue_pending(struct dma_chan *chan); #define to_mv_xor_chan(chan) \ container_of(chan, struct mv_xor_chan, common) -#define to_mv_xor_device(dev) \ - container_of(dev, struct mv_xor_device, common) - #define to_mv_xor_slot(tx) \ container_of(tx, struct mv_xor_desc_slot, async_tx) -- cgit v1.2.3 From c35064c4b6f4e03a4f40cc88e3257525a7b31a68 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 13:01:59 +0100 Subject: dma: mv_xor: simplify dma_sync_single_for_cpu() calls In mv_xor_memcpy_self_test() and mv_xor_xor_self_test(), all DMA functions are called by passing dma_chan->device->dev as the 'device *', except the calls to dma_sync_single_for_cpu() which uselessly goes through mv_chan->device->pdev->dev. Simplify this by using dma_chan->device->dev direclty in dma_sync_single_for_cpu() calls. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a9994713072e..b799d33d46bc 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -905,7 +905,6 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) dma_cookie_t cookie; struct dma_async_tx_descriptor *tx; int err = 0; - struct mv_xor_chan *mv_chan; src = kmalloc(sizeof(u8) * MV_XOR_TEST_SIZE, GFP_KERNEL); if (!src) @@ -951,8 +950,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) goto free_resources; } - mv_chan = to_mv_xor_chan(dma_chan); - dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma, + dma_sync_single_for_cpu(dma_chan->device->dev, dest_dma, MV_XOR_TEST_SIZE, DMA_FROM_DEVICE); if (memcmp(src, dest, MV_XOR_TEST_SIZE)) { dev_err(dma_chan->device->dev, @@ -984,7 +982,6 @@ mv_xor_xor_self_test(struct mv_xor_device *device) u8 cmp_byte = 0; u32 cmp_word; int err = 0; - struct mv_xor_chan *mv_chan; for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) { xor_srcs[src_idx] = alloc_page(GFP_KERNEL); @@ -1049,8 +1046,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) goto free_resources; } - mv_chan = to_mv_xor_chan(dma_chan); - dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma, + dma_sync_single_for_cpu(dma_chan->device->dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE); for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) { u32 *ptr = page_address(dest); -- cgit v1.2.3 From c98c17813e3985ebfd657496bfb49d7174d1fad1 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 14:17:18 +0100 Subject: dma: mv_xor: introduce a mv_chan_to_devp() helper In many place, we need to get the 'struct device *' pointer from a 'struct mv_chan *', so we add a helper that makes this a bit easier. It will also help reducing the change noise in further patches. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 61 +++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index b799d33d46bc..38dac0d9265c 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -39,6 +39,9 @@ static void mv_xor_issue_pending(struct dma_chan *chan); #define to_mv_xor_slot(tx) \ container_of(tx, struct mv_xor_desc_slot, async_tx) +#define mv_chan_to_devp(chan) \ + ((chan)->device->common.dev) + static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags) { struct mv_xor_desc *hw_desc = desc->hw_desc; @@ -163,7 +166,7 @@ static int mv_is_err_intr(u32 intr_cause) static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan) { u32 val = ~(1 << (chan->idx * 16)); - dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val); + dev_dbg(mv_chan_to_devp(chan), "%s, val 0x%08x\n", __func__, val); __raw_writel(val, XOR_INTR_CAUSE(chan)); } @@ -203,7 +206,7 @@ static void mv_set_mode(struct mv_xor_chan *chan, op_mode = XOR_OPERATION_MODE_MEMSET; break; default: - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "error: unsupported operation %d.\n", type); BUG(); @@ -220,7 +223,7 @@ static void mv_chan_activate(struct mv_xor_chan *chan) { u32 activation; - dev_dbg(chan->device->common.dev, " activate chan.\n"); + dev_dbg(mv_chan_to_devp(chan), " activate chan.\n"); activation = __raw_readl(XOR_ACTIVATION(chan)); activation |= 0x1; __raw_writel(activation, XOR_ACTIVATION(chan)); @@ -248,7 +251,7 @@ static int mv_chan_xor_slot_count(size_t len, int src_cnt) static void mv_xor_free_slots(struct mv_xor_chan *mv_chan, struct mv_xor_desc_slot *slot) { - dev_dbg(mv_chan->device->common.dev, "%s %d slot %p\n", + dev_dbg(mv_chan_to_devp(mv_chan), "%s %d slot %p\n", __func__, __LINE__, slot); slot->slots_per_op = 0; @@ -263,7 +266,7 @@ static void mv_xor_free_slots(struct mv_xor_chan *mv_chan, static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan, struct mv_xor_desc_slot *sw_desc) { - dev_dbg(mv_chan->device->common.dev, "%s %d: sw_desc %p\n", + dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: sw_desc %p\n", __func__, __LINE__, sw_desc); if (sw_desc->type != mv_chan->current_type) mv_set_mode(mv_chan, sw_desc->type); @@ -350,7 +353,7 @@ mv_xor_clean_completed_slots(struct mv_xor_chan *mv_chan) { struct mv_xor_desc_slot *iter, *_iter; - dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__); + dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__); list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots, completed_node) { @@ -366,7 +369,7 @@ static int mv_xor_clean_slot(struct mv_xor_desc_slot *desc, struct mv_xor_chan *mv_chan) { - dev_dbg(mv_chan->device->common.dev, "%s %d: desc %p flags %d\n", + dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: desc %p flags %d\n", __func__, __LINE__, desc, desc->async_tx.flags); list_del(&desc->chain_node); /* the client is allowed to attach dependent operations @@ -390,8 +393,8 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) u32 current_desc = mv_chan_get_current_desc(mv_chan); int seen_current = 0; - dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__); - dev_dbg(mv_chan->device->common.dev, "current_desc %x\n", current_desc); + dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__); + dev_dbg(mv_chan_to_devp(mv_chan), "current_desc %x\n", current_desc); mv_xor_clean_completed_slots(mv_chan); /* free completed slots from the chain starting with @@ -544,7 +547,7 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx) dma_cookie_t cookie; int new_hw_chain = 1; - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s sw_desc %p: async_tx %p\n", __func__, sw_desc, &sw_desc->async_tx); @@ -567,7 +570,7 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx) if (!mv_can_chain(grp_start)) goto submit_done; - dev_dbg(mv_chan->device->common.dev, "Append to last desc %x\n", + dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %x\n", old_chain_tail->async_tx.phys); /* fix up the hardware chain */ @@ -636,7 +639,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) struct mv_xor_desc_slot, slot_node); - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "allocated %d descriptor slots last_used: %p\n", mv_chan->slots_allocated, mv_chan->last_used); @@ -651,7 +654,7 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, struct mv_xor_desc_slot *sw_desc, *grp_start; int slot_cnt; - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s dest: %x src %x len: %u flags: %ld\n", __func__, dest, src, len, flags); if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) @@ -675,7 +678,7 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, } spin_unlock_bh(&mv_chan->lock); - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s sw_desc %p async_tx %p\n", __func__, sw_desc, sw_desc ? &sw_desc->async_tx : 0); @@ -690,7 +693,7 @@ mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, struct mv_xor_desc_slot *sw_desc, *grp_start; int slot_cnt; - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s dest: %x len: %u flags: %ld\n", __func__, dest, len, flags); if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) @@ -713,7 +716,7 @@ mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, sw_desc->unmap_len = len; } spin_unlock_bh(&mv_chan->lock); - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s sw_desc %p async_tx %p \n", __func__, sw_desc, &sw_desc->async_tx); return sw_desc ? &sw_desc->async_tx : NULL; @@ -732,7 +735,7 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s src_cnt: %d len: dest %x %u flags: %ld\n", __func__, src_cnt, len, dest, flags); @@ -753,7 +756,7 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, mv_desc_set_src_addr(grp_start, src_cnt, src[src_cnt]); } spin_unlock_bh(&mv_chan->lock); - dev_dbg(mv_chan->device->common.dev, + dev_dbg(mv_chan_to_devp(mv_chan), "%s sw_desc %p async_tx %p \n", __func__, sw_desc, &sw_desc->async_tx); return sw_desc ? &sw_desc->async_tx : NULL; @@ -786,12 +789,12 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) } mv_chan->last_used = NULL; - dev_dbg(mv_chan->device->common.dev, "%s slots_allocated %d\n", + dev_dbg(mv_chan_to_devp(mv_chan), "%s slots_allocated %d\n", __func__, mv_chan->slots_allocated); spin_unlock_bh(&mv_chan->lock); if (in_use_descs) - dev_err(mv_chan->device->common.dev, + dev_err(mv_chan_to_devp(mv_chan), "freeing %d in use descriptors!\n", in_use_descs); } @@ -823,27 +826,27 @@ static void mv_dump_xor_regs(struct mv_xor_chan *chan) u32 val; val = __raw_readl(XOR_CONFIG(chan)); - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "config 0x%08x.\n", val); val = __raw_readl(XOR_ACTIVATION(chan)); - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "activation 0x%08x.\n", val); val = __raw_readl(XOR_INTR_CAUSE(chan)); - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "intr cause 0x%08x.\n", val); val = __raw_readl(XOR_INTR_MASK(chan)); - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "intr mask 0x%08x.\n", val); val = __raw_readl(XOR_ERROR_CAUSE(chan)); - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "error cause 0x%08x.\n", val); val = __raw_readl(XOR_ERROR_ADDR(chan)); - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "error addr 0x%08x.\n", val); } @@ -851,12 +854,12 @@ static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan, u32 intr_cause) { if (intr_cause & (1 << 4)) { - dev_dbg(chan->device->common.dev, + dev_dbg(mv_chan_to_devp(chan), "ignore this error\n"); return; } - dev_err(chan->device->common.dev, + dev_err(mv_chan_to_devp(chan), "error on chan %d. intr cause 0x%08x.\n", chan->idx, intr_cause); @@ -869,7 +872,7 @@ static irqreturn_t mv_xor_interrupt_handler(int irq, void *data) struct mv_xor_chan *chan = data; u32 intr_cause = mv_chan_get_intr_cause(chan); - dev_dbg(chan->device->common.dev, "intr cause %x\n", intr_cause); + dev_dbg(mv_chan_to_devp(chan), "intr cause %x\n", intr_cause); if (mv_is_err_intr(intr_cause)) mv_xor_err_interrupt_handler(chan, intr_cause); -- cgit v1.2.3 From ecde6cd4924205e815adf8f1b0df98965e804e7f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 14:37:36 +0100 Subject: dma: mv_xor: get rid of the pdev pointer in mv_xor_device It was only used in places where we could get the 'struct device *' pointer through a different way. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 9 ++++----- drivers/dma/mv_xor.h | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 38dac0d9265c..6e705ea001da 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -308,8 +308,7 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc, */ if (desc->group_head && desc->unmap_len) { struct mv_xor_desc_slot *unmap = desc->group_head; - struct device *dev = - &mv_chan->device->pdev->dev; + struct device *dev = mv_chan_to_devp(mv_chan); u32 len = unmap->unmap_len; enum dma_ctrl_flags flags = desc->async_tx.flags; u32 src_cnt; @@ -1077,10 +1076,11 @@ static int mv_xor_channel_remove(struct mv_xor_device *device) { struct dma_chan *chan, *_chan; struct mv_xor_chan *mv_chan; + struct device *dev = device->common.dev; dma_async_device_unregister(&device->common); - dma_free_coherent(&device->pdev->dev, device->pool_size, + dma_free_coherent(dev, device->pool_size, device->dma_desc_pool_virt, device->dma_desc_pool); list_for_each_entry_safe(chan, _chan, &device->common.channels, @@ -1123,7 +1123,6 @@ mv_xor_channel_add(struct mv_xor_private *msp, /* discover transaction capabilites from the platform data */ dma_dev->cap_mask = cap_mask; - adev->pdev = pdev; adev->shared = msp; INIT_LIST_HEAD(&dma_dev->channels); @@ -1208,7 +1207,7 @@ mv_xor_channel_add(struct mv_xor_private *msp, return adev; err_free_dma: - dma_free_coherent(&adev->pdev->dev, pool_size, + dma_free_coherent(&pdev->dev, pool_size, adev->dma_desc_pool_virt, adev->dma_desc_pool); return ERR_PTR(ret); } diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 52ca6172bc6b..05add24ad772 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -70,7 +70,6 @@ struct mv_xor_private { * @common: embedded struct dma_device */ struct mv_xor_device { - struct platform_device *pdev; dma_addr_t dma_desc_pool; void *dma_desc_pool_virt; size_t pool_size; -- cgit v1.2.3 From 98817b99599fc18b5e4bf5bc63ad899b83404a68 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 14:57:44 +0100 Subject: dma: mv_xor: in mv_xor_chan, rename 'common' to 'dmachan' The mv_xor_chan structure embeds a 'struct dma_chan', which is named 'common', a not very meaningful name. Rename it to 'dmachan', which will help avoid confusions later as we merge the mv_xor_device and mv_xor_chan structures together. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 12 ++++++------ drivers/dma/mv_xor.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 6e705ea001da..491f506b798b 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -34,7 +34,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan); #define to_mv_xor_chan(chan) \ - container_of(chan, struct mv_xor_chan, common) + container_of(chan, struct mv_xor_chan, dmachan) #define to_mv_xor_slot(tx) \ container_of(tx, struct mv_xor_desc_slot, async_tx) @@ -284,7 +284,7 @@ static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan, mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys); } mv_chan->pending += sw_desc->slot_cnt; - mv_xor_issue_pending(&mv_chan->common); + mv_xor_issue_pending(&mv_chan->dmachan); } static dma_cookie_t @@ -437,7 +437,7 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) } if (cookie > 0) - mv_chan->common.completed_cookie = cookie; + mv_chan->dmachan.completed_cookie = cookie; } static void @@ -1177,10 +1177,10 @@ mv_xor_channel_add(struct mv_xor_private *msp, INIT_LIST_HEAD(&mv_chan->chain); INIT_LIST_HEAD(&mv_chan->completed_slots); INIT_LIST_HEAD(&mv_chan->all_slots); - mv_chan->common.device = dma_dev; - dma_cookie_init(&mv_chan->common); + mv_chan->dmachan.device = dma_dev; + dma_cookie_init(&mv_chan->dmachan); - list_add_tail(&mv_chan->common.device_node, &dma_dev->channels); + list_add_tail(&mv_chan->dmachan.device_node, &dma_dev->channels); if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) { ret = mv_xor_memcpy_self_test(adev); diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 05add24ad772..ad18f6447cec 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -101,7 +101,7 @@ struct mv_xor_chan { struct list_head chain; struct list_head completed_slots; struct mv_xor_device *device; - struct dma_chan common; + struct dma_chan dmachan; struct mv_xor_desc_slot *last_used; struct list_head all_slots; int slots_allocated; -- cgit v1.2.3 From 8c75979d7ac8cdec927605336aeebea0c7f88f74 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:00:25 +0100 Subject: dma: mv_xor: in mv_xor_device, rename 'common' to 'dmadev' The mv_xor_device structure embeds a 'struct dma_device', which is named 'common', a not very meaningful name. Rename it to 'dmadev', which will help avoid confusions later as we merge the mv_xor_device and mv_xor_chan structures together. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 14 +++++++------- drivers/dma/mv_xor.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 491f506b798b..a64e30e27a19 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -40,7 +40,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan); container_of(tx, struct mv_xor_desc_slot, async_tx) #define mv_chan_to_devp(chan) \ - ((chan)->device->common.dev) + ((chan)->device->dmadev.dev) static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags) { @@ -923,7 +923,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) ((u8 *) src)[i] = (u8)i; /* Start copy, using first DMA channel */ - dma_chan = container_of(device->common.channels.next, + dma_chan = container_of(device->dmadev.channels.next, struct dma_chan, device_node); if (mv_xor_alloc_chan_resources(dma_chan) < 1) { @@ -1016,7 +1016,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) memset(page_address(dest), 0, PAGE_SIZE); - dma_chan = container_of(device->common.channels.next, + dma_chan = container_of(device->dmadev.channels.next, struct dma_chan, device_node); if (mv_xor_alloc_chan_resources(dma_chan) < 1) { @@ -1076,14 +1076,14 @@ static int mv_xor_channel_remove(struct mv_xor_device *device) { struct dma_chan *chan, *_chan; struct mv_xor_chan *mv_chan; - struct device *dev = device->common.dev; + struct device *dev = device->dmadev.dev; - dma_async_device_unregister(&device->common); + dma_async_device_unregister(&device->dmadev); dma_free_coherent(dev, device->pool_size, device->dma_desc_pool_virt, device->dma_desc_pool); - list_for_each_entry_safe(chan, _chan, &device->common.channels, + list_for_each_entry_safe(chan, _chan, &device->dmadev.channels, device_node) { mv_chan = to_mv_xor_chan(chan); list_del(&chan->device_node); @@ -1107,7 +1107,7 @@ mv_xor_channel_add(struct mv_xor_private *msp, if (!adev) return ERR_PTR(-ENOMEM); - dma_dev = &adev->common; + dma_dev = &adev->dmadev; /* allocate coherent memory for hardware descriptors * note: writecombine gives slightly better performance, but diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index ad18f6447cec..84255e699830 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -73,7 +73,7 @@ struct mv_xor_device { dma_addr_t dma_desc_pool; void *dma_desc_pool_virt; size_t pool_size; - struct dma_device common; + struct dma_device dmadev; struct mv_xor_private *shared; }; -- cgit v1.2.3 From 275cc0c8bd3c0a6b826d46a4d1a8135897387ca9 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:09:42 +0100 Subject: dma: mv_xor: use mv_xor_chan pointers as arguments to self-test functions In preparation for the removal of the mv_xor_device structure, we directly pass mv_xor_chan pointers to the self-test functions included in the driver. These functions were anyway selecting the first (and only channel) available in each DMA device, so the behaviour is unchanged. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a64e30e27a19..75a80510dba9 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -898,7 +898,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan) */ #define MV_XOR_TEST_SIZE 2000 -static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) +static int __devinit mv_xor_memcpy_self_test(struct mv_xor_chan *mv_chan) { int i; void *src, *dest; @@ -922,10 +922,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device) for (i = 0; i < MV_XOR_TEST_SIZE; i++) ((u8 *) src)[i] = (u8)i; - /* Start copy, using first DMA channel */ - dma_chan = container_of(device->dmadev.channels.next, - struct dma_chan, - device_node); + dma_chan = &mv_chan->dmachan; if (mv_xor_alloc_chan_resources(dma_chan) < 1) { err = -ENODEV; goto out; @@ -971,7 +968,7 @@ out: #define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */ static int __devinit -mv_xor_xor_self_test(struct mv_xor_device *device) +mv_xor_xor_self_test(struct mv_xor_chan *mv_chan) { int i, src_idx; struct page *dest; @@ -1016,9 +1013,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device) memset(page_address(dest), 0, PAGE_SIZE); - dma_chan = container_of(device->dmadev.channels.next, - struct dma_chan, - device_node); + dma_chan = &mv_chan->dmachan; if (mv_xor_alloc_chan_resources(dma_chan) < 1) { err = -ENODEV; goto out; @@ -1183,14 +1178,14 @@ mv_xor_channel_add(struct mv_xor_private *msp, list_add_tail(&mv_chan->dmachan.device_node, &dma_dev->channels); if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) { - ret = mv_xor_memcpy_self_test(adev); + ret = mv_xor_memcpy_self_test(mv_chan); dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret); if (ret) goto err_free_dma; } if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { - ret = mv_xor_xor_self_test(adev); + ret = mv_xor_xor_self_test(mv_chan); dev_dbg(&pdev->dev, "xor self test returned %d\n", ret); if (ret) goto err_free_dma; -- cgit v1.2.3 From 1ef48a262b0d50add7d293a37b8c8bad4bec30a1 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:17:05 +0100 Subject: dma: mv_xor: merge mv_xor_device and mv_xor_chan Even though the DMA engine infrastructure has support for multiple channels per device, the mv_xor driver registers one DMA engine device for each channel, because the mv_xor channels inside the same XOR engine have different capabilities, and the DMA engine infrastructure only allows to express capabilities at the DMA engine device level. The mv_xor driver has therefore been registering one DMA engine device and one DMA engine channel for each XOR channel since its introduction in the kernel. However, it kept two separate internal structures, mv_xor_device and mv_xor_channel, which didn't make a lot of sense since there was a 1:1 mapping between those structures. This patch gets rid of this duplication, and merges everything into the mv_xor_chan structure. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 64 +++++++++++++++++++++++----------------------------- drivers/dma/mv_xor.h | 25 +++++--------------- 2 files changed, 34 insertions(+), 55 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 75a80510dba9..3b81ee1b555d 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -40,7 +40,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan); container_of(tx, struct mv_xor_desc_slot, async_tx) #define mv_chan_to_devp(chan) \ - ((chan)->device->dmadev.dev) + ((chan)->dmadev.dev) static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags) { @@ -603,7 +603,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) int idx; struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); struct mv_xor_desc_slot *slot = NULL; - int num_descs_in_pool = mv_chan->device->pool_size/MV_XOR_SLOT_SIZE; + int num_descs_in_pool = mv_chan->pool_size/MV_XOR_SLOT_SIZE; /* Allocate descriptor slots */ idx = mv_chan->slots_allocated; @@ -614,7 +614,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) " %d descriptor slots", idx); break; } - hw_desc = (char *) mv_chan->device->dma_desc_pool_virt; + hw_desc = (char *) mv_chan->dma_desc_pool_virt; slot->hw_desc = (void *) &hw_desc[idx * MV_XOR_SLOT_SIZE]; dma_async_tx_descriptor_init(&slot->async_tx, chan); @@ -622,7 +622,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) INIT_LIST_HEAD(&slot->chain_node); INIT_LIST_HEAD(&slot->slot_node); INIT_LIST_HEAD(&slot->tx_list); - hw_desc = (char *) mv_chan->device->dma_desc_pool; + hw_desc = (char *) mv_chan->dma_desc_pool; slot->async_tx.phys = (dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE]; slot->idx = idx++; @@ -1067,58 +1067,58 @@ out: return err; } -static int mv_xor_channel_remove(struct mv_xor_device *device) +static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) { struct dma_chan *chan, *_chan; - struct mv_xor_chan *mv_chan; - struct device *dev = device->dmadev.dev; + struct device *dev = mv_chan->dmadev.dev; - dma_async_device_unregister(&device->dmadev); + dma_async_device_unregister(&mv_chan->dmadev); - dma_free_coherent(dev, device->pool_size, - device->dma_desc_pool_virt, device->dma_desc_pool); + dma_free_coherent(dev, mv_chan->pool_size, + mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); - list_for_each_entry_safe(chan, _chan, &device->dmadev.channels, + list_for_each_entry_safe(chan, _chan, &mv_chan->dmadev.channels, device_node) { - mv_chan = to_mv_xor_chan(chan); list_del(&chan->device_node); } return 0; } -static struct mv_xor_device * +static struct mv_xor_chan * mv_xor_channel_add(struct mv_xor_private *msp, struct platform_device *pdev, int hw_id, dma_cap_mask_t cap_mask, size_t pool_size, int irq) { int ret = 0; - struct mv_xor_device *adev; struct mv_xor_chan *mv_chan; struct dma_device *dma_dev; - adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL); - if (!adev) - return ERR_PTR(-ENOMEM); + mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL); + if (!mv_chan) { + ret = -ENOMEM; + goto err_free_dma; + } + + mv_chan->idx = hw_id; - dma_dev = &adev->dmadev; + dma_dev = &mv_chan->dmadev; /* allocate coherent memory for hardware descriptors * note: writecombine gives slightly better performance, but * requires that we explicitly flush the writes */ - 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) + mv_chan->pool_size = pool_size; + mv_chan->dma_desc_pool_virt = + dma_alloc_writecombine(&pdev->dev, mv_chan->pool_size, + &mv_chan->dma_desc_pool, GFP_KERNEL); + if (!mv_chan->dma_desc_pool_virt) return ERR_PTR(-ENOMEM); /* discover transaction capabilites from the platform data */ dma_dev->cap_mask = cap_mask; - adev->shared = msp; + mv_chan->shared = msp; INIT_LIST_HEAD(&dma_dev->channels); @@ -1139,15 +1139,7 @@ mv_xor_channel_add(struct mv_xor_private *msp, dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor; } - mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL); - if (!mv_chan) { - ret = -ENOMEM; - goto err_free_dma; - } - mv_chan->device = adev; - mv_chan->idx = hw_id; - mv_chan->mmr_base = adev->shared->xor_base; - + mv_chan->mmr_base = msp->xor_base; if (!mv_chan->mmr_base) { ret = -ENOMEM; goto err_free_dma; @@ -1199,11 +1191,11 @@ mv_xor_channel_add(struct mv_xor_private *msp, dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : ""); dma_async_device_register(dma_dev); - return adev; + return mv_chan; err_free_dma: dma_free_coherent(&pdev->dev, pool_size, - adev->dma_desc_pool_virt, adev->dma_desc_pool); + mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); return ERR_PTR(ret); } diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 84255e699830..16de1f62c950 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -57,24 +57,7 @@ struct mv_xor_private { void __iomem *xor_base; void __iomem *xor_high_base; struct clk *clk; - struct mv_xor_device *channels[MV_XOR_MAX_CHANNELS]; -}; - - -/** - * struct mv_xor_device - internal representation of a XOR device - * @pdev: Platform device - * @id: HW XOR Device selector - * @dma_desc_pool: base of DMA descriptor region (DMA address) - * @dma_desc_pool_virt: base of DMA descriptor region (CPU address) - * @common: embedded struct dma_device - */ -struct mv_xor_device { - dma_addr_t dma_desc_pool; - void *dma_desc_pool_virt; - size_t pool_size; - struct dma_device dmadev; - struct mv_xor_private *shared; + struct mv_xor_chan *channels[MV_XOR_MAX_CHANNELS]; }; /** @@ -100,7 +83,11 @@ struct mv_xor_chan { enum dma_transaction_type current_type; struct list_head chain; struct list_head completed_slots; - struct mv_xor_device *device; + dma_addr_t dma_desc_pool; + void *dma_desc_pool_virt; + size_t pool_size; + struct dma_device dmadev; + struct mv_xor_private *shared; struct dma_chan dmachan; struct mv_xor_desc_slot *last_used; struct list_head all_slots; -- cgit v1.2.3 From 297eedbae1677c8276df082fb17fb1344058fed0 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:29:53 +0100 Subject: dma: mv_xor: rename mv_xor_private to mv_xor_device Now that mv_xor_device is no longer used to designate the per-channel DMA devices, use it know to designate the XOR engine themselves (currently composed of two XOR channels). So, now we have the nice organization where: - mv_xor_device represents each XOR engine in the system - mv_xor_chan represents each XOR channel of a given XOR engine Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 66 ++++++++++++++++++++++++++-------------------------- drivers/dma/mv_xor.h | 4 ++-- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 3b81ee1b555d..aec771917d54 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1086,7 +1086,7 @@ static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) } static struct mv_xor_chan * -mv_xor_channel_add(struct mv_xor_private *msp, +mv_xor_channel_add(struct mv_xor_device *xordev, struct platform_device *pdev, int hw_id, dma_cap_mask_t cap_mask, size_t pool_size, int irq) @@ -1118,7 +1118,7 @@ mv_xor_channel_add(struct mv_xor_private *msp, /* discover transaction capabilites from the platform data */ dma_dev->cap_mask = cap_mask; - mv_chan->shared = msp; + mv_chan->shared = xordev; INIT_LIST_HEAD(&dma_dev->channels); @@ -1139,7 +1139,7 @@ mv_xor_channel_add(struct mv_xor_private *msp, dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor; } - mv_chan->mmr_base = msp->xor_base; + mv_chan->mmr_base = xordev->xor_base; if (!mv_chan->mmr_base) { ret = -ENOMEM; goto err_free_dma; @@ -1200,10 +1200,10 @@ mv_xor_channel_add(struct mv_xor_private *msp, } static void -mv_xor_conf_mbus_windows(struct mv_xor_private *msp, +mv_xor_conf_mbus_windows(struct mv_xor_device *xordev, const struct mbus_dram_target_info *dram) { - void __iomem *base = msp->xor_base; + void __iomem *base = xordev->xor_base; u32 win_enable = 0; int i; @@ -1233,50 +1233,50 @@ mv_xor_conf_mbus_windows(struct mv_xor_private *msp, static int mv_xor_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; - struct mv_xor_private *msp; + struct mv_xor_device *xordev; struct mv_xor_platform_data *pdata = pdev->dev.platform_data; struct resource *res; int i, ret; dev_notice(&pdev->dev, "Marvell XOR driver\n"); - msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL); - if (!msp) + xordev = devm_kzalloc(&pdev->dev, sizeof(*xordev), GFP_KERNEL); + if (!xordev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - msp->xor_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!msp->xor_base) + xordev->xor_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!xordev->xor_base) return -EBUSY; res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) return -ENODEV; - msp->xor_high_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!msp->xor_high_base) + xordev->xor_high_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!xordev->xor_high_base) return -EBUSY; - platform_set_drvdata(pdev, msp); + platform_set_drvdata(pdev, xordev); /* * (Re-)program MBUS remapping windows if we are asked to. */ dram = mv_mbus_dram_info(); if (dram) - mv_xor_conf_mbus_windows(msp, dram); + mv_xor_conf_mbus_windows(xordev, dram); /* Not all platforms can gate the clock, so it is not * an error if the clock does not exists. */ - msp->clk = clk_get(&pdev->dev, NULL); - if (!IS_ERR(msp->clk)) - clk_prepare_enable(msp->clk); + xordev->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(xordev->clk)) + clk_prepare_enable(xordev->clk); if (pdata && pdata->channels) { for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { @@ -1295,12 +1295,12 @@ static int mv_xor_probe(struct platform_device *pdev) goto err_channel_add; } - msp->channels[i] = - mv_xor_channel_add(msp, pdev, cd->hw_id, + xordev->channels[i] = + mv_xor_channel_add(xordev, pdev, cd->hw_id, cd->cap_mask, cd->pool_size, irq); - if (IS_ERR(msp->channels[i])) { - ret = PTR_ERR(msp->channels[i]); + if (IS_ERR(xordev->channels[i])) { + ret = PTR_ERR(xordev->channels[i]); goto err_channel_add; } } @@ -1310,27 +1310,27 @@ static int mv_xor_probe(struct platform_device *pdev) err_channel_add: for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) - if (msp->channels[i]) - mv_xor_channel_remove(msp->channels[i]); + if (xordev->channels[i]) + mv_xor_channel_remove(xordev->channels[i]); - clk_disable_unprepare(msp->clk); - clk_put(msp->clk); + clk_disable_unprepare(xordev->clk); + clk_put(xordev->clk); return ret; } static int mv_xor_remove(struct platform_device *pdev) { - struct mv_xor_private *msp = platform_get_drvdata(pdev); + struct mv_xor_device *xordev = platform_get_drvdata(pdev); int i; for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { - if (msp->channels[i]) - mv_xor_channel_remove(msp->channels[i]); + if (xordev->channels[i]) + mv_xor_channel_remove(xordev->channels[i]); } - if (!IS_ERR(msp->clk)) { - clk_disable_unprepare(msp->clk); - clk_put(msp->clk); + if (!IS_ERR(xordev->clk)) { + clk_disable_unprepare(xordev->clk); + clk_put(xordev->clk); } return 0; diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 16de1f62c950..cedeaa04f238 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -53,7 +53,7 @@ #define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2)) #define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) -struct mv_xor_private { +struct mv_xor_device { void __iomem *xor_base; void __iomem *xor_high_base; struct clk *clk; @@ -87,7 +87,7 @@ struct mv_xor_chan { void *dma_desc_pool_virt; size_t pool_size; struct dma_device dmadev; - struct mv_xor_private *shared; + struct mv_xor_device *shared; struct dma_chan dmachan; struct mv_xor_desc_slot *last_used; struct list_head all_slots; -- cgit v1.2.3 From c819ce177eb4dc796996618c1d53856cad1201ec Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:32:24 +0100 Subject: dma: mv_xor: remove useless backpointer from mv_xor_chan to mv_xor_device The backpointer from mv_xor_chan to mv_xor_device is now useless, get rid of it. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 1 - drivers/dma/mv_xor.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index aec771917d54..a6a5a28574c4 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1118,7 +1118,6 @@ mv_xor_channel_add(struct mv_xor_device *xordev, /* discover transaction capabilites from the platform data */ dma_dev->cap_mask = cap_mask; - mv_chan->shared = xordev; INIT_LIST_HEAD(&dma_dev->channels); diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index cedeaa04f238..dab9f30e564a 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -87,7 +87,6 @@ struct mv_xor_chan { void *dma_desc_pool_virt; size_t pool_size; struct dma_device dmadev; - struct mv_xor_device *shared; struct dma_chan dmachan; struct mv_xor_desc_slot *last_used; struct list_head all_slots; -- cgit v1.2.3 From 9aedbdbab39c8aa58c0b2a0791fb10df6eebc123 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:36:37 +0100 Subject: dma: mv_xor: remove hw_id field from platform_data There is no need for the platform_data to give this ID, it is simply the channel number, so we can compute it inside the driver when registering the channels. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index a6a5a28574c4..fc983bf38438 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1088,7 +1088,7 @@ static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) static struct mv_xor_chan * mv_xor_channel_add(struct mv_xor_device *xordev, struct platform_device *pdev, - int hw_id, dma_cap_mask_t cap_mask, + int idx, dma_cap_mask_t cap_mask, size_t pool_size, int irq) { int ret = 0; @@ -1101,7 +1101,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, goto err_free_dma; } - mv_chan->idx = hw_id; + mv_chan->idx = idx; dma_dev = &mv_chan->dmadev; @@ -1295,7 +1295,7 @@ static int mv_xor_probe(struct platform_device *pdev) } xordev->channels[i] = - mv_xor_channel_add(xordev, pdev, cd->hw_id, + mv_xor_channel_add(xordev, pdev, i, cd->cap_mask, cd->pool_size, irq); if (IS_ERR(xordev->channels[i])) { -- cgit v1.2.3 From b503fa01990f6875640339d8f4ba98dbc068f821 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 15:55:30 +0100 Subject: dma: mv_xor: remove the pool_size from platform_data The pool_size is always PAGE_SIZE, and since it is a software configuration paramter (and not a hardware description parameter), we cannot make it part of the Device Tree binding, so we'd better remove it from the platform_data as well. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 15 ++++++--------- drivers/dma/mv_xor.h | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index fc983bf38438..ec741b4607e2 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -603,7 +603,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) int idx; struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); struct mv_xor_desc_slot *slot = NULL; - int num_descs_in_pool = mv_chan->pool_size/MV_XOR_SLOT_SIZE; + int num_descs_in_pool = MV_XOR_POOL_SIZE/MV_XOR_SLOT_SIZE; /* Allocate descriptor slots */ idx = mv_chan->slots_allocated; @@ -1074,7 +1074,7 @@ static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) dma_async_device_unregister(&mv_chan->dmadev); - dma_free_coherent(dev, mv_chan->pool_size, + dma_free_coherent(dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); list_for_each_entry_safe(chan, _chan, &mv_chan->dmadev.channels, @@ -1088,8 +1088,7 @@ static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) static struct mv_xor_chan * mv_xor_channel_add(struct mv_xor_device *xordev, struct platform_device *pdev, - int idx, dma_cap_mask_t cap_mask, - size_t pool_size, int irq) + int idx, dma_cap_mask_t cap_mask, int irq) { int ret = 0; struct mv_xor_chan *mv_chan; @@ -1109,9 +1108,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev, * note: writecombine gives slightly better performance, but * requires that we explicitly flush the writes */ - mv_chan->pool_size = pool_size; mv_chan->dma_desc_pool_virt = - dma_alloc_writecombine(&pdev->dev, mv_chan->pool_size, + dma_alloc_writecombine(&pdev->dev, MV_XOR_POOL_SIZE, &mv_chan->dma_desc_pool, GFP_KERNEL); if (!mv_chan->dma_desc_pool_virt) return ERR_PTR(-ENOMEM); @@ -1193,7 +1191,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, return mv_chan; err_free_dma: - dma_free_coherent(&pdev->dev, pool_size, + dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); return ERR_PTR(ret); } @@ -1296,8 +1294,7 @@ static int mv_xor_probe(struct platform_device *pdev) xordev->channels[i] = mv_xor_channel_add(xordev, pdev, i, - cd->cap_mask, - cd->pool_size, irq); + cd->cap_mask, irq); if (IS_ERR(xordev->channels[i])) { ret = PTR_ERR(xordev->channels[i]); goto err_channel_add; diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index dab9f30e564a..698b4487b348 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -24,6 +24,7 @@ #include #define USE_TIMER +#define MV_XOR_POOL_SIZE PAGE_SIZE #define MV_XOR_SLOT_SIZE 64 #define MV_XOR_THRESHOLD 1 #define MV_XOR_MAX_CHANNELS 2 -- cgit v1.2.3 From 88eb92cb4d0a1520c2f9a653fba0f838871af3ab Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 16:11:18 +0100 Subject: dma: mv_xor: add missing free_irq() call Even though the driver cannot be unloaded at the moment, it is still good to properly free the IRQ handlers in the channel removal function. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 5 ++++- drivers/dma/mv_xor.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index ec741b4607e2..d48245c0b0b0 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1082,6 +1082,8 @@ static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) list_del(&chan->device_node); } + free_irq(mv_chan->irq, mv_chan); + return 0; } @@ -1101,6 +1103,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, } mv_chan->idx = idx; + mv_chan->irq = irq; dma_dev = &mv_chan->dmadev; @@ -1147,7 +1150,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, /* clear errors before enabling interrupts */ mv_xor_device_clear_err_status(mv_chan); - ret = devm_request_irq(&pdev->dev, irq, + ret = devm_request_irq(&pdev->dev, mv_chan->irq, mv_xor_interrupt_handler, 0, dev_name(&pdev->dev), mv_chan); if (ret) diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 698b4487b348..17043287b71a 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -81,6 +81,7 @@ struct mv_xor_chan { spinlock_t lock; /* protects the descriptor slot pool */ void __iomem *mmr_base; unsigned int idx; + int irq; enum dma_transaction_type current_type; struct list_head chain; struct list_head completed_slots; -- cgit v1.2.3 From f7d12ef53ddfd8175933af42bfc477376d19e19e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 15 Nov 2012 16:47:58 +0100 Subject: dma: mv_xor: add Device Tree binding This patch finally adds a Device Tree binding to the mv_xor driver. Thanks to the previous cleanup patches, the Device Tree binding is relatively simply: one DT node per XOR engine, with sub-nodes for each XOR channel of the XOR engine. The binding obviously comes with the necessary documentation. Signed-off-by: Thomas Petazzoni Cc: devicetree-discuss@lists.ozlabs.org --- drivers/dma/mv_xor.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index d48245c0b0b0..b1c4edd56ebc 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include "dmaengine.h" @@ -1278,7 +1281,42 @@ static int mv_xor_probe(struct platform_device *pdev) if (!IS_ERR(xordev->clk)) clk_prepare_enable(xordev->clk); - if (pdata && pdata->channels) { + if (pdev->dev.of_node) { + struct device_node *np; + int i = 0; + + for_each_child_of_node(pdev->dev.of_node, np) { + dma_cap_mask_t cap_mask; + int irq; + + dma_cap_zero(cap_mask); + if (of_property_read_bool(np, "dmacap,memcpy")) + dma_cap_set(DMA_MEMCPY, cap_mask); + if (of_property_read_bool(np, "dmacap,xor")) + dma_cap_set(DMA_XOR, cap_mask); + if (of_property_read_bool(np, "dmacap,memset")) + dma_cap_set(DMA_MEMSET, cap_mask); + if (of_property_read_bool(np, "dmacap,interrupt")) + dma_cap_set(DMA_INTERRUPT, cap_mask); + + irq = irq_of_parse_and_map(np, 0); + if (irq < 0) { + ret = irq; + goto err_channel_add; + } + + xordev->channels[i] = + mv_xor_channel_add(xordev, pdev, i, + cap_mask, irq); + if (IS_ERR(xordev->channels[i])) { + ret = PTR_ERR(xordev->channels[i]); + irq_dispose_mapping(irq); + goto err_channel_add; + } + + i++; + } + } else if (pdata && pdata->channels) { for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) { struct mv_xor_channel_data *cd; int irq; @@ -1309,8 +1347,11 @@ static int mv_xor_probe(struct platform_device *pdev) err_channel_add: for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) - if (xordev->channels[i]) + if (xordev->channels[i]) { + if (pdev->dev.of_node) + irq_dispose_mapping(xordev->channels[i]->irq); mv_xor_channel_remove(xordev->channels[i]); + } clk_disable_unprepare(xordev->clk); clk_put(xordev->clk); @@ -1335,12 +1376,21 @@ static int mv_xor_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static struct of_device_id mv_xor_dt_ids[] __devinitdata = { + { .compatible = "marvell,orion-xor", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mv_xor_dt_ids); +#endif + static struct platform_driver mv_xor_driver = { .probe = mv_xor_probe, .remove = mv_xor_remove, .driver = { - .owner = THIS_MODULE, - .name = MV_XOR_NAME, + .owner = THIS_MODULE, + .name = MV_XOR_NAME, + .of_match_table = of_match_ptr(mv_xor_dt_ids), }, }; -- cgit v1.2.3 From cd09fea446f485f1514ad444cb06a35e1dd63326 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 18 Nov 2012 18:25:12 +0100 Subject: dma: mv_xor: add missing __devinit and __devexit qualifiers on probe and remove The ->probe() and ->remove() functions were missing the usual __devinit and __devexit qualifiers. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index b1c4edd56ebc..97c8611f5ffb 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1233,7 +1233,7 @@ mv_xor_conf_mbus_windows(struct mv_xor_device *xordev, writel(win_enable, base + WINDOW_BAR_ENABLE(1)); } -static int mv_xor_probe(struct platform_device *pdev) +static int __devinit mv_xor_probe(struct platform_device *pdev) { const struct mbus_dram_target_info *dram; struct mv_xor_device *xordev; @@ -1358,7 +1358,7 @@ err_channel_add: return ret; } -static int mv_xor_remove(struct platform_device *pdev) +static int __devexit mv_xor_remove(struct platform_device *pdev) { struct mv_xor_device *xordev = platform_get_drvdata(pdev); int i; @@ -1386,7 +1386,7 @@ MODULE_DEVICE_TABLE(of, mv_xor_dt_ids); static struct platform_driver mv_xor_driver = { .probe = mv_xor_probe, - .remove = mv_xor_remove, + .remove = __devexit_p(mv_xor_remove), .driver = { .owner = THIS_MODULE, .name = MV_XOR_NAME, -- cgit v1.2.3 From 34c93c8657935d30649e777c4aa05f74f16aa418 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 18 Nov 2012 11:44:56 +0100 Subject: dma: mv_xor: Add a device_control function The dmatest module for DMA engines calls device_control(dtc->chan, DMA_TERMINATE_ALL, 0); after completing the tests. The documentation in include/linux/dmaengine.h suggests this function is optional and dma_async_device_register() also does not BUG_ON() when not passed a function. However, dmatest is not the only code in the kernel unconditionally calling device_control. So add an implementation indicating all operations are not implemented. Signed-off-by: Andrew Lunn Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 97c8611f5ffb..f450fe8cbd61 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1070,6 +1070,14 @@ out: return err; } +/* This driver does not implement any of the optional DMA operations. */ +static int +mv_xor_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + unsigned long arg) +{ + return -ENOSYS; +} + static int mv_xor_channel_remove(struct mv_xor_chan *mv_chan) { struct dma_chan *chan, *_chan; @@ -1130,6 +1138,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, dma_dev->device_free_chan_resources = mv_xor_free_chan_resources; dma_dev->device_tx_status = mv_xor_status; dma_dev->device_issue_pending = mv_xor_issue_pending; + dma_dev->device_control = mv_xor_control; dma_dev->dev = &pdev->dev; /* set prep routines based on capability */ -- cgit v1.2.3 From c4b4b732b2e99e6e302d90d57f2a4f5c9516d9a3 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 22 Nov 2012 18:16:37 +0100 Subject: dma: mv_xor: clear the window override control registers The XOR channels on Marvell SoCs have a Window Override Control register that allow to do some fancy things with addresses. Those features are not used by the driver, but some U-Boot versions anyway modify those registers. For some reason, the U-Boot on OpenBlocks AX3-4 was setting an invalid value in those registers when the addition 2 GB DRAM chip was plugged into the board, causing the XOR driver to fail in using the XOR engines. By setting those registers to 0 during the driver initialization, we ensure that the registers are configured according with the driver operation model. Thanks to Lior Amsalem for his help in debugging this problem. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 2 ++ drivers/dma/mv_xor.h | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index f450fe8cbd61..2c69b89eac4f 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1240,6 +1240,8 @@ mv_xor_conf_mbus_windows(struct mv_xor_device *xordev, writel(win_enable, base + WINDOW_BAR_ENABLE(0)); writel(win_enable, base + WINDOW_BAR_ENABLE(1)); + writel(0, base + WINDOW_OVERRIDE_CTRL(0)); + writel(0, base + WINDOW_OVERRIDE_CTRL(1)); } static int __devinit mv_xor_probe(struct platform_device *pdev) diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 17043287b71a..c632a4761fcf 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -53,6 +53,7 @@ #define WINDOW_SIZE(w) (0x270 + ((w) << 2)) #define WINDOW_REMAP_HIGH(w) (0x290 + ((w) << 2)) #define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) +#define WINDOW_OVERRIDE_CTRL(chan) (0x2A0 + ((chan) << 2)) struct mv_xor_device { void __iomem *xor_base; -- cgit v1.2.3 From 2d0a074517da34a6386bdd9a22bc006c8fa21044 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 22 Nov 2012 18:19:09 +0100 Subject: dma: mv_xor: use request_irq() instead of devm_request_irq() Even through the usage of devm_*() functions is generally recommended over their classic variants, in the case of devm_request_irq() combined with irq_of_parse_and_map(), it doesn't work nicely. We have the following scenario: irq_of_parse_and_map(...) devm_request_irq(...) For some reason, the driver initialization fails at a later point. Since irq_of_parse_and_map() is no device-managed, we do a: irq_dispose_mapping(...) Unfortunately, this doesn't work, because the free_irq() must be done prior to calling irq_dispose_mapping(). But with the devm mechanism, the automatic free_irq() would happen only after we get out of the ->probe() function. So basically, we revert to using request_irq() with traditional error handling, so that in case of error, free_irq() gets called before irq_dispose_mapping(). Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 2c69b89eac4f..0d4c24e529f7 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1162,9 +1162,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev, /* clear errors before enabling interrupts */ mv_xor_device_clear_err_status(mv_chan); - ret = devm_request_irq(&pdev->dev, mv_chan->irq, - mv_xor_interrupt_handler, - 0, dev_name(&pdev->dev), mv_chan); + ret = request_irq(mv_chan->irq, mv_xor_interrupt_handler, + 0, dev_name(&pdev->dev), mv_chan); if (ret) goto err_free_dma; @@ -1185,14 +1184,14 @@ mv_xor_channel_add(struct mv_xor_device *xordev, ret = mv_xor_memcpy_self_test(mv_chan); dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret); if (ret) - goto err_free_dma; + goto err_free_irq; } if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { ret = mv_xor_xor_self_test(mv_chan); dev_dbg(&pdev->dev, "xor self test returned %d\n", ret); if (ret) - goto err_free_dma; + goto err_free_irq; } dev_info(&pdev->dev, "Marvell XOR: " @@ -1205,6 +1204,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev, dma_async_device_register(dma_dev); return mv_chan; +err_free_irq: + free_irq(mv_chan->irq, mv_chan); err_free_dma: dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); -- cgit v1.2.3 From f8eb9e7d2a198fe3a0f76d9e5b374160c26e4621 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 22 Nov 2012 18:22:12 +0100 Subject: dma: mv_xor: fix error checking of irq_of_parse_and_map() The irq_of_parse_and_map() function returns 0 on failure, and does not return an error code, so we fix the calling site of irq_of_parse_and_map() in the mv_xor driver. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 0d4c24e529f7..f2edd6a5536e 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1312,8 +1312,8 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) dma_cap_set(DMA_INTERRUPT, cap_mask); irq = irq_of_parse_and_map(np, 0); - if (irq < 0) { - ret = irq; + if (!irq) { + ret = -ENODEV; goto err_channel_add; } -- cgit v1.2.3 From 73d9cdca1ced6ab32be363b58699039bd82b062a Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Thu, 22 Nov 2012 18:22:59 +0100 Subject: dma: mv_xor: fix error handling path The ->probe() function of the mv_xor function contains in its error handling code a loop to cleanup the XOR channels that had been successfully initialized if some other XOR channel fails to be initialized. It does that by traveling the list of XOR channels, and cleanup those for which the pointer is not NULL. However, since the mv_xor_channel_add() function return a PTR_ERR style value, the pointer is not NULL on error. So, when handling the error of a given channel initialization, we cleanup this channel initialization and mark this channel entry as NULL in the array. This allows the remaining of the cleanup (for other channels) to work properly. Signed-off-by: Thomas Petazzoni --- drivers/dma/mv_xor.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/dma') diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index f2edd6a5536e..9659e58fc8b2 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1322,6 +1322,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev) cap_mask, irq); if (IS_ERR(xordev->channels[i])) { ret = PTR_ERR(xordev->channels[i]); + xordev->channels[i] = NULL; irq_dispose_mapping(irq); goto err_channel_add; } -- cgit v1.2.3