串口初始化:
static inline void mx6q_sabresd_init_uart(void)
{
imx6q_add_imx_uart(2, NULL);
imx6q_add_imx_uart(0, NULL);
}
跟踪这个函数:imx6q_add_imx_uart
#define imx6q_add_imx_uart(id, pdata) \
imx_add_imx_uart_1irq(&imx6q_imx_uart_data[id], pdata)
先关注一下参数imx6q_imx_uart_data[]:
const struct imx_imx_uart_1irq_data imx6sl_imx_uart_data[] __initconst = {
#define imx6sl_imx_uart_data_entry(_id, _hwid) \
imx_imx_uart_1irq_data_entry(MX6SL, _id, _hwid, SZ_4K)
imx6sl_imx_uart_data_entry(0, 1),
imx6sl_imx_uart_data_entry(1, 2),
imx6sl_imx_uart_data_entry(2, 3),
imx6sl_imx_uart_data_entry(3, 4),
imx6sl_imx_uart_data_entry(4, 5),
};
跟踪一下imx_inx_yart_1irq_data_entry:
#define imx_imx_uart_1irq_data_entry(soc, _id, _hwid, _size) \
[_id] = { \
.id = _id, \
.iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
.iosize = _size, \
.irq = soc ## _INT_UART ## _hwid, \
}
然后再看看这句:imx6sl_imx_uart_data_entry(0, 1),
我们把他展开iobase=MX6SL_UART1_BASE_ADDR
arm$ grep MX6SL_UART1_BASE_ADDR * -R
plat-mxc/include/mach/mx6.h:#define MX6SL_UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* MX6SL */
通过这个命令我们找到这个宏定义。然后再展开0X02000000+0x20000=0x02020000;这应该就是一个物理地址。
然后再回来看看这个函数:
imx_add_imx_uart_1irq
struct platform_device *__init imx_add_imx_uart_1irq( const struct imx_imx_uart_1irq_data *data, const struct imxuart_platform_data *pdata) { struct resource res[] = { { .start = data->iobase, .end = data->iobase + data->iosize - 1, .flags = IORESOURCE_MEM, }, { .start = data->irq, .end = data->irq, .flags = IORESOURCE_IRQ, }, }; return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); }
然后是这个函数imx_add_platform_device
static inline struct platform_device *imx_add_platform_device( const char *name, int id, const struct resource *res, unsigned int num_resources, const void *data, size_t size_data) { return imx_add_platform_device_dmamask( name, id, res, num_resources, data, size_data, 0); }
然后这个是最终的设备注册函数。struct platform_device *__init imx_add_platform_device_dmamask( const char *name, int id, const struct resource *res, unsigned int num_resources, const void *data, size_t size_data, u64 dmamask) { int ret = -ENOMEM; struct platform_device *pdev; pdev = platform_device_alloc(name, id); if (!pdev) goto err; if (dmamask) { /* * This memory isn't freed when the device is put, * I don't have a nice idea for that though. Conceptually * dma_mask in struct device should not be a pointer. * See http://thread.gmane.org/gmane.linux.kernel.pci/9081