Commit 74843787 authored by Mans Rullgard's avatar Mans Rullgard Committed by Hans-Christian Egtvedt

mmc: atmel-mci: restore dma on AVR32

Commit ecb89f2f ("mmc: atmel-mci: remove compat for non DT board
when requesting dma chan") broke dma on AVR32 and any other boards not
using DT.  This restores a fallback mechanism for such cases.
Signed-off-by: default avatarMans Rullgard <mans@mansr.com>
Acked-by: default avatarHans-Christian Noren Egtvedt <egtvedt@samfundet.no>
Acked-by: default avatarLudovic Desroches <ludovic.desroches@atmel.com>
Acked-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent a193f07d
...@@ -1321,6 +1321,21 @@ static struct clk atmel_mci0_pclk = { ...@@ -1321,6 +1321,21 @@ static struct clk atmel_mci0_pclk = {
.index = 9, .index = 9,
}; };
static bool at32_mci_dma_filter(struct dma_chan *chan, void *pdata)
{
struct mci_dma_data *sl = pdata;
if (!sl)
return false;
if (find_slave_dev(sl) == chan->device->dev) {
chan->private = slave_data_ptr(sl);
return true;
}
return false;
}
struct platform_device *__init struct platform_device *__init
at32_add_device_mci(unsigned int id, struct mci_platform_data *data) at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
{ {
...@@ -1355,6 +1370,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) ...@@ -1355,6 +1370,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
slave->sdata.dst_master = 0; slave->sdata.dst_master = 0;
data->dma_slave = slave; data->dma_slave = slave;
data->dma_filter = at32_mci_dma_filter;
if (platform_device_add_data(pdev, data, if (platform_device_add_data(pdev, data,
sizeof(struct mci_platform_data))) sizeof(struct mci_platform_data)))
......
...@@ -2280,6 +2280,23 @@ static int atmci_configure_dma(struct atmel_mci *host) ...@@ -2280,6 +2280,23 @@ static int atmci_configure_dma(struct atmel_mci *host)
{ {
host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev, host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev,
"rxtx"); "rxtx");
if (PTR_ERR(host->dma.chan) == -ENODEV) {
struct mci_platform_data *pdata = host->pdev->dev.platform_data;
dma_cap_mask_t mask;
if (!pdata->dma_filter)
return -ENODEV;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
host->dma.chan = dma_request_channel(mask, pdata->dma_filter,
pdata->dma_slave);
if (!host->dma.chan)
host->dma.chan = ERR_PTR(-ENODEV);
}
if (IS_ERR(host->dma.chan)) if (IS_ERR(host->dma.chan))
return PTR_ERR(host->dma.chan); return PTR_ERR(host->dma.chan);
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __LINUX_ATMEL_MCI_H #define __LINUX_ATMEL_MCI_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/dmaengine.h>
#define ATMCI_MAX_NR_SLOTS 2 #define ATMCI_MAX_NR_SLOTS 2
...@@ -37,6 +38,7 @@ struct mci_slot_pdata { ...@@ -37,6 +38,7 @@ struct mci_slot_pdata {
*/ */
struct mci_platform_data { struct mci_platform_data {
struct mci_dma_data *dma_slave; struct mci_dma_data *dma_slave;
dma_filter_fn dma_filter;
struct mci_slot_pdata slot[ATMCI_MAX_NR_SLOTS]; struct mci_slot_pdata slot[ATMCI_MAX_NR_SLOTS];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment