without id_table, of_match_table can't match device tree node.And with id_table, of_match_table can. Why?

51 Views Asked by At

I have a problem when I use of_match_table to match device tree node.

Device tree node information (laser-radio) like this

{
    i2c@7000c000 {
        laser-radio@29 {
        compatible = "lyz,vl53l0x";
        reg = <0x29>;
        };
    };
};

and when I just use of_match_table()

static const struct of_device_id vl53l0x_dt_match[] = {
    { .compatible = "lyz,vl53l0x" },
    { }
};
MODULE_DEVICE_TABLE(of, vl53l0x_dt_match);

struct i2c_driver vl53l0x_driver = {
    .driver =
        {
            .name = "vl53l0x",
            .owner = THIS_MODULE,
            .of_match_table = vl53l0x_dt_match,
        },
    .probe = vl53l0x_probe,
    .remove = vl53l0x_remove,
};

This doesn't work. but if I use id_table

static const struct i2c_device_id vl53l0x_id[] = {
    { "vl53l0x", 0 },
    {}
};
MODULE_DEVICE_TABLE(i2c, vl53l0x_id);

static const struct of_device_id vl53l0x_dt_match[] = {
    { .compatible = "lyz,vl53l0x" },
    { }
};
MODULE_DEVICE_TABLE(of, vl53l0x_dt_match);

struct i2c_driver vl53l0x_driver = {
    .driver =
        {
            .name = "vl53l0x",
            .owner = THIS_MODULE,
            .of_match_table = vl53l0x_dt_match,
        },
    .probe = vl53l0x_probe,
    .remove = vl53l0x_remove,
    .id_table = vl53l0x_id,
};

It works. I don't know why, and when I print compatible it also show lyz,vl53l0x.

How to use of_match_table to match a node? Did I do something wrong?

(linux 4.9)

I also conducted some interesting experiments and found that the node was indeed matched. It's just that when I commented out the '.id_table', even though the match occurred, it wouldn't enter the probe function. However, with only the '.id_table', it can enter the probe function after matching.

experiment steps:

  1. add some printk into i2c_device_match
  2. insmod
static int i2c_device_match(struct device *dev, struct device_driver *drv) {
  struct i2c_client *client = i2c_verify_client(dev);
  struct i2c_driver *driver;
    printk("lyz : i2c_device_match\n");
  if (!client){
    return 0;
    }
    printk("%s:  drv->of_match_table->compatible= %s\n", __func__, drv->of_match_table->compatible);
  /* Attempt an OF style match */
  if (of_driver_match_device(dev, drv)){
        printk("lyz : get right match\n");
        return 1;
    }

  ...
  return 0;
}

If with .id_table with id_table

If without .id_table without id_table

0

There are 0 best solutions below