From 32cab45987a8518095046ff692b323c8b2b8f894 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 21 Sep 2012 15:05:46 +0300 Subject: [PATCH] --- yaml --- r: 332881 b: refs/heads/master c: 482c67ea7bab80b956185a3e7553151820bc5876 h: refs/heads/master i: 332879: f143770b8bac2007941cb21672fcbb40b4056687 v: v3 --- [refs] | 2 +- trunk/drivers/dma/dw_dmac.c | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index f49f445c54f9..eeead76fd70a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2a9fe9ae3a7b3986a4229900e900bfaa72c7a152 +refs/heads/master: 482c67ea7bab80b956185a3e7553151820bc5876 diff --git a/trunk/drivers/dma/dw_dmac.c b/trunk/drivers/dma/dw_dmac.c index e817610d97c9..d71bc7167891 100644 --- a/trunk/drivers/dma/dw_dmac.c +++ b/trunk/drivers/dma/dw_dmac.c @@ -1379,6 +1379,10 @@ static int __devinit dw_probe(struct platform_device *pdev) struct resource *io; struct dw_dma *dw; size_t size; + void __iomem *regs; + bool autocfg; + unsigned int dw_params; + unsigned int nr_channels; int irq; int err; int i; @@ -1395,23 +1399,32 @@ static int __devinit dw_probe(struct platform_device *pdev) if (irq < 0) return irq; - size = sizeof(struct dw_dma); - size += pdata->nr_channels * sizeof(struct dw_dma_chan); + regs = devm_request_and_ioremap(&pdev->dev, io); + if (!regs) + return -EBUSY; + + dw_params = dma_read_byaddr(regs, DW_PARAMS); + autocfg = dw_params >> DW_PARAMS_EN & 0x1; + + if (autocfg) + nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1; + else + nr_channels = pdata->nr_channels; + + size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan); dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (!dw) return -ENOMEM; - dw->regs = devm_request_and_ioremap(&pdev->dev, io); - if (!dw->regs) - return -EBUSY; - dw->clk = devm_clk_get(&pdev->dev, "hclk"); if (IS_ERR(dw->clk)) return PTR_ERR(dw->clk); clk_prepare_enable(dw->clk); + dw->regs = regs; + /* Calculate all channel mask before DMA setup */ - dw->all_chan_mask = (1 << pdata->nr_channels) - 1; + dw->all_chan_mask = (1 << nr_channels) - 1; /* force dma off, just in case */ dw_dma_off(dw); @@ -1429,7 +1442,7 @@ static int __devinit dw_probe(struct platform_device *pdev) tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw); INIT_LIST_HEAD(&dw->dma.channels); - for (i = 0; i < pdata->nr_channels; i++) { + for (i = 0; i < nr_channels; i++) { struct dw_dma_chan *dwc = &dw->chan[i]; dwc->chan.device = &dw->dma; @@ -1442,7 +1455,7 @@ static int __devinit dw_probe(struct platform_device *pdev) /* 7 is highest priority & 0 is lowest. */ if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING) - dwc->priority = pdata->nr_channels - i - 1; + dwc->priority = nr_channels - i - 1; else dwc->priority = i; @@ -1483,7 +1496,7 @@ static int __devinit dw_probe(struct platform_device *pdev) dma_writel(dw, CFG, DW_CFG_DMA_EN); printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n", - dev_name(&pdev->dev), pdata->nr_channels); + dev_name(&pdev->dev), nr_channels); dma_async_device_register(&dw->dma);