linux/drivers/input/input.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * The input core
 *
 * Copyright (c) 1999-2002 Vojtech Pavlik
 */


#define pr_fmt(fmt)

#include <linux/init.h>
#include <linux/types.h>
#include <linux/idr.h>
#include <linux/input/mt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/major.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/pm.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/kstrtox.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
#include "input-compat.h"
#include "input-core-private.h"
#include "input-poller.h"

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

#define INPUT_MAX_CHAR_DEVICES
#define INPUT_FIRST_DYNAMIC_DEV
static DEFINE_IDA(input_ida);

static LIST_HEAD(input_dev_list);
static LIST_HEAD(input_handler_list);

/*
 * input_mutex protects access to both input_dev_list and input_handler_list.
 * This also causes input_[un]register_device and input_[un]register_handler
 * be mutually exclusive which simplifies locking in drivers implementing
 * input handlers.
 */
static DEFINE_MUTEX(input_mutex);

static const struct input_value input_value_sync =;

static const unsigned int input_max_code[EV_CNT] =;

static inline int is_event_supported(unsigned int code,
				     unsigned long *bm, unsigned int max)
{}

static int input_defuzz_abs_event(int value, int old_val, int fuzz)
{}

static void input_start_autorepeat(struct input_dev *dev, int code)
{}

static void input_stop_autorepeat(struct input_dev *dev)
{}

/*
 * Pass values first through all filters and then, if event has not been
 * filtered out, through all open handles. This order is achieved by placing
 * filters at the head of the list of handles attached to the device, and
 * placing regular handles at the tail of the list.
 *
 * This function is called with dev->event_lock held and interrupts disabled.
 */
static void input_pass_values(struct input_dev *dev,
			      struct input_value *vals, unsigned int count)
{}

#define INPUT_IGNORE_EVENT
#define INPUT_PASS_TO_HANDLERS
#define INPUT_PASS_TO_DEVICE
#define INPUT_SLOT
#define INPUT_FLUSH
#define INPUT_PASS_TO_ALL

static int input_handle_abs_event(struct input_dev *dev,
				  unsigned int code, int *pval)
{}

static int input_get_disposition(struct input_dev *dev,
			  unsigned int type, unsigned int code, int *pval)
{}

static void input_event_dispose(struct input_dev *dev, int disposition,
				unsigned int type, unsigned int code, int value)
{}

void input_handle_event(struct input_dev *dev,
			unsigned int type, unsigned int code, int value)
{}

/**
 * input_event() - report new input event
 * @dev: device that generated the event
 * @type: type of the event
 * @code: event code
 * @value: value of the event
 *
 * This function should be used by drivers implementing various input
 * devices to report input events. See also input_inject_event().
 *
 * NOTE: input_event() may be safely used right after input device was
 * allocated with input_allocate_device(), even before it is registered
 * with input_register_device(), but the event will not reach any of the
 * input handlers. Such early invocation of input_event() may be used
 * to 'seed' initial state of a switch or initial position of absolute
 * axis, etc.
 */
void input_event(struct input_dev *dev,
		 unsigned int type, unsigned int code, int value)
{}
EXPORT_SYMBOL();

/**
 * input_inject_event() - send input event from input handler
 * @handle: input handle to send event through
 * @type: type of the event
 * @code: event code
 * @value: value of the event
 *
 * Similar to input_event() but will ignore event if device is
 * "grabbed" and handle injecting event is not the one that owns
 * the device.
 */
void input_inject_event(struct input_handle *handle,
			unsigned int type, unsigned int code, int value)
{}
EXPORT_SYMBOL();

/**
 * input_alloc_absinfo - allocates array of input_absinfo structs
 * @dev: the input device emitting absolute events
 *
 * If the absinfo struct the caller asked for is already allocated, this
 * functions will not do anything.
 */
void input_alloc_absinfo(struct input_dev *dev)
{}
EXPORT_SYMBOL();

void input_set_abs_params(struct input_dev *dev, unsigned int axis,
			  int min, int max, int fuzz, int flat)
{}
EXPORT_SYMBOL();

/**
 * input_copy_abs - Copy absinfo from one input_dev to another
 * @dst: Destination input device to copy the abs settings to
 * @dst_axis: ABS_* value selecting the destination axis
 * @src: Source input device to copy the abs settings from
 * @src_axis: ABS_* value selecting the source axis
 *
 * Set absinfo for the selected destination axis by copying it from
 * the specified source input device's source axis.
 * This is useful to e.g. setup a pen/stylus input-device for combined
 * touchscreen/pen hardware where the pen uses the same coordinates as
 * the touchscreen.
 */
