static int callback(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
/* test if this device was inited */
if (v4l2_dev == NULL)
return 0;
...
return 0;
}
int iterate(void *p)
{
struct device_driver *drv;
int err;
/* Find driver "ivtv" on the PCI bus.
pci_bus_type is a global. For USB buses use usb_bus_type. */
drv = driver_find("ivtv", &pci_bus_type);
/* iterate over all ivtv device instances */
err = driver_for_each_device(drv, NULL, p, callback);
put_driver(drv);
return err;
}
有时需要保持设备实例的运行计数器。这通常用于将设备实例映射到模块选项数组的索引。推荐的方法如下:
static atomic_t drv_instance = ATOMIC_INIT(0);
static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
...
state->instance = atomic_inc_return(&drv_instance) - 1;
}
如果你有多个设备节点,则很难知道何时可以安全地为可热插拔设备注销v4l2_device。为此,v4l2_device具有引用计数支持。每次调用video_register_device时增加计数,释放该设备节点时减小计数。当引用计数达到零时,则会调用v4l2_device_release回调。你可以在那里进行最终清理。如果创建了其他设备节点,则也可以通过调用以下方式手动增加和减少引用计数:v4l2_device_get。或:v4l2_device_put。由于初始引用计数为因此还需要在disconnect回调或remove回调中调用v4l2_device_put,否则引用计数永远不会达到0。1v4l2_devicefunctionsanddatastructuresstructv4l2_device是V4L2设备驱动程序的主要结构体。定义:
struct v4l2_device {
struct device *dev;
struct media_device *mdev;
struct list_head subdevs;
spinlock_t lock;
char name[V4L2_DEVICE_NAME_SIZE];
void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg);
struct v4l2_ctrl_handler *ctrl_handler;
struct v4l2_prio_state prio;
struct kref ref;
void (*release)(struct v4l2_device *v4l2_dev);
};
static atomic_t drv_instance = ATOMIC_INIT(0);
…
instance = v4l2_device_set_name(&v4l2_dev, “foo”, &drv_instance);
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点