I can elaborate on samsi's answer with a bit more detail:
Near the bottom of your arizona-spi.c
driver (just above the module license, description, etc.), you'll see a helper macro call:
module_spi_driver(arizona_spi_driver);
For modules that don't do anything special during module_init/module_exit()
, this helper macro helps to reduce a bit of boilerplate, but essentially this is a call to:
spi_driver_register(&arizona_spi_driver);
If you are to follow all the function calls through to where the matching takes place, you'll see something like this:
spi_driver_register();
--> driver_register();
--> bus_add_driver(drv);
--> driver_attach(drv);
The code will look at the bus (spi) and iterate over each device on the bus, calling __driver_attach
on each one:
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
__driver_attach
will look for the existence of a drv->bus->match
function pointer, which in this case exists, and you will find it in drivers/spi/spi.c
:
struct bus_type spi_bus_type = {
.name = "spi",
.dev_attrs = spi_dev_attrs,
.match = spi_match_device, <--- here
.uevent = spi_uevent,
.suspend = spi_suspend,
.resume = spi_resume,
};
spi_match_device()
will first check for a driver override, then check for a Device Tree / OF-style match, then an ACPI match, then the ID table from your driver, (arizona_spi_ids
), then lastly attempt a modalias
match with the driver name.
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);
const struct spi_driver *sdrv = to_spi_driver(drv);
/* Check override first, and if set, only use the named driver */
if (spi->driver_override)
return strcmp(spi->driver_override, drv->name) == 0;
/* Attempt an OF style match */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try ACPI */
if (acpi_driver_match_device(dev, drv))
return 1;
if (sdrv->id_table)
return !!spi_match_id(sdrv->id_table, spi);
return strcmp(spi->modalias, drv->name) == 0;
}
In order for a Device Tree / OF match to occur, you need an exact match with a node in your device tree, for example:
Device Tree Node:
my_device@1 {
compatible = "wlf,model", "wlf,model-rev2";
...
}
OF match table in your driver:
static const struct of_device_id my_driver_of_match[] = {
{ .compatible = "wlf,model" },
{ .compatible = "wlf,model-rev1" },
{ .compatible = NULL }
};
In this case "wlf,model"
in your DT matches with "wlf,model"
in your OF match table. If an exact match doesn't occur, it will fall through to an ID table match, then to an ACPI match, and so on.
In your case, it looks like it failed a DT match, but succeeded on an ID table match in your driver.