void input_copy_abs(struct input_dev *dst, unsigned int dst_axis,
		    const struct input_dev *src, unsigned int src_axis)
{}
EXPORT_SYMBOL();

/**
 * input_grab_device - grabs device for exclusive use
 * @handle: input handle that wants to own the device
 *
 * When a device is grabbed by an input handle all events generated by
 * the device are delivered only to this handle. Also events injected
 * by other input handles are ignored while device is grabbed.
 */
int input_grab_device(struct input_handle *handle)
{}
EXPORT_SYMBOL();

static void __input_release_device(struct input_handle *handle)
{}

/**
 * input_release_device - release previously grabbed device
 * @handle: input handle that owns the device
 *
 * Releases previously grabbed device so that other input handles can
 * start receiving input events. Upon release all handlers attached
 * to the device have their start() method called so they have a change
 * to synchronize device state with the rest of the system.
 */
void input_release_device(struct input_handle *handle)
{}
EXPORT_SYMBOL();

/**
 * input_open_device - open input device
 * @handle: handle through which device is being accessed
 *
 * This function should be called by input handlers when they
 * want to start receive events from given input device.
 */
int input_open_device(struct input_handle *handle)
{}
EXPORT_SYMBOL();

int input_flush_device(struct input_handle *handle, struct file *file)
{}
EXPORT_SYMBOL();

/**
 * input_close_device - close input device
 * @handle: handle through which device is being accessed
 *
 * This function should be called by input handlers when they
 * want to stop receive events from given input device.
 */
void input_close_device(struct input_handle *handle)
{}
EXPORT_SYMBOL();

/*
 * Simulate keyup events for all keys that are marked as pressed.
 * The function must be called with dev->event_lock held.
 */
static bool input_dev_release_keys(struct input_dev *dev)
{}

/*
 * Prepare device for unregistering
 */
static void input_disconnect_device(struct input_dev *dev)
{}

/**
 * input_scancode_to_scalar() - converts scancode in &struct input_keymap_entry
 * @ke: keymap entry containing scancode to be converted.
 * @scancode: pointer to the location where converted scancode should
 *	be stored.
 *
 * This function is used to convert scancode stored in &struct keymap_entry
 * into scalar form understood by legacy keymap handling methods. These
 * methods expect scancodes to be represented as 'unsigned int'.
 */
int input_scancode_to_scalar(const struct input_keymap_entry *ke,
			     unsigned int *scancode)
{}
EXPORT_SYMBOL();

/*
 * Those routines handle the default case where no [gs]etkeycode() is
 * defined. In this case, an array indexed by the scancode is used.
 */

static unsigned int input_fetch_keycode(struct input_dev *dev,
					unsigned int index)
{}

static int input_default_getkeycode(struct input_dev *dev,
				    struct input_keymap_entry *ke)
{}

static int input_default_setkeycode(struct input_dev *dev,
				    const struct input_keymap_entry *ke,
				    unsigned int *old_keycode)
{}

/**
 * input_get_keycode - retrieve keycode currently mapped to a given scancode
 * @dev: input device which keymap is being queried
 * @ke: keymap entry
 *
 * This function should be called by anyone interested in retrieving current
 * keymap. Presently evdev handlers use it.
 */
int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke)
{}
EXPORT_SYMBOL();

/**
 * input_set_keycode - attribute a keycode to a given scancode
 * @dev: input device which keymap is being updated
 * @ke: new keymap entry
 *
 * This function should be called by anyone needing to update current
 * keymap. Presently keyboard and evdev handlers use it.
 */
int input_set_keycode(struct input_dev *dev,
		      const struct input_keymap_entry *ke)
{}
EXPORT_SYMBOL();

bool input_match_device_id(const struct input_dev *dev,
			   const struct input_device_id *id)
{}
EXPORT_SYMBOL();

static const struct input_device_id *input_match_device(struct input_handler *handler,
							struct input_dev *dev)
{}

static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
{}

#ifdef CONFIG_COMPAT

static int input_bits_to_string(char *buf, int buf_size,
				unsigned long bits, bool skip_empty)
{}

#else /* !CONFIG_COMPAT */

static int input_bits_to_string(char *buf, int buf_size,
				unsigned long bits, bool skip_empty)
{
	return bits || !skip_empty ?
		snprintf(buf, buf_size, "%lx", bits) : 0;
}

#endif

#ifdef CONFIG_PROC_FS

static struct proc_dir_entry *proc_bus_input_dir;
static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait);
static int input_devices_state;

static inline void input_wakeup_procfs_readers(void)
{}

struct input_seq_state {};

