Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma

Pull second set of slave-dmaengine updates from Vinod Koul:
"Arnd's patch moves the dw_dmac to use generic DMA binding. I agreed
to merge this late as it will avoid the conflicts between trees.

The second patch from Matt adding a dma_request_slave_channel_compat
API was supposed to be picked up, but somehow never got picked up.
Some patches dependent on this are already in -next :("

* 'next' of git://git.infradead.org/users/vkoul/slave-dma:
dmaengine: dw_dmac: move to generic DMA binding
dmaengine: add dma_request_slave_channel_compat()

+127 -116
+36 -34
Documentation/devicetree/bindings/dma/snps-dma.txt
··· 3 3 Required properties: 4 4 - compatible: "snps,dma-spear1340" 5 5 - reg: Address range of the DMAC registers 6 - - interrupt-parent: Should be the phandle for the interrupt controller 7 - that services interrupts for this device 8 6 - interrupt: Should contain the DMAC interrupt number 9 - - nr_channels: Number of channels supported by hardware 10 - - is_private: The device channels should be marked as private and not for by the 11 - general purpose DMA channel allocator. False if not passed. 7 + - dma-channels: Number of channels supported by hardware 8 + - dma-requests: Number of DMA request lines supported, up to 16 9 + - dma-masters: Number of AHB masters supported by the controller 10 + - #dma-cells: must be <3> 12 11 - chan_allocation_order: order of allocation of channel, 0 (default): ascending, 13 12 1: descending 14 13 - chan_priority: priority of channels. 0 (default): increase from chan 0->n, 1: 15 14 increase from chan n->0 16 15 - block_size: Maximum block size supported by the controller 17 - - nr_masters: Number of AHB masters supported by the controller 18 16 - data_width: Maximum data width supported by hardware per AHB master 19 17 (0 - 8bits, 1 - 16bits, ..., 5 - 256bits) 20 - - slave_info: 21 - - bus_id: name of this device channel, not just a device name since 22 - devices may have more than one channel e.g. "foo_tx". For using the 23 - dw_generic_filter(), slave drivers must pass exactly this string as 24 - param to filter function. 25 - - cfg_hi: Platform-specific initializer for the CFG_HI register 26 - - cfg_lo: Platform-specific initializer for the CFG_LO register 27 - - src_master: src master for transfers on allocated channel. 28 - - dst_master: dest master for transfers on allocated channel. 18 + 19 + 20 + Optional properties: 21 + - interrupt-parent: Should be the phandle for the interrupt controller 22 + that services interrupts for this device 23 + - is_private: The device channels should be marked as private and not for by the 24 + general purpose DMA channel allocator. False if not passed. 29 25 30 26 Example: 31 27 32 - dma@fc000000 { 28 + dmahost: dma@fc000000 { 33 29 compatible = "snps,dma-spear1340"; 34 30 reg = <0xfc000000 0x1000>; 35 31 interrupt-parent = <&vic1>; 36 32 interrupts = <12>; 37 33 38 - nr_channels = <8>; 34 + dma-channels = <8>; 35 + dma-requests = <16>; 36 + dma-masters = <2>; 37 + #dma-cells = <3>; 39 38 chan_allocation_order = <1>; 40 39 chan_priority = <1>; 41 40 block_size = <0xfff>; 42 - nr_masters = <2>; 43 41 data_width = <3 3 0 0>; 42 + }; 44 43 45 - slave_info { 46 - uart0-tx { 47 - bus_id = "uart0-tx"; 48 - cfg_hi = <0x4000>; /* 0x8 << 11 */ 49 - cfg_lo = <0>; 50 - src_master = <0>; 51 - dst_master = <1>; 52 - }; 53 - spi0-tx { 54 - bus_id = "spi0-tx"; 55 - cfg_hi = <0x2000>; /* 0x4 << 11 */ 56 - cfg_lo = <0>; 57 - src_master = <0>; 58 - dst_master = <0>; 59 - }; 60 - }; 44 + DMA clients connected to the Designware DMA controller must use the format 45 + described in the dma.txt file, using a four-cell specifier for each channel. 46 + The four cells in order are: 47 + 48 + 1. A phandle pointing to the DMA controller 49 + 2. The DMA request line number 50 + 3. Source master for transfers on allocated channel 51 + 4. Destination master for transfers on allocated channel 52 + 53 + Example: 54 + 55 + serial@e0000000 { 56 + compatible = "arm,pl011", "arm,primecell"; 57 + reg = <0xe0000000 0x1000>; 58 + interrupts = <0 35 0x4>; 59 + status = "disabled"; 60 + dmas = <&dmahost 12 0 1>, 61 + <&dmahost 13 0 1 0>; 62 + dma-names = "rx", "rx"; 61 63 };
+72 -73
drivers/dma/dw_dmac.c
··· 20 20 #include <linux/interrupt.h> 21 21 #include <linux/io.h> 22 22 #include <linux/of.h> 23 + #include <linux/of_dma.h> 23 24 #include <linux/mm.h> 24 25 #include <linux/module.h> 25 26 #include <linux/platform_device.h> ··· 172 171 if (dwc->initialized == true) 173 172 return; 174 173 175 - if (dws) { 174 + if (dws && dws->cfg_hi == ~0 && dws->cfg_lo == ~0) { 175 + /* autoconfigure based on request line from DT */ 176 + if (dwc->direction == DMA_MEM_TO_DEV) 177 + cfghi = DWC_CFGH_DST_PER(dwc->request_line); 178 + else if (dwc->direction == DMA_DEV_TO_MEM) 179 + cfghi = DWC_CFGH_SRC_PER(dwc->request_line); 180 + } else if (dws) { 176 181 /* 177 182 * We need controller-specific data to set up slave 178 183 * transfers. ··· 1233 1226 dev_vdbg(chan2dev(chan), "%s: done\n", __func__); 1234 1227 } 1235 1228 1236 - bool dw_dma_generic_filter(struct dma_chan *chan, void *param) 1229 + struct dw_dma_filter_args { 1230 + struct dw_dma *dw; 1231 + unsigned int req; 1232 + unsigned int src; 1233 + unsigned int dst; 1234 + }; 1235 + 1236 + static bool dw_dma_generic_filter(struct dma_chan *chan, void *param) 1237 1237 { 1238 + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); 1238 1239 struct dw_dma *dw = to_dw_dma(chan->device); 1239 - static struct dw_dma *last_dw; 1240 - static char *last_bus_id; 1241 - int i = -1; 1240 + struct dw_dma_filter_args *fargs = param; 1241 + struct dw_dma_slave *dws = &dwc->slave; 1242 1242 1243 - /* 1244 - * dmaengine framework calls this routine for all channels of all dma 1245 - * controller, until true is returned. If 'param' bus_id is not 1246 - * registered with a dma controller (dw), then there is no need of 1247 - * running below function for all channels of dw. 1248 - * 1249 - * This block of code does this by saving the parameters of last 1250 - * failure. If dw and param are same, i.e. trying on same dw with 1251 - * different channel, return false. 1252 - */ 1253 - if ((last_dw == dw) && (last_bus_id == param)) 1254 - return false; 1255 - /* 1256 - * Return true: 1257 - * - If dw_dma's platform data is not filled with slave info, then all 1258 - * dma controllers are fine for transfer. 1259 - * - Or if param is NULL 1260 - */ 1261 - if (!dw->sd || !param) 1262 - return true; 1243 + /* ensure the device matches our channel */ 1244 + if (chan->device != &fargs->dw->dma) 1245 + return false; 1263 1246 1264 - while (++i < dw->sd_count) { 1265 - if (!strcmp(dw->sd[i].bus_id, param)) { 1266 - chan->private = &dw->sd[i]; 1267 - last_dw = NULL; 1268 - last_bus_id = NULL; 1247 + dws->dma_dev = dw->dma.dev; 1248 + dws->cfg_hi = ~0; 1249 + dws->cfg_lo = ~0; 1250 + dws->src_master = fargs->src; 1251 + dws->dst_master = fargs->dst; 1269 1252 1270 - return true; 1271 - } 1272 - } 1253 + dwc->request_line = fargs->req; 1273 1254 1274 - last_dw = dw; 1275 - last_bus_id = param; 1276 - return false; 1255 + chan->private = dws; 1256 + 1257 + return true; 1277 1258 } 1278 - EXPORT_SYMBOL(dw_dma_generic_filter); 1259 + 1260 + static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec, 1261 + struct of_dma *ofdma) 1262 + { 1263 + struct dw_dma *dw = ofdma->of_dma_data; 1264 + struct dw_dma_filter_args fargs = { 1265 + .dw = dw, 1266 + }; 1267 + dma_cap_mask_t cap; 1268 + 1269 + if (dma_spec->args_count != 3) 1270 + return NULL; 1271 + 1272 + fargs.req = be32_to_cpup(dma_spec->args+0); 1273 + fargs.src = be32_to_cpup(dma_spec->args+1); 1274 + fargs.dst = be32_to_cpup(dma_spec->args+2); 1275 + 1276 + if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS || 1277 + fargs.src >= dw->nr_masters || 1278 + fargs.dst >= dw->nr_masters)) 1279 + return NULL; 1280 + 1281 + dma_cap_zero(cap); 1282 + dma_cap_set(DMA_SLAVE, cap); 1283 + 1284 + /* TODO: there should be a simpler way to do this */ 1285 + return dma_request_channel(cap, dw_dma_generic_filter, &fargs); 1286 + } 1279 1287 1280 1288 /* --------------------- Cyclic DMA API extensions -------------------- */ 1281 1289 ··· 1576 1554 static struct dw_dma_platform_data * 1577 1555 dw_dma_parse_dt(struct platform_device *pdev) 1578 1556 { 1579 - struct device_node *sn, *cn, *np = pdev->dev.of_node; 1557 + struct device_node *np = pdev->dev.of_node; 1580 1558 struct dw_dma_platform_data *pdata; 1581 - struct dw_dma_slave *sd; 1582 1559 u32 tmp, arr[4]; 1583 1560 1584 1561 if (!np) { ··· 1589 1568 if (!pdata) 1590 1569 return NULL; 1591 1570 1592 - if (of_property_read_u32(np, "nr_channels", &pdata->nr_channels)) 1571 + if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels)) 1593 1572 return NULL; 1594 1573 1595 1574 if (of_property_read_bool(np, "is_private")) ··· 1604 1583 if (!of_property_read_u32(np, "block_size", &tmp)) 1605 1584 pdata->block_size = tmp; 1606 1585 1607 - if (!of_property_read_u32(np, "nr_masters", &tmp)) { 1586 + if (!of_property_read_u32(np, "dma-masters", &tmp)) { 1608 1587 if (tmp > 4) 1609 1588 return NULL; 1610 1589 ··· 1615 1594 pdata->nr_masters)) 1616 1595 for (tmp = 0; tmp < pdata->nr_masters; tmp++) 1617 1596 pdata->data_width[tmp] = arr[tmp]; 1618 - 1619 - /* parse slave data */ 1620 - sn = of_find_node_by_name(np, "slave_info"); 1621 - if (!sn) 1622 - return pdata; 1623 - 1624 - /* calculate number of slaves */ 1625 - tmp = of_get_child_count(sn); 1626 - if (!tmp) 1627 - return NULL; 1628 - 1629 - sd = devm_kzalloc(&pdev->dev, sizeof(*sd) * tmp, GFP_KERNEL); 1630 - if (!sd) 1631 - return NULL; 1632 - 1633 - pdata->sd = sd; 1634 - pdata->sd_count = tmp; 1635 - 1636 - for_each_child_of_node(sn, cn) { 1637 - sd->dma_dev = &pdev->dev; 1638 - of_property_read_string(cn, "bus_id", &sd->bus_id); 1639 - of_property_read_u32(cn, "cfg_hi", &sd->cfg_hi); 1640 - of_property_read_u32(cn, "cfg_lo", &sd->cfg_lo); 1641 - if (!of_property_read_u32(cn, "src_master", &tmp)) 1642 - sd->src_master = tmp; 1643 - 1644 - if (!of_property_read_u32(cn, "dst_master", &tmp)) 1645 - sd->dst_master = tmp; 1646 - sd++; 1647 - } 1648 1597 1649 1598 return pdata; 1650 1599 } ··· 1696 1705 clk_prepare_enable(dw->clk); 1697 1706 1698 1707 dw->regs = regs; 1699 - dw->sd = pdata->sd; 1700 - dw->sd_count = pdata->sd_count; 1701 1708 1702 1709 /* get hardware configuration parameters */ 1703 1710 if (autocfg) { ··· 1826 1837 1827 1838 dma_async_device_register(&dw->dma); 1828 1839 1840 + if (pdev->dev.of_node) { 1841 + err = of_dma_controller_register(pdev->dev.of_node, 1842 + dw_dma_xlate, dw); 1843 + if (err && err != -ENODEV) 1844 + dev_err(&pdev->dev, 1845 + "could not register of_dma_controller\n"); 1846 + } 1847 + 1829 1848 return 0; 1830 1849 } 1831 1850 ··· 1842 1845 struct dw_dma *dw = platform_get_drvdata(pdev); 1843 1846 struct dw_dma_chan *dwc, *_dwc; 1844 1847 1848 + if (pdev->dev.of_node) 1849 + of_dma_controller_free(pdev->dev.of_node); 1845 1850 dw_dma_off(dw); 1846 1851 dma_async_device_unregister(&dw->dma); 1847 1852
+3 -4
drivers/dma/dw_dmac_regs.h
··· 13 13 #include <linux/dw_dmac.h> 14 14 15 15 #define DW_DMA_MAX_NR_CHANNELS 8 16 + #define DW_DMA_MAX_NR_REQUESTS 16 16 17 17 18 /* flow controller */ 18 19 enum dw_dma_fc { ··· 212 211 /* hardware configuration */ 213 212 unsigned int block_size; 214 213 bool nollp; 214 + unsigned int request_line; 215 + struct dw_dma_slave slave; 215 216 216 217 /* configuration passed via DMA_SLAVE_CONFIG */ 217 218 struct dma_slave_config dma_sconfig; ··· 241 238 struct dma_pool *desc_pool; 242 239 struct tasklet_struct tasklet; 243 240 struct clk *clk; 244 - 245 - /* slave information */ 246 - struct dw_dma_slave *sd; 247 - unsigned int sd_count; 248 241 249 242 u8 all_chan_mask; 250 243
+16
include/linux/dmaengine.h
··· 1001 1001 struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); 1002 1002 struct dma_chan *net_dma_find_channel(void); 1003 1003 #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) 1004 + #define dma_request_slave_channel_compat(mask, x, y, dev, name) \ 1005 + __dma_request_slave_channel_compat(&(mask), x, y, dev, name) 1006 + 1007 + static inline struct dma_chan 1008 + *__dma_request_slave_channel_compat(dma_cap_mask_t *mask, dma_filter_fn fn, 1009 + void *fn_param, struct device *dev, 1010 + char *name) 1011 + { 1012 + struct dma_chan *chan; 1013 + 1014 + chan = dma_request_slave_channel(dev, name); 1015 + if (chan) 1016 + return chan; 1017 + 1018 + return __dma_request_channel(mask, fn, fn_param); 1019 + } 1004 1020 1005 1021 /* --- Helper iov-locking functions --- */ 1006 1022
-5
include/linux/dw_dmac.h
··· 27 27 */ 28 28 struct dw_dma_slave { 29 29 struct device *dma_dev; 30 - const char *bus_id; 31 30 u32 cfg_hi; 32 31 u32 cfg_lo; 33 32 u8 src_master; ··· 59 60 unsigned short block_size; 60 61 unsigned char nr_masters; 61 62 unsigned char data_width[4]; 62 - 63 - struct dw_dma_slave *sd; 64 - unsigned int sd_count; 65 63 }; 66 64 67 65 /* bursts size */ ··· 110 114 dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan); 111 115 112 116 dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan); 113 - bool dw_dma_generic_filter(struct dma_chan *chan, void *param); 114 117 115 118 #endif /* DW_DMAC_H */