The first day of the ARTS challenge check-in --- matching rules for Linux drivers and devices (Tips)

foreword

(1) Because in Linux driver development, the driver can be matched with the device c file or with the device tree dts file. In order to understand the matching rules between drivers and them, I consulted some information and read the source code, and finally planned to use pictures to write a blog in a concrete way.
(2) The information on the Internet is basically the same, and the source code is posted dryly, and then analyzed. However, the call relationship in Linux is too complicated, and it is easy to get dizzy.
(3) Therefore, based on the analysis of the big guys, I slowly looked at the code bit by bit. Finally, I have a certain understanding of the matching rules between drivers and devices.
(4)Through the source code, we can know that there are 5 matching rules for Linux. But many times, there are only 4 on the Internet, either ignoring the acpi matching rules, or ignoring the driver_override matching rules in the device. I also read the tutorials of Punctual Atom, Wei Dongshan, and Beijing Xunwei, and found that they all ignored these matching rules to a certain extent. I'll explain why it's ignored later.

Five matching rules for Linux drivers and devices

Driver and device matching source code

(1) In the Linux platform bus, we use the platform_match() function to match the device and the driver.
(2) The platform_match() function is defined in the file drivers/base/platform.c, and
the content of the function is as follows:

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);
}

(3) From the above code, we can see that there are four if judgments, and the last return also calls the strcmp() function to compare strings. Therefore we can conclude that:In Linux, there are 5 matching rules for drivers and devices.

match rule 1

(1) First of all, we need to know what dev, drv, pdev and pdrv represent respectively. In fact, we can see it from his variable definition.
<1>pdev = platform_device
<2>dev = platform_device.dev
<3>pdrv = platform_driver
<4>drv = platform_driver.driver
(2) It can be seen from this,He first judges whether platform_device.driver_override has been assigned a value. If it is assigned, no matter whether it is matched or not, the following procedures will not proceed again!
(3) If platform_device.driver_override is assigned, then we start to judge whether platform_device.driver_override == platform_driver.driver.name is true. If it is established, the match is successful, otherwise the match fails.

if (pdev->driver_override)
	return !strcmp(pdev->driver_override, drv->name);

insert image description here

match rule 2

(1)This one is mainly used to match with the device tree. Here is a knowledge point, we can see that this function is of type, and the functions prefixed with of are used to match with the device tree.
(2) We can see that this is actually platform_driver.driver.of_match_table matching with the compatible attribute of the device tree . (As shown below)

static inline int of_driver_match_device(struct device *dev,const struct device_driver *drv)
{
    
    
	return of_match_device(drv->of_match_table, dev) != NULL;
}
if (of_driver_match_device(dev, drv))
	return 1;
	

insert image description here

match rule 3

(1) Many people in this article directly say ACPI matching method, and then there is no more. At first I thought it was because too few people used it, so I avoided talking about it. It turns out that you can't change it at all.
(2) ACPI is mainly used on traditional PC platforms of x86 architecture, especially on desktops and laptops. It is more complex and contains rich system management and power management functions. It cannot be modified by the developer, only by the motherboard vendor to modify the BIOS firmware.
(3)So you don't have to worry about this.

if (acpi_driver_match_device(dev, drv))
	return 1;

match rule 4

(1)The fourth rule is to judge whether the platform_driver.id_table has been assigned a value. If it is assigned, no matter whether it is matched or not, the following procedures will not be carried out again!
(2) To put it bluntly, it is to let platform_driver.id_table.name == platform_device.name perform name matching. If the names are the same, the matching is successful.

static const struct platform_device_id *platform_match_id(
			const struct platform_device_id *id,
			struct platform_device *pdev)
{
    
    
	while (id->name[0]) {
    
    
		if (strcmp(pdev->name, id->name) == 0) {
    
    
			pdev->id_entry = id;
			return id;
		}
		id++;
	}
	return NULL;
}
if (pdrv->id_table)
	return platform_match_id(pdrv->id_table, pdev) != NULL;

insert image description here

match rule 5

(1) This is the next step, platform_device.driver_override and platform_driver.id_table are not defined. At the same time, the device tree did not match successfully. This match is made eventually.
(2) This matching is very simple, whether platform_device.name == platform_driver.driver.name is equal, if equal, it means that the driver and device match successfully. Otherwise, the complete matching between the driver and the device fails.

return (strcmp(pdev->name, drv->name) == 0);

insert image description here

Summarize

(1) Generally speaking, we only write two in the platform_driver structure of the driver.
<1>platform_driver.driver.name is used to match the c file.
<2>platform_driver.driver.of_match_table is used to match with the device tree.
(2)Note: If we only write the above two matching methods, neither platform_device.driver_override nor platform_driver.id_table can be assigned!
(3) Why do people often say that the Linux driver has only 4 matching rules? The reason is simple, ACPI developers cannot make changes, only motherboard suppliers can modify the BIOS firmware, so everyone chooses to ignore it.
(4) Why do many people ignore the driver_override matching rules? Very simple, if the driver_override matching rule is assigned, then the following four rules will be invalid. So generally do not write this one.

static struct platform_driver gpio_platform_driver = {
    
    
	.driver		= {
    
    
		.name	= "100ask_gpio_plat_drv", //用于和设备c文件匹配
		.of_match_table = gpio_dt_ids,  //用于与设备树匹配
	},
	.probe		= gpio_drv_probe,
	.remove		= gpio_drv_remove,
};

Guess you like

Origin blog.csdn.net/qq_63922192/article/details/132035696