static __poll_t input_proc_devices_poll(struct file *file, poll_table *wait)
{}

static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
{}

static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{}

static void input_seq_stop(struct seq_file *seq, void *v)
{}

static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
				   unsigned long *bitmap, int max)
{}

static int input_devices_seq_show(struct seq_file *seq, void *v)
{}

static const struct seq_operations input_devices_seq_ops =;

static int input_proc_devices_open(struct inode *inode, struct file *file)
{}

static const struct proc_ops input_devices_proc_ops =;

static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
{}

static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{}

static int input_handlers_seq_show(struct seq_file *seq, void *v)
{}

static const struct seq_operations input_handlers_seq_ops =;

static int input_proc_handlers_open(struct inode *inode, struct file *file)
{}

static const struct proc_ops input_handlers_proc_ops =;

static int __init input_proc_init(void)
{}

static void input_proc_exit(void)
{}

#else /* !CONFIG_PROC_FS */
static inline void input_wakeup_procfs_readers(void) { }
static inline int input_proc_init(void) { return 0; }
static inline void input_proc_exit(void) { }
#endif

#define INPUT_DEV_STRING_ATTR_SHOW(name)

INPUT_DEV_STRING_ATTR_SHOW();
INPUT_DEV_STRING_ATTR_SHOW();
INPUT_DEV_STRING_ATTR_SHOW();

static int input_print_modalias_bits(char *buf, int size,
				     char name, const unsigned long *bm,
				     unsigned int min_bit, unsigned int max_bit)
{}

static int input_print_modalias_parts(char *buf, int size, int full_len,
				      const struct input_dev *id)
{}

static int input_print_modalias(char *buf, int size, const struct input_dev *id)
{}

static ssize_t input_dev_show_modalias(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{}
static DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);

static int input_print_bitmap(char *buf, int buf_size, const unsigned long *bitmap,
			      int max, int add_cr);

static ssize_t input_dev_show_properties(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{}
static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);

static int input_inhibit_device(struct input_dev *dev);
static int input_uninhibit_device(struct input_dev *dev);

static ssize_t inhibited_show(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{}

static ssize_t inhibited_store(struct device *dev,
			       struct device_attribute *attr, const char *buf,
			       size_t len)
{}

static DEVICE_ATTR_RW(inhibited);

static struct attribute *input_dev_attrs[] =;

static const struct attribute_group input_dev_attr_group =;

#define INPUT_DEV_ID_ATTR(name)

INPUT_DEV_ID_ATTR();
INPUT_DEV_ID_ATTR();
INPUT_DEV_ID_ATTR();
INPUT_DEV_ID_ATTR();

static struct attribute *input_dev_id_attrs[] =;

static const struct attribute_group input_dev_id_attr_group =;

static int input_print_bitmap(char *buf, int buf_size, const unsigned long *bitmap,
			      int max, int add_cr)
{}

#define INPUT_DEV_CAP_ATTR(ev, bm)

INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();
INPUT_DEV_CAP_ATTR();

static struct attribute *input_dev_caps_attrs[] =;

static const struct attribute_group input_dev_caps_attr_group =;

static const struct attribute_group *input_dev_attr_groups[] =;

static void input_dev_release(struct device *device)
{}

/*
 * Input uevent interface - loading event handlers based on
 * device bitfields.
 */
static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
				   const char *name, const unsigned long *bitmap, int max)
{}

/*
 * This is a pretty gross hack. When building uevent data the driver core
 * may try adding more environment variables to kobj_uevent_env without
 * telling us, so we have no idea how much of the buffer we can use to
 * avoid overflows/-ENOMEM elsewhere. To work around this let's artificially
 * reduce amount of memory we will use for the modalias environment variable.
 *
 * The potential additions are:
 *
 * SEQNUM=18446744073709551615 - (%llu - 28 bytes)
 * HOME=/ (6 bytes)
 * PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes)
 *
 * 68 bytes total. Allow extra buffer - 96 bytes
 */
#define UEVENT_ENV_EXTRA_LEN

static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
					 const struct input_dev *dev)
{}

#define INPUT_ADD_HOTPLUG_VAR(fmt, val...)

#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max)

#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev)

static int input_dev_uevent(const struct device *device, struct kobj_uevent_env *env)
{}

#define INPUT_DO_TOGGLE(dev, type, bits, on)

static void input_dev_toggle(struct input_dev *dev, bool activate)
{}

/**
 * input_reset_device() - reset/restore the state of input device
 * @dev: input device whose state needs to be reset
 *
 * This function tries to reset the state of an opened input device and
 * bring internal state and state if the hardware in sync with each other.
 * We mark all keys as released, restore LED state, repeat rate, etc.
 */
