atmel-mci: fix initialization of dma slave data

The conversion of atmel-mci to dma_request_channel missed the
initialization of the channel dma_slave information.  The filter_fn passed
to dma_request_channel is responsible for initializing the channel's
private data.  This implementation has the additional benefit of enabling
a generic client-channel data passing mechanism.

Reviewed-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Dan Williams 2009-02-18 14:48:26 -08:00 committed by Linus Torvalds
parent 9ccf3b5e84
commit 287d859222
5 changed files with 9 additions and 7 deletions

View File

@ -518,6 +518,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
dma_chan_name(chan), err); dma_chan_name(chan), err);
else else
break; break;
chan->private = NULL;
chan = NULL; chan = NULL;
} }
} }
@ -536,6 +537,7 @@ void dma_release_channel(struct dma_chan *chan)
WARN_ONCE(chan->client_count != 1, WARN_ONCE(chan->client_count != 1,
"chan reference count %d != 1\n", chan->client_count); "chan reference count %d != 1\n", chan->client_count);
dma_chan_put(chan); dma_chan_put(chan);
chan->private = NULL;
mutex_unlock(&dma_list_mutex); mutex_unlock(&dma_list_mutex);
} }
EXPORT_SYMBOL_GPL(dma_release_channel); EXPORT_SYMBOL_GPL(dma_release_channel);

View File

@ -560,7 +560,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
unsigned long flags) unsigned long flags)
{ {
struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma_slave *dws = dwc->dws; struct dw_dma_slave *dws = chan->private;
struct dw_desc *prev; struct dw_desc *prev;
struct dw_desc *first; struct dw_desc *first;
u32 ctllo; u32 ctllo;
@ -790,7 +790,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
cfghi = DWC_CFGH_FIFO_MODE; cfghi = DWC_CFGH_FIFO_MODE;
cfglo = 0; cfglo = 0;
dws = dwc->dws; dws = chan->private;
if (dws) { if (dws) {
/* /*
* We need controller-specific data to set up slave * We need controller-specific data to set up slave
@ -866,7 +866,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
spin_lock_bh(&dwc->lock); spin_lock_bh(&dwc->lock);
list_splice_init(&dwc->free_list, &list); list_splice_init(&dwc->free_list, &list);
dwc->descs_allocated = 0; dwc->descs_allocated = 0;
dwc->dws = NULL;
/* Disable interrupts */ /* Disable interrupts */
channel_clear_bit(dw, MASK.XFER, dwc->mask); channel_clear_bit(dw, MASK.XFER, dwc->mask);

View File

@ -139,8 +139,6 @@ struct dw_dma_chan {
struct list_head queue; struct list_head queue;
struct list_head free_list; struct list_head free_list;
struct dw_dma_slave *dws;
unsigned int descs_allocated; unsigned int descs_allocated;
}; };

View File

@ -1548,9 +1548,10 @@ static bool filter(struct dma_chan *chan, void *slave)
{ {
struct dw_dma_slave *dws = slave; struct dw_dma_slave *dws = slave;
if (dws->dma_dev == chan->device->dev) if (dws->dma_dev == chan->device->dev) {
chan->private = dws;
return true; return true;
else } else
return false; return false;
} }
#endif #endif

View File

@ -121,6 +121,7 @@ struct dma_chan_percpu {
* @local: per-cpu pointer to a struct dma_chan_percpu * @local: per-cpu pointer to a struct dma_chan_percpu
* @client-count: how many clients are using this channel * @client-count: how many clients are using this channel
* @table_count: number of appearances in the mem-to-mem allocation table * @table_count: number of appearances in the mem-to-mem allocation table
* @private: private data for certain client-channel associations
*/ */
struct dma_chan { struct dma_chan {
struct dma_device *device; struct dma_device *device;
@ -134,6 +135,7 @@ struct dma_chan {
struct dma_chan_percpu *local; struct dma_chan_percpu *local;
int client_count; int client_count;
int table_count; int table_count;
void *private;
}; };
/** /**