DMA控制器驱动框架中的第二个函数:
s3c24xx_dma_order_set(&s3c2440_dma_order);
参数s3c2440_dma_order是一个全局变量,抽象的是下图物理channel和逻辑channel及其互相关系:
static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
.channels = {
[DMACH_SDI] = {
.list = {
[0] = 3 | DMA_CH_VALID,
[1] = 2 | DMA_CH_VALID,
[2] = 1 | DMA_CH_VALID,
[3] = 0 | DMA_CH_VALID,
},
},
[DMACH_I2S_IN] = {
.list = {
[0] = 1 | DMA_CH_VALID,
[1] = 2 | DMA_CH_VALID,
},
},
......
},
};
对于SDIO/MMC/SD,其DMA源有4个(上图红框),位于物理channel的0~3通道;同样,I2SSDI的DMA源有2个,位于通道0、1等等。
再来看s3c24xx_dma_order_set()函数:
int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
{
struct s3c24xx_dma_order *nord = dma_order;
if (nord == NULL)
nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
if (nord == NULL) {
printk(KERN_ERR "no memory to store dma channel order\n");
return -ENOMEM;
}
dma_order = nord;
memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
return 0;
}
还是很简单:为全局变量dma_order分配空间并把s3c2440_dma_order的内容copy过去,何必多此一举?
最后一个函数:
s3c24xx_dma_init_map(&s3c2440_dma_sel);
int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
{
struct s3c24xx_dma_map *nmap;
size_t map_sz = sizeof(*nmap) * sel->map_size;
int ptr;
nmap = kmalloc(map_sz, GFP_KERNEL);
if (nmap == NULL)
return -ENOMEM;
memcpy(nmap, sel->map, map_sz);
memcpy(&dma_sel, sel, sizeof(*sel));
dma_sel.map = nmap;
for (ptr = 0; ptr < sel->map_size; ptr++)
s3c24xx_dma_check_entry(nmap+ptr, ptr);
return 0;
}
和
s
3
c
2