内核代码看到这样一个函数
static inline void dev_set_drvdata(struct device *dev, void *data)
{
dev->driver_data = data;
}
这个函数有什么用?
看里面的代码含义大概就能知道,给 driver_data这个指针赋值,之后在其他地方就可以用这个指针的内容拿到私有结构体成员。
在 include/linux/device.h
里面,可以看到dev这个结构体中关于void*driver_data的定义
void *driver_data; /* Driver data, set and get with
dev_set_drvdata/dev_get_drvdata */
看注释可以看到还有dev_get_drvdata和dev_set_drvdata函数
dev_get_drvdata的函数原型是这样
static inline void *dev_get_drvdata(const struct device *dev)
{
return dev->driver_data;
}
要注意的是,这个函数返回是没有做任何判断的,直接就把指针返回了,如果使用这个指针的人不注意的话,那是有可能导致内核挂逼的。
下面这个驱动代码
在注册了input子系统之后,使用dev_set_drvdata把这个指针赋值给device结构体里面的变量。
static int rb532_button_probe(struct platform_device *pdev)
{
struct input_polled_dev *poll_dev;
int error;
poll_dev = input_allocate_polled_device();
if (!poll_dev)
return -ENOMEM;
poll_dev->poll = rb532_button_poll;
poll_dev->poll_interval = RB532_BTN_RATE;
poll_dev->input->name = "rb532 button";
poll_dev->input->phys = "rb532/button0";
poll_dev->input->id.bustype = BUS_HOST;
poll_dev->input->dev.parent = &pdev->dev;
dev_set_drvdata(&pdev->dev, poll_dev);
input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM);
之后在使用的地方再使用dev_get_drvdata来获取数据指针
这样就可以不使用全局变量,这也体现了内核高内聚低耦合的特点。
static int rb532_button_remove(struct platform_device *pdev)
{
struct input_polled_dev *poll_dev
= dev_get_drvdata(&pdev->dev);
input_unregister_polled_device(poll_dev);
input_free_polled_device(poll_dev);
return 0;
}
除了在同一个驱动代码里面使用,如果在不同的文件中,也是可以使用到的。