void input_reset_device(struct input_dev *dev)
{}
EXPORT_SYMBOL();

static int input_inhibit_device(struct input_dev *dev)
{}

static int input_uninhibit_device(struct input_dev *dev)
{}

static int input_dev_suspend(struct device *dev)
{}

static int input_dev_resume(struct device *dev)
{}

static int input_dev_freeze(struct device *dev)
{}

static int input_dev_poweroff(struct device *dev)
{}

static const struct dev_pm_ops input_dev_pm_ops =;

static const struct device_type input_dev_type =;

static char *input_devnode(const struct device *dev, umode_t *mode)
{}

const struct class input_class =;
EXPORT_SYMBOL_GPL();

/**
 * input_allocate_device - allocate memory for new input device
 *
 * Returns prepared struct input_dev or %NULL.
 *
 * NOTE: Use input_free_device() to free devices that have not been
 * registered; input_unregister_device() should be used for already
 * registered devices.
 */
struct input_dev *input_allocate_device(void)
{}
EXPORT_SYMBOL();

struct input_devres {};

static int devm_input_device_match(struct device *dev, void *res, void *data)
{}

static void devm_input_device_release(struct device *dev, void *res)
{}

/**
 * devm_input_allocate_device - allocate managed input device
 * @dev: device owning the input device being created
 *
 * Returns prepared struct input_dev or %NULL.
 *
 * Managed input devices do not need to be explicitly unregistered or
 * freed as it will be done automatically when owner device unbinds from
 * its driver (or binding fails). Once managed input device is allocated,
 * it is ready to be set up and registered in the same fashion as regular
 * input device. There are no special devm_input_device_[un]register()
 * variants, regular ones work with both managed and unmanaged devices,
 * should you need them. In most cases however, managed input device need
 * not be explicitly unregistered or freed.
 *
 * NOTE: the owner device is set up as parent of input device and users
 * should not override it.
 */
struct input_dev *devm_input_allocate_device(struct device *dev)
{}
EXPORT_SYMBOL();

/**
 * input_free_device - free memory occupied by input_dev structure
 * @dev: input device to free
 *
 * This function should only be used if input_register_device()
 * was not called yet or if it failed. Once device was registered
 * use input_unregister_device() and memory will be freed once last
 * reference to the device is dropped.
 *
 * Device should be allocated by input_allocate_device().
 *
 * NOTE: If there are references to the input device then memory
 * will not be freed until last reference is dropped.
 */
void input_free_device(struct input_dev *dev)
{}
EXPORT_SYMBOL();

/**
 * input_set_timestamp - set timestamp for input events
 * @dev: input device to set timestamp for
 * @timestamp: the time at which the event has occurred
 *   in CLOCK_MONOTONIC
 *
 * This function is intended to provide to the input system a more
 * accurate time of when an event actually occurred. The driver should
 * call this function as soon as a timestamp is acquired ensuring
 * clock conversions in input_set_timestamp are done correctly.
 *
 * The system entering suspend state between timestamp acquisition and
 * calling input_set_timestamp can result in inaccurate conversions.
 */
void input_set_timestamp(struct input_dev *dev, ktime_t timestamp)
{}
EXPORT_SYMBOL();

/**
 * input_get_timestamp - get timestamp for input events
 * @dev: input device to get timestamp from
 *
 * A valid timestamp is a timestamp of non-zero value.
 */
ktime_t *input_get_timestamp(struct input_dev *dev)
{}
EXPORT_SYMBOL();

/**
 * input_set_capability - mark device as capable of a certain event
 * @dev: device that is capable of emitting or accepting event
 * @type: type of the event (EV_KEY, EV_REL, etc...)
 * @code: event code
 *
 * In addition to setting up corresponding bit in appropriate capability
 * bitmap the function also adjusts dev->evbit.
 */
void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)
{}
EXPORT_SYMBOL();

static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
{}

#define INPUT_CLEANSE_BITMASK(dev, type, bits)

static void input_cleanse_bitmasks(struct input_dev *dev)
{}

static void __input_unregister_device(struct input_dev *dev)
{}

static void devm_input_device_unregister(struct device *dev, void *res)
{}

/*
 * Generate software autorepeat event. Note that we take
 * dev->event_lock here to avoid racing with input_event
 * which may cause keys get "stuck".
 */
static void input_repeat_key(struct timer_list *t)
{}

/**
 * input_enable_softrepeat - enable software autorepeat
 * @dev: input device
 * @delay: repeat delay
 * @period: repeat period
 *
 * Enable software autorepeat on the input device.
 */
