diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2013-04-09 07:05:46 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-04-15 12:34:19 -0400 |
commit | 42c91ee71d6dfa074b4c79abb95eb095430f83af (patch) | |
tree | 0dd3d1510d1646c8190f7bec45075aba18410db5 /drivers/dma | |
parent | 4e82f5ddd1e46fadc3a3c5aafdaec2d1416de9fe (diff) |
dw_dmac: add ACPI support
Since we have proper ACPI DMA helpers implemented, the driver may use it. This
patch introduces custom filter function together with acpi_device_id table.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/dw_dmac.c | 68 | ||||
-rw-r--r-- | drivers/dma/dw_dmac_regs.h | 1 |
2 files changed, 50 insertions, 19 deletions
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index e33dc3bdbdba..2e5deaa82b60 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/acpi.h> | ||
29 | #include <linux/acpi_dma.h> | ||
28 | 30 | ||
29 | #include "dw_dmac_regs.h" | 31 | #include "dw_dmac_regs.h" |
30 | #include "dmaengine.h" | 32 | #include "dmaengine.h" |
@@ -983,13 +985,6 @@ static inline void convert_burst(u32 *maxburst) | |||
983 | *maxburst = 0; | 985 | *maxburst = 0; |
984 | } | 986 | } |
985 | 987 | ||
986 | static inline void convert_slave_id(struct dw_dma_chan *dwc) | ||
987 | { | ||
988 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | ||
989 | |||
990 | dwc->dma_sconfig.slave_id -= dw->request_line_base; | ||
991 | } | ||
992 | |||
993 | static int | 988 | static int |
994 | set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) | 989 | set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) |
995 | { | 990 | { |
@@ -1008,7 +1003,6 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) | |||
1008 | 1003 | ||
1009 | convert_burst(&dwc->dma_sconfig.src_maxburst); | 1004 | convert_burst(&dwc->dma_sconfig.src_maxburst); |
1010 | convert_burst(&dwc->dma_sconfig.dst_maxburst); | 1005 | convert_burst(&dwc->dma_sconfig.dst_maxburst); |
1011 | convert_slave_id(dwc); | ||
1012 | 1006 | ||
1013 | return 0; | 1007 | return 0; |
1014 | } | 1008 | } |
@@ -1284,6 +1278,46 @@ static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, | |||
1284 | return dma_request_channel(cap, dw_dma_of_filter, &fargs); | 1278 | return dma_request_channel(cap, dw_dma_of_filter, &fargs); |
1285 | } | 1279 | } |
1286 | 1280 | ||
1281 | #ifdef CONFIG_ACPI | ||
1282 | static 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 | |||
1298 | static 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 */ | ||
1318 | static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {} | ||
1319 | #endif /* !CONFIG_ACPI */ | ||
1320 | |||
1287 | /* --------------------- Cyclic DMA API extensions -------------------- */ | 1321 | /* --------------------- Cyclic DMA API extensions -------------------- */ |
1288 | 1322 | ||
1289 | /** | 1323 | /** |
@@ -1620,7 +1654,6 @@ dw_dma_parse_dt(struct platform_device *pdev) | |||
1620 | 1654 | ||
1621 | static int dw_probe(struct platform_device *pdev) | 1655 | static int dw_probe(struct platform_device *pdev) |
1622 | { | 1656 | { |
1623 | const struct platform_device_id *match; | ||
1624 | struct dw_dma_platform_data *pdata; | 1657 | struct dw_dma_platform_data *pdata; |
1625 | struct resource *io; | 1658 | struct resource *io; |
1626 | struct dw_dma *dw; | 1659 | struct dw_dma *dw; |
@@ -1704,11 +1737,6 @@ static int dw_probe(struct platform_device *pdev) | |||
1704 | memcpy(dw->data_width, pdata->data_width, 4); | 1737 | memcpy(dw->data_width, pdata->data_width, 4); |
1705 | } | 1738 | } |
1706 | 1739 | ||
1707 | /* Get the base request line if set */ | ||
1708 | match = platform_get_device_id(pdev); | ||
1709 | if (match) | ||
1710 | dw->request_line_base = (unsigned int)match->driver_data; | ||
1711 | |||
1712 | /* Calculate all channel mask before DMA setup */ | 1740 | /* Calculate all channel mask before DMA setup */ |
1713 | dw->all_chan_mask = (1 << nr_channels) - 1; | 1741 | dw->all_chan_mask = (1 << nr_channels) - 1; |
1714 | 1742 | ||
@@ -1833,6 +1861,9 @@ static int dw_probe(struct platform_device *pdev) | |||
1833 | "could not register of_dma_controller\n"); | 1861 | "could not register of_dma_controller\n"); |
1834 | } | 1862 | } |
1835 | 1863 | ||
1864 | if (ACPI_HANDLE(&pdev->dev)) | ||
1865 | dw_dma_acpi_controller_register(dw); | ||
1866 | |||
1836 | return 0; | 1867 | return 0; |
1837 | } | 1868 | } |
1838 | 1869 | ||
@@ -1904,11 +1935,12 @@ static const struct of_device_id dw_dma_of_id_table[] = { | |||
1904 | MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); | 1935 | MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); |
1905 | #endif | 1936 | #endif |
1906 | 1937 | ||
1907 | static const struct platform_device_id dw_dma_ids[] = { | 1938 | #ifdef CONFIG_ACPI |
1908 | /* Name, Request Line Base */ | 1939 | static const struct acpi_device_id dw_dma_acpi_id_table[] = { |
1909 | { "INTL9C60", (kernel_ulong_t)16 }, | 1940 | { "INTL9C60", 0 }, |
1910 | { } | 1941 | { } |
1911 | }; | 1942 | }; |
1943 | #endif | ||
1912 | 1944 | ||
1913 | static struct platform_driver dw_driver = { | 1945 | static struct platform_driver dw_driver = { |
1914 | .probe = dw_probe, | 1946 | .probe = dw_probe, |
@@ -1918,8 +1950,8 @@ static struct platform_driver dw_driver = { | |||
1918 | .name = "dw_dmac", | 1950 | .name = "dw_dmac", |
1919 | .pm = &dw_dev_pm_ops, | 1951 | .pm = &dw_dev_pm_ops, |
1920 | .of_match_table = of_match_ptr(dw_dma_of_id_table), | 1952 | .of_match_table = of_match_ptr(dw_dma_of_id_table), |
1953 | .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), | ||
1921 | }, | 1954 | }, |
1922 | .id_table = dw_dma_ids, | ||
1923 | }; | 1955 | }; |
1924 | 1956 | ||
1925 | static int __init dw_init(void) | 1957 | static int __init dw_init(void) |
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h index 9b0e12e85e31..9d417200bd57 100644 --- a/drivers/dma/dw_dmac_regs.h +++ b/drivers/dma/dw_dmac_regs.h | |||
@@ -250,7 +250,6 @@ struct dw_dma { | |||
250 | /* hardware configuration */ | 250 | /* hardware configuration */ |
251 | unsigned char nr_masters; | 251 | unsigned char nr_masters; |
252 | unsigned char data_width[4]; | 252 | unsigned char data_width[4]; |
253 | unsigned int request_line_base; | ||
254 | 253 | ||
255 | struct dw_dma_chan chan[0]; | 254 | struct dw_dma_chan chan[0]; |
256 | }; | 255 | }; |