aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/imx-sdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/imx-sdma.c')
-rw-r--r--drivers/dma/imx-sdma.c150
1 files changed, 59 insertions, 91 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index d0df198f62e9..18c0a131e4e4 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -830,20 +830,29 @@ static int sdma_load_context(struct sdma_channel *sdmac)
830 return ret; 830 return ret;
831} 831}
832 832
833static void sdma_disable_channel(struct sdma_channel *sdmac) 833static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
834{
835 return container_of(chan, struct sdma_channel, chan);
836}
837
838static int sdma_disable_channel(struct dma_chan *chan)
834{ 839{
840 struct sdma_channel *sdmac = to_sdma_chan(chan);
835 struct sdma_engine *sdma = sdmac->sdma; 841 struct sdma_engine *sdma = sdmac->sdma;
836 int channel = sdmac->channel; 842 int channel = sdmac->channel;
837 843
838 writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP); 844 writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
839 sdmac->status = DMA_ERROR; 845 sdmac->status = DMA_ERROR;
846
847 return 0;
840} 848}
841 849
842static int sdma_config_channel(struct sdma_channel *sdmac) 850static int sdma_config_channel(struct dma_chan *chan)
843{ 851{
852 struct sdma_channel *sdmac = to_sdma_chan(chan);
844 int ret; 853 int ret;
845 854
846 sdma_disable_channel(sdmac); 855 sdma_disable_channel(chan);
847 856
848 sdmac->event_mask[0] = 0; 857 sdmac->event_mask[0] = 0;
849 sdmac->event_mask[1] = 0; 858 sdmac->event_mask[1] = 0;
@@ -935,11 +944,6 @@ out:
935 return ret; 944 return ret;
936} 945}
937 946
938static struct sdma_channel *to_sdma_chan(struct dma_chan *chan)
939{
940 return container_of(chan, struct sdma_channel, chan);
941}
942
943static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx) 947static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
944{ 948{
945 unsigned long flags; 949 unsigned long flags;
@@ -1004,7 +1008,7 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
1004 struct sdma_channel *sdmac = to_sdma_chan(chan); 1008 struct sdma_channel *sdmac = to_sdma_chan(chan);
1005 struct sdma_engine *sdma = sdmac->sdma; 1009 struct sdma_engine *sdma = sdmac->sdma;
1006 1010
1007 sdma_disable_channel(sdmac); 1011 sdma_disable_channel(chan);
1008 1012
1009 if (sdmac->event_id0) 1013 if (sdmac->event_id0)
1010 sdma_event_disable(sdmac, sdmac->event_id0); 1014 sdma_event_disable(sdmac, sdmac->event_id0);
@@ -1203,35 +1207,24 @@ err_out:
1203 return NULL; 1207 return NULL;
1204} 1208}
1205 1209
1206static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, 1210static int sdma_config(struct dma_chan *chan,
1207 unsigned long arg) 1211 struct dma_slave_config *dmaengine_cfg)
1208{ 1212{
1209 struct sdma_channel *sdmac = to_sdma_chan(chan); 1213 struct sdma_channel *sdmac = to_sdma_chan(chan);
1210 struct dma_slave_config *dmaengine_cfg = (void *)arg;
1211
1212 switch (cmd) {
1213 case DMA_TERMINATE_ALL:
1214 sdma_disable_channel(sdmac);
1215 return 0;
1216 case DMA_SLAVE_CONFIG:
1217 if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
1218 sdmac->per_address = dmaengine_cfg->src_addr;
1219 sdmac->watermark_level = dmaengine_cfg->src_maxburst *
1220 dmaengine_cfg->src_addr_width;
1221 sdmac->word_size = dmaengine_cfg->src_addr_width;
1222 } else {
1223 sdmac->per_address = dmaengine_cfg->dst_addr;
1224 sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
1225 dmaengine_cfg->dst_addr_width;
1226 sdmac->word_size = dmaengine_cfg->dst_addr_width;
1227 }
1228 sdmac->direction = dmaengine_cfg->direction;
1229 return sdma_config_channel(sdmac);
1230 default:
1231 return -ENOSYS;
1232 }
1233 1214
1234 return -EINVAL; 1215 if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
1216 sdmac->per_address = dmaengine_cfg->src_addr;
1217 sdmac->watermark_level = dmaengine_cfg->src_maxburst *
1218 dmaengine_cfg->src_addr_width;
1219 sdmac->word_size = dmaengine_cfg->src_addr_width;
1220 } else {
1221 sdmac->per_address = dmaengine_cfg->dst_addr;
1222 sdmac->watermark_level = dmaengine_cfg->dst_maxburst *
1223 dmaengine_cfg->dst_addr_width;
1224 sdmac->word_size = dmaengine_cfg->dst_addr_width;
1225 }
1226 sdmac->direction = dmaengine_cfg->direction;
1227 return sdma_config_channel(chan);
1235} 1228}
1236 1229
1237static enum dma_status sdma_tx_status(struct dma_chan *chan, 1230static enum dma_status sdma_tx_status(struct dma_chan *chan,
@@ -1303,15 +1296,15 @@ static void sdma_load_firmware(const struct firmware *fw, void *context)
1303 if (header->ram_code_start + header->ram_code_size > fw->size) 1296 if (header->ram_code_start + header->ram_code_size > fw->size)
1304 goto err_firmware; 1297 goto err_firmware;
1305 switch (header->version_major) { 1298 switch (header->version_major) {
1306 case 1: 1299 case 1:
1307 sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; 1300 sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
1308 break; 1301 break;
1309 case 2: 1302 case 2:
1310 sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2; 1303 sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2;
1311 break; 1304 break;
1312 default: 1305 default:
1313 dev_err(sdma->dev, "unknown firmware version\n"); 1306 dev_err(sdma->dev, "unknown firmware version\n");
1314 goto err_firmware; 1307 goto err_firmware;
1315 } 1308 }
1316 1309
1317 addr = (void *)header + header->script_addrs_start; 1310 addr = (void *)header + header->script_addrs_start;
@@ -1479,7 +1472,7 @@ static int sdma_probe(struct platform_device *pdev)
1479 if (ret) 1472 if (ret)
1480 return ret; 1473 return ret;
1481 1474
1482 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); 1475 sdma = devm_kzalloc(&pdev->dev, sizeof(*sdma), GFP_KERNEL);
1483 if (!sdma) 1476 if (!sdma)
1484 return -ENOMEM; 1477 return -ENOMEM;
1485 1478
@@ -1488,48 +1481,34 @@ static int sdma_probe(struct platform_device *pdev)
1488 sdma->dev = &pdev->dev; 1481 sdma->dev = &pdev->dev;
1489 sdma->drvdata = drvdata; 1482 sdma->drvdata = drvdata;
1490 1483
1491 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1492 irq = platform_get_irq(pdev, 0); 1484 irq = platform_get_irq(pdev, 0);
1493 if (!iores || irq < 0) { 1485 if (irq < 0)
1494 ret = -EINVAL; 1486 return irq;
1495 goto err_irq;
1496 }
1497 1487
1498 if (!request_mem_region(iores->start, resource_size(iores), pdev->name)) { 1488 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1499 ret = -EBUSY; 1489 sdma->regs = devm_ioremap_resource(&pdev->dev, iores);
1500 goto err_request_region; 1490 if (IS_ERR(sdma->regs))
1501 } 1491 return PTR_ERR(sdma->regs);
1502 1492
1503 sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 1493 sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
1504 if (IS_ERR(sdma->clk_ipg)) { 1494 if (IS_ERR(sdma->clk_ipg))
1505 ret = PTR_ERR(sdma->clk_ipg); 1495 return PTR_ERR(sdma->clk_ipg);
1506 goto err_clk;
1507 }
1508 1496
1509 sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); 1497 sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
1510 if (IS_ERR(sdma->clk_ahb)) { 1498 if (IS_ERR(sdma->clk_ahb))
1511 ret = PTR_ERR(sdma->clk_ahb); 1499 return PTR_ERR(sdma->clk_ahb);
1512 goto err_clk;
1513 }
1514 1500
1515 clk_prepare(sdma->clk_ipg); 1501 clk_prepare(sdma->clk_ipg);
1516 clk_prepare(sdma->clk_ahb); 1502 clk_prepare(sdma->clk_ahb);
1517 1503
1518 sdma->regs = ioremap(iores->start, resource_size(iores)); 1504 ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma",
1519 if (!sdma->regs) { 1505 sdma);
1520 ret = -ENOMEM;
1521 goto err_ioremap;
1522 }
1523
1524 ret = request_irq(irq, sdma_int_handler, 0, "sdma", sdma);
1525 if (ret) 1506 if (ret)
1526 goto err_request_irq; 1507 return ret;
1527 1508
1528 sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); 1509 sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL);
1529 if (!sdma->script_addrs) { 1510 if (!sdma->script_addrs)
1530 ret = -ENOMEM; 1511 return -ENOMEM;
1531 goto err_alloc;
1532 }
1533 1512
1534 /* initially no scripts available */ 1513 /* initially no scripts available */
1535 saddr_arr = (s32 *)sdma->script_addrs; 1514 saddr_arr = (s32 *)sdma->script_addrs;
@@ -1600,7 +1579,12 @@ static int sdma_probe(struct platform_device *pdev)
1600 sdma->dma_device.device_tx_status = sdma_tx_status; 1579 sdma->dma_device.device_tx_status = sdma_tx_status;
1601 sdma->dma_device.device_prep_slave_sg = sdma_prep_slave_sg; 1580 sdma->dma_device.device_prep_slave_sg = sdma_prep_slave_sg;
1602 sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; 1581 sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic;
1603 sdma->dma_device.device_control = sdma_control; 1582 sdma->dma_device.device_config = sdma_config;
1583 sdma->dma_device.device_terminate_all = sdma_disable_channel;
1584 sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
1585 sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
1586 sdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
1587 sdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
1604 sdma->dma_device.device_issue_pending = sdma_issue_pending; 1588 sdma->dma_device.device_issue_pending = sdma_issue_pending;
1605 sdma->dma_device.dev->dma_parms = &sdma->dma_parms; 1589 sdma->dma_device.dev->dma_parms = &sdma->dma_parms;
1606 dma_set_max_seg_size(sdma->dma_device.dev, 65535); 1590 dma_set_max_seg_size(sdma->dma_device.dev, 65535);
@@ -1629,38 +1613,22 @@ err_register:
1629 dma_async_device_unregister(&sdma->dma_device); 1613 dma_async_device_unregister(&sdma->dma_device);
1630err_init: 1614err_init:
1631 kfree(sdma->script_addrs); 1615 kfree(sdma->script_addrs);
1632err_alloc:
1633 free_irq(irq, sdma);
1634err_request_irq:
1635 iounmap(sdma->regs);
1636err_ioremap:
1637err_clk:
1638 release_mem_region(iores->start, resource_size(iores));
1639err_request_region:
1640err_irq:
1641 kfree(sdma);
1642 return ret; 1616 return ret;
1643} 1617}
1644 1618
1645static int sdma_remove(struct platform_device *pdev) 1619static int sdma_remove(struct platform_device *pdev)
1646{ 1620{
1647 struct sdma_engine *sdma = platform_get_drvdata(pdev); 1621 struct sdma_engine *sdma = platform_get_drvdata(pdev);
1648 struct resource *iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1649 int irq = platform_get_irq(pdev, 0);
1650 int i; 1622 int i;
1651 1623
1652 dma_async_device_unregister(&sdma->dma_device); 1624 dma_async_device_unregister(&sdma->dma_device);
1653 kfree(sdma->script_addrs); 1625 kfree(sdma->script_addrs);
1654 free_irq(irq, sdma);
1655 iounmap(sdma->regs);
1656 release_mem_region(iores->start, resource_size(iores));
1657 /* Kill the tasklet */ 1626 /* Kill the tasklet */
1658 for (i = 0; i < MAX_DMA_CHANNELS; i++) { 1627 for (i = 0; i < MAX_DMA_CHANNELS; i++) {
1659 struct sdma_channel *sdmac = &sdma->channel[i]; 1628 struct sdma_channel *sdmac = &sdma->channel[i];
1660 1629
1661 tasklet_kill(&sdmac->tasklet); 1630 tasklet_kill(&sdmac->tasklet);
1662 } 1631 }
1663 kfree(sdma);
1664 1632
1665 platform_set_drvdata(pdev, NULL); 1633 platform_set_drvdata(pdev, NULL);
1666 dev_info(&pdev->dev, "Removed...\n"); 1634 dev_info(&pdev->dev, "Removed...\n");