Linux Kernel input设备之input设备注册

来源:互联网 发布:java 高效率排序 编辑:程序博客网 时间:2024/04/25 13:20
/**
 * input_register_device - register device with input core * @dev: device to be registered * * This function registers device with input core. The device must be * allocated with input_allocate_device() and all it's capabilities * set up before registering. * If function fails the device must be freed with input_free_device(). * Once device has been successfully registered it can be unregistered * with input_unregister_device(); input_free_device() should not be * called in this case. * * Note that this function is also used to register managed input devices * (ones allocated with devm_input_allocate_device()). Such managed input * devices need not be explicitly unregistered or freed, their tear down * is controlled by the devres infrastructure. It is also worth noting * that tear down of managed input devices is internally a 2-step process: * registered managed input device is first unregistered, but stays in * memory and can still handle input_event() calls (although events will * not be delivered anywhere). The freeing of managed input device will * happen later, when devres stack is unwound to the point where device * allocation was made. */int input_register_device(struct input_dev *dev){struct input_devres *devres = NULL;struct input_handler *handler;unsigned int packet_size;const char *path;int error;if (dev->devres_managed) {devres = devres_alloc(devm_input_device_unregister,      sizeof(struct input_devres), GFP_KERNEL);if (!devres)return -ENOMEM;devres->input = dev;}/* Every input device generates EV_SYN/SYN_REPORT events. */__set_bit(EV_SYN, dev->evbit);/* KEY_RESERVED is not supposed to be transmitted to userspace. */__clear_bit(KEY_RESERVED, dev->keybit);/* Make sure that bitmasks not mentioned in dev->evbit are clean. */input_cleanse_bitmasks(dev);packet_size = input_estimate_events_per_packet(dev);if (dev->hint_events_per_packet < packet_size)dev->hint_events_per_packet = packet_size;dev->max_vals = dev->hint_events_per_packet + 2;dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL);if (!dev->vals) {error = -ENOMEM;goto err_devres_free;}/* * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. */if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD])input_enable_softrepeat(dev, 250, 33);if (!dev->getkeycode)dev->getkeycode = input_default_getkeycode;if (!dev->setkeycode)dev->setkeycode = input_default_setkeycode;error = device_add(&dev->dev);if (error)goto err_free_vals;path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);pr_info("%s as %s\n",dev->name ? dev->name : "Unspecified device",path ? path : "N/A");kfree(path);error = mutex_lock_interruptible(&input_mutex);if (error)goto err_device_del;list_add_tail(&dev->node, &input_dev_list);list_for_each_entry(handler, &input_handler_list, node)input_attach_handler(dev, handler);input_wakeup_procfs_readers();mutex_unlock(&input_mutex);if (dev->devres_managed) {dev_dbg(dev->dev.parent, "%s: registering %s with devres.\n",__func__, dev_name(&dev->dev));devres_add(dev->dev.parent, devres);}return 0;err_device_del:device_del(&dev->dev);err_free_vals:kfree(dev->vals);dev->vals = NULL;err_devres_free:devres_free(devres);return error;}
                                             
0 0
原创粉丝点击