串口初始化:
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
这个是最终的设备注册函数。