void input_enable_softrepeat(struct input_dev *dev, int delay, int period)
{}
EXPORT_SYMBOL();

bool input_device_enabled(struct input_dev *dev)
{}
EXPORT_SYMBOL_GPL();

static int input_device_tune_vals(struct input_dev *dev)
{}

/**
 * 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)
{}
EXPORT_SYMBOL();

/**
 * input_unregister_device - unregister previously registered device
 * @dev: device to be unregistered
 *
 * This function unregisters an input device. Once device is unregistered
 * the caller should not try to access it as it may get freed at any moment.
 */
void input_unregister_device(struct input_dev *dev)
{}
EXPORT_SYMBOL();

static int input_handler_check_methods(const struct input_handler *handler)
{}

/**
 * input_register_handler - register a new input handler
 * @handler: handler to be registered
 *
 * This function registers a new input handler (interface) for input
 * devices in the system and attaches it to all input devices that
 * are compatible with the handler.
 */
int input_register_handler(struct input_handler *handler)
{}
EXPORT_SYMBOL();

/**
 * input_unregister_handler - unregisters an input handler
 * @handler: handler to be unregistered
 *
 * This function disconnects a handler from its input devices and
 * removes it from lists of known handlers.
 */
void input_unregister_handler(struct input_handler *handler)
{}
EXPORT_SYMBOL();

/**
 * input_handler_for_each_handle - handle iterator
 * @handler: input handler to iterate
 * @data: data for the callback
 * @fn: function to be called for each handle
 *
 * Iterate over @bus's list of devices, and call @fn for each, passing
 * it @data and stop when @fn returns a non-zero value. The function is
 * using RCU to traverse the list and therefore may be using in atomic
 * contexts. The @fn callback is invoked from RCU critical section and
 * thus must not sleep.
 */
int input_handler_for_each_handle(struct input_handler *handler, void *data,
				  int (*fn)(struct input_handle *, void *))
{}
EXPORT_SYMBOL();

/*
 * An implementation of input_handle's handle_events() method that simply
 * invokes handler->event() method for each event one by one.
 */
static unsigned int input_handle_events_default(struct input_handle *handle,
						struct input_value *vals,
						unsigned int count)
{}

/*
 * An implementation of input_handle's handle_events() method that invokes
 * handler->filter() method for each event one by one and removes events
 * that were filtered out from the "vals" array.
 */
static unsigned int input_handle_events_filter(struct input_handle *handle,
					       struct input_value *vals,
					       unsigned int count)
{}

/*
 * An implementation of input_handle's handle_events() method that does nothing.
 */
static unsigned int input_handle_events_null(struct input_handle *handle,
					     struct input_value *vals,
					     unsigned int count)
{}

/*
 * Sets up appropriate handle->event_handler based on the input_handler
 * associated with the handle.
 */
static void input_handle_setup_event_handler(struct input_handle *handle)
{}

/**
 * input_register_handle - register a new input handle
 * @handle: handle to register
 *
 * This function puts a new input handle onto device's
 * and handler's lists so that events can flow through
 * it once it is opened using input_open_device().
 *
 * This function is supposed to be called from handler's
 * connect() method.
 */
int input_register_handle(struct input_handle *handle)
{}
EXPORT_SYMBOL();

/**
 * input_unregister_handle - unregister an input handle
 * @handle: handle to unregister
 *
 * This function removes input handle from device's
 * and handler's lists.
 *
 * This function is supposed to be called from handler's
 * disconnect() method.
 */
void input_unregister_handle(struct input_handle *handle)
{}
EXPORT_SYMBOL();

/**
 * input_get_new_minor - allocates a new input minor number
 * @legacy_base: beginning or the legacy range to be searched
 * @legacy_num: size of legacy range
 * @allow_dynamic: whether we can also take ID from the dynamic range
 *
 * This function allocates a new device minor for from input major namespace.
 * Caller can request legacy minor by specifying @legacy_base and @legacy_num
 * parameters and whether ID can be allocated from dynamic range if there are
 * no free IDs in legacy range.
 */
int input_get_new_minor(int legacy_base, unsigned int legacy_num,
			bool allow_dynamic)
{}
EXPORT_SYMBOL();

/**
 * input_free_minor - release previously allocated minor
 * @minor: minor to be released
 *
 * This function releases previously allocated input minor so that it can be
 * reused later.
 */
void input_free_minor(unsigned int minor)
{}
EXPORT_SYMBOL();

static int __init input_init(void)
{}

static void __exit input_exit(void)
{}

subsys_initcall(input_init);
module_exit(input_exit);