aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/atmel-mci.c98
1 files changed, 27 insertions, 71 deletions
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
1446static inline struct atmel_mci *
1447dma_client_to_atmel_mci(struct dma_client *client)
1448{
1449 return container_of(client, struct atmel_mci, dma.client);
1450}
1451
1452static 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
1498static int __init atmci_init_slot(struct atmel_mci *host, 1444static 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
1548static 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
1601static int __init atmci_probe(struct platform_device *pdev) 1559static 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
1698err_init_slot: 1654err_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);
1704err_request_irq: 1660err_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
1762module_init(atmci_init); 1718late_initcall(atmci_init); /* try to load after dma driver when built-in */
1763module_exit(atmci_exit); 1719module_exit(atmci_exit);
1764 1720
1765MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); 1721MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver");