如何为sysfs_notify()获取正确的kobject?
PMBus驱动sysfs_notify配合poll失效的解决方法
问题
开发PMBus设备驱动内核模块时,已实现GPIO中断统计边沿触发次数,sysfs条目显示次数正常,但在中断处理程序中调用sysfs_notify()后,用户态poll()该sysfs文件无响应。经排查,是sysfs_notify()传入的kobject对应的设备路径与sysfs属性所在的路径不一致:
num_gpio_faults_show()中设备路径为/devices/.../22-0046/hwmon/hwmon3(带hwmon子设备)- 中断处理程序中使用i2c_client的设备路径为
/devices/.../22-0046,缺少hwmon部分
核心原因
属性组通过pmbus_driver_info.groups注册,最终会被添加到PMBus创建的hwmon子设备上,而非i2c_client对应的主设备。直接使用i2c_client的device调用sysfs_notify(),无法触发hwmon设备下sysfs文件的poll通知。
解决方案
利用PMBus提供的register_device回调,获取hwmon子设备的指针并保存,中断时使用该指针的kobject调用sysfs_notify()。
修改步骤
- 扩展设备数据结构体,新增成员保存hwmon设备指针:
struct tps25990_data { struct device *dev; struct device *hwmon_dev; // 新增:存储hwmon子设备指针 struct pmbus_driver_info info; ... unsigned int num_gpio_faults; };
- 实现register_device回调函数,在PMBus创建hwmon设备时保存其指针:
static int tps25990_register_device(struct i2c_client *client, struct device *dev) { const struct pmbus_driver_info *info = pmbus_get_driver_info(client); struct tps25990_data *data = to_tps25990_data(info); data->hwmon_dev = dev; return 0; }
- 在probe函数中注册回调:
static int tps25990_probe(struct i2c_client *client) { ... struct tps25990_data *data; struct pmbus_driver_info *info; ... info = &data->info; info->groups = tps25990_attribute_groups; info->register_device = tps25990_register_device; // 注册回调 ... }
- 修改中断处理程序,使用hwmon设备的kobject调用sysfs_notify:
static irqreturn_t efuse_fault_gpio_irq_handler(int irq, void *dev_id){ struct tps25990_data *data = dev_id; printk(KERN_INFO "Efuse fault detected on gpio%d\n", desc_to_gpio(data->fault_gpio)); data->num_gpio_faults++; // 使用hwmon设备的kobject发送通知 if (data->hwmon_dev) { sysfs_notify(&data->hwmon_dev->kobj, NULL, "num_gpio_faults"); } return IRQ_HANDLED; }
说明
PMBus的register_device回调是官方提供的、安全获取hwmon设备指针的方式,避免了直接访问未导出的struct pmbus_data结构体。修改后,sysfs_notify()将针对属性所在的hwmon设备发送通知,用户态poll()即可正常响应。
内容的提问来源于stack exchange,提问作者mattmunee
相关产品推荐
相关产品推荐

