UART截取字符到字符设备

 

要求:

msm_geni_serial_init() (drivers/tty/serial/msm_geni_serial.c)

-> platform_driver_register(&msm_geni_serial_platform_driver) (include/linux/platform_device.h)

static struct platform_driver msm_geni_serial_platform_driver = {
	.remove = msm_geni_serial_remove,
	.probe = msm_geni_serial_probe, /* probe函数,在这里进行uart_add_one_port */
    /* 注意,在platform_driver定义的时候就已经初始化device_driver了 */
	.driver = {
		.name = "msm_geni_serial",
		.of_match_table = msm_geni_device_tbl,
		.pm = &msm_geni_serial_pm_ops,
	},
};
/*
 * use a macro to avoid include chaining to get THIS_MODULE
 * 这个做法挺有趣,为了屏蔽THIS_MODULE,将_platfomr_driver_register使用一层宏封装起来
 */
#define platform_driver_register(drv) \
	__platform_driver_register(drv, THIS_MODULE)

-> __platform_driver_register() 对drv->driver的部分成员进行赋值:

/**
 * __platform_driver_register - register a driver for platform-level devices
 * @drv: platform driver structure
 * @owner: owning module/driver
 */
int __platform_driver_register(struct platform_driver *drv,
				struct module *owner)
{
	drv->driver.owner = owner;
	drv->driver.bus = &platform_bus_type;
	drv->driver.probe = platform_drv_probe;
	drv->driver.remove = platform_drv_remove;
	drv->driver.shutdown = platform_drv_shutdown;

	return driver_register(&drv->driver);
}

platform_driver长什么样呢?

struct platform_driver {
	int (*probe)(struct platform_device *);
	int (*remove)(struct platform_device *);
	void (*shutdown)(struct platform_device *);
	int (*suspend)(struct platform_device *, pm_message_t state);
	int (*resume)(struct platform_device *);
	struct device_driver driver; /* 上一块代码里的drv->driver即为device_driver,是所有设备驱动共用的一些属性,是驱动程序在内核驱动框架中的抽象 */
	const struct platform_device_id *id_table;
	bool prevent_deferred_probe;
};

-> driver_register(&drv->driver) drv->driver指device_driver

-> bus_add_driver(drv) 从这里开始,drv指device_driver

int bus_add_driver(struct device_driver *drv)
{
    ...
}

-> driver_attach(drv)

-> bus_for_each_dev(drv->bus, NULL, drv, __driver_attach)

bus_for_each_dev是个device iterator,对bus的device list进行遍历,并对其中所有device调用fn,这个fn就是__driver_attach:

static int __driver_attach(struct device *dev, void *data)
{
	struct device_driver *drv = data;
	int ret;

	/*
	 * Lock device and try to bind to it. We drop the error
	 * here and always return 0, because we need to keep trying
	 * to bind to devices and some drivers will return an error
	 * simply if it didn't support the device.
	 *
	 * driver_probe_device() will spit a warning if there
	 * is an error.
	 */

	ret = driver_match_device(drv, dev);
	if (ret == 0) {
		/* no match */
		return 0;
	} else if (ret == -EPROBE_DEFER) {
		dev_dbg(dev, "Device match requests probe deferral\n");
		driver_deferred_probe_add(dev);
	} else if (ret < 0) {
		dev_dbg(dev, "Bus failed to match device: %d", ret);
		return ret;
	} /* ret > 0 means positive match */

	if (dev->parent && dev->bus->need_parent_lock)
		device_lock(dev->parent);
	device_lock(dev);
    /* dev没有dead(dev处于或已经从系统中移除),且dev没有driver时 */
	if (!dev->p->dead && !dev->driver)
		driver_probe_device(drv, dev);
	device_unlock(dev);
	if (dev->parent && dev->bus->need_parent_lock)
		device_unlock(dev->parent);

	return 0;
}

-> driver_match_device(drv, dev) & driver_probe_device(drv, dev)

driver_match_device会调用drv->bus->match,将device_driver和device进行匹配:

static inline int driver_match_device(struct device_driver *drv,
				      struct device *dev)
{
	return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}

这里的match是platform_match,drv->bus在前面的__platform_driver_register中就已经完成赋值了,match函数长这样:

static int platform_match(struct device *dev, struct device_driver *drv)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct platform_driver *pdrv = to_platform_driver(drv);

	/* When driver_override is set, only bind to the matching driver */
	if (pdev->driver_override)
		return !strcmp(pdev->driver_override, drv->name);

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))
		return 1;

	/* Then try ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	/* Then try to match against the id table */
	if (pdrv->id_table)
		return platform_match_id(pdrv->id_table, pdev) != NULL;

	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0);
}

driver_probe_device尝试将device和driver绑定

driver_probe_device(drv, dev) -> really_probe()

static int really_probe(struct device *dev, struct device_driver *drv)
{
...
re_probe:
    ...
    /* dev->bus并没有被赋值 */ 
    if (dev->bus->probe) {
		ret = dev->bus->probe(dev);
		if (ret)
			goto probe_failed;
    /*而drv->probe在__platform_driver_register里就已经赋值 */
	} else if (drv->probe) {
		ret = drv->probe(dev);
		if (ret)
			goto probe_failed;
	}
    ...
}

drv->probe即为platform_drv_probe:

static int platform_drv_probe(struct device *_dev)
{
    /* 
     * to_platform_driver用container_of宏将包含_dev_driver的platform_driver提取出来     
     * to_platform_device同理
     */
	struct platform_driver *drv = to_platform_driver(_dev->driver);
	struct platform_device *dev = to_platform_device(_dev);
	int ret;

	ret = of_clk_set_defaults(_dev->of_node, false);
	if (ret < 0)
		return ret;

	ret = dev_pm_domain_attach(_dev, true);
	if (ret)
		goto out;
	/* 调用了platform_driver的probe方法,即msm_geni_serial_probe */
	if (drv->probe) {
		ret = drv->probe(dev);
		if (ret)
			dev_pm_domain_detach(_dev, true);
	}
    ...
}