};
struct jz4780_dma_filter_data {
@@ -648,7 +653,7 @@ static irqreturn_t jz4780_dma_irq_handler(int
irq, void *data)
pending = jz4780_dma_readl(jzdma, JZ_DMA_REG_DIRQP);
- for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) {
+ for (i = 0; i < jzdma->nb_channels; i++) {
if (!(pending & (1<<i)))
continue;
@@ -728,7 +733,7 @@ static struct dma_chan
*jz4780_of_dma_xlate(struct of_phandle_args *dma_spec,
data.channel = dma_spec->args[1];
if (data.channel > -1) {
- if (data.channel >= JZ_DMA_NR_CHANNELS) {
+ if (data.channel >= jzdma->nb_channels) {
dev_err(jzdma->dma_device.dev,
"device requested non-existent
channel %u\n",
data.channel);
@@ -752,19 +757,45 @@ static struct dma_chan
*jz4780_of_dma_xlate(struct of_phandle_args *dma_spec,
}
}
+static const unsigned int jz4780_dma_nb_channels[] = {
+ [ID_JZ4780] = 32,
+};
+
+static const struct of_device_id jz4780_dma_dt_match[] = {
+ { .compatible = "ingenic,jz4780-dma", .data = (void
*)ID_JZ4780 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, jz4780_dma_dt_match);
+
static int jz4780_dma_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ const struct of_device_id *of_id = of_match_device(
+ jz4780_dma_dt_match, dev);
struct jz4780_dma_dev *jzdma;
struct jz4780_dma_chan *jzchan;
struct dma_device *dd;
struct resource *res;
+ enum jz_version version;
+ unsigned int nb_channels;
int i, ret;
- jzdma = devm_kzalloc(dev, sizeof(*jzdma), GFP_KERNEL);
+ if (of_id)
+ version = (enum jz_version)of_id->data;
+ else
+ version = ID_JZ4780; /* Default when not probed
from DT */
+
+ nb_channels = jz4780_dma_nb_channels[version];
+
+ jzdma = devm_kzalloc(dev, sizeof(*jzdma)
+ + sizeof(*jzdma->chan) *
nb_channels,
+ GFP_KERNEL);
if (!jzdma)
return -ENOMEM;
+ jzdma->nb_channels = nb_channels;
+ jzdma->version = version;
+
platform_set_drvdata(pdev, jzdma);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -839,7 +870,7 @@ static int jz4780_dma_probe(struct
platform_device *pdev)
INIT_LIST_HEAD(&dd->channels);
- for (i = 0; i < JZ_DMA_NR_CHANNELS; i++) {
+ for (i = 0; i < jzdma->nb_channels; i++) {
jzchan = &jzdma->chan[i];
jzchan->id = i;
@@ -884,19 +915,13 @@ static int jz4780_dma_remove(struct
platform_device *pdev)
free_irq(jzdma->irq, jzdma);
- for (i = 0; i < JZ_DMA_NR_CHANNELS; i++)
+ for (i = 0; i < jzdma->nb_channels; i++)
tasklet_kill(&jzdma->chan[i].vchan.task);
dma_async_device_unregister(&jzdma->dma_device);
return 0;
}
-static const struct of_device_id jz4780_dma_dt_match[] = {
- { .compatible = "ingenic,jz4780-dma", .data = NULL },
- {},
-};
-MODULE_DEVICE_TABLE(of, jz4780_dma_dt_match);
-
static struct platform_driver jz4780_dma_driver = {
.probe = jz4780_dma_probe,
.remove = jz4780_dma_remove,
--
2.18.0