Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: sf-pdma: Get number of channel by device tree

It currently assumes that there are always four channels, it would
cause the error if there is actually less than four channels. Change
that by getting number of channel from device tree.

For backwards-compatibility, it uses the default value (i.e. 4) when
there is no 'dma-channels' information in dts.

Signed-off-by: Zong Li <zong.li@sifive.com>
Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Link: https://lore.kernel.org/r/f08a95b6582a51712c5b2c3cb859136d07bfa8b9.1648461096.git.zong.li@sifive.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Zong Li and committed by
Vinod Koul
e2dfce24 06006ad2

+18 -14
+16 -8
drivers/dma/sf-pdma/sf-pdma.c
··· 482 482 static int sf_pdma_probe(struct platform_device *pdev) 483 483 { 484 484 struct sf_pdma *pdma; 485 - struct sf_pdma_chan *chan; 486 485 struct resource *res; 487 - int len, chans; 488 - int ret; 486 + int ret, n_chans; 489 487 const enum dma_slave_buswidth widths = 490 488 DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES | 491 489 DMA_SLAVE_BUSWIDTH_4_BYTES | DMA_SLAVE_BUSWIDTH_8_BYTES | 492 490 DMA_SLAVE_BUSWIDTH_16_BYTES | DMA_SLAVE_BUSWIDTH_32_BYTES | 493 491 DMA_SLAVE_BUSWIDTH_64_BYTES; 494 492 495 - chans = PDMA_NR_CH; 496 - len = sizeof(*pdma) + sizeof(*chan) * chans; 497 - pdma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); 493 + ret = of_property_read_u32(pdev->dev.of_node, "dma-channels", &n_chans); 494 + if (ret) { 495 + /* backwards-compatibility for no dma-channels property */ 496 + dev_dbg(&pdev->dev, "set number of channels to default value: 4\n"); 497 + n_chans = PDMA_MAX_NR_CH; 498 + } else if (n_chans > PDMA_MAX_NR_CH) { 499 + dev_err(&pdev->dev, "the number of channels exceeds the maximum\n"); 500 + return -EINVAL; 501 + } 502 + 503 + pdma = devm_kzalloc(&pdev->dev, struct_size(pdma, chans, n_chans), 504 + GFP_KERNEL); 498 505 if (!pdma) 499 506 return -ENOMEM; 500 507 501 - pdma->n_chans = chans; 508 + pdma->n_chans = n_chans; 502 509 503 510 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 504 511 pdma->membase = devm_ioremap_resource(&pdev->dev, res); ··· 563 556 struct sf_pdma_chan *ch; 564 557 int i; 565 558 566 - for (i = 0; i < PDMA_NR_CH; i++) { 559 + for (i = 0; i < pdma->n_chans; i++) { 567 560 ch = &pdma->chans[i]; 568 561 569 562 devm_free_irq(&pdev->dev, ch->txirq, ch); ··· 581 574 582 575 static const struct of_device_id sf_pdma_dt_ids[] = { 583 576 { .compatible = "sifive,fu540-c000-pdma" }, 577 + { .compatible = "sifive,pdma0" }, 584 578 {}, 585 579 }; 586 580 MODULE_DEVICE_TABLE(of, sf_pdma_dt_ids);
+2 -6
drivers/dma/sf-pdma/sf-pdma.h
··· 22 22 #include "../dmaengine.h" 23 23 #include "../virt-dma.h" 24 24 25 - #define PDMA_NR_CH 4 26 - 27 - #if (PDMA_NR_CH != 4) 28 - #error "Please define PDMA_NR_CH to 4" 29 - #endif 25 + #define PDMA_MAX_NR_CH 4 30 26 31 27 #define PDMA_BASE_ADDR 0x3000000 32 28 #define PDMA_CHAN_OFFSET 0x1000 ··· 114 118 void __iomem *membase; 115 119 void __iomem *mappedbase; 116 120 u32 n_chans; 117 - struct sf_pdma_chan chans[PDMA_NR_CH]; 121 + struct sf_pdma_chan chans[]; 118 122 }; 119 123 120 124 #endif /* _SF_PDMA_H */