aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/Makefile2
-rw-r--r--drivers/dma/dw/Kconfig8
-rw-r--r--drivers/dma/dw/Makefile6
-rw-r--r--drivers/dma/dw/core.c (renamed from drivers/dma/dw/dw_dmac.c)311
-rw-r--r--drivers/dma/dw/internal.h70
-rw-r--r--drivers/dma/dw/platform.c317
-rw-r--r--drivers/dma/dw/regs.h (renamed from drivers/dma/dw/dw_dmac_regs.h)1
7 files changed, 436 insertions, 279 deletions
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index ac44ca0d468a..6e2a521fbbe3 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_FSL_DMA) += fsldma.o
15obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o 15obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o
16obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ 16obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
17obj-$(CONFIG_MV_XOR) += mv_xor.o 17obj-$(CONFIG_MV_XOR) += mv_xor.o
18obj-$(CONFIG_DW_DMAC) += dw/ 18obj-$(CONFIG_DW_DMAC_CORE) += dw/
19obj-$(CONFIG_AT_HDMAC) += at_hdmac.o 19obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
20obj-$(CONFIG_MX3_IPU) += ipu/ 20obj-$(CONFIG_MX3_IPU) += ipu/
21obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o 21obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig
index 38a215af5ccc..efd9e02a58eb 100644
--- a/drivers/dma/dw/Kconfig
+++ b/drivers/dma/dw/Kconfig
@@ -2,10 +2,14 @@
2# DMA engine configuration for dw 2# DMA engine configuration for dw
3# 3#
4 4
5config DW_DMAC 5config DW_DMAC_CORE
6 tristate "Synopsys DesignWare AHB DMA support" 6 tristate "Synopsys DesignWare AHB DMA support"
7 depends on GENERIC_HARDIRQS 7 depends on GENERIC_HARDIRQS
8 select DMA_ENGINE 8 select DMA_ENGINE
9
10config DW_DMAC
11 tristate "Synopsys DesignWare AHB DMA platform driver"
12 select DW_DMAC_CORE
9 default y if CPU_AT32AP7000 13 default y if CPU_AT32AP7000
10 help 14 help
11 Support the Synopsys DesignWare AHB DMA controller. This 15 Support the Synopsys DesignWare AHB DMA controller. This
@@ -14,7 +18,7 @@ config DW_DMAC
14config DW_DMAC_BIG_ENDIAN_IO 18config DW_DMAC_BIG_ENDIAN_IO
15 bool "Use big endian I/O register access" 19 bool "Use big endian I/O register access"
16 default y if AVR32 20 default y if AVR32
17 depends on DW_DMAC 21 depends on DW_DMAC_CORE
18 help 22 help
19 Say yes here to use big endian I/O access when reading and writing 23 Say yes here to use big endian I/O access when reading and writing
20 to the DMA controller registers. This is needed on some platforms, 24 to the DMA controller registers. This is needed on some platforms,
diff --git a/drivers/dma/dw/Makefile b/drivers/dma/dw/Makefile
index dd8d9936beef..47f36746c559 100644
--- a/drivers/dma/dw/Makefile
+++ b/drivers/dma/dw/Makefile
@@ -1 +1,5 @@
1obj-$(CONFIG_DW_DMAC) += dw_dmac.o 1obj-$(CONFIG_DW_DMAC_CORE) += dw_dmac_core.o
2dw_dmac_core-objs := core.o
3
4obj-$(CONFIG_DW_DMAC) += dw_dmac.o
5dw_dmac-objs := platform.o
diff --git a/drivers/dma/dw/dw_dmac.c b/drivers/dma/dw/core.c
index 15f3f4f79c10..eea479c12173 100644
--- a/drivers/dma/dw/dw_dmac.c
+++ b/drivers/dma/dw/core.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2007-2008 Atmel Corporation 4 * Copyright (C) 2007-2008 Atmel Corporation
5 * Copyright (C) 2010-2011 ST Microelectronics 5 * Copyright (C) 2010-2011 ST Microelectronics
6 * Copyright (C) 2013 Intel Corporation
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -19,17 +20,12 @@
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <linux/of.h>
23#include <linux/of_dma.h>
24#include <linux/mm.h> 23#include <linux/mm.h>
25#include <linux/module.h> 24#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h> 25#include <linux/slab.h>
28#include <linux/acpi.h>
29#include <linux/acpi_dma.h>
30 26
31#include "../dmaengine.h" 27#include "../dmaengine.h"
32#include "dw_dmac_regs.h" 28#include "internal.h"
33 29
34/* 30/*
35 * This supports the Synopsys "DesignWare AHB Central DMA Controller", 31 * This supports the Synopsys "DesignWare AHB Central DMA Controller",
@@ -41,16 +37,6 @@
41 * which does not support descriptor writeback. 37 * which does not support descriptor writeback.
42 */ 38 */
43 39
44static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
45{
46 return slave ? slave->dst_master : 0;
47}
48
49static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
50{
51 return slave ? slave->src_master : 1;
52}
53
54static inline void dwc_set_masters(struct dw_dma_chan *dwc) 40static inline void dwc_set_masters(struct dw_dma_chan *dwc)
55{ 41{
56 struct dw_dma *dw = to_dw_dma(dwc->chan.device); 42 struct dw_dma *dw = to_dw_dma(dwc->chan.device);
@@ -1225,99 +1211,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
1225 dev_vdbg(chan2dev(chan), "%s: done\n", __func__); 1211 dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
1226} 1212}
1227 1213
1228/*----------------------------------------------------------------------*/
1229
1230struct dw_dma_of_filter_args {
1231 struct dw_dma *dw;
1232 unsigned int req;
1233 unsigned int src;
1234 unsigned int dst;
1235};
1236
1237static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
1238{
1239 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
1240 struct dw_dma_of_filter_args *fargs = param;
1241
1242 /* Ensure the device matches our channel */
1243 if (chan->device != &fargs->dw->dma)
1244 return false;
1245
1246 dwc->request_line = fargs->req;
1247 dwc->src_master = fargs->src;
1248 dwc->dst_master = fargs->dst;
1249
1250 return true;
1251}
1252
1253static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
1254 struct of_dma *ofdma)
1255{
1256 struct dw_dma *dw = ofdma->of_dma_data;
1257 struct dw_dma_of_filter_args fargs = {
1258 .dw = dw,
1259 };
1260 dma_cap_mask_t cap;
1261
1262 if (dma_spec->args_count != 3)
1263 return NULL;
1264
1265 fargs.req = dma_spec->args[0];
1266 fargs.src = dma_spec->args[1];
1267 fargs.dst = dma_spec->args[2];
1268
1269 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
1270 fargs.src >= dw->nr_masters ||
1271 fargs.dst >= dw->nr_masters))
1272 return NULL;
1273
1274 dma_cap_zero(cap);
1275 dma_cap_set(DMA_SLAVE, cap);
1276
1277 /* TODO: there should be a simpler way to do this */
1278 return dma_request_channel(cap, dw_dma_of_filter, &fargs);
1279}
1280
1281#ifdef CONFIG_ACPI
1282static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
1283{
1284 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
1285 struct acpi_dma_spec *dma_spec = param;
1286
1287 if (chan->device->dev != dma_spec->dev ||
1288 chan->chan_id != dma_spec->chan_id)
1289 return false;
1290
1291 dwc->request_line = dma_spec->slave_id;
1292 dwc->src_master = dwc_get_sms(NULL);
1293 dwc->dst_master = dwc_get_dms(NULL);
1294
1295 return true;
1296}
1297
1298static void dw_dma_acpi_controller_register(struct dw_dma *dw)
1299{
1300 struct device *dev = dw->dma.dev;
1301 struct acpi_dma_filter_info *info;
1302 int ret;
1303
1304 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
1305 if (!info)
1306 return;
1307
1308 dma_cap_zero(info->dma_cap);
1309 dma_cap_set(DMA_SLAVE, info->dma_cap);
1310 info->filter_fn = dw_dma_acpi_filter;
1311
1312 ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
1313 info);
1314 if (ret)
1315 dev_err(dev, "could not register acpi_dma_controller\n");
1316}
1317#else /* !CONFIG_ACPI */
1318static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
1319#endif /* !CONFIG_ACPI */
1320
1321/* --------------------- Cyclic DMA API extensions -------------------- */ 1214/* --------------------- Cyclic DMA API extensions -------------------- */
1322 1215
1323/** 1216/**
@@ -1598,101 +1491,24 @@ static void dw_dma_off(struct dw_dma *dw)
1598 dw->chan[i].initialized = false; 1491 dw->chan[i].initialized = false;
1599} 1492}
1600 1493
1601#ifdef CONFIG_OF 1494int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
1602static struct dw_dma_platform_data *
1603dw_dma_parse_dt(struct platform_device *pdev)
1604{
1605 struct device_node *np = pdev->dev.of_node;
1606 struct dw_dma_platform_data *pdata;
1607 u32 tmp, arr[4];
1608
1609 if (!np) {
1610 dev_err(&pdev->dev, "Missing DT data\n");
1611 return NULL;
1612 }
1613
1614 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
1615 if (!pdata)
1616 return NULL;
1617
1618 if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
1619 return NULL;
1620
1621 if (of_property_read_bool(np, "is_private"))
1622 pdata->is_private = true;
1623
1624 if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
1625 pdata->chan_allocation_order = (unsigned char)tmp;
1626
1627 if (!of_property_read_u32(np, "chan_priority", &tmp))
1628 pdata->chan_priority = tmp;
1629
1630 if (!of_property_read_u32(np, "block_size", &tmp))
1631 pdata->block_size = tmp;
1632
1633 if (!of_property_read_u32(np, "dma-masters", &tmp)) {
1634 if (tmp > 4)
1635 return NULL;
1636
1637 pdata->nr_masters = tmp;
1638 }
1639
1640 if (!of_property_read_u32_array(np, "data_width", arr,
1641 pdata->nr_masters))
1642 for (tmp = 0; tmp < pdata->nr_masters; tmp++)
1643 pdata->data_width[tmp] = arr[tmp];
1644
1645 return pdata;
1646}
1647#else
1648static inline struct dw_dma_platform_data *
1649dw_dma_parse_dt(struct platform_device *pdev)
1650{ 1495{
1651 return NULL;
1652}
1653#endif
1654
1655static int dw_probe(struct platform_device *pdev)
1656{
1657 struct dw_dma_platform_data *pdata;
1658 struct resource *io;
1659 struct dw_dma *dw; 1496 struct dw_dma *dw;
1660 size_t size; 1497 size_t size;
1661 void __iomem *regs;
1662 bool autocfg; 1498 bool autocfg;
1663 unsigned int dw_params; 1499 unsigned int dw_params;
1664 unsigned int nr_channels; 1500 unsigned int nr_channels;
1665 unsigned int max_blk_size = 0; 1501 unsigned int max_blk_size = 0;
1666 int irq;
1667 int err; 1502 int err;
1668 int i; 1503 int i;
1669 1504
1670 irq = platform_get_irq(pdev, 0); 1505 dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
1671 if (irq < 0)
1672 return irq;
1673
1674 io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1675 regs = devm_ioremap_resource(&pdev->dev, io);
1676 if (IS_ERR(regs))
1677 return PTR_ERR(regs);
1678
1679 /* Apply default dma_mask if needed */
1680 if (!pdev->dev.dma_mask) {
1681 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
1682 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
1683 }
1684
1685 dw_params = dma_read_byaddr(regs, DW_PARAMS);
1686 autocfg = dw_params >> DW_PARAMS_EN & 0x1; 1506 autocfg = dw_params >> DW_PARAMS_EN & 0x1;
1687 1507
1688 dev_dbg(&pdev->dev, "DW_PARAMS: 0x%08x\n", dw_params); 1508 dev_dbg(chip->dev, "DW_PARAMS: 0x%08x\n", dw_params);
1689
1690 pdata = dev_get_platdata(&pdev->dev);
1691 if (!pdata)
1692 pdata = dw_dma_parse_dt(pdev);
1693 1509
1694 if (!pdata && autocfg) { 1510 if (!pdata && autocfg) {
1695 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 1511 pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL);
1696 if (!pdata) 1512 if (!pdata)
1697 return -ENOMEM; 1513 return -ENOMEM;
1698 1514
@@ -1709,16 +1525,17 @@ static int dw_probe(struct platform_device *pdev)
1709 nr_channels = pdata->nr_channels; 1525 nr_channels = pdata->nr_channels;
1710 1526
1711 size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan); 1527 size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
1712 dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); 1528 dw = devm_kzalloc(chip->dev, size, GFP_KERNEL);
1713 if (!dw) 1529 if (!dw)
1714 return -ENOMEM; 1530 return -ENOMEM;
1715 1531
1716 dw->clk = devm_clk_get(&pdev->dev, "hclk"); 1532 dw->clk = devm_clk_get(chip->dev, "hclk");
1717 if (IS_ERR(dw->clk)) 1533 if (IS_ERR(dw->clk))
1718 return PTR_ERR(dw->clk); 1534 return PTR_ERR(dw->clk);
1719 clk_prepare_enable(dw->clk); 1535 clk_prepare_enable(dw->clk);
1720 1536
1721 dw->regs = regs; 1537 dw->regs = chip->regs;
1538 chip->dw = dw;
1722 1539
1723 /* Get hardware configuration parameters */ 1540 /* Get hardware configuration parameters */
1724 if (autocfg) { 1541 if (autocfg) {
@@ -1743,18 +1560,16 @@ static int dw_probe(struct platform_device *pdev)
1743 /* Disable BLOCK interrupts as well */ 1560 /* Disable BLOCK interrupts as well */
1744 channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); 1561 channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
1745 1562
1746 err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0, 1563 err = devm_request_irq(chip->dev, chip->irq, dw_dma_interrupt, 0,
1747 "dw_dmac", dw); 1564 "dw_dmac", dw);
1748 if (err) 1565 if (err)
1749 return err; 1566 return err;
1750 1567
1751 platform_set_drvdata(pdev, dw);
1752
1753 /* Create a pool of consistent memory blocks for hardware descriptors */ 1568 /* Create a pool of consistent memory blocks for hardware descriptors */
1754 dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev, 1569 dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev,
1755 sizeof(struct dw_desc), 4, 0); 1570 sizeof(struct dw_desc), 4, 0);
1756 if (!dw->desc_pool) { 1571 if (!dw->desc_pool) {
1757 dev_err(&pdev->dev, "No memory for descriptors dma pool\n"); 1572 dev_err(chip->dev, "No memory for descriptors dma pool\n");
1758 return -ENOMEM; 1573 return -ENOMEM;
1759 } 1574 }
1760 1575
@@ -1795,12 +1610,12 @@ static int dw_probe(struct platform_device *pdev)
1795 /* Hardware configuration */ 1610 /* Hardware configuration */
1796 if (autocfg) { 1611 if (autocfg) {
1797 unsigned int dwc_params; 1612 unsigned int dwc_params;
1613 void __iomem *addr = chip->regs + r * sizeof(u32);
1798 1614
1799 dwc_params = dma_read_byaddr(regs + r * sizeof(u32), 1615 dwc_params = dma_read_byaddr(addr, DWC_PARAMS);
1800 DWC_PARAMS);
1801 1616
1802 dev_dbg(&pdev->dev, "DWC_PARAMS[%d]: 0x%08x\n", i, 1617 dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
1803 dwc_params); 1618 dwc_params);
1804 1619
1805 /* Decode maximum block size for given channel. The 1620 /* Decode maximum block size for given channel. The
1806 * stored 4 bit value represents blocks from 0x00 for 3 1621 * stored 4 bit value represents blocks from 0x00 for 3
@@ -1831,7 +1646,7 @@ static int dw_probe(struct platform_device *pdev)
1831 dma_cap_set(DMA_SLAVE, dw->dma.cap_mask); 1646 dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
1832 if (pdata->is_private) 1647 if (pdata->is_private)
1833 dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask); 1648 dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
1834 dw->dma.dev = &pdev->dev; 1649 dw->dma.dev = chip->dev;
1835 dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources; 1650 dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
1836 dw->dma.device_free_chan_resources = dwc_free_chan_resources; 1651 dw->dma.device_free_chan_resources = dwc_free_chan_resources;
1837 1652
@@ -1845,32 +1660,20 @@ static int dw_probe(struct platform_device *pdev)
1845 1660
1846 dma_writel(dw, CFG, DW_CFG_DMA_EN); 1661 dma_writel(dw, CFG, DW_CFG_DMA_EN);
1847 1662
1848 dev_info(&pdev->dev, "DesignWare DMA Controller, %d channels\n", 1663 dev_info(chip->dev, "DesignWare DMA Controller, %d channels\n",
1849 nr_channels); 1664 nr_channels);
1850 1665
1851 dma_async_device_register(&dw->dma); 1666 dma_async_device_register(&dw->dma);
1852 1667
1853 if (pdev->dev.of_node) {
1854 err = of_dma_controller_register(pdev->dev.of_node,
1855 dw_dma_of_xlate, dw);
1856 if (err)
1857 dev_err(&pdev->dev,
1858 "could not register of_dma_controller\n");
1859 }
1860
1861 if (ACPI_HANDLE(&pdev->dev))
1862 dw_dma_acpi_controller_register(dw);
1863
1864 return 0; 1668 return 0;
1865} 1669}
1670EXPORT_SYMBOL_GPL(dw_dma_probe);
1866 1671
1867static int dw_remove(struct platform_device *pdev) 1672int dw_dma_remove(struct dw_dma_chip *chip)
1868{ 1673{
1869 struct dw_dma *dw = platform_get_drvdata(pdev); 1674 struct dw_dma *dw = chip->dw;
1870 struct dw_dma_chan *dwc, *_dwc; 1675 struct dw_dma_chan *dwc, *_dwc;
1871 1676
1872 if (pdev->dev.of_node)
1873 of_dma_controller_free(pdev->dev.of_node);
1874 dw_dma_off(dw); 1677 dw_dma_off(dw);
1875 dma_async_device_unregister(&dw->dma); 1678 dma_async_device_unregister(&dw->dma);
1876 1679
@@ -1884,86 +1687,44 @@ static int dw_remove(struct platform_device *pdev)
1884 1687
1885 return 0; 1688 return 0;
1886} 1689}
1690EXPORT_SYMBOL_GPL(dw_dma_remove);
1887 1691
1888static void dw_shutdown(struct platform_device *pdev) 1692void dw_dma_shutdown(struct dw_dma_chip *chip)
1889{ 1693{
1890 struct dw_dma *dw = platform_get_drvdata(pdev); 1694 struct dw_dma *dw = chip->dw;
1891 1695
1892 dw_dma_off(dw); 1696 dw_dma_off(dw);
1893 clk_disable_unprepare(dw->clk); 1697 clk_disable_unprepare(dw->clk);
1894} 1698}
1699EXPORT_SYMBOL_GPL(dw_dma_shutdown);
1895 1700
1896static int dw_suspend_noirq(struct device *dev) 1701#ifdef CONFIG_PM_SLEEP
1702
1703int dw_dma_suspend(struct dw_dma_chip *chip)
1897{ 1704{
1898 struct platform_device *pdev = to_platform_device(dev); 1705 struct dw_dma *dw = chip->dw;
1899 struct dw_dma *dw = platform_get_drvdata(pdev);
1900 1706
1901 dw_dma_off(dw); 1707 dw_dma_off(dw);
1902 clk_disable_unprepare(dw->clk); 1708 clk_disable_unprepare(dw->clk);
1903 1709
1904 return 0; 1710 return 0;
1905} 1711}
1712EXPORT_SYMBOL_GPL(dw_dma_suspend);
1906 1713
1907static int dw_resume_noirq(struct device *dev) 1714int dw_dma_resume(struct dw_dma_chip *chip)
1908{ 1715{
1909 struct platform_device *pdev = to_platform_device(dev); 1716 struct dw_dma *dw = chip->dw;
1910 struct dw_dma *dw = platform_get_drvdata(pdev);
1911 1717
1912 clk_prepare_enable(dw->clk); 1718 clk_prepare_enable(dw->clk);
1913 dma_writel(dw, CFG, DW_CFG_DMA_EN); 1719 dma_writel(dw, CFG, DW_CFG_DMA_EN);
1914 1720
1915 return 0; 1721 return 0;
1916} 1722}
1723EXPORT_SYMBOL_GPL(dw_dma_resume);
1917 1724
1918static const struct dev_pm_ops dw_dev_pm_ops = { 1725#endif /* CONFIG_PM_SLEEP */
1919 .suspend_noirq = dw_suspend_noirq,
1920 .resume_noirq = dw_resume_noirq,
1921 .freeze_noirq = dw_suspend_noirq,
1922 .thaw_noirq = dw_resume_noirq,
1923 .restore_noirq = dw_resume_noirq,
1924 .poweroff_noirq = dw_suspend_noirq,
1925};
1926
1927#ifdef CONFIG_OF
1928static const struct of_device_id dw_dma_of_id_table[] = {
1929 { .compatible = "snps,dma-spear1340" },
1930 {}
1931};
1932MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
1933#endif
1934
1935#ifdef CONFIG_ACPI
1936static const struct acpi_device_id dw_dma_acpi_id_table[] = {
1937 { "INTL9C60", 0 },
1938 { }
1939};
1940#endif
1941
1942static struct platform_driver dw_driver = {
1943 .probe = dw_probe,
1944 .remove = dw_remove,
1945 .shutdown = dw_shutdown,
1946 .driver = {
1947 .name = "dw_dmac",
1948 .pm = &dw_dev_pm_ops,
1949 .of_match_table = of_match_ptr(dw_dma_of_id_table),
1950 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
1951 },
1952};
1953
1954static int __init dw_init(void)
1955{
1956 return platform_driver_register(&dw_driver);
1957}
1958subsys_initcall(dw_init);
1959
1960static void __exit dw_exit(void)
1961{
1962 platform_driver_unregister(&dw_driver);
1963}
1964module_exit(dw_exit);
1965 1726
1966MODULE_LICENSE("GPL v2"); 1727MODULE_LICENSE("GPL v2");
1967MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); 1728MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller core driver");
1968MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); 1729MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
1969MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); 1730MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h
new file mode 100644
index 000000000000..32667f9e0dda
--- /dev/null
+++ b/drivers/dma/dw/internal.h
@@ -0,0 +1,70 @@
1/*
2 * Driver for the Synopsys DesignWare DMA Controller
3 *
4 * Copyright (C) 2013 Intel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _DW_DMAC_INTERNAL_H
12#define _DW_DMAC_INTERNAL_H
13
14#include <linux/device.h>
15#include <linux/dw_dmac.h>
16
17#include "regs.h"
18
19/**
20 * struct dw_dma_chip - representation of DesignWare DMA controller hardware
21 * @dev: struct device of the DMA controller
22 * @irq: irq line
23 * @regs: memory mapped I/O space
24 * @dw: struct dw_dma that is filed by dw_dma_probe()
25 */
26struct dw_dma_chip {
27 struct device *dev;
28 int irq;
29 void __iomem *regs;
30 struct dw_dma *dw;
31};
32
33/* Export to the platform drivers */
34int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata);
35int dw_dma_remove(struct dw_dma_chip *chip);
36
37void dw_dma_shutdown(struct dw_dma_chip *chip);
38
39#ifdef CONFIG_PM_SLEEP
40
41int dw_dma_suspend(struct dw_dma_chip *chip);
42int dw_dma_resume(struct dw_dma_chip *chip);
43
44#endif /* CONFIG_PM_SLEEP */
45
46/**
47 * dwc_get_dms - get destination master
48 * @slave: pointer to the custom slave configuration
49 *
50 * Returns destination master in the custom slave configuration if defined, or
51 * default value otherwise.
52 */
53static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
54{
55 return slave ? slave->dst_master : 0;
56}
57
58/**
59 * dwc_get_sms - get source master
60 * @slave: pointer to the custom slave configuration
61 *
62 * Returns source master in the custom slave configuration if defined, or
63 * default value otherwise.
64 */
65static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
66{
67 return slave ? slave->src_master : 1;
68}
69
70#endif /* _DW_DMAC_INTERNAL_H */
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c
new file mode 100644
index 000000000000..6c9449cffae8
--- /dev/null
+++ b/drivers/dma/dw/platform.c
@@ -0,0 +1,317 @@
1/*
2 * Platform driver for the Synopsys DesignWare DMA Controller
3 *
4 * Copyright (C) 2007-2008 Atmel Corporation
5 * Copyright (C) 2010-2011 ST Microelectronics
6 * Copyright (C) 2013 Intel Corporation
7 *
8 * Some parts of this driver are derived from the original dw_dmac.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/clk.h>
18#include <linux/platform_device.h>
19#include <linux/dmaengine.h>
20#include <linux/dma-mapping.h>
21#include <linux/of.h>
22#include <linux/of_dma.h>
23#include <linux/acpi.h>
24#include <linux/acpi_dma.h>
25
26#include "internal.h"
27
28struct dw_dma_of_filter_args {
29 struct dw_dma *dw;
30 unsigned int req;
31 unsigned int src;
32 unsigned int dst;
33};
34
35static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
36{
37 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
38 struct dw_dma_of_filter_args *fargs = param;
39
40 /* Ensure the device matches our channel */
41 if (chan->device != &fargs->dw->dma)
42 return false;
43
44 dwc->request_line = fargs->req;
45 dwc->src_master = fargs->src;
46 dwc->dst_master = fargs->dst;
47
48 return true;
49}
50
51static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
52 struct of_dma *ofdma)
53{
54 struct dw_dma *dw = ofdma->of_dma_data;
55 struct dw_dma_of_filter_args fargs = {
56 .dw = dw,
57 };
58 dma_cap_mask_t cap;
59
60 if (dma_spec->args_count != 3)
61 return NULL;
62
63 fargs.req = dma_spec->args[0];
64 fargs.src = dma_spec->args[1];
65 fargs.dst = dma_spec->args[2];
66
67 if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
68 fargs.src >= dw->nr_masters ||
69 fargs.dst >= dw->nr_masters))
70 return NULL;
71
72 dma_cap_zero(cap);
73 dma_cap_set(DMA_SLAVE, cap);
74
75 /* TODO: there should be a simpler way to do this */
76 return dma_request_channel(cap, dw_dma_of_filter, &fargs);
77}
78
79#ifdef CONFIG_ACPI
80static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
81{
82 struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
83 struct acpi_dma_spec *dma_spec = param;
84
85 if (chan->device->dev != dma_spec->dev ||
86 chan->chan_id != dma_spec->chan_id)
87 return false;
88
89 dwc->request_line = dma_spec->slave_id;
90 dwc->src_master = dwc_get_sms(NULL);
91 dwc->dst_master = dwc_get_dms(NULL);
92
93 return true;
94}
95
96static void dw_dma_acpi_controller_register(struct dw_dma *dw)
97{
98 struct device *dev = dw->dma.dev;
99 struct acpi_dma_filter_info *info;
100 int ret;
101
102 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
103 if (!info)
104 return;
105
106 dma_cap_zero(info->dma_cap);
107 dma_cap_set(DMA_SLAVE, info->dma_cap);
108 info->filter_fn = dw_dma_acpi_filter;
109
110 ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
111 info);
112 if (ret)
113 dev_err(dev, "could not register acpi_dma_controller\n");
114}
115#else /* !CONFIG_ACPI */
116static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
117#endif /* !CONFIG_ACPI */
118
119#ifdef CONFIG_OF
120static struct dw_dma_platform_data *
121dw_dma_parse_dt(struct platform_device *pdev)
122{
123 struct device_node *np = pdev->dev.of_node;
124 struct dw_dma_platform_data *pdata;
125 u32 tmp, arr[4];
126
127 if (!np) {
128 dev_err(&pdev->dev, "Missing DT data\n");
129 return NULL;
130 }
131
132 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
133 if (!pdata)
134 return NULL;
135
136 if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
137 return NULL;
138
139 if (of_property_read_bool(np, "is_private"))
140 pdata->is_private = true;
141
142 if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
143 pdata->chan_allocation_order = (unsigned char)tmp;
144
145 if (!of_property_read_u32(np, "chan_priority", &tmp))
146 pdata->chan_priority = tmp;
147
148 if (!of_property_read_u32(np, "block_size", &tmp))
149 pdata->block_size = tmp;
150
151 if (!of_property_read_u32(np, "dma-masters", &tmp)) {
152 if (tmp > 4)
153 return NULL;
154
155 pdata->nr_masters = tmp;
156 }
157
158 if (!of_property_read_u32_array(np, "data_width", arr,
159 pdata->nr_masters))
160 for (tmp = 0; tmp < pdata->nr_masters; tmp++)
161 pdata->data_width[tmp] = arr[tmp];
162
163 return pdata;
164}
165#else
166static inline struct dw_dma_platform_data *
167dw_dma_parse_dt(struct platform_device *pdev)
168{
169 return NULL;
170}
171#endif
172
173static int dw_probe(struct platform_device *pdev)
174{
175 struct dw_dma_chip *chip;
176 struct device *dev = &pdev->dev;
177 struct resource *mem;
178 struct dw_dma_platform_data *pdata;
179 int err;
180
181 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
182 if (!chip)
183 return -ENOMEM;
184
185 chip->irq = platform_get_irq(pdev, 0);
186 if (chip->irq < 0)
187 return chip->irq;
188
189 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
190 chip->regs = devm_ioremap_resource(dev, mem);
191 if (IS_ERR(chip->regs))
192 return PTR_ERR(chip->regs);
193
194 /* Apply default dma_mask if needed */
195 if (!dev->dma_mask) {
196 dev->dma_mask = &dev->coherent_dma_mask;
197 dev->coherent_dma_mask = DMA_BIT_MASK(32);
198 }
199
200 pdata = dev_get_platdata(dev);
201 if (!pdata)
202 pdata = dw_dma_parse_dt(pdev);
203
204 chip->dev = dev;
205
206 err = dw_dma_probe(chip, pdata);
207 if (err)
208 return err;
209
210 platform_set_drvdata(pdev, chip);
211
212 if (pdev->dev.of_node) {
213 err = of_dma_controller_register(pdev->dev.of_node,
214 dw_dma_of_xlate, chip->dw);
215 if (err)
216 dev_err(&pdev->dev,
217 "could not register of_dma_controller\n");
218 }
219
220 if (ACPI_HANDLE(&pdev->dev))
221 dw_dma_acpi_controller_register(chip->dw);
222
223 return 0;
224}
225
226static int dw_remove(struct platform_device *pdev)
227{
228 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
229
230 if (pdev->dev.of_node)
231 of_dma_controller_free(pdev->dev.of_node);
232
233 return dw_dma_remove(chip);
234}
235
236static void dw_shutdown(struct platform_device *pdev)
237{
238 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
239
240 dw_dma_shutdown(chip);
241}
242
243#ifdef CONFIG_OF
244static const struct of_device_id dw_dma_of_id_table[] = {
245 { .compatible = "snps,dma-spear1340" },
246 {}
247};
248MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
249#endif
250
251#ifdef CONFIG_ACPI
252static const struct acpi_device_id dw_dma_acpi_id_table[] = {
253 { "INTL9C60", 0 },
254 { }
255};
256#endif
257
258#ifdef CONFIG_PM_SLEEP
259
260static int dw_suspend_noirq(struct device *dev)
261{
262 struct platform_device *pdev = to_platform_device(dev);
263 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
264
265 return dw_dma_suspend(chip);
266}
267
268static int dw_resume_noirq(struct device *dev)
269{
270 struct platform_device *pdev = to_platform_device(dev);
271 struct dw_dma_chip *chip = platform_get_drvdata(pdev);
272
273 return dw_dma_resume(chip);
274}
275
276#else /* !CONFIG_PM_SLEEP */
277
278#define dw_suspend_noirq NULL
279#define dw_resume_noirq NULL
280
281#endif /* !CONFIG_PM_SLEEP */
282
283static const struct dev_pm_ops dw_dev_pm_ops = {
284 .suspend_noirq = dw_suspend_noirq,
285 .resume_noirq = dw_resume_noirq,
286 .freeze_noirq = dw_suspend_noirq,
287 .thaw_noirq = dw_resume_noirq,
288 .restore_noirq = dw_resume_noirq,
289 .poweroff_noirq = dw_suspend_noirq,
290};
291
292static struct platform_driver dw_driver = {
293 .probe = dw_probe,
294 .remove = dw_remove,
295 .shutdown = dw_shutdown,
296 .driver = {
297 .name = "dw_dmac",
298 .pm = &dw_dev_pm_ops,
299 .of_match_table = of_match_ptr(dw_dma_of_id_table),
300 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
301 },
302};
303
304static int __init dw_init(void)
305{
306 return platform_driver_register(&dw_driver);
307}
308subsys_initcall(dw_init);
309
310static void __exit dw_exit(void)
311{
312 platform_driver_unregister(&dw_driver);
313}
314module_exit(dw_exit);
315
316MODULE_LICENSE("GPL v2");
317MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");
diff --git a/drivers/dma/dw/dw_dmac_regs.h b/drivers/dma/dw/regs.h
index 9d417200bd57..07c5a6ecb52b 100644
--- a/drivers/dma/dw/dw_dmac_regs.h
+++ b/drivers/dma/dw/regs.h
@@ -9,6 +9,7 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/interrupt.h>
12#include <linux/dmaengine.h> 13#include <linux/dmaengine.h>
13#include <linux/dw_dmac.h> 14#include <linux/dw_dmac.h>
14 15