*
* (Bursts are irrelevant for mem to mem transfers - there are no burst signals)
*
* Details of each tranfer on a particular channel
* are held in the DMA channel array
* A workqueue uses those details to initiate the actual transfer
* The DMAC interrupt clears the relevant transfer in the channel array
*
* ASSUMES only one DMAC device exists in the system
* ASSUMES default (little) endianness for DMA transfers
*
* Only DMAC flow control is implemented
*
*/
#include <linux/device.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/dmapool.h>
#include <asm/dma.h>
#include <asm/mach/dma.h>
#include <asm/atomic.h>
#include <asm/processor.h>
#include <linux/amba/bus.h>
#include <linux/dmaengine.h>
#include <asm/cacheflush.h>
#include <linux/amba/pl08x.h>
int ctr_chan[2];
/*
* Predeclare the DMAENGINE API functions
*/
static int pl08x_alloc_chan_resources(struct dma_chan *chan,
struct dma_client *client);
static void pl08x_free_chan_resources(struct dma_chan *chan);
static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
size_t len, unsigned long flags);
static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
struct dma_chan *chan, unsigned long flags);
static enum dma_status pl08x_dma_is_complete(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t *last,
dma_cookie_t *used);
static void pl08x_issue_pending(struct dma_chan *chan);
static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_data_direction direction,
unsigned long flags);
static void pl08x_terminate_all(struct dma_chan *chan);
struct dma_device dmac = {
.device_alloc_chan_resources = pl08x_alloc_chan_resources,
.device_free_chan_resources = pl08x_free_chan_resources,
.device_prep_dma_memcpy = pl08x_prep_dma_memcpy,
.device_prep_dma_xor = NULL,
.device_prep_dma_zero_sum = NULL,
.device_prep_dma_memset = NULL,
.device_prep_dma_interrupt = pl08x_prep_dma_interrupt,
.device_is_tx_complete = pl08x_dma_is_complete,
.device_issue_pending = pl08x_issue_pending,
.device_prep_slave_sg = pl08x_prep_slave_sg,
.device_terminate_all = pl08x_terminate_all,
};
|
这个dma_device是在dmaengine.h中定义的
其就是定义了一个架构,实现了DMA驱动的与具体设备无关的部分,然后提供具体接口,然后你具体的DMA驱动,去实现对应的接口
这样的好处是,省却了你的具体驱动,去关心太多那些通用dma驱动都应该要实现的一些功能等,省却了具体驱动编程者的精力
|