aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dw
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2013-06-05 08:26:45 -0400
committerVinod Koul <vinod.koul@intel.com>2013-07-05 02:10:44 -0400
commit9cade1a46c77dfc96d57a3ea6354e95b2a7fcf61 (patch)
tree52340617645937017301473d5333abb47c4b33cd /drivers/dma/dw
parent61a7649620d54a037c612f9a713abe5178cddc65 (diff)
dma: dw: split driver to library part and platform code
To simplify the driver development let's split driver to library and platform code parts. It helps us to add PCI driver in future. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> [Fixed compile error and few checkpatch issues] Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/dw')
-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
6 files changed, 435 insertions, 278 deletions
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