Skip to content

Commit

Permalink
mmc: atmel-mci: restore dma on AVR32
Browse files Browse the repository at this point in the history
Commit ecb89f2 ("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: Mans Rullgard <[email protected]>
Acked-by: Hans-Christian Noren Egtvedt <[email protected]>
Acked-by: Ludovic Desroches <[email protected]>
Acked-by: Ulf Hansson <[email protected]>
  • Loading branch information
mansr authored and egtvedt committed Jan 14, 2016
1 parent a193f07 commit 7484378
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
16 changes: 16 additions & 0 deletions arch/avr32/mach-at32ap/at32ap700x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,21 @@ static struct clk atmel_mci0_pclk = {
.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
at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
{
Expand Down Expand Up @@ -1355,6 +1370,7 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
slave->sdata.dst_master = 0;

data->dma_slave = slave;
data->dma_filter = at32_mci_dma_filter;

if (platform_device_add_data(pdev, data,
sizeof(struct mci_platform_data)))
Expand Down
17 changes: 17 additions & 0 deletions drivers/mmc/host/atmel-mci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2280,6 +2280,23 @@ static int atmci_configure_dma(struct atmel_mci *host)
{
host->dma.chan = dma_request_slave_channel_reason(&host->pdev->dev,
"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))
return PTR_ERR(host->dma.chan);

Expand Down
2 changes: 2 additions & 0 deletions include/linux/atmel-mci.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define __LINUX_ATMEL_MCI_H

#include <linux/types.h>
#include <linux/dmaengine.h>

#define ATMCI_MAX_NR_SLOTS 2

Expand Down Expand Up @@ -37,6 +38,7 @@ struct mci_slot_pdata {
*/
struct mci_platform_data {
struct mci_dma_data *dma_slave;
dma_filter_fn dma_filter;
struct mci_slot_pdata slot[ATMCI_MAX_NR_SLOTS];
};

Expand Down

0 comments on commit 7484378

Please sign in to comment.