Friday 22 May 2020

Who calls the probe() of driver

The probe() function of the driver is called as a result of calling the register_driver for that specific bus. More precisely, it's called by the probe() of that bus_type structure. In your case: i2c_bus_type.
Examples:  call chain of I2C  device:
  • i2c_register_driver
  • driver_register
  • bus_add_driver
  • driver_attach
  • __driver_attach (for your device)
  • driver_probe_device
  • really_probe
  • i2c_device_probe (this is what dev->bus->probe is for an i2c driver)
  • driver_probe_function
Example: call chain ofplatform device driver:
  1. The starting trigger function for the driver->probe() callback is the module_init() macro called while loading the driver; this macro is defined in include/linux/module.h.
  2. module_init(my_driver_init) has the callback to my_driver_init() function. my_driver_init() function should have a call to platform_driver_register(my_driver)
  3. platform_driver_register(my_driver) assigns my_driver -> probe() handle to generic drv -> probe() and calls the driver_register(my_driver) function.
  4. driver_register(my_driver) function adds my_driver to the platform bus and calls driver_attach() function.
  5. In the same way, even the platform_device needs to attach to the platform bus.
  6. Finally, only if the driver_match_device() returns success based on the .name & .id_table of the driver matches in the platform devices list that comes either from ACPI/DTS, then the driver_probe_device() gets called that has the drv->probe() callback.

Driver registration


I2C from the drive device registration, using i2c-core.c to provide the interface: i2c_register_driver; its call.:
I2c_register_driver  -->   driver_register  -->   bus_add_driver,

 1.bus_add_driver:
    • About device_driver data structure struct driver_private *p
    • The device driver model is hierarchical management through the kobject of the device driver, 
    • so device_driver should contain the kobject members, Linux is to include kobject in struct  in driver_private, containing struct  in device_driver; driver_private; we can understand driver_private is a private device_driver, operated by the kernel.

    • struct driver_private Is dynamic in the beginning, the driving applications for registration, and initialization.

  •           klist_init(&priv->klist_devices, NULL, NULL);

           Initialize the device list, each with the matching device will be added to the list by.
  •           priv->kobj.kset = bus->p->drivers_kset;

           Specify the drive of kset,
  •          kobject_init_and_add
          The initialization of kobject, and add kobject to the kset collection (bus->p->drivers_kset).
          This function is called kobject_add_internal will add kobject to the corresponding kset; major is, if              kobject parent if NULL, then the parent will be set to the kset collection of the kobject:
          Parent  =  kobject_get (& kobj-> kset-> kobj),

         The next is to create a folder for the kobject: create_dir (kobj); so as to display from the /sys/                     directory.

  •         driver_attach, will drive and device for binding
         Will traverse the bus equipment list, search can match the equipment, and binding.
         driver_attach -->  Bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
         The function pointer __driver_attach into bus_for_each_dev, will each get device drive matching.

         bus_for_each_dev:
        All equipment traversal on the bus, because the bus equipment is bus-> p-> a klist_devices node             list, so the function is actually to the linked list traversal, can refer to a specific klist.

      __driver_attach(Source location drivers/base/dd.c):
     Apparatus and drive matching, if the match is successful, attempt to bind.

         1 the first matching confirmation: driver_match_device(drv,  dev),
                  The call:  --> drv->bus->match --> i2c_device_match 
                  -->  of_driver_match_device
                 i2c_match_id

         Drive matching query in two ways:
         Method 1:
                    by comparing the of_driver_match_device of_device_id,
         Method 2:
                   by comparing the i2c_match_id id_table,
                  i2c_driver->id_table->name Client-> and name are the same;.

          2 if the matching is confirmed, for driving and binding device: driver_probe_device,
                    The call:  driver_probe_device --> really_probe
                     --> dev->bus->probe
                    driver_bound

really_probe, 
             we will drive the pointer points to the driven equipment: dev->driver = drv.
             Corresponding to i2c_bus_type, dev-> bus-> probe  that is: i2c_device_probe, probe function                     calls the final drive.

driver_bound, will drive the binding and equipment:
           It is a call to klist_add_tail: the device node is added to the klist_devices driver;

  •          Call klist_add_tail, The driver is registered to add to the bus klist_drivers,
          klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);

  •          module_add_driver(drv->owner,  drv)
         Create a drivers directory in the sysfs

No comments:

Post a Comment