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>
This commit is contained in:
Thomas Petazzoni 2012-10-29 16:54:49 +01:00
parent a6b4a9d2c1
commit 60d151f387
3 changed files with 53 additions and 3 deletions

View File

@ -1292,7 +1292,9 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
{ {
const struct mbus_dram_target_info *dram; const struct mbus_dram_target_info *dram;
struct mv_xor_shared_private *msp; struct mv_xor_shared_private *msp;
struct mv_xor_shared_platform_data *pdata = pdev->dev.platform_data;
struct resource *res; struct resource *res;
int i, ret;
dev_notice(&pdev->dev, "Marvell shared XOR driver\n"); 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)) if (!IS_ERR(msp->clk))
clk_prepare_enable(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; 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) static int mv_xor_shared_remove(struct platform_device *pdev)
{ {
struct mv_xor_shared_private *msp = platform_get_drvdata(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)) { if (!IS_ERR(msp->clk)) {
clk_disable_unprepare(msp->clk); clk_disable_unprepare(msp->clk);

View File

@ -26,6 +26,7 @@
#define USE_TIMER #define USE_TIMER
#define MV_XOR_SLOT_SIZE 64 #define MV_XOR_SLOT_SIZE 64
#define MV_XOR_THRESHOLD 1 #define MV_XOR_THRESHOLD 1
#define MV_XOR_MAX_CHANNELS 2
#define XOR_OPERATION_MODE_XOR 0 #define XOR_OPERATION_MODE_XOR 0
#define XOR_OPERATION_MODE_MEMCPY 2 #define XOR_OPERATION_MODE_MEMCPY 2
@ -53,9 +54,10 @@
#define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2)) #define WINDOW_BAR_ENABLE(chan) (0x240 + ((chan) << 2))
struct mv_xor_shared_private { struct mv_xor_shared_private {
void __iomem *xor_base; void __iomem *xor_base;
void __iomem *xor_high_base; void __iomem *xor_high_base;
struct clk *clk; struct clk *clk;
struct mv_xor_device *channels[MV_XOR_MAX_CHANNELS];
}; };

View File

@ -20,5 +20,8 @@ struct mv_xor_platform_data {
size_t pool_size; size_t pool_size;
}; };
struct mv_xor_shared_platform_data {
struct mv_xor_platform_data *channels;
};
#endif #endif