diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-01-06 13:38:16 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-01-06 13:38:16 -0500 |
commit | 74465b4ff9ac1da503025c0a0042e023bfa6505c (patch) | |
tree | ce63f4a4b055b65cae1edaddd334931bf512c76e | |
parent | 33df8ca068123457db56c316946a3c0e4ef787d6 (diff) |
atmel-mci: convert to dma_request_channel and down-level dma_slave
dma_request_channel provides an exclusive channel, so we no longer need to
pass slave data through dmaengine.
Cc: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | arch/avr32/include/asm/atmel-mci.h | 6 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/at32ap700x.c | 15 | ||||
-rw-r--r-- | drivers/dma/dmaengine.c | 8 | ||||
-rw-r--r-- | drivers/dma/dw_dmac.c | 25 | ||||
-rw-r--r-- | drivers/mmc/host/atmel-mci.c | 98 | ||||
-rw-r--r-- | include/linux/dmaengine.h | 38 | ||||
-rw-r--r-- | include/linux/dw_dmac.h | 31 |
7 files changed, 62 insertions, 159 deletions
diff --git a/arch/avr32/include/asm/atmel-mci.h b/arch/avr32/include/asm/atmel-mci.h index 59f3fadd0b68..e5e54c6f35d9 100644 --- a/arch/avr32/include/asm/atmel-mci.h +++ b/arch/avr32/include/asm/atmel-mci.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #define ATMEL_MCI_MAX_NR_SLOTS 2 | 4 | #define ATMEL_MCI_MAX_NR_SLOTS 2 |
5 | 5 | ||
6 | struct dma_slave; | 6 | #include <linux/dw_dmac.h> |
7 | 7 | ||
8 | /** | 8 | /** |
9 | * struct mci_slot_pdata - board-specific per-slot configuration | 9 | * struct mci_slot_pdata - board-specific per-slot configuration |
@@ -28,11 +28,11 @@ struct mci_slot_pdata { | |||
28 | 28 | ||
29 | /** | 29 | /** |
30 | * struct mci_platform_data - board-specific MMC/SDcard configuration | 30 | * struct mci_platform_data - board-specific MMC/SDcard configuration |
31 | * @dma_slave: DMA slave interface to use in data transfers, or NULL. | 31 | * @dma_slave: DMA slave interface to use in data transfers. |
32 | * @slot: Per-slot configuration data. | 32 | * @slot: Per-slot configuration data. |
33 | */ | 33 | */ |
34 | struct mci_platform_data { | 34 | struct mci_platform_data { |
35 | struct dma_slave *dma_slave; | 35 | struct dw_dma_slave dma_slave; |
36 | struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS]; | 36 | struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS]; |
37 | }; | 37 | }; |
38 | 38 | ||
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c index 066252eebf61..414f174e38cd 100644 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ b/arch/avr32/mach-at32ap/at32ap700x.c | |||
@@ -1305,7 +1305,7 @@ struct platform_device *__init | |||
1305 | at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | 1305 | at32_add_device_mci(unsigned int id, struct mci_platform_data *data) |
1306 | { | 1306 | { |
1307 | struct platform_device *pdev; | 1307 | struct platform_device *pdev; |
1308 | struct dw_dma_slave *dws; | 1308 | struct dw_dma_slave *dws = &data->dma_slave; |
1309 | u32 pioa_mask; | 1309 | u32 pioa_mask; |
1310 | u32 piob_mask; | 1310 | u32 piob_mask; |
1311 | 1311 | ||
@@ -1324,22 +1324,13 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) | |||
1324 | ARRAY_SIZE(atmel_mci0_resource))) | 1324 | ARRAY_SIZE(atmel_mci0_resource))) |
1325 | goto fail; | 1325 | goto fail; |
1326 | 1326 | ||
1327 | if (data->dma_slave) | 1327 | dws->dma_dev = &dw_dmac0_device.dev; |
1328 | dws = kmemdup(to_dw_dma_slave(data->dma_slave), | 1328 | dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT; |
1329 | sizeof(struct dw_dma_slave), GFP_KERNEL); | ||
1330 | else | ||
1331 | dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL); | ||
1332 | |||
1333 | dws->slave.dev = &pdev->dev; | ||
1334 | dws->slave.dma_dev = &dw_dmac0_device.dev; | ||
1335 | dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT; | ||
1336 | dws->cfg_hi = (DWC_CFGH_SRC_PER(0) | 1329 | dws->cfg_hi = (DWC_CFGH_SRC_PER(0) |
1337 | | DWC_CFGH_DST_PER(1)); | 1330 | | DWC_CFGH_DST_PER(1)); |
1338 | dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | 1331 | dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL |
1339 | | DWC_CFGL_HS_SRC_POL); | 1332 | | DWC_CFGL_HS_SRC_POL); |
1340 | 1333 | ||
1341 | data->dma_slave = &dws->slave; | ||
1342 | |||
1343 | if (platform_device_add_data(pdev, data, | 1334 | if (platform_device_add_data(pdev, data, |
1344 | sizeof(struct mci_platform_data))) | 1335 | sizeof(struct mci_platform_data))) |
1345 | goto fail; | 1336 | goto fail; |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 7a0594f24a3f..90aca505a1df 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -234,10 +234,6 @@ static void dma_client_chan_alloc(struct dma_client *client) | |||
234 | list_for_each_entry(device, &dma_device_list, global_node) { | 234 | list_for_each_entry(device, &dma_device_list, global_node) { |
235 | if (dma_has_cap(DMA_PRIVATE, device->cap_mask)) | 235 | if (dma_has_cap(DMA_PRIVATE, device->cap_mask)) |
236 | continue; | 236 | continue; |
237 | /* Does the client require a specific DMA controller? */ | ||
238 | if (client->slave && client->slave->dma_dev | ||
239 | && client->slave->dma_dev != device->dev) | ||
240 | continue; | ||
241 | if (!dma_device_satisfies_mask(device, client->cap_mask)) | 237 | if (!dma_device_satisfies_mask(device, client->cap_mask)) |
242 | continue; | 238 | continue; |
243 | 239 | ||
@@ -613,10 +609,6 @@ void dma_async_client_register(struct dma_client *client) | |||
613 | struct dma_chan *chan; | 609 | struct dma_chan *chan; |
614 | int err; | 610 | int err; |
615 | 611 | ||
616 | /* validate client data */ | ||
617 | BUG_ON(dma_has_cap(DMA_SLAVE, client->cap_mask) && | ||
618 | !client->slave); | ||
619 | |||
620 | mutex_lock(&dma_list_mutex); | 612 | mutex_lock(&dma_list_mutex); |
621 | dmaengine_ref_count++; | 613 | dmaengine_ref_count++; |
622 | 614 | ||
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 377dafa37a20..dbd50804e5d2 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c | |||
@@ -567,7 +567,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
567 | if (unlikely(!dws || !sg_len)) | 567 | if (unlikely(!dws || !sg_len)) |
568 | return NULL; | 568 | return NULL; |
569 | 569 | ||
570 | reg_width = dws->slave.reg_width; | 570 | reg_width = dws->reg_width; |
571 | prev = first = NULL; | 571 | prev = first = NULL; |
572 | 572 | ||
573 | sg_len = dma_map_sg(chan->dev.parent, sgl, sg_len, direction); | 573 | sg_len = dma_map_sg(chan->dev.parent, sgl, sg_len, direction); |
@@ -579,7 +579,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
579 | | DWC_CTLL_DST_FIX | 579 | | DWC_CTLL_DST_FIX |
580 | | DWC_CTLL_SRC_INC | 580 | | DWC_CTLL_SRC_INC |
581 | | DWC_CTLL_FC_M2P); | 581 | | DWC_CTLL_FC_M2P); |
582 | reg = dws->slave.tx_reg; | 582 | reg = dws->tx_reg; |
583 | for_each_sg(sgl, sg, sg_len, i) { | 583 | for_each_sg(sgl, sg, sg_len, i) { |
584 | struct dw_desc *desc; | 584 | struct dw_desc *desc; |
585 | u32 len; | 585 | u32 len; |
@@ -625,7 +625,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
625 | | DWC_CTLL_SRC_FIX | 625 | | DWC_CTLL_SRC_FIX |
626 | | DWC_CTLL_FC_P2M); | 626 | | DWC_CTLL_FC_P2M); |
627 | 627 | ||
628 | reg = dws->slave.rx_reg; | 628 | reg = dws->rx_reg; |
629 | for_each_sg(sgl, sg, sg_len, i) { | 629 | for_each_sg(sgl, sg, sg_len, i) { |
630 | struct dw_desc *desc; | 630 | struct dw_desc *desc; |
631 | u32 len; | 631 | u32 len; |
@@ -764,7 +764,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan, | |||
764 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 764 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
765 | struct dw_dma *dw = to_dw_dma(chan->device); | 765 | struct dw_dma *dw = to_dw_dma(chan->device); |
766 | struct dw_desc *desc; | 766 | struct dw_desc *desc; |
767 | struct dma_slave *slave; | ||
768 | struct dw_dma_slave *dws; | 767 | struct dw_dma_slave *dws; |
769 | int i; | 768 | int i; |
770 | u32 cfghi; | 769 | u32 cfghi; |
@@ -772,12 +771,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan, | |||
772 | 771 | ||
773 | dev_vdbg(&chan->dev, "alloc_chan_resources\n"); | 772 | dev_vdbg(&chan->dev, "alloc_chan_resources\n"); |
774 | 773 | ||
775 | /* Channels doing slave DMA can only handle one client. */ | ||
776 | if (dwc->dws || (client && client->slave)) { | ||
777 | if (chan->client_count) | ||
778 | return -EBUSY; | ||
779 | } | ||
780 | |||
781 | /* ASSERT: channel is idle */ | 774 | /* ASSERT: channel is idle */ |
782 | if (dma_readl(dw, CH_EN) & dwc->mask) { | 775 | if (dma_readl(dw, CH_EN) & dwc->mask) { |
783 | dev_dbg(&chan->dev, "DMA channel not idle?\n"); | 776 | dev_dbg(&chan->dev, "DMA channel not idle?\n"); |
@@ -789,23 +782,17 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan, | |||
789 | cfghi = DWC_CFGH_FIFO_MODE; | 782 | cfghi = DWC_CFGH_FIFO_MODE; |
790 | cfglo = 0; | 783 | cfglo = 0; |
791 | 784 | ||
792 | slave = client->slave; | 785 | dws = dwc->dws; |
793 | if (slave) { | 786 | if (dws) { |
794 | /* | 787 | /* |
795 | * We need controller-specific data to set up slave | 788 | * We need controller-specific data to set up slave |
796 | * transfers. | 789 | * transfers. |
797 | */ | 790 | */ |
798 | BUG_ON(!slave->dma_dev || slave->dma_dev != dw->dma.dev); | 791 | BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev); |
799 | |||
800 | dws = container_of(slave, struct dw_dma_slave, slave); | ||
801 | 792 | ||
802 | dwc->dws = dws; | ||
803 | cfghi = dws->cfg_hi; | 793 | cfghi = dws->cfg_hi; |
804 | cfglo = dws->cfg_lo; | 794 | cfglo = dws->cfg_lo; |
805 | } else { | ||
806 | dwc->dws = NULL; | ||
807 | } | 795 | } |
808 | |||
809 | channel_writel(dwc, CFG_LO, cfglo); | 796 | channel_writel(dwc, CFG_LO, cfglo); |
810 | channel_writel(dwc, CFG_HI, cfghi); | 797 | channel_writel(dwc, CFG_HI, cfghi); |
811 | 798 | ||
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 6c11f4d4c4e9..7a34118507db 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -1441,60 +1441,6 @@ static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) | |||
1441 | return IRQ_HANDLED; | 1441 | return IRQ_HANDLED; |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | #ifdef CONFIG_MMC_ATMELMCI_DMA | ||
1445 | |||
1446 | static inline struct atmel_mci * | ||
1447 | dma_client_to_atmel_mci(struct dma_client *client) | ||
1448 | { | ||
1449 | return container_of(client, struct atmel_mci, dma.client); | ||
1450 | } | ||
1451 | |||
1452 | static enum dma_state_client atmci_dma_event(struct dma_client *client, | ||
1453 | struct dma_chan *chan, enum dma_state state) | ||
1454 | { | ||
1455 | struct atmel_mci *host; | ||
1456 | enum dma_state_client ret = DMA_NAK; | ||
1457 | |||
1458 | host = dma_client_to_atmel_mci(client); | ||
1459 | |||
1460 | switch (state) { | ||
1461 | case DMA_RESOURCE_AVAILABLE: | ||
1462 | spin_lock_bh(&host->lock); | ||
1463 | if (!host->dma.chan) { | ||
1464 | host->dma.chan = chan; | ||
1465 | ret = DMA_ACK; | ||
1466 | } | ||
1467 | spin_unlock_bh(&host->lock); | ||
1468 | |||
1469 | if (ret == DMA_ACK) | ||
1470 | dev_info(&host->pdev->dev, | ||
1471 | "Using %s for DMA transfers\n", | ||
1472 | chan->dev.bus_id); | ||
1473 | break; | ||
1474 | |||
1475 | case DMA_RESOURCE_REMOVED: | ||
1476 | spin_lock_bh(&host->lock); | ||
1477 | if (host->dma.chan == chan) { | ||
1478 | host->dma.chan = NULL; | ||
1479 | ret = DMA_ACK; | ||
1480 | } | ||
1481 | spin_unlock_bh(&host->lock); | ||
1482 | |||
1483 | if (ret == DMA_ACK) | ||
1484 | dev_info(&host->pdev->dev, | ||
1485 | "Lost %s, falling back to PIO\n", | ||
1486 | chan->dev.bus_id); | ||
1487 | break; | ||
1488 | |||
1489 | default: | ||
1490 | break; | ||
1491 | } | ||
1492 | |||
1493 | |||
1494 | return ret; | ||
1495 | } | ||
1496 | #endif /* CONFIG_MMC_ATMELMCI_DMA */ | ||
1497 | |||
1498 | static int __init atmci_init_slot(struct atmel_mci *host, | 1444 | static int __init atmci_init_slot(struct atmel_mci *host, |
1499 | struct mci_slot_pdata *slot_data, unsigned int id, | 1445 | struct mci_slot_pdata *slot_data, unsigned int id, |
1500 | u32 sdc_reg) | 1446 | u32 sdc_reg) |
@@ -1598,6 +1544,18 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot, | |||
1598 | mmc_free_host(slot->mmc); | 1544 | mmc_free_host(slot->mmc); |
1599 | } | 1545 | } |
1600 | 1546 | ||
1547 | #ifdef CONFIG_MMC_ATMELMCI_DMA | ||
1548 | static enum dma_state_client filter(struct dma_chan *chan, void *slave) | ||
1549 | { | ||
1550 | struct dw_dma_slave *dws = slave; | ||
1551 | |||
1552 | if (dws->dma_dev == chan->device->dev) | ||
1553 | return DMA_ACK; | ||
1554 | else | ||
1555 | return DMA_DUP; | ||
1556 | } | ||
1557 | #endif | ||
1558 | |||
1601 | static int __init atmci_probe(struct platform_device *pdev) | 1559 | static int __init atmci_probe(struct platform_device *pdev) |
1602 | { | 1560 | { |
1603 | struct mci_platform_data *pdata; | 1561 | struct mci_platform_data *pdata; |
@@ -1650,22 +1608,20 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1650 | goto err_request_irq; | 1608 | goto err_request_irq; |
1651 | 1609 | ||
1652 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1610 | #ifdef CONFIG_MMC_ATMELMCI_DMA |
1653 | if (pdata->dma_slave) { | 1611 | if (pdata->dma_slave.dma_dev) { |
1654 | struct dma_slave *slave = pdata->dma_slave; | 1612 | struct dw_dma_slave *dws = &pdata->dma_slave; |
1613 | dma_cap_mask_t mask; | ||
1655 | 1614 | ||
1656 | slave->tx_reg = regs->start + MCI_TDR; | 1615 | dws->tx_reg = regs->start + MCI_TDR; |
1657 | slave->rx_reg = regs->start + MCI_RDR; | 1616 | dws->rx_reg = regs->start + MCI_RDR; |
1658 | 1617 | ||
1659 | /* Try to grab a DMA channel */ | 1618 | /* Try to grab a DMA channel */ |
1660 | host->dma.client.event_callback = atmci_dma_event; | 1619 | dma_cap_zero(mask); |
1661 | dma_cap_set(DMA_SLAVE, host->dma.client.cap_mask); | 1620 | dma_cap_set(DMA_SLAVE, mask); |
1662 | host->dma.client.slave = slave; | 1621 | host->dma.chan = dma_request_channel(mask, filter, dws); |
1663 | |||
1664 | dma_async_client_register(&host->dma.client); | ||
1665 | dma_async_client_chan_request(&host->dma.client); | ||
1666 | } else { | ||
1667 | dev_notice(&pdev->dev, "DMA not available, using PIO\n"); | ||
1668 | } | 1622 | } |
1623 | if (!host->dma.chan) | ||
1624 | dev_notice(&pdev->dev, "DMA not available, using PIO\n"); | ||
1669 | #endif /* CONFIG_MMC_ATMELMCI_DMA */ | 1625 | #endif /* CONFIG_MMC_ATMELMCI_DMA */ |
1670 | 1626 | ||
1671 | platform_set_drvdata(pdev, host); | 1627 | platform_set_drvdata(pdev, host); |
@@ -1697,8 +1653,8 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
1697 | 1653 | ||
1698 | err_init_slot: | 1654 | err_init_slot: |
1699 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1655 | #ifdef CONFIG_MMC_ATMELMCI_DMA |
1700 | if (pdata->dma_slave) | 1656 | if (host->dma.chan) |
1701 | dma_async_client_unregister(&host->dma.client); | 1657 | dma_release_channel(host->dma.chan); |
1702 | #endif | 1658 | #endif |
1703 | free_irq(irq, host); | 1659 | free_irq(irq, host); |
1704 | err_request_irq: | 1660 | err_request_irq: |
@@ -1729,8 +1685,8 @@ static int __exit atmci_remove(struct platform_device *pdev) | |||
1729 | clk_disable(host->mck); | 1685 | clk_disable(host->mck); |
1730 | 1686 | ||
1731 | #ifdef CONFIG_MMC_ATMELMCI_DMA | 1687 | #ifdef CONFIG_MMC_ATMELMCI_DMA |
1732 | if (host->dma.client.slave) | 1688 | if (host->dma.chan) |
1733 | dma_async_client_unregister(&host->dma.client); | 1689 | dma_release_channel(host->dma.chan); |
1734 | #endif | 1690 | #endif |
1735 | 1691 | ||
1736 | free_irq(platform_get_irq(pdev, 0), host); | 1692 | free_irq(platform_get_irq(pdev, 0), host); |
@@ -1759,7 +1715,7 @@ static void __exit atmci_exit(void) | |||
1759 | platform_driver_unregister(&atmci_driver); | 1715 | platform_driver_unregister(&atmci_driver); |
1760 | } | 1716 | } |
1761 | 1717 | ||
1762 | module_init(atmci_init); | 1718 | late_initcall(atmci_init); /* try to load after dma driver when built-in */ |
1763 | module_exit(atmci_exit); | 1719 | module_exit(atmci_exit); |
1764 | 1720 | ||
1765 | MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); | 1721 | MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); |
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 6f2d070ac7f3..d63544cf8a1a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -96,17 +96,6 @@ enum dma_transaction_type { | |||
96 | /* last transaction type for creation of the capabilities mask */ | 96 | /* last transaction type for creation of the capabilities mask */ |
97 | #define DMA_TX_TYPE_END (DMA_SLAVE + 1) | 97 | #define DMA_TX_TYPE_END (DMA_SLAVE + 1) |
98 | 98 | ||
99 | /** | ||
100 | * enum dma_slave_width - DMA slave register access width. | ||
101 | * @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses | ||
102 | * @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses | ||
103 | * @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses | ||
104 | */ | ||
105 | enum dma_slave_width { | ||
106 | DMA_SLAVE_WIDTH_8BIT, | ||
107 | DMA_SLAVE_WIDTH_16BIT, | ||
108 | DMA_SLAVE_WIDTH_32BIT, | ||
109 | }; | ||
110 | 99 | ||
111 | /** | 100 | /** |
112 | * enum dma_ctrl_flags - DMA flags to augment operation preparation, | 101 | * enum dma_ctrl_flags - DMA flags to augment operation preparation, |
@@ -133,32 +122,6 @@ enum dma_ctrl_flags { | |||
133 | typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t; | 122 | typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t; |
134 | 123 | ||
135 | /** | 124 | /** |
136 | * struct dma_slave - Information about a DMA slave | ||
137 | * @dev: device acting as DMA slave | ||
138 | * @dma_dev: required DMA master device. If non-NULL, the client can not be | ||
139 | * bound to other masters than this. | ||
140 | * @tx_reg: physical address of data register used for | ||
141 | * memory-to-peripheral transfers | ||
142 | * @rx_reg: physical address of data register used for | ||
143 | * peripheral-to-memory transfers | ||
144 | * @reg_width: peripheral register width | ||
145 | * | ||
146 | * If dma_dev is non-NULL, the client can not be bound to other DMA | ||
147 | * masters than the one corresponding to this device. The DMA master | ||
148 | * driver may use this to determine if there is controller-specific | ||
149 | * data wrapped around this struct. Drivers of platform code that sets | ||
150 | * the dma_dev field must therefore make sure to use an appropriate | ||
151 | * controller-specific dma slave structure wrapping this struct. | ||
152 | */ | ||
153 | struct dma_slave { | ||
154 | struct device *dev; | ||
155 | struct device *dma_dev; | ||
156 | dma_addr_t tx_reg; | ||
157 | dma_addr_t rx_reg; | ||
158 | enum dma_slave_width reg_width; | ||
159 | }; | ||
160 | |||
161 | /** | ||
162 | * struct dma_chan_percpu - the per-CPU part of struct dma_chan | 125 | * struct dma_chan_percpu - the per-CPU part of struct dma_chan |
163 | * @refcount: local_t used for open-coded "bigref" counting | 126 | * @refcount: local_t used for open-coded "bigref" counting |
164 | * @memcpy_count: transaction counter | 127 | * @memcpy_count: transaction counter |
@@ -248,7 +211,6 @@ typedef enum dma_state_client (*dma_filter_fn)(struct dma_chan *chan, void *filt | |||
248 | struct dma_client { | 211 | struct dma_client { |
249 | dma_event_callback event_callback; | 212 | dma_event_callback event_callback; |
250 | dma_cap_mask_t cap_mask; | 213 | dma_cap_mask_t cap_mask; |
251 | struct dma_slave *slave; | ||
252 | struct list_head global_node; | 214 | struct list_head global_node; |
253 | }; | 215 | }; |
254 | 216 | ||
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h index 04d217b442bf..d797dde247f7 100644 --- a/include/linux/dw_dmac.h +++ b/include/linux/dw_dmac.h | |||
@@ -22,14 +22,34 @@ struct dw_dma_platform_data { | |||
22 | }; | 22 | }; |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * enum dw_dma_slave_width - DMA slave register access width. | ||
26 | * @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses | ||
27 | * @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses | ||
28 | * @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses | ||
29 | */ | ||
30 | enum dw_dma_slave_width { | ||
31 | DW_DMA_SLAVE_WIDTH_8BIT, | ||
32 | DW_DMA_SLAVE_WIDTH_16BIT, | ||
33 | DW_DMA_SLAVE_WIDTH_32BIT, | ||
34 | }; | ||
35 | |||
36 | /** | ||
25 | * struct dw_dma_slave - Controller-specific information about a slave | 37 | * struct dw_dma_slave - Controller-specific information about a slave |
26 | * @slave: Generic information about the slave | 38 | * |
27 | * @ctl_lo: Platform-specific initializer for the CTL_LO register | 39 | * @dma_dev: required DMA master device |
40 | * @tx_reg: physical address of data register used for | ||
41 | * memory-to-peripheral transfers | ||
42 | * @rx_reg: physical address of data register used for | ||
43 | * peripheral-to-memory transfers | ||
44 | * @reg_width: peripheral register width | ||
28 | * @cfg_hi: Platform-specific initializer for the CFG_HI register | 45 | * @cfg_hi: Platform-specific initializer for the CFG_HI register |
29 | * @cfg_lo: Platform-specific initializer for the CFG_LO register | 46 | * @cfg_lo: Platform-specific initializer for the CFG_LO register |
30 | */ | 47 | */ |
31 | struct dw_dma_slave { | 48 | struct dw_dma_slave { |
32 | struct dma_slave slave; | 49 | struct device *dma_dev; |
50 | dma_addr_t tx_reg; | ||
51 | dma_addr_t rx_reg; | ||
52 | enum dw_dma_slave_width reg_width; | ||
33 | u32 cfg_hi; | 53 | u32 cfg_hi; |
34 | u32 cfg_lo; | 54 | u32 cfg_lo; |
35 | }; | 55 | }; |
@@ -54,9 +74,4 @@ struct dw_dma_slave { | |||
54 | #define DWC_CFGL_HS_DST_POL (1 << 18) /* dst handshake active low */ | 74 | #define DWC_CFGL_HS_DST_POL (1 << 18) /* dst handshake active low */ |
55 | #define DWC_CFGL_HS_SRC_POL (1 << 19) /* src handshake active low */ | 75 | #define DWC_CFGL_HS_SRC_POL (1 << 19) /* src handshake active low */ |
56 | 76 | ||
57 | static inline struct dw_dma_slave *to_dw_dma_slave(struct dma_slave *slave) | ||
58 | { | ||
59 | return container_of(slave, struct dw_dma_slave, slave); | ||
60 | } | ||
61 | |||
62 | #endif /* DW_DMAC_H */ | 77 | #endif /* DW_DMAC_H */ |