musb_core.c 中的 musb_init_controller() 中,会调用到 dma_controller_create(),代码 如下:
#ifndef CONFIG_MUSB_PIO_ONLY //如果没有选上 PIO 模式,则使能 DMA 模式
if (use_dma && dev->dma_mask) {
struct dma_controller *c;
c = dma_controller_create(musb, musb->mregs);
musb->dma_controller = c;
if (c)
(void) c->start(c);
}
#endif
1. dma_controller_create() 定义在 cartesio_dma.c 中:
struct dma_controller *__init
dma_controller_create(struct musb *musb, void __iomem *base)
{
struct musb_dma_controller *controller;
struct device *dev = musb->controller;
struct platform_device *pdev = to_platform_device(dev);
struct musb_hdrc_platform_data *plat = dev->platform_data;
struct resource *res;
controller = kzalloc(sizeof(*controller), GFP_KERNEL);
if (!controller)
return NULL;
controller->dma_client = plat->dma_slave;
controller->channel_count = MUSB_DMA_CHANNELS;
controller->private_data = musb;
/* need to set physical address in case of DMA */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
controller->musb_base_phy = (unsigned int *)res->start;
controller->controller.start = dma_controller_start;
controller->controller.stop = dma_controller_stop;
controller->controller.channel_alloc = dma_channel_allocate;
controller->controller.channel_release = dma_channel_release;
controller->controller.channel_program = dma_channel_program;
controller->controller.channel_abort = dma_channel_abort;
return &controller->controller;
}
2. dma_controller_start() / dma_controller_stop()
static int dma_controller_start(struct dma_controller *c)
{
struct musb_dma_controller *controller = container_of(c,
struct musb_dma_controller, controller);
/* Preallocate 1 bulk TX and 1 bulk RX dma channels. */
controller->bulk_dma_channels[0] = dma_channel_preallocate(c, 1);
controller->bulk_dma_channels[1] = dma_channel_preallocate(c, 0);
return 0;
}
static struct dma_channel *dma_channel_preallocate(struct dma_controller *c,
u8 transmit)
static struct dma_channel *dma_channel_preallocate(struct dma_controller *c,
u8 transmit)
{
struct musb_dma_controller *controller = container_of(c,
struct musb_dma_controller, controller);
struct musb *musb = controller->private_data;
struct musb_dma_channel *musb_channel;
struct dma_channel *channel;
struct pl080_dma_slave *client;
dma_cap_mask_t mask;
u8 bit;
for (bit = 0; bit < MUSB_DMA_CHANNELS; bit++) {
if (!(controller->used_channels & (1 << bit)))
break;
}
if (bit == MUSB_DMA_CHANNELS) {
dev_err(musb->controller, "No USB DMA channel free\n");
return NULL;
}
controller->used_channels |= (1 << bit);
musb_channel = &(controller->channel[bit]);
musb_channel->controller = controller;
musb_channel->idx = bit;
musb_channel->transmit = transmit;
channel = &(musb_channel->channel);
channel->private_data = musb_channel;
channel->status = MUSB_DMA_STATUS_UNKNOWN;
/* dma max_len is not used, as we use scatter gather. */
channel->max_len = 0x10000;
/* dma mode 1 => 1; dma mode 0 => 0 always use 1*/
channel->desired_mode = 1;
channel->actual_len = 0;
client = &controller->dma_client;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
musb_channel-