diff options
Diffstat (limited to 'drivers/dma/dw_dmac.c')
-rw-r--r-- | drivers/dma/dw_dmac.c | 203 |
1 files changed, 110 insertions, 93 deletions
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 43a5329d4483..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" |
@@ -49,29 +51,22 @@ static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave) | |||
49 | return slave ? slave->src_master : 1; | 51 | return slave ? slave->src_master : 1; |
50 | } | 52 | } |
51 | 53 | ||
52 | #define SRC_MASTER 0 | 54 | static inline void dwc_set_masters(struct dw_dma_chan *dwc) |
53 | #define DST_MASTER 1 | ||
54 | |||
55 | static inline unsigned int dwc_get_master(struct dma_chan *chan, int master) | ||
56 | { | 55 | { |
57 | struct dw_dma *dw = to_dw_dma(chan->device); | 56 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); |
58 | struct dw_dma_slave *dws = chan->private; | 57 | struct dw_dma_slave *dws = dwc->chan.private; |
59 | unsigned int m; | 58 | unsigned char mmax = dw->nr_masters - 1; |
60 | |||
61 | if (master == SRC_MASTER) | ||
62 | m = dwc_get_sms(dws); | ||
63 | else | ||
64 | m = dwc_get_dms(dws); | ||
65 | 59 | ||
66 | return min_t(unsigned int, dw->nr_masters - 1, m); | 60 | if (dwc->request_line == ~0) { |
61 | dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws)); | ||
62 | dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws)); | ||
63 | } | ||
67 | } | 64 | } |
68 | 65 | ||
69 | #define DWC_DEFAULT_CTLLO(_chan) ({ \ | 66 | #define DWC_DEFAULT_CTLLO(_chan) ({ \ |
70 | struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \ | 67 | struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \ |
71 | struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ | 68 | struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \ |
72 | bool _is_slave = is_slave_direction(_dwc->direction); \ | 69 | bool _is_slave = is_slave_direction(_dwc->direction); \ |
73 | int _dms = dwc_get_master(_chan, DST_MASTER); \ | ||
74 | int _sms = dwc_get_master(_chan, SRC_MASTER); \ | ||
75 | u8 _smsize = _is_slave ? _sconfig->src_maxburst : \ | 70 | u8 _smsize = _is_slave ? _sconfig->src_maxburst : \ |
76 | DW_DMA_MSIZE_16; \ | 71 | DW_DMA_MSIZE_16; \ |
77 | u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \ | 72 | u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \ |
@@ -81,8 +76,8 @@ static inline unsigned int dwc_get_master(struct dma_chan *chan, int master) | |||
81 | | DWC_CTLL_SRC_MSIZE(_smsize) \ | 76 | | DWC_CTLL_SRC_MSIZE(_smsize) \ |
82 | | DWC_CTLL_LLP_D_EN \ | 77 | | DWC_CTLL_LLP_D_EN \ |
83 | | DWC_CTLL_LLP_S_EN \ | 78 | | DWC_CTLL_LLP_S_EN \ |
84 | | DWC_CTLL_DMS(_dms) \ | 79 | | DWC_CTLL_DMS(_dwc->dst_master) \ |
85 | | DWC_CTLL_SMS(_sms)); \ | 80 | | DWC_CTLL_SMS(_dwc->src_master)); \ |
86 | }) | 81 | }) |
87 | 82 | ||
88 | /* | 83 | /* |
@@ -92,13 +87,6 @@ static inline unsigned int dwc_get_master(struct dma_chan *chan, int master) | |||
92 | */ | 87 | */ |
93 | #define NR_DESCS_PER_CHANNEL 64 | 88 | #define NR_DESCS_PER_CHANNEL 64 |
94 | 89 | ||
95 | static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master) | ||
96 | { | ||
97 | struct dw_dma *dw = to_dw_dma(chan->device); | ||
98 | |||
99 | return dw->data_width[dwc_get_master(chan, master)]; | ||
100 | } | ||
101 | |||
102 | /*----------------------------------------------------------------------*/ | 90 | /*----------------------------------------------------------------------*/ |
103 | 91 | ||
104 | static struct device *chan2dev(struct dma_chan *chan) | 92 | static struct device *chan2dev(struct dma_chan *chan) |
@@ -172,13 +160,7 @@ static void dwc_initialize(struct dw_dma_chan *dwc) | |||
172 | if (dwc->initialized == true) | 160 | if (dwc->initialized == true) |
173 | return; | 161 | return; |
174 | 162 | ||
175 | if (dws && dws->cfg_hi == ~0 && dws->cfg_lo == ~0) { | 163 | if (dws) { |
176 | /* autoconfigure based on request line from DT */ | ||
177 | if (dwc->direction == DMA_MEM_TO_DEV) | ||
178 | cfghi = DWC_CFGH_DST_PER(dwc->request_line); | ||
179 | else if (dwc->direction == DMA_DEV_TO_MEM) | ||
180 | cfghi = DWC_CFGH_SRC_PER(dwc->request_line); | ||
181 | } else if (dws) { | ||
182 | /* | 164 | /* |
183 | * We need controller-specific data to set up slave | 165 | * We need controller-specific data to set up slave |
184 | * transfers. | 166 | * transfers. |
@@ -189,9 +171,9 @@ static void dwc_initialize(struct dw_dma_chan *dwc) | |||
189 | cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK; | 171 | cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK; |
190 | } else { | 172 | } else { |
191 | if (dwc->direction == DMA_MEM_TO_DEV) | 173 | if (dwc->direction == DMA_MEM_TO_DEV) |
192 | cfghi = DWC_CFGH_DST_PER(dwc->dma_sconfig.slave_id); | 174 | cfghi = DWC_CFGH_DST_PER(dwc->request_line); |
193 | else if (dwc->direction == DMA_DEV_TO_MEM) | 175 | else if (dwc->direction == DMA_DEV_TO_MEM) |
194 | cfghi = DWC_CFGH_SRC_PER(dwc->dma_sconfig.slave_id); | 176 | cfghi = DWC_CFGH_SRC_PER(dwc->request_line); |
195 | } | 177 | } |
196 | 178 | ||
197 | channel_writel(dwc, CFG_LO, cfglo); | 179 | channel_writel(dwc, CFG_LO, cfglo); |
@@ -473,16 +455,16 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) | |||
473 | (unsigned long long)llp); | 455 | (unsigned long long)llp); |
474 | 456 | ||
475 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { | 457 | list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { |
476 | /* initial residue value */ | 458 | /* Initial residue value */ |
477 | dwc->residue = desc->total_len; | 459 | dwc->residue = desc->total_len; |
478 | 460 | ||
479 | /* check first descriptors addr */ | 461 | /* Check first descriptors addr */ |
480 | if (desc->txd.phys == llp) { | 462 | if (desc->txd.phys == llp) { |
481 | spin_unlock_irqrestore(&dwc->lock, flags); | 463 | spin_unlock_irqrestore(&dwc->lock, flags); |
482 | return; | 464 | return; |
483 | } | 465 | } |
484 | 466 | ||
485 | /* check first descriptors llp */ | 467 | /* Check first descriptors llp */ |
486 | if (desc->lli.llp == llp) { | 468 | if (desc->lli.llp == llp) { |
487 | /* This one is currently in progress */ | 469 | /* This one is currently in progress */ |
488 | dwc->residue -= dwc_get_sent(dwc); | 470 | dwc->residue -= dwc_get_sent(dwc); |
@@ -588,7 +570,7 @@ inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan) | |||
588 | } | 570 | } |
589 | EXPORT_SYMBOL(dw_dma_get_dst_addr); | 571 | EXPORT_SYMBOL(dw_dma_get_dst_addr); |
590 | 572 | ||
591 | /* called with dwc->lock held and all DMAC interrupts disabled */ | 573 | /* Called with dwc->lock held and all DMAC interrupts disabled */ |
592 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | 574 | static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, |
593 | u32 status_err, u32 status_xfer) | 575 | u32 status_err, u32 status_xfer) |
594 | { | 576 | { |
@@ -626,7 +608,7 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
626 | 608 | ||
627 | dwc_chan_disable(dw, dwc); | 609 | dwc_chan_disable(dw, dwc); |
628 | 610 | ||
629 | /* make sure DMA does not restart by loading a new list */ | 611 | /* Make sure DMA does not restart by loading a new list */ |
630 | channel_writel(dwc, LLP, 0); | 612 | channel_writel(dwc, LLP, 0); |
631 | channel_writel(dwc, CTL_LO, 0); | 613 | channel_writel(dwc, CTL_LO, 0); |
632 | channel_writel(dwc, CTL_HI, 0); | 614 | channel_writel(dwc, CTL_HI, 0); |
@@ -745,6 +727,7 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
745 | size_t len, unsigned long flags) | 727 | size_t len, unsigned long flags) |
746 | { | 728 | { |
747 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 729 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
730 | struct dw_dma *dw = to_dw_dma(chan->device); | ||
748 | struct dw_desc *desc; | 731 | struct dw_desc *desc; |
749 | struct dw_desc *first; | 732 | struct dw_desc *first; |
750 | struct dw_desc *prev; | 733 | struct dw_desc *prev; |
@@ -767,8 +750,8 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
767 | 750 | ||
768 | dwc->direction = DMA_MEM_TO_MEM; | 751 | dwc->direction = DMA_MEM_TO_MEM; |
769 | 752 | ||
770 | data_width = min_t(unsigned int, dwc_get_data_width(chan, SRC_MASTER), | 753 | data_width = min_t(unsigned int, dw->data_width[dwc->src_master], |
771 | dwc_get_data_width(chan, DST_MASTER)); | 754 | dw->data_width[dwc->dst_master]); |
772 | 755 | ||
773 | src_width = dst_width = min_t(unsigned int, data_width, | 756 | src_width = dst_width = min_t(unsigned int, data_width, |
774 | dwc_fast_fls(src | dest | len)); | 757 | dwc_fast_fls(src | dest | len)); |
@@ -826,6 +809,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
826 | unsigned long flags, void *context) | 809 | unsigned long flags, void *context) |
827 | { | 810 | { |
828 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 811 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
812 | struct dw_dma *dw = to_dw_dma(chan->device); | ||
829 | struct dma_slave_config *sconfig = &dwc->dma_sconfig; | 813 | struct dma_slave_config *sconfig = &dwc->dma_sconfig; |
830 | struct dw_desc *prev; | 814 | struct dw_desc *prev; |
831 | struct dw_desc *first; | 815 | struct dw_desc *first; |
@@ -859,7 +843,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
859 | ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) : | 843 | ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) : |
860 | DWC_CTLL_FC(DW_DMA_FC_D_M2P); | 844 | DWC_CTLL_FC(DW_DMA_FC_D_M2P); |
861 | 845 | ||
862 | data_width = dwc_get_data_width(chan, SRC_MASTER); | 846 | data_width = dw->data_width[dwc->src_master]; |
863 | 847 | ||
864 | for_each_sg(sgl, sg, sg_len, i) { | 848 | for_each_sg(sgl, sg, sg_len, i) { |
865 | struct dw_desc *desc; | 849 | struct dw_desc *desc; |
@@ -919,7 +903,7 @@ slave_sg_todev_fill_desc: | |||
919 | ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) : | 903 | ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) : |
920 | DWC_CTLL_FC(DW_DMA_FC_D_P2M); | 904 | DWC_CTLL_FC(DW_DMA_FC_D_P2M); |
921 | 905 | ||
922 | data_width = dwc_get_data_width(chan, DST_MASTER); | 906 | data_width = dw->data_width[dwc->dst_master]; |
923 | 907 | ||
924 | for_each_sg(sgl, sg, sg_len, i) { | 908 | for_each_sg(sgl, sg, sg_len, i) { |
925 | struct dw_desc *desc; | 909 | struct dw_desc *desc; |
@@ -1001,13 +985,6 @@ static inline void convert_burst(u32 *maxburst) | |||
1001 | *maxburst = 0; | 985 | *maxburst = 0; |
1002 | } | 986 | } |
1003 | 987 | ||
1004 | static inline void convert_slave_id(struct dw_dma_chan *dwc) | ||
1005 | { | ||
1006 | struct dw_dma *dw = to_dw_dma(dwc->chan.device); | ||
1007 | |||
1008 | dwc->dma_sconfig.slave_id -= dw->request_line_base; | ||
1009 | } | ||
1010 | |||
1011 | static int | 988 | static int |
1012 | 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) |
1013 | { | 990 | { |
@@ -1020,9 +997,12 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) | |||
1020 | memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); | 997 | memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig)); |
1021 | dwc->direction = sconfig->direction; | 998 | dwc->direction = sconfig->direction; |
1022 | 999 | ||
1000 | /* Take the request line from slave_id member */ | ||
1001 | if (dwc->request_line == ~0) | ||
1002 | dwc->request_line = sconfig->slave_id; | ||
1003 | |||
1023 | convert_burst(&dwc->dma_sconfig.src_maxburst); | 1004 | convert_burst(&dwc->dma_sconfig.src_maxburst); |
1024 | convert_burst(&dwc->dma_sconfig.dst_maxburst); | 1005 | convert_burst(&dwc->dma_sconfig.dst_maxburst); |
1025 | convert_slave_id(dwc); | ||
1026 | 1006 | ||
1027 | return 0; | 1007 | return 0; |
1028 | } | 1008 | } |
@@ -1030,10 +1010,11 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig) | |||
1030 | static inline void dwc_chan_pause(struct dw_dma_chan *dwc) | 1010 | static inline void dwc_chan_pause(struct dw_dma_chan *dwc) |
1031 | { | 1011 | { |
1032 | u32 cfglo = channel_readl(dwc, CFG_LO); | 1012 | u32 cfglo = channel_readl(dwc, CFG_LO); |
1013 | unsigned int count = 20; /* timeout iterations */ | ||
1033 | 1014 | ||
1034 | channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); | 1015 | channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); |
1035 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY)) | 1016 | while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--) |
1036 | cpu_relax(); | 1017 | udelay(2); |
1037 | 1018 | ||
1038 | dwc->paused = true; | 1019 | dwc->paused = true; |
1039 | } | 1020 | } |
@@ -1169,6 +1150,8 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) | |||
1169 | * doesn't mean what you think it means), and status writeback. | 1150 | * doesn't mean what you think it means), and status writeback. |
1170 | */ | 1151 | */ |
1171 | 1152 | ||
1153 | dwc_set_masters(dwc); | ||
1154 | |||
1172 | spin_lock_irqsave(&dwc->lock, flags); | 1155 | spin_lock_irqsave(&dwc->lock, flags); |
1173 | i = dwc->descs_allocated; | 1156 | i = dwc->descs_allocated; |
1174 | while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) { | 1157 | while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) { |
@@ -1226,6 +1209,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
1226 | list_splice_init(&dwc->free_list, &list); | 1209 | list_splice_init(&dwc->free_list, &list); |
1227 | dwc->descs_allocated = 0; | 1210 | dwc->descs_allocated = 0; |
1228 | dwc->initialized = false; | 1211 | dwc->initialized = false; |
1212 | dwc->request_line = ~0; | ||
1229 | 1213 | ||
1230 | /* Disable interrupts */ | 1214 | /* Disable interrupts */ |
1231 | channel_clear_bit(dw, MASK.XFER, dwc->mask); | 1215 | channel_clear_bit(dw, MASK.XFER, dwc->mask); |
@@ -1241,42 +1225,36 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
1241 | dev_vdbg(chan2dev(chan), "%s: done\n", __func__); | 1225 | dev_vdbg(chan2dev(chan), "%s: done\n", __func__); |
1242 | } | 1226 | } |
1243 | 1227 | ||
1244 | struct dw_dma_filter_args { | 1228 | /*----------------------------------------------------------------------*/ |
1229 | |||
1230 | struct dw_dma_of_filter_args { | ||
1245 | struct dw_dma *dw; | 1231 | struct dw_dma *dw; |
1246 | unsigned int req; | 1232 | unsigned int req; |
1247 | unsigned int src; | 1233 | unsigned int src; |
1248 | unsigned int dst; | 1234 | unsigned int dst; |
1249 | }; | 1235 | }; |
1250 | 1236 | ||
1251 | static bool dw_dma_generic_filter(struct dma_chan *chan, void *param) | 1237 | static bool dw_dma_of_filter(struct dma_chan *chan, void *param) |
1252 | { | 1238 | { |
1253 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1239 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
1254 | struct dw_dma *dw = to_dw_dma(chan->device); | 1240 | struct dw_dma_of_filter_args *fargs = param; |
1255 | struct dw_dma_filter_args *fargs = param; | ||
1256 | struct dw_dma_slave *dws = &dwc->slave; | ||
1257 | 1241 | ||
1258 | /* ensure the device matches our channel */ | 1242 | /* Ensure the device matches our channel */ |
1259 | if (chan->device != &fargs->dw->dma) | 1243 | if (chan->device != &fargs->dw->dma) |
1260 | return false; | 1244 | return false; |
1261 | 1245 | ||
1262 | dws->dma_dev = dw->dma.dev; | ||
1263 | dws->cfg_hi = ~0; | ||
1264 | dws->cfg_lo = ~0; | ||
1265 | dws->src_master = fargs->src; | ||
1266 | dws->dst_master = fargs->dst; | ||
1267 | |||
1268 | dwc->request_line = fargs->req; | 1246 | dwc->request_line = fargs->req; |
1269 | 1247 | dwc->src_master = fargs->src; | |
1270 | chan->private = dws; | 1248 | dwc->dst_master = fargs->dst; |
1271 | 1249 | ||
1272 | return true; | 1250 | return true; |
1273 | } | 1251 | } |
1274 | 1252 | ||
1275 | static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec, | 1253 | static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, |
1276 | struct of_dma *ofdma) | 1254 | struct of_dma *ofdma) |
1277 | { | 1255 | { |
1278 | struct dw_dma *dw = ofdma->of_dma_data; | 1256 | struct dw_dma *dw = ofdma->of_dma_data; |
1279 | struct dw_dma_filter_args fargs = { | 1257 | struct dw_dma_of_filter_args fargs = { |
1280 | .dw = dw, | 1258 | .dw = dw, |
1281 | }; | 1259 | }; |
1282 | dma_cap_mask_t cap; | 1260 | dma_cap_mask_t cap; |
@@ -1297,8 +1275,48 @@ static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec, | |||
1297 | dma_cap_set(DMA_SLAVE, cap); | 1275 | dma_cap_set(DMA_SLAVE, cap); |
1298 | 1276 | ||
1299 | /* TODO: there should be a simpler way to do this */ | 1277 | /* TODO: there should be a simpler way to do this */ |
1300 | return dma_request_channel(cap, dw_dma_generic_filter, &fargs); | 1278 | return dma_request_channel(cap, dw_dma_of_filter, &fargs); |
1279 | } | ||
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"); | ||
1301 | } | 1316 | } |
1317 | #else /* !CONFIG_ACPI */ | ||
1318 | static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {} | ||
1319 | #endif /* !CONFIG_ACPI */ | ||
1302 | 1320 | ||
1303 | /* --------------------- Cyclic DMA API extensions -------------------- */ | 1321 | /* --------------------- Cyclic DMA API extensions -------------------- */ |
1304 | 1322 | ||
@@ -1322,7 +1340,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1322 | 1340 | ||
1323 | spin_lock_irqsave(&dwc->lock, flags); | 1341 | spin_lock_irqsave(&dwc->lock, flags); |
1324 | 1342 | ||
1325 | /* assert channel is idle */ | 1343 | /* Assert channel is idle */ |
1326 | if (dma_readl(dw, CH_EN) & dwc->mask) { | 1344 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
1327 | dev_err(chan2dev(&dwc->chan), | 1345 | dev_err(chan2dev(&dwc->chan), |
1328 | "BUG: Attempted to start non-idle channel\n"); | 1346 | "BUG: Attempted to start non-idle channel\n"); |
@@ -1334,7 +1352,7 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1334 | dma_writel(dw, CLEAR.ERROR, dwc->mask); | 1352 | dma_writel(dw, CLEAR.ERROR, dwc->mask); |
1335 | dma_writel(dw, CLEAR.XFER, dwc->mask); | 1353 | dma_writel(dw, CLEAR.XFER, dwc->mask); |
1336 | 1354 | ||
1337 | /* setup DMAC channel registers */ | 1355 | /* Setup DMAC channel registers */ |
1338 | channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys); | 1356 | channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys); |
1339 | channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN); | 1357 | channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN); |
1340 | channel_writel(dwc, CTL_HI, 0); | 1358 | channel_writel(dwc, CTL_HI, 0); |
@@ -1501,7 +1519,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan, | |||
1501 | last = desc; | 1519 | last = desc; |
1502 | } | 1520 | } |
1503 | 1521 | ||
1504 | /* lets make a cyclic list */ | 1522 | /* Let's make a cyclic list */ |
1505 | last->lli.llp = cdesc->desc[0]->txd.phys; | 1523 | last->lli.llp = cdesc->desc[0]->txd.phys; |
1506 | 1524 | ||
1507 | dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu " | 1525 | dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu " |
@@ -1636,7 +1654,6 @@ dw_dma_parse_dt(struct platform_device *pdev) | |||
1636 | 1654 | ||
1637 | static int dw_probe(struct platform_device *pdev) | 1655 | static int dw_probe(struct platform_device *pdev) |
1638 | { | 1656 | { |
1639 | const struct platform_device_id *match; | ||
1640 | struct dw_dma_platform_data *pdata; | 1657 | struct dw_dma_platform_data *pdata; |
1641 | struct resource *io; | 1658 | struct resource *io; |
1642 | struct dw_dma *dw; | 1659 | struct dw_dma *dw; |
@@ -1706,7 +1723,7 @@ static int dw_probe(struct platform_device *pdev) | |||
1706 | 1723 | ||
1707 | dw->regs = regs; | 1724 | dw->regs = regs; |
1708 | 1725 | ||
1709 | /* get hardware configuration parameters */ | 1726 | /* Get hardware configuration parameters */ |
1710 | if (autocfg) { | 1727 | if (autocfg) { |
1711 | max_blk_size = dma_readl(dw, MAX_BLK_SIZE); | 1728 | max_blk_size = dma_readl(dw, MAX_BLK_SIZE); |
1712 | 1729 | ||
@@ -1720,18 +1737,13 @@ static int dw_probe(struct platform_device *pdev) | |||
1720 | memcpy(dw->data_width, pdata->data_width, 4); | 1737 | memcpy(dw->data_width, pdata->data_width, 4); |
1721 | } | 1738 | } |
1722 | 1739 | ||
1723 | /* Get the base request line if set */ | ||
1724 | match = platform_get_device_id(pdev); | ||
1725 | if (match) | ||
1726 | dw->request_line_base = (unsigned int)match->driver_data; | ||
1727 | |||
1728 | /* Calculate all channel mask before DMA setup */ | 1740 | /* Calculate all channel mask before DMA setup */ |
1729 | dw->all_chan_mask = (1 << nr_channels) - 1; | 1741 | dw->all_chan_mask = (1 << nr_channels) - 1; |
1730 | 1742 | ||
1731 | /* force dma off, just in case */ | 1743 | /* Force dma off, just in case */ |
1732 | dw_dma_off(dw); | 1744 | dw_dma_off(dw); |
1733 | 1745 | ||
1734 | /* disable BLOCK interrupts as well */ | 1746 | /* Disable BLOCK interrupts as well */ |
1735 | channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); | 1747 | channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); |
1736 | 1748 | ||
1737 | err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0, | 1749 | err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0, |
@@ -1741,7 +1753,7 @@ static int dw_probe(struct platform_device *pdev) | |||
1741 | 1753 | ||
1742 | platform_set_drvdata(pdev, dw); | 1754 | platform_set_drvdata(pdev, dw); |
1743 | 1755 | ||
1744 | /* create a pool of consistent memory blocks for hardware descriptors */ | 1756 | /* Create a pool of consistent memory blocks for hardware descriptors */ |
1745 | dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev, | 1757 | dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev, |
1746 | sizeof(struct dw_desc), 4, 0); | 1758 | sizeof(struct dw_desc), 4, 0); |
1747 | if (!dw->desc_pool) { | 1759 | if (!dw->desc_pool) { |
@@ -1781,8 +1793,9 @@ static int dw_probe(struct platform_device *pdev) | |||
1781 | channel_clear_bit(dw, CH_EN, dwc->mask); | 1793 | channel_clear_bit(dw, CH_EN, dwc->mask); |
1782 | 1794 | ||
1783 | dwc->direction = DMA_TRANS_NONE; | 1795 | dwc->direction = DMA_TRANS_NONE; |
1796 | dwc->request_line = ~0; | ||
1784 | 1797 | ||
1785 | /* hardware configuration */ | 1798 | /* Hardware configuration */ |
1786 | if (autocfg) { | 1799 | if (autocfg) { |
1787 | unsigned int dwc_params; | 1800 | unsigned int dwc_params; |
1788 | 1801 | ||
@@ -1842,12 +1855,15 @@ static int dw_probe(struct platform_device *pdev) | |||
1842 | 1855 | ||
1843 | if (pdev->dev.of_node) { | 1856 | if (pdev->dev.of_node) { |
1844 | err = of_dma_controller_register(pdev->dev.of_node, | 1857 | err = of_dma_controller_register(pdev->dev.of_node, |
1845 | dw_dma_xlate, dw); | 1858 | dw_dma_of_xlate, dw); |
1846 | if (err && err != -ENODEV) | 1859 | if (err) |
1847 | dev_err(&pdev->dev, | 1860 | dev_err(&pdev->dev, |
1848 | "could not register of_dma_controller\n"); | 1861 | "could not register of_dma_controller\n"); |
1849 | } | 1862 | } |
1850 | 1863 | ||
1864 | if (ACPI_HANDLE(&pdev->dev)) | ||
1865 | dw_dma_acpi_controller_register(dw); | ||
1866 | |||
1851 | return 0; | 1867 | return 0; |
1852 | } | 1868 | } |
1853 | 1869 | ||
@@ -1912,18 +1928,19 @@ static const struct dev_pm_ops dw_dev_pm_ops = { | |||
1912 | }; | 1928 | }; |
1913 | 1929 | ||
1914 | #ifdef CONFIG_OF | 1930 | #ifdef CONFIG_OF |
1915 | static const struct of_device_id dw_dma_id_table[] = { | 1931 | static const struct of_device_id dw_dma_of_id_table[] = { |
1916 | { .compatible = "snps,dma-spear1340" }, | 1932 | { .compatible = "snps,dma-spear1340" }, |
1917 | {} | 1933 | {} |
1918 | }; | 1934 | }; |
1919 | MODULE_DEVICE_TABLE(of, dw_dma_id_table); | 1935 | MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); |
1920 | #endif | 1936 | #endif |
1921 | 1937 | ||
1922 | static const struct platform_device_id dw_dma_ids[] = { | 1938 | #ifdef CONFIG_ACPI |
1923 | /* Name, Request Line Base */ | 1939 | static const struct acpi_device_id dw_dma_acpi_id_table[] = { |
1924 | { "INTL9C60", (kernel_ulong_t)16 }, | 1940 | { "INTL9C60", 0 }, |
1925 | { } | 1941 | { } |
1926 | }; | 1942 | }; |
1943 | #endif | ||
1927 | 1944 | ||
1928 | static struct platform_driver dw_driver = { | 1945 | static struct platform_driver dw_driver = { |
1929 | .probe = dw_probe, | 1946 | .probe = dw_probe, |
@@ -1932,9 +1949,9 @@ static struct platform_driver dw_driver = { | |||
1932 | .driver = { | 1949 | .driver = { |
1933 | .name = "dw_dmac", | 1950 | .name = "dw_dmac", |
1934 | .pm = &dw_dev_pm_ops, | 1951 | .pm = &dw_dev_pm_ops, |
1935 | .of_match_table = of_match_ptr(dw_dma_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), | ||
1936 | }, | 1954 | }, |
1937 | .id_table = dw_dma_ids, | ||
1938 | }; | 1955 | }; |
1939 | 1956 | ||
1940 | static int __init dw_init(void) | 1957 | static int __init dw_init(void) |