Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 127983
b: refs/heads/master
c: 74465b4
h: refs/heads/master
i:
  127981: 1285d43
  127979: fcdf421
  127975: 7e70fb7
  127967: 7b3997d
v: v3
  • Loading branch information
Dan Williams committed Jan 6, 2009
1 parent 40c02c5 commit 1f0808d
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 160 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 33df8ca068123457db56c316946a3c0e4ef787d6
refs/heads/master: 74465b4ff9ac1da503025c0a0042e023bfa6505c
6 changes: 3 additions & 3 deletions trunk/arch/avr32/include/asm/atmel-mci.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define ATMEL_MCI_MAX_NR_SLOTS 2

struct dma_slave;
#include <linux/dw_dmac.h>

/**
* struct mci_slot_pdata - board-specific per-slot configuration
Expand All @@ -28,11 +28,11 @@ struct mci_slot_pdata {

/**
* struct mci_platform_data - board-specific MMC/SDcard configuration
* @dma_slave: DMA slave interface to use in data transfers, or NULL.
* @dma_slave: DMA slave interface to use in data transfers.
* @slot: Per-slot configuration data.
*/
struct mci_platform_data {
struct dma_slave *dma_slave;
struct dw_dma_slave dma_slave;
struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS];
};

Expand Down
15 changes: 3 additions & 12 deletions trunk/arch/avr32/mach-at32ap/at32ap700x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ struct platform_device *__init
at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
{
struct platform_device *pdev;
struct dw_dma_slave *dws;
struct dw_dma_slave *dws = &data->dma_slave;
u32 pioa_mask;
u32 piob_mask;

Expand All @@ -1324,22 +1324,13 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
ARRAY_SIZE(atmel_mci0_resource)))
goto fail;

if (data->dma_slave)
dws = kmemdup(to_dw_dma_slave(data->dma_slave),
sizeof(struct dw_dma_slave), GFP_KERNEL);
else
dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);

dws->slave.dev = &pdev->dev;
dws->slave.dma_dev = &dw_dmac0_device.dev;
dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT;
dws->dma_dev = &dw_dmac0_device.dev;
dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
| DWC_CFGH_DST_PER(1));
dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
| DWC_CFGL_HS_SRC_POL);

data->dma_slave = &dws->slave;

if (platform_device_add_data(pdev, data,
sizeof(struct mci_platform_data)))
goto fail;
Expand Down
8 changes: 0 additions & 8 deletions trunk/drivers/dma/dmaengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,6 @@ static void dma_client_chan_alloc(struct dma_client *client)
list_for_each_entry(device, &dma_device_list, global_node) {
if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
continue;
/* Does the client require a specific DMA controller? */
if (client->slave && client->slave->dma_dev
&& client->slave->dma_dev != device->dev)
continue;
if (!dma_device_satisfies_mask(device, client->cap_mask))
continue;

Expand Down Expand Up @@ -613,10 +609,6 @@ void dma_async_client_register(struct dma_client *client)
struct dma_chan *chan;
int err;

/* validate client data */
BUG_ON(dma_has_cap(DMA_SLAVE, client->cap_mask) &&
!client->slave);

mutex_lock(&dma_list_mutex);
dmaengine_ref_count++;

Expand Down
25 changes: 6 additions & 19 deletions trunk/drivers/dma/dw_dmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
if (unlikely(!dws || !sg_len))
return NULL;

reg_width = dws->slave.reg_width;
reg_width = dws->reg_width;
prev = first = NULL;

sg_len = dma_map_sg(chan->dev.parent, sgl, sg_len, direction);
Expand All @@ -579,7 +579,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
| DWC_CTLL_DST_FIX
| DWC_CTLL_SRC_INC
| DWC_CTLL_FC_M2P);
reg = dws->slave.tx_reg;
reg = dws->tx_reg;
for_each_sg(sgl, sg, sg_len, i) {
struct dw_desc *desc;
u32 len;
Expand Down Expand Up @@ -625,7 +625,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
| DWC_CTLL_SRC_FIX
| DWC_CTLL_FC_P2M);

