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.

dmaengine: cirrus: Convert to DT for Cirrus EP93xx

Convert Cirrus EP93xx DMA to device tree usage:

- add OF ID match table with data
- add of_probe for device tree
- add xlate for m2m/m2p
- drop subsys_initcall code
- drop platform probe
- drop platform structs usage

>From now on it only supports device tree probing.

Co-developed-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

authored by

Nikita Shubin and committed by
Arnd Bergmann
2e7f55ce 581e2ff8

+191 -54
+185 -54
drivers/dma/ep93xx_dma.c
··· 20 20 #include <linux/dmaengine.h> 21 21 #include <linux/module.h> 22 22 #include <linux/mod_devicetable.h> 23 + #include <linux/of_dma.h> 24 + #include <linux/overflow.h> 23 25 #include <linux/platform_device.h> 24 26 #include <linux/slab.h> 25 27 ··· 106 104 #define DMA_MAX_CHAN_BYTES 0xffff 107 105 #define DMA_MAX_CHAN_DESCRIPTORS 32 108 106 107 + enum ep93xx_dma_type { 108 + M2P_DMA, 109 + M2M_DMA, 110 + }; 111 + 109 112 struct ep93xx_dma_engine; 110 113 static int ep93xx_dma_slave_config_write(struct dma_chan *chan, 111 114 enum dma_transfer_direction dir, ··· 136 129 struct list_head node; 137 130 }; 138 131 132 + struct ep93xx_dma_chan_cfg { 133 + u8 port; 134 + enum dma_transfer_direction dir; 135 + }; 136 + 139 137 /** 140 138 * struct ep93xx_dma_chan - an EP93xx DMA M2P/M2M channel 141 139 * @chan: dmaengine API channel 142 140 * @edma: pointer to the engine device 143 141 * @regs: memory mapped registers 142 + * @dma_cfg: channel number, direction 144 143 * @irq: interrupt number of the channel 145 144 * @clk: clock used by this channel 146 145 * @tasklet: channel specific tasklet used for callbacks ··· 170 157 * descriptor in the chain. When a descriptor is moved to the @active queue, 171 158 * the first and chained descriptors are flattened into a single list. 172 159 * 173 - * @chan.private holds pointer to &struct ep93xx_dma_data which contains 174 - * necessary channel configuration information. For memcpy channels this must 175 - * be %NULL. 176 160 */ 177 161 struct ep93xx_dma_chan { 178 162 struct dma_chan chan; 179 163 const struct ep93xx_dma_engine *edma; 180 164 void __iomem *regs; 165 + struct ep93xx_dma_chan_cfg dma_cfg; 181 166 int irq; 182 167 struct clk *clk; 183 168 struct tasklet_struct tasklet; ··· 225 214 226 215 size_t num_channels; 227 216 struct ep93xx_dma_chan channels[] __counted_by(num_channels); 217 + }; 218 + 219 + struct ep93xx_edma_data { 220 + u32 id; 221 + size_t num_channels; 228 222 }; 229 223 230 224 static inline struct device *chan2dev(struct ep93xx_dma_chan *edmac) ··· 334 318 335 319 static int m2p_hw_setup(struct ep93xx_dma_chan *edmac) 336 320 { 337 - struct ep93xx_dma_data *data = edmac->chan.private; 338 321 u32 control; 339 322 340 - writel(data->port & 0xf, edmac->regs + M2P_PPALLOC); 323 + writel(edmac->dma_cfg.port & 0xf, edmac->regs + M2P_PPALLOC); 341 324 342 325 control = M2P_CONTROL_CH_ERROR_INT | M2P_CONTROL_ICE 343 326 | M2P_CONTROL_ENABLE; ··· 473 458 474 459 static int m2m_hw_setup(struct ep93xx_dma_chan *edmac) 475 460 { 476 - const struct ep93xx_dma_data *data = edmac->chan.private; 477 461 u32 control = 0; 478 462 479 - if (!data) { 463 + if (edmac->dma_cfg.dir == DMA_MEM_TO_MEM) { 480 464 /* This is memcpy channel, nothing to configure */ 481 465 writel(control, edmac->regs + M2M_CONTROL); 482 466 return 0; 483 467 } 484 468 485 - switch (data->port) { 469 + switch (edmac->dma_cfg.port) { 486 470 case EP93XX_DMA_SSP: 487 471 /* 488 472 * This was found via experimenting - anything less than 5 ··· 491 477 control = (5 << M2M_CONTROL_PWSC_SHIFT); 492 478 control |= M2M_CONTROL_NO_HDSK; 493 479 494 - if (data->direction == DMA_MEM_TO_DEV) { 480 + if (edmac->dma_cfg.dir == DMA_MEM_TO_DEV) { 495 481 control |= M2M_CONTROL_DAH; 496 482 control |= M2M_CONTROL_TM_TX; 497 483 control |= M2M_CONTROL_RSS_SSPTX; ··· 507 493 * This IDE part is totally untested. Values below are taken 508 494 * from the EP93xx Users's Guide and might not be correct. 509 495 */ 510 - if (data->direction == DMA_MEM_TO_DEV) { 496 + if (edmac->dma_cfg.dir == DMA_MEM_TO_DEV) { 511 497 /* Worst case from the UG */ 512 498 control = (3 << M2M_CONTROL_PWSC_SHIFT); 513 499 control |= M2M_CONTROL_DAH; ··· 562 548 563 549 static void m2m_hw_submit(struct ep93xx_dma_chan *edmac) 564 550 { 565 - struct ep93xx_dma_data *data = edmac->chan.private; 566 551 u32 control = readl(edmac->regs + M2M_CONTROL); 567 552 568 553 /* ··· 587 574 control |= M2M_CONTROL_ENABLE; 588 575 writel(control, edmac->regs + M2M_CONTROL); 589 576 590 - if (!data) { 577 + if (edmac->dma_cfg.dir == DMA_MEM_TO_MEM) { 591 578 /* 592 579 * For memcpy channels the software trigger must be asserted 593 580 * in order to start the memcpy operation. ··· 649 636 */ 650 637 if (ep93xx_dma_advance_active(edmac)) { 651 638 m2m_fill_desc(edmac); 652 - if (done && !edmac->chan.private) { 639 + if (done && edmac->dma_cfg.dir == DMA_MEM_TO_MEM) { 653 640 /* Software trigger for memcpy channel */ 654 641 control = readl(edmac->regs + M2M_CONTROL); 655 642 control |= M2M_CONTROL_START; ··· 880 867 static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan) 881 868 { 882 869 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); 883 - struct ep93xx_dma_data *data = chan->private; 884 870 const char *name = dma_chan_name(chan); 885 871 int ret, i; 886 872 887 873 /* Sanity check the channel parameters */ 888 874 if (!edmac->edma->m2m) { 889 - if (!data) 875 + if (edmac->dma_cfg.port < EP93XX_DMA_I2S1 || 876 + edmac->dma_cfg.port > EP93XX_DMA_IRDA) 890 877 return -EINVAL; 891 - if (data->port < EP93XX_DMA_I2S1 || 892 - data->port > EP93XX_DMA_IRDA) 893 - return -EINVAL; 894 - if (data->direction != ep93xx_dma_chan_direction(chan)) 878 + if (edmac->dma_cfg.dir != ep93xx_dma_chan_direction(chan)) 895 879 return -EINVAL; 896 880 } else { 897 - if (data) { 898 - switch (data->port) { 881 + if (edmac->dma_cfg.dir != DMA_MEM_TO_MEM) { 882 + switch (edmac->dma_cfg.port) { 899 883 case EP93XX_DMA_SSP: 900 884 case EP93XX_DMA_IDE: 901 - if (!is_slave_direction(data->direction)) 885 + if (!is_slave_direction(edmac->dma_cfg.dir)) 902 886 return -EINVAL; 903 887 break; 904 888 default: ··· 903 893 } 904 894 } 905 895 } 906 - 907 - if (data && data->name) 908 - name = data->name; 909 896 910 897 ret = clk_prepare_enable(edmac->clk); 911 898 if (ret) ··· 1322 1315 ep93xx_dma_advance_work(to_ep93xx_dma_chan(chan)); 1323 1316 } 1324 1317 1325 - static int __init ep93xx_dma_probe(struct platform_device *pdev) 1318 + static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pdev) 1326 1319 { 1327 - struct ep93xx_dma_platform_data *pdata = dev_get_platdata(&pdev->dev); 1320 + const struct ep93xx_edma_data *data; 1321 + struct device *dev = &pdev->dev; 1328 1322 struct ep93xx_dma_engine *edma; 1329 1323 struct dma_device *dma_dev; 1330 - int ret, i; 1324 + char dma_clk_name[5]; 1325 + int i; 1331 1326 1332 - edma = kzalloc(struct_size(edma, channels, pdata->num_channels), GFP_KERNEL); 1327 + data = device_get_match_data(dev); 1328 + if (!data) 1329 + return ERR_PTR(dev_err_probe(dev, -ENODEV, "No device match found\n")); 1330 + 1331 + edma = devm_kzalloc(dev, struct_size(edma, channels, data->num_channels), 1332 + GFP_KERNEL); 1333 1333 if (!edma) 1334 - return -ENOMEM; 1334 + return ERR_PTR(-ENOMEM); 1335 1335 1336 + edma->m2m = data->id; 1337 + edma->num_channels = data->num_channels; 1336 1338 dma_dev = &edma->dma_dev; 1337 - edma->m2m = platform_get_device_id(pdev)->driver_data; 1338 - edma->num_channels = pdata->num_channels; 1339 1339 1340 1340 INIT_LIST_HEAD(&dma_dev->channels); 1341 - for (i = 0; i < pdata->num_channels; i++) { 1342 - const struct ep93xx_dma_chan_data *cdata = &pdata->channels[i]; 1341 + for (i = 0; i < edma->num_channels; i++) { 1343 1342 struct ep93xx_dma_chan *edmac = &edma->channels[i]; 1344 1343 1345 1344 edmac->chan.device = dma_dev; 1346 - edmac->regs = cdata->base; 1347 - edmac->irq = cdata->irq; 1345 + edmac->regs = devm_platform_ioremap_resource(pdev, i); 1346 + if (IS_ERR(edmac->regs)) 1347 + return edmac->regs; 1348 + 1349 + edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); 1350 + if (edmac->irq < 0) 1351 + return ERR_PTR(edmac->irq); 1352 + 1348 1353 edmac->edma = edma; 1349 1354 1350 - edmac->clk = clk_get(NULL, cdata->name); 1355 + if (edma->m2m) 1356 + sprintf(dma_clk_name, "m2m%u", i); 1357 + else 1358 + sprintf(dma_clk_name, "m2p%u", i); 1359 + 1360 + edmac->clk = devm_clk_get(dev, dma_clk_name); 1351 1361 if (IS_ERR(edmac->clk)) { 1352 - dev_warn(&pdev->dev, "failed to get clock for %s\n", 1353 - cdata->name); 1354 - continue; 1362 + dev_err_probe(dev, PTR_ERR(edmac->clk), 1363 + "no %s clock found\n", dma_clk_name); 1364 + return ERR_CAST(edmac->clk); 1355 1365 } 1356 1366 1357 1367 spin_lock_init(&edmac->lock); ··· 1380 1356 list_add_tail(&edmac->chan.device_node, 1381 1357 &dma_dev->channels); 1382 1358 } 1359 + 1360 + return edma; 1361 + } 1362 + 1363 + static bool ep93xx_m2p_dma_filter(struct dma_chan *chan, void *filter_param) 1364 + { 1365 + struct ep93xx_dma_chan *echan = to_ep93xx_dma_chan(chan); 1366 + struct ep93xx_dma_chan_cfg *cfg = filter_param; 1367 + 1368 + if (cfg->dir != ep93xx_dma_chan_direction(chan)) 1369 + return false; 1370 + 1371 + echan->dma_cfg = *cfg; 1372 + return true; 1373 + } 1374 + 1375 + static struct dma_chan *ep93xx_m2p_dma_of_xlate(struct of_phandle_args *dma_spec, 1376 + struct of_dma *ofdma) 1377 + { 1378 + struct ep93xx_dma_engine *edma = ofdma->of_dma_data; 1379 + dma_cap_mask_t mask = edma->dma_dev.cap_mask; 1380 + struct ep93xx_dma_chan_cfg dma_cfg; 1381 + u8 port = dma_spec->args[0]; 1382 + u8 direction = dma_spec->args[1]; 1383 + 1384 + if (port > EP93XX_DMA_IRDA) 1385 + return NULL; 1386 + 1387 + if (!is_slave_direction(direction)) 1388 + return NULL; 1389 + 1390 + dma_cfg.port = port; 1391 + dma_cfg.dir = direction; 1392 + 1393 + return __dma_request_channel(&mask, ep93xx_m2p_dma_filter, &dma_cfg, ofdma->of_node); 1394 + } 1395 + 1396 + static bool ep93xx_m2m_dma_filter(struct dma_chan *chan, void *filter_param) 1397 + { 1398 + struct ep93xx_dma_chan *echan = to_ep93xx_dma_chan(chan); 1399 + struct ep93xx_dma_chan_cfg *cfg = filter_param; 1400 + 1401 + echan->dma_cfg = *cfg; 1402 + 1403 + return true; 1404 + } 1405 + 1406 + static struct dma_chan *ep93xx_m2m_dma_of_xlate(struct of_phandle_args *dma_spec, 1407 + struct of_dma *ofdma) 1408 + { 1409 + struct ep93xx_dma_engine *edma = ofdma->of_dma_data; 1410 + dma_cap_mask_t mask = edma->dma_dev.cap_mask; 1411 + struct ep93xx_dma_chan_cfg dma_cfg; 1412 + u8 port = dma_spec->args[0]; 1413 + u8 direction = dma_spec->args[1]; 1414 + 1415 + if (!is_slave_direction(direction)) 1416 + return NULL; 1417 + 1418 + switch (port) { 1419 + case EP93XX_DMA_SSP: 1420 + case EP93XX_DMA_IDE: 1421 + break; 1422 + default: 1423 + return NULL; 1424 + } 1425 + 1426 + dma_cfg.port = port; 1427 + dma_cfg.dir = direction; 1428 + 1429 + return __dma_request_channel(&mask, ep93xx_m2m_dma_filter, &dma_cfg, ofdma->of_node); 1430 + } 1431 + 1432 + static int ep93xx_dma_probe(struct platform_device *pdev) 1433 + { 1434 + struct ep93xx_dma_engine *edma; 1435 + struct dma_device *dma_dev; 1436 + int ret; 1437 + 1438 + edma = ep93xx_dma_of_probe(pdev); 1439 + if (!edma) 1440 + return PTR_ERR(edma); 1441 + 1442 + dma_dev = &edma->dma_dev; 1383 1443 1384 1444 dma_cap_zero(dma_dev->cap_mask); 1385 1445 dma_cap_set(DMA_SLAVE, dma_dev->cap_mask); ··· 1501 1393 } 1502 1394 1503 1395 ret = dma_async_device_register(dma_dev); 1504 - if (unlikely(ret)) { 1505 - for (i = 0; i < edma->num_channels; i++) { 1506 - struct ep93xx_dma_chan *edmac = &edma->channels[i]; 1507 - if (!IS_ERR_OR_NULL(edmac->clk)) 1508 - clk_put(edmac->clk); 1509 - } 1510 - kfree(edma); 1396 + if (ret) 1397 + return ret; 1398 + 1399 + if (edma->m2m) { 1400 + ret = of_dma_controller_register(pdev->dev.of_node, ep93xx_m2m_dma_of_xlate, 1401 + edma); 1511 1402 } else { 1512 - dev_info(dma_dev->dev, "EP93xx M2%s DMA ready\n", 1513 - edma->m2m ? "M" : "P"); 1403 + ret = of_dma_controller_register(pdev->dev.of_node, ep93xx_m2p_dma_of_xlate, 1404 + edma); 1514 1405 } 1406 + if (ret) 1407 + goto err_dma_unregister; 1408 + 1409 + dev_info(dma_dev->dev, "EP93xx M2%s DMA ready\n", edma->m2m ? "M" : "P"); 1410 + 1411 + return 0; 1412 + 1413 + err_dma_unregister: 1414 + dma_async_device_unregister(dma_dev); 1515 1415 1516 1416 return ret; 1517 1417 } 1418 + 1419 + static const struct ep93xx_edma_data edma_m2p = { 1420 + .id = M2P_DMA, 1421 + .num_channels = 10, 1422 + }; 1423 + 1424 + static const struct ep93xx_edma_data edma_m2m = { 1425 + .id = M2M_DMA, 1426 + .num_channels = 2, 1427 + }; 1428 + 1429 + static const struct of_device_id ep93xx_dma_of_ids[] = { 1430 + { .compatible = "cirrus,ep9301-dma-m2p", .data = &edma_m2p }, 1431 + { .compatible = "cirrus,ep9301-dma-m2m", .data = &edma_m2m }, 1432 + { /* sentinel */ } 1433 + }; 1434 + MODULE_DEVICE_TABLE(of, ep93xx_dma_of_ids); 1518 1435 1519 1436 static const struct platform_device_id ep93xx_dma_driver_ids[] = { 1520 1437 { "ep93xx-dma-m2p", 0 }, ··· 1550 1417 static struct platform_driver ep93xx_dma_driver = { 1551 1418 .driver = { 1552 1419 .name = "ep93xx-dma", 1420 + .of_match_table = ep93xx_dma_of_ids, 1553 1421 }, 1554 1422 .id_table = ep93xx_dma_driver_ids, 1423 + .probe = ep93xx_dma_probe, 1555 1424 }; 1556 1425 1557 - static int __init ep93xx_dma_module_init(void) 1558 - { 1559 - return platform_driver_probe(&ep93xx_dma_driver, ep93xx_dma_probe); 1560 - } 1561 - subsys_initcall(ep93xx_dma_module_init); 1426 + module_platform_driver(ep93xx_dma_driver); 1562 1427 1563 1428 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); 1564 1429 MODULE_DESCRIPTION("EP93xx DMA driver");
+6
include/linux/platform_data/dma-ep93xx.h
··· 3 3 #define __ASM_ARCH_DMA_H 4 4 5 5 #include <linux/types.h> 6 + #include <linux/device.h> 6 7 #include <linux/dmaengine.h> 7 8 #include <linux/dma-mapping.h> 9 + #include <linux/property.h> 10 + #include <linux/string.h> 8 11 9 12 /* 10 13 * M2P channels. ··· 73 70 74 71 static inline bool ep93xx_dma_chan_is_m2p(struct dma_chan *chan) 75 72 { 73 + if (device_is_compatible(chan->device->dev, "cirrus,ep9301-dma-m2p")) 74 + return true; 75 + 76 76 return !strcmp(dev_name(chan->device->dev), "ep93xx-dma-m2p"); 77 77 } 78 78