@@ -1379,6 +1379,10 @@ static int __devinit dw_probe(struct platform_device *pdev)
13791379 struct resource * io ;
13801380 struct dw_dma * dw ;
13811381 size_t size ;
1382+ void __iomem * regs ;
1383+ bool autocfg ;
1384+ unsigned int dw_params ;
1385+ unsigned int nr_channels ;
13821386 int irq ;
13831387 int err ;
13841388 int i ;
@@ -1395,23 +1399,32 @@ static int __devinit dw_probe(struct platform_device *pdev)
13951399 if (irq < 0 )
13961400 return irq ;
13971401
1398- size = sizeof (struct dw_dma );
1399- size += pdata -> nr_channels * sizeof (struct dw_dma_chan );
1402+ regs = devm_request_and_ioremap (& pdev -> dev , io );
1403+ if (!regs )
1404+ return - EBUSY ;
1405+
1406+ dw_params = dma_read_byaddr (regs , DW_PARAMS );
1407+ autocfg = dw_params >> DW_PARAMS_EN & 0x1 ;
1408+
1409+ if (autocfg )
1410+ nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7 ) + 1 ;
1411+ else
1412+ nr_channels = pdata -> nr_channels ;
1413+
1414+ size = sizeof (struct dw_dma ) + nr_channels * sizeof (struct dw_dma_chan );
14001415 dw = devm_kzalloc (& pdev -> dev , size , GFP_KERNEL );
14011416 if (!dw )
14021417 return - ENOMEM ;
14031418
1404- dw -> regs = devm_request_and_ioremap (& pdev -> dev , io );
1405- if (!dw -> regs )
1406- return - EBUSY ;
1407-
14081419 dw -> clk = devm_clk_get (& pdev -> dev , "hclk" );
14091420 if (IS_ERR (dw -> clk ))
14101421 return PTR_ERR (dw -> clk );
14111422 clk_prepare_enable (dw -> clk );
14121423
1424+ dw -> regs = regs ;
1425+
14131426 /* Calculate all channel mask before DMA setup */
1414- dw -> all_chan_mask = (1 << pdata -> nr_channels ) - 1 ;
1427+ dw -> all_chan_mask = (1 << nr_channels ) - 1 ;
14151428
14161429 /* force dma off, just in case */
14171430 dw_dma_off (dw );
@@ -1429,7 +1442,7 @@ static int __devinit dw_probe(struct platform_device *pdev)
14291442 tasklet_init (& dw -> tasklet , dw_dma_tasklet , (unsigned long )dw );
14301443
14311444 INIT_LIST_HEAD (& dw -> dma .channels );
1432- for (i = 0 ; i < pdata -> nr_channels ; i ++ ) {
1445+ for (i = 0 ; i < nr_channels ; i ++ ) {
14331446 struct dw_dma_chan * dwc = & dw -> chan [i ];
14341447
14351448 dwc -> chan .device = & dw -> dma ;
@@ -1442,7 +1455,7 @@ static int __devinit dw_probe(struct platform_device *pdev)
14421455
14431456 /* 7 is highest priority & 0 is lowest. */
14441457 if (pdata -> chan_priority == CHAN_PRIORITY_ASCENDING )
1445- dwc -> priority = pdata -> nr_channels - i - 1 ;
1458+ dwc -> priority = nr_channels - i - 1 ;
14461459 else
14471460 dwc -> priority = i ;
14481461
@@ -1483,7 +1496,7 @@ static int __devinit dw_probe(struct platform_device *pdev)
14831496 dma_writel (dw , CFG , DW_CFG_DMA_EN );
14841497
14851498 printk (KERN_INFO "%s: DesignWare DMA Controller, %d channels\n" ,
1486- dev_name (& pdev -> dev ), pdata -> nr_channels );
1499+ dev_name (& pdev -> dev ), nr_channels );
14871500
14881501 dma_async_device_register (& dw -> dma );
14891502
0 commit comments