struct platform_driver {
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
int (*resume)(struct platform_device *);
struct device_driver driver;
};
这个结构体在platfoem_driver.h中定义。字面翻译为平台驱动,里面包含了探测,删除,关闭,挂起,重启回调函数,同时包含一个设备驱动结构体。
static int serial_imx_probe(struct platform_device *pdev)
{
struct imx_port *sport;
struct imxuart_platform_data *pdata;
void __iomem *base;
int ret = 0;
struct resource *res;
sport = kzalloc(sizeof(*sport), GFP_KERNEL);//申请内存,底层是calloc
if (!sport)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);//第一条注释
if (!res) {
ret = -ENODEV;
goto free;
}
base = ioremap(res->start, PAGE_SIZE);//ioremap将一个IO地址空间映射到内核的虚拟地址空间上去,便于访问。(这是百度百科参考的优快云的结果,呃呃)具体不深入
if (!base) {
ret = -ENOMEM;
goto free;
}
sport->port.dev = &pdev->dev;//下面都是对sport这个结构体的赋值
sport->port.mapbase = res->start;
sport->port.membase = base;
sport->port.type = PORT_IMX,
sport->port.iotype = UPIO_MEM;
sport->port.irq = platform_get_irq(pdev, 0);
sport->rxirq = platform_get_irq(pdev, 0);
sport->txirq = platform_get_irq(pdev, 1);
sport->rtsirq = platform_get_irq(pdev, 2);
sport->port.fifosize = 32;
sport->port.ops = &imx_pops;
sport->port.flags = UPF_BOOT_AUTOCONF;
sport->port.line = pdev->id;
init_timer(&sport->timer);
sport->timer.function = imx_timeout;
sport->timer.data = (unsigned long)sport;
sport->clk = clk_get(&pdev->dev, "uart");
if (IS_ERR(sport->clk)) {
ret = PTR_ERR(sport->clk);
goto unmap;
}
if (uart_at_24)
clk_set_parent(sport->clk, clk_get(NULL, "osc"));
clk_enable(sport->clk);
sport->port.uartclk = clk_get_rate(sport->clk);
imx_ports[pdev->id] = sport;
pdata = pdev->dev.platform_data;
if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
sport->have_rtscts = 1;
if (pdata && (pdata->flags & IMXUART_USE_DCEDTE))
sport->use_dcedte = 1;
if (pdata && (pdata->flags & IMXUART_SDMA))
sport->enable_dma = 1;
#ifdef CONFIG_IRDA
if (pdata && (pdata->flags & IMXUART_IRDA))
sport->use_irda = 1;
#endif
if (pdata && pdata->init) {
ret = pdata->init(pdev);
if (ret)
goto clkput;
}
ret = uart_add_one_port(&imx_reg, &sport->port);
if (ret)
goto deinit;
platform_set_drvdata(pdev, &sport->port);
clk_disable(sport->clk);
return 0;
deinit:
if (pdata && pdata->exit)
pdata->exit(pdev);
clkput:
clk_put(sport->clk);
clk_disable(sport->clk);
unmap:
iounmap(sport->port.membase);
free:
kfree(sport);
return ret;
}
这是imx串口的probe回调函数,看看这个函数做了什么:
1.
platform_get_resource(pdev, IORESOURCE_MEM, 0)
看看这个函数干了什么,字面上是获得资源,跟踪之后(略)可以看到是通过传入的platdorm_device返回resource结构体,将resource结构体摘录如下:
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
可以看到这个结构体包含一个起始地址,一个结束地址,一个name一个flages以及一个父节点,兄弟节点,子节点。说明这个资源结构体应该是通过树的形式管理的。