From 21fe5dd4ccc9389f3e0ed5d32ccf696b5e641b3b Mon Sep 17 00:00:00 2001 From: "rick.chan" Date: Fri, 24 Jul 2020 15:29:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20Linux=20id=5Ftable=20?= =?UTF-8?q?=E4=B8=8E=20of=5Fmatch=5Ftable.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: rick.chan --- .../Linux_id_table_与_of_match_table.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/Linux_id_table_与_of_match_table.md diff --git a/Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/Linux_id_table_与_of_match_table.md b/Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/Linux_id_table_与_of_match_table.md new file mode 100644 index 0000000..28ddd80 --- /dev/null +++ b/Software/Development/OperatingSystem/Linux/Kernel/Modules/DeviceTree/Linux_id_table_与_of_match_table.md @@ -0,0 +1,55 @@ +# Linux id_table 与 of_match_table + +I’m currently trying to understand how linux drivers work. As far as I know, A driver’s probe/init function is called when the kernel parses the corresponding .compatible string in the device tree. However, in the arizona-spi driver it looks like there are multiple compatible strings referenced in different members: + +```cpp +static const struct spi_device_id arizona_spi_ids[] = { +{ "wm5102", WM5102 }, +{ "wm5110", WM5110 }, +{ }, +}; +MODULE_DEVICE_TABLE(spi, arizona_spi_ids); + +static struct spi_driver arizona_spi_driver = { +.driver = { + .name = "arizona", + .owner = THIS_MODULE, + .pm = &arizona_pm_ops, + + // Contains e.g. "wlf,wm5102" + .of_match_table = of_match_ptr(arizona_of_match), + +}, +.probe = arizona_spi_probe, +.remove = arizona_spi_remove, +.id_table = arizona_spi_ids, // Contains "wm5102" and "wm5110" +}; +``` + +So what is the difference between arizona_spi_driver.id_table and arizona_spi_driver.driver.of_match_table? + +There are several mechanism for driver matching. The id_table is intended to be used for finding a match from stripped device-tree entries (without vendor part), while of_match_table is used to find a match from full device-tree entries (the ones with vendor part). + +If you check, arizona_of_match is defined as this: + +```cpp +const struct of_device_id arizona_of_match[] = { + { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, + { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, + { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, + { .compatible = "wlf,wm8997", .data = (void *)WM8997 }, + {}, +}; +``` + +'wlf' is the vendor part for this case, while arizona_spi_ids doesn’t contain the vendor part. + +Hence, if you have something like this in your device tree: + +```cpp +compatible = "myvendor,wm5102" +``` + +Your device will match against id_table but not against of_match_table since the vendor is different. + +The kernel will do matching against of_match_table first before check id_table (seespi_get_device_id in here). The device matching priority is: of_match_table > acpi_driver > id_table.