reg = dws->slave.rx_reg;
reg = dws->rx_reg;
for_each_sg(sgl, sg, sg_len, i) {
struct dw_desc *desc;
u32 len;
Expand Down Expand Up @@ -764,20 +764,13 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan,
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
struct dw_desc *desc;
struct dma_slave *slave;
struct dw_dma_slave *dws;
int i;
u32 cfghi;
u32 cfglo;

dev_vdbg(&chan->dev, "alloc_chan_resources\n");

/* Channels doing slave DMA can only handle one client. */
if (dwc->dws || (client && client->slave)) {
if (chan->client_count)
return -EBUSY;
}

/* ASSERT: channel is idle */
if (dma_readl(dw, CH_EN) & dwc->mask) {
dev_dbg(&chan->dev, "DMA channel not idle?\n");
Expand All @@ -789,23 +782,17 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan,
cfghi = DWC_CFGH_FIFO_MODE;
cfglo = 0;

slave = client->slave;
if (slave) {
dws = dwc->dws;
if (dws) {
/*
* We need controller-specific data to set up slave
* transfers.
*/
BUG_ON(!slave->dma_dev || slave->dma_dev != dw->dma.dev);

dws = container_of(slave, struct dw_dma_slave, slave);
BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);

dwc->dws = dws;
cfghi = dws->cfg_hi;
cfglo = dws->cfg_lo;
} else {
dwc->dws = NULL;
}

channel_writel(dwc, CFG_LO, cfglo);
channel_writel(dwc, CFG_HI, cfghi);

Expand Down
98 changes: 27 additions & 71 deletions trunk/drivers/mmc/host/atmel-mci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1441,60 +1441,6 @@ static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}

#ifdef CONFIG_MMC_ATMELMCI_DMA

static inline struct atmel_mci *
dma_client_to_atmel_mci(struct dma_client *client)
{
return container_of(client, struct atmel_mci, dma.client);
}

static enum dma_state_client atmci_dma_event(struct dma_client *client,
struct dma_chan *chan, enum dma_state state)
{
struct atmel_mci *host;
enum dma_state_client ret = DMA_NAK;

host = dma_client_to_atmel_mci(client);

switch (state) {
case DMA_RESOURCE_AVAILABLE:
spin_lock_bh(&host->lock);
if (!host->dma.chan) {
host->dma.chan = chan;
ret = DMA_ACK;
}
spin_unlock_bh(&host->lock);

if (ret == DMA_ACK)
dev_info(&host->pdev->dev,
"Using %s for DMA transfers\n",
chan->dev.bus_id);
break;

case DMA_RESOURCE_REMOVED:
spin_lock_bh(&host->lock);
if (host->dma.chan == chan) {
host->dma.chan = NULL;
ret = DMA_ACK;
}
spin_unlock_bh(&host->lock);

if (ret == DMA_ACK)
dev_info(&host->pdev->dev,
"Lost %s, falling back to PIO\n",
chan->dev.bus_id);
break;

default:
break;
}


return ret;
}
#endif /* CONFIG_MMC_ATMELMCI_DMA */

static int __init atmci_init_slot(struct atmel_mci *host,
struct mci_slot_pdata *slot_data, unsigned int id,
u32 sdc_reg)
Expand Down Expand Up @@ -1598,6 +1544,18 @@ static void __exit atmci_cleanup_slot(struct atmel_mci_slot *slot,
mmc_free_host(slot->mmc);
}

#ifdef CONFIG_MMC_ATMELMCI_DMA
static enum dma_state_client filter(struct dma_chan *chan, void *slave)
{
struct dw_dma_slave *dws = slave;

if (dws->dma_dev == chan->device->dev)
return DMA_ACK;
else
return DMA_DUP;
}
#endif

static int __init atmci_probe(struct platform_device *pdev)
{
struct mci_platform_data *pdata;
Expand Down Expand Up @@ -1650,22 +1608,20 @@ static int __init atmci_probe(struct platform_device *pdev)
goto err_request_irq;

#ifdef CONFIG_MMC_ATMELMCI_DMA
if (pdata->dma_slave) {
struct dma_slave *slave = pdata->dma_slave;
if (pdata->dma_slave.dma_dev) {
struct dw_dma_slave *dws = &pdata->dma_slave;
dma_cap_mask_t mask;

slave->tx_reg = regs->start + MCI_TDR;
slave->rx_reg = regs->start + MCI_RDR;
dws->tx_reg = regs->start + MCI_TDR;
dws->rx_reg = regs->start + MCI_RDR;

/* Try to grab a DMA channel */
host->dma.client.event_callback = atmci_dma_event;
dma_cap_set(DMA_SLAVE, host->dma.client.cap_mask);
host->dma.client.slave = slave;

dma_async_client_register(&host->dma.client);
dma_async_client_chan_request(&host->dma.client);
} else {
dev_notice(&pdev->dev, "DMA not available, using PIO\n");
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
host->dma.chan = dma_request_channel(mask, filter, dws);
}
if (!host->dma.chan)
dev_notice(&pdev->dev, "DMA not available, using PIO\n");
#endif /* CONFIG_MMC_ATMELMCI_DMA */

platform_set_drvdata(pdev, host);
Expand Down Expand Up @@ -1697,8 +1653,8 @@ static int __init atmci_probe(struct platform_device *pdev)

err_init_slot:
#ifdef CONFIG_MMC_ATMELMCI_DMA
if (pdata->dma_slave)
dma_async_client_unregister(&host->dma.client);
if (host->dma.chan)
dma_release_channel(host->dma.chan);
#endif
free_irq(irq, host);
err_request_irq:
Expand Down Expand Up @@ -1729,8 +1685,8 @@ static int __exit atmci_remove(struct platform_device *pdev)
clk_disable(host->mck);

#ifdef CONFIG_MMC_ATMELMCI_DMA
if (host->dma.client.slave)
dma_async_client_unregister(&host->dma.client);
if (host->dma.chan)
dma_release_channel(host->dma.chan);
#endif

free_irq(platform_get_irq(pdev, 0), host);
Expand Down Expand Up @@ -1759,7 +1715,7 @@ static void __exit atmci_exit(void)
platform_driver_unregister(&atmci_driver);
}

module_init(atmci_init);
late_initcall(atmci_init); /* try to load after dma driver when built-in */
module_exit(atmci_exit);

MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver");
Expand Down
38 changes: 0 additions & 38 deletions trunk/include/linux/dmaengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,6 @@ enum dma_transaction_type {
/* last transaction type for creation of the capabilities mask */
#define DMA_TX_TYPE_END (DMA_SLAVE + 1)

/**
* enum dma_slave_width - DMA slave register access width.
* @DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
* @DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
* @DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
*/
enum dma_slave_width {
DMA_SLAVE_WIDTH_8BIT,
DMA_SLAVE_WIDTH_16BIT,
DMA_SLAVE_WIDTH_32BIT,
};

/**
* enum dma_ctrl_flags - DMA flags to augment operation preparation,
Expand All @@ -132,32 +121,6 @@ enum dma_ctrl_flags {
*/
typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;

/**
* struct dma_slave - Information about a DMA slave
* @dev: device acting as DMA slave
* @dma_dev: required DMA master device. If non-NULL, the client can not be
* bound to other masters than this.
* @tx_reg: physical address of data register used for
* memory-to-peripheral transfers
* @rx_reg: physical address of data register used for
* peripheral-to-memory transfers
* @reg_width: peripheral register width
*
* If dma_dev is non-NULL, the client can not be bound to other DMA
* masters than the one corresponding to this device. The DMA master
* driver may use this to determine if there is controller-specific
* data wrapped around this struct. Drivers of platform code that sets
* the dma_dev field must therefore make sure to use an appropriate
* controller-specific dma slave structure wrapping this struct.
*/
struct dma_slave {
struct device *dev;
struct device *dma_dev;
dma_addr_t tx_reg;
dma_addr_t rx_reg;
enum dma_slave_width reg_width;
};

/**
* struct dma_chan_percpu - the per-CPU part of struct dma_chan
* @refcount: local_t used for open-coded "bigref" counting
Expand Down Expand Up @@ -248,7 +211,6 @@ typedef enum dma_state_client (*dma_filter_fn)(struct dma_chan *chan, void *filt
struct dma_client {
dma_event_callback event_callback;
dma_cap_mask_t cap_mask;
struct dma_slave *slave;
struct list_head global_node;
};

Expand Down
Loading

0 comments on commit 1f0808d

Please sign in to comment.