aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dw/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/dw/core.c')
-rw-r--r--drivers/dma/dw/core.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index cfdbb92aae1d..a27ded53ab4f 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -1493,6 +1493,13 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1493 dw->regs = chip->regs; 1493 dw->regs = chip->regs;
1494 chip->dw = dw; 1494 chip->dw = dw;
1495 1495
1496 dw->clk = devm_clk_get(chip->dev, "hclk");
1497 if (IS_ERR(dw->clk))
1498 return PTR_ERR(dw->clk);
1499 err = clk_prepare_enable(dw->clk);
1500 if (err)
1501 return err;
1502
1496 dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); 1503 dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
1497 autocfg = dw_params >> DW_PARAMS_EN & 0x1; 1504 autocfg = dw_params >> DW_PARAMS_EN & 0x1;
1498 1505
@@ -1500,15 +1507,19 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1500 1507
1501 if (!pdata && autocfg) { 1508 if (!pdata && autocfg) {
1502 pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); 1509 pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL);
1503 if (!pdata) 1510 if (!pdata) {
1504 return -ENOMEM; 1511 err = -ENOMEM;
1512 goto err_pdata;
1513 }
1505 1514
1506 /* Fill platform data with the default values */ 1515 /* Fill platform data with the default values */
1507 pdata->is_private = true; 1516 pdata->is_private = true;
1508 pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING; 1517 pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
1509 pdata->chan_priority = CHAN_PRIORITY_ASCENDING; 1518 pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
1510 } else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) 1519 } else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) {
1511 return -EINVAL; 1520 err = -EINVAL;
1521 goto err_pdata;
1522 }
1512 1523
1513 if (autocfg) 1524 if (autocfg)
1514 nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1; 1525 nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
@@ -1517,13 +1528,10 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1517 1528
1518 dw->chan = devm_kcalloc(chip->dev, nr_channels, sizeof(*dw->chan), 1529 dw->chan = devm_kcalloc(chip->dev, nr_channels, sizeof(*dw->chan),
1519 GFP_KERNEL); 1530 GFP_KERNEL);
1520 if (!dw->chan) 1531 if (!dw->chan) {
1521 return -ENOMEM; 1532 err = -ENOMEM;
1522 1533 goto err_pdata;
1523 dw->clk = devm_clk_get(chip->dev, "hclk"); 1534 }
1524 if (IS_ERR(dw->clk))
1525 return PTR_ERR(dw->clk);
1526 clk_prepare_enable(dw->clk);
1527 1535
1528 /* Get hardware configuration parameters */ 1536 /* Get hardware configuration parameters */
1529 if (autocfg) { 1537 if (autocfg) {
@@ -1548,21 +1556,22 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1548 /* Disable BLOCK interrupts as well */ 1556 /* Disable BLOCK interrupts as well */
1549 channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); 1557 channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
1550 1558
1551 err = devm_request_irq(chip->dev, chip->irq, dw_dma_interrupt,
1552 IRQF_SHARED, "dw_dmac", dw);
1553 if (err)
1554 return err;
1555
1556 /* Create a pool of consistent memory blocks for hardware descriptors */ 1559 /* Create a pool of consistent memory blocks for hardware descriptors */
1557 dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev, 1560 dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev,
1558 sizeof(struct dw_desc), 4, 0); 1561 sizeof(struct dw_desc), 4, 0);
1559 if (!dw->desc_pool) { 1562 if (!dw->desc_pool) {
1560 dev_err(chip->dev, "No memory for descriptors dma pool\n"); 1563 dev_err(chip->dev, "No memory for descriptors dma pool\n");
1561 return -ENOMEM; 1564 err = -ENOMEM;
1565 goto err_pdata;
1562 } 1566 }
1563 1567
1564 tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw); 1568 tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
1565 1569
1570 err = request_irq(chip->irq, dw_dma_interrupt, IRQF_SHARED,
1571 "dw_dmac", dw);
1572 if (err)
1573 goto err_pdata;
1574
1566 INIT_LIST_HEAD(&dw->dma.channels); 1575 INIT_LIST_HEAD(&dw->dma.channels);
1567 for (i = 0; i < nr_channels; i++) { 1576 for (i = 0; i < nr_channels; i++) {
1568 struct dw_dma_chan *dwc = &dw->chan[i]; 1577 struct dw_dma_chan *dwc = &dw->chan[i];
@@ -1650,12 +1659,20 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1650 1659
1651 dma_writel(dw, CFG, DW_CFG_DMA_EN); 1660 dma_writel(dw, CFG, DW_CFG_DMA_EN);
1652 1661
1662 err = dma_async_device_register(&dw->dma);
1663 if (err)
1664 goto err_dma_register;
1665
1653 dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n", 1666 dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
1654 nr_channels); 1667 nr_channels);
1655 1668
1656 dma_async_device_register(&dw->dma);
1657
1658 return 0; 1669 return 0;
1670
1671err_dma_register:
1672 free_irq(chip->irq, dw);
1673err_pdata:
1674 clk_disable_unprepare(dw->clk);
1675 return err;
1659} 1676}
1660EXPORT_SYMBOL_GPL(dw_dma_probe); 1677EXPORT_SYMBOL_GPL(dw_dma_probe);
1661 1678
@@ -1667,6 +1684,7 @@ int dw_dma_remove(struct dw_dma_chip *chip)
1667 dw_dma_off(dw); 1684 dw_dma_off(dw);
1668 dma_async_device_unregister(&dw->dma); 1685 dma_async_device_unregister(&dw->dma);
1669 1686
1687 free_irq(chip->irq, dw);
1670 tasklet_kill(&dw->tasklet); 1688 tasklet_kill(&dw->tasklet);
1671 1689
1672 list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels, 1690 list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
@@ -1675,6 +1693,8 @@ int dw_dma_remove(struct dw_dma_chip *chip)
1675 channel_clear_bit(dw, CH_EN, dwc->mask); 1693 channel_clear_bit(dw, CH_EN, dwc->mask);
1676 } 1694 }
1677 1695
1696 clk_disable_unprepare(dw->clk);
1697
1678 return 0; 1698 return 0;
1679} 1699}
1680EXPORT_SYMBOL_GPL(dw_dma_remove); 1700EXPORT_SYMBOL_GPL(dw_dma_remove);