diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2012-10-29 16:54:49 +0100 |
---|---|---|
committer | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2012-11-20 15:58:56 +0100 |
commit | 60d151f38799d5e15845ee04b73cbf3839f1b06c (patch) | |
tree | e360fb470a5ba59e6a5363d964b355d3fdae5456 /drivers/dma/mv_xor.c | |
parent | a6b4a9d2c1063ffc52ca94b6c1b24f9b6d5b79c5 (diff) | |
download | lwn-60d151f38799d5e15845ee04b73cbf3839f1b06c.tar.gz lwn-60d151f38799d5e15845ee04b73cbf3839f1b06c.zip |
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 <thomas.petazzoni@free-electrons.com>
Diffstat (limited to 'drivers/dma/mv_xor.c')
-rw-r--r-- | drivers/dma/mv_xor.c | 45 |
1 files changed, 45 insertions, 0 deletions
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); |