谁调用了驱动程序的probe()

时间:2011-09-28 05:07:29

标签: linux-kernel linux-device-driver

如何调用probe()调用?谁叫它?根据我的理解,__init()注册driver,然后以某种方式probe()调用register设备数据和irq等。究竟是怎么回事?

我正在使用触摸屏驱动程序,其__init将自己注册到i2c driver。然后探测期望i2c_clien t返回null的数据。我想跟踪它的填充位置。

6 个答案:

答案 0 :(得分:35)

长话短说:驱动程序的probe()函数是为该特定总线调用register_driver而调用的。更确切地说,它由probe()结构的bus_type调用。在您的情况下:i2c_bus_type

以下是I2C案例中的调用链:

  • i2c_register_driver
  • driver_register
  • bus_add_driver
  • driver_attach
  • __ driver_attach(适用于您的设备)
  • driver_probe_device
  • really_probe
  • i2c_device_probe(这是dev-> bus->探针用于i2c驱动程序)
  • your_probe_function

答案 1 :(得分:11)

我准备了一个跟踪平台驱动器探测功能的图表。您正在使用I2C驱动程序,其中AFAIK是一个平台驱动程序。我希望这可以帮助您追踪问题。

enter image description here

另外,请查看以下链接以查看有关kernelnewbies的讨论。

https://www.mail-archive.com/kernelnewbies%40kernelnewbies.org/msg12423.html

答案 2 :(得分:3)

让我们考虑$timeout

的示例
  1. platform device driver回调的起始触发函数是加载驱动程序时调用的driver->probe()宏;此module_init()macro

  2. 中定义
  3. include/linux/module.h具有module_init(my_driver_init)功能的回调功能。 my_driver_init()函数应该调用my_driver_init()

  4. platform_driver_register(my_driver)platform_driver_register(my_driver)句柄分配给通用my_driver -> probe()并调用drv -> probe()函数。

  5. driver_register(my_driver)函数将driver_register(my_driver)添加到平台总线并调用my_driver函数。

  6. 同样,即使driver_attach()需要连接到平台总线。

  7. 最后,仅当platform_device根据driver_match_device()&来自.name的平台设备列表中的.id_table个匹配driver,然后ACPI/DTS调用driver_probe_device()回调。

答案 3 :(得分:2)

@iSegFault :将调用probe()以确保设备存在且功能正常。如果设备不是可热插拔的,则probe()的功能可以放在init中()方法。这将减少驱动程序的运行时内存占用。 P.S link

Probe()在设备启动时或设备连接时发生。对于“平台”设备,当注册平台设备并且其设备名称与设备驱动程序上指定的名称匹配时,将调用探测功能。 P.S link

i2c_detect函数探测I2C适配器,查找addr_data结构中指定的不同地址。如果找到设备,则调用chip_detect函数。 P.S link

一定能清除您怀疑的链接。 P.S link

在内核2.4.29中,我可以告诉你探测是如何发生的?请看下面(文件名: drivers / acorn / char / pcf8583.c

static struct i2c_driver pcf8583_driver = {
name:       "PCF8583",
id:     I2C_DRIVERID_PCF8583,
flags:      I2C_DF_NOTIFY,
attach_adapter: pcf8583_probe, /* This will be called from i2c-core.c P.S see below function i2c_add_driver()*/
detach_client:  pcf8583_detach,
command:    pcf8583_command

};

文件名: drivers / i2c / i2c-core.c

int i2c_add_driver(struct i2c_driver *driver)
{
    ........................
    ........................

    /* now look for instances of driver on our adapters
     */
    if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
        for (i=0;i<I2C_ADAP_MAX;i++)
            if (adapters[i]!=NULL)
                /* Ignore errors */
                driver->attach_adapter(adapters[i]); /*This is a location from where probe is called. Pointer **driver** is of type **pcf8583_driver** which you have passed into this function*/
    }
    ADAP_UNLOCK();
    return 0;
}

很少有重要的链接:

1)http://www.slideshare.net/varunmahajan06/i2c-subsystem-in-linux2624

2)http://www.programering.com/a/MjNwcTMwATM.html

3)http://www.linuxjournal.com/article/6717

4)http://www.developermemo.com/2943157/

5)http://free-electrons.com/doc/kernel-architecture.pdf

6)http://www.techques.com/question/1-3014627/Probe-problem-when-writing-a-I2C-device-driver

在PCI for kernel-2.4.29中,当识别出供应商和设备ID时会调用它。 PCI总线驱动程序为您完成此操作。请参阅以下代码:

文件名: drivers / pci / pci.c

static int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
{
   const struct pci_device_id *id;
   int ret = 0;
   if (drv->id_table) {
    id = pci_match_device(drv->id_table, dev); /* check for device presence*/
    if (!id) {
     ret = 0;
     goto out;
    }
   } else
  id = NULL;
  dev_probe_lock();
  if (drv->probe(dev, id) >= 0) { /* This is a location from where probe is called*/
   dev->driver = drv;
   ret = 1;
   }
   dev_probe_unlock();
  out:
  return ret;
}

答案 4 :(得分:1)

将为已检测设备的每个接口调用探测功能,但已注册的设备除外。

答案 5 :(得分:0)

名称将表单驱动程序结构与设备结构匹配时,将调用探测函数。下面提到的例如驱动器和设备结构。

1:驱动程序结构

 static struct driver your_driver = {
        .driver = {
              .name = YUR_NAME,

                  },

例如。

static struct i2c_driver l3gd20_driver = {
        .driver = {

                        .name = l3gd20_gyr,

                   }

2:设备结构

static structure device  your_devices = {
              .name = YUR_NAME,
              },

例如

static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
                {
                I2C_BOARD_INFO("l3gd20_gyr", 0x6a),
                 },

注意:当驱动程序和设备的名称(l3gd20_gyr)匹配时,您的探测器将被调用。