cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

input-poller.c (5401B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Support for polling mode for input devices.
      4 */
      5
      6#include <linux/device.h>
      7#include <linux/input.h>
      8#include <linux/jiffies.h>
      9#include <linux/mutex.h>
     10#include <linux/slab.h>
     11#include <linux/types.h>
     12#include <linux/workqueue.h>
     13#include "input-poller.h"
     14
     15struct input_dev_poller {
     16	void (*poll)(struct input_dev *dev);
     17
     18	unsigned int poll_interval; /* msec */
     19	unsigned int poll_interval_max; /* msec */
     20	unsigned int poll_interval_min; /* msec */
     21
     22	struct input_dev *input;
     23	struct delayed_work work;
     24};
     25
     26static void input_dev_poller_queue_work(struct input_dev_poller *poller)
     27{
     28	unsigned long delay;
     29
     30	delay = msecs_to_jiffies(poller->poll_interval);
     31	if (delay >= HZ)
     32		delay = round_jiffies_relative(delay);
     33
     34	queue_delayed_work(system_freezable_wq, &poller->work, delay);
     35}
     36
     37static void input_dev_poller_work(struct work_struct *work)
     38{
     39	struct input_dev_poller *poller =
     40		container_of(work, struct input_dev_poller, work.work);
     41
     42	poller->poll(poller->input);
     43	input_dev_poller_queue_work(poller);
     44}
     45
     46void input_dev_poller_finalize(struct input_dev_poller *poller)
     47{
     48	if (!poller->poll_interval)
     49		poller->poll_interval = 500;
     50	if (!poller->poll_interval_max)
     51		poller->poll_interval_max = poller->poll_interval;
     52}
     53
     54void input_dev_poller_start(struct input_dev_poller *poller)
     55{
     56	/* Only start polling if polling is enabled */
     57	if (poller->poll_interval > 0) {
     58		poller->poll(poller->input);
     59		input_dev_poller_queue_work(poller);
     60	}
     61}
     62
     63void input_dev_poller_stop(struct input_dev_poller *poller)
     64{
     65	cancel_delayed_work_sync(&poller->work);
     66}
     67
     68int input_setup_polling(struct input_dev *dev,
     69			void (*poll_fn)(struct input_dev *dev))
     70{
     71	struct input_dev_poller *poller;
     72
     73	poller = kzalloc(sizeof(*poller), GFP_KERNEL);
     74	if (!poller) {
     75		/*
     76		 * We want to show message even though kzalloc() may have
     77		 * printed backtrace as knowing what instance of input
     78		 * device we were dealing with is helpful.
     79		 */
     80		dev_err(dev->dev.parent ?: &dev->dev,
     81			"%s: unable to allocate poller structure\n", __func__);
     82		return -ENOMEM;
     83	}
     84
     85	INIT_DELAYED_WORK(&poller->work, input_dev_poller_work);
     86	poller->input = dev;
     87	poller->poll = poll_fn;
     88
     89	dev->poller = poller;
     90	return 0;
     91}
     92EXPORT_SYMBOL(input_setup_polling);
     93
     94static bool input_dev_ensure_poller(struct input_dev *dev)
     95{
     96	if (!dev->poller) {
     97		dev_err(dev->dev.parent ?: &dev->dev,
     98			"poller structure has not been set up\n");
     99		return false;
    100	}
    101
    102	return true;
    103}
    104
    105void input_set_poll_interval(struct input_dev *dev, unsigned int interval)
    106{
    107	if (input_dev_ensure_poller(dev))
    108		dev->poller->poll_interval = interval;
    109}
    110EXPORT_SYMBOL(input_set_poll_interval);
    111
    112void input_set_min_poll_interval(struct input_dev *dev, unsigned int interval)
    113{
    114	if (input_dev_ensure_poller(dev))
    115		dev->poller->poll_interval_min = interval;
    116}
    117EXPORT_SYMBOL(input_set_min_poll_interval);
    118
    119void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval)
    120{
    121	if (input_dev_ensure_poller(dev))
    122		dev->poller->poll_interval_max = interval;
    123}
    124EXPORT_SYMBOL(input_set_max_poll_interval);
    125
    126int input_get_poll_interval(struct input_dev *dev)
    127{
    128	if (!dev->poller)
    129		return -EINVAL;
    130
    131	return dev->poller->poll_interval;
    132}
    133EXPORT_SYMBOL(input_get_poll_interval);
    134
    135/* SYSFS interface */
    136
    137static ssize_t input_dev_get_poll_interval(struct device *dev,
    138					   struct device_attribute *attr,
    139					   char *buf)
    140{
    141	struct input_dev *input = to_input_dev(dev);
    142
    143	return sprintf(buf, "%d\n", input->poller->poll_interval);
    144}
    145
    146static ssize_t input_dev_set_poll_interval(struct device *dev,
    147					   struct device_attribute *attr,
    148					   const char *buf, size_t count)
    149{
    150	struct input_dev *input = to_input_dev(dev);
    151	struct input_dev_poller *poller = input->poller;
    152	unsigned int interval;
    153	int err;
    154
    155	err = kstrtouint(buf, 0, &interval);
    156	if (err)
    157		return err;
    158
    159	if (interval < poller->poll_interval_min)
    160		return -EINVAL;
    161
    162	if (interval > poller->poll_interval_max)
    163		return -EINVAL;
    164
    165	mutex_lock(&input->mutex);
    166
    167	poller->poll_interval = interval;
    168
    169	if (input_device_enabled(input)) {
    170		cancel_delayed_work_sync(&poller->work);
    171		if (poller->poll_interval > 0)
    172			input_dev_poller_queue_work(poller);
    173	}
    174
    175	mutex_unlock(&input->mutex);
    176
    177	return count;
    178}
    179
    180static DEVICE_ATTR(poll, 0644,
    181		   input_dev_get_poll_interval, input_dev_set_poll_interval);
    182
    183static ssize_t input_dev_get_poll_max(struct device *dev,
    184				      struct device_attribute *attr, char *buf)
    185{
    186	struct input_dev *input = to_input_dev(dev);
    187
    188	return sprintf(buf, "%d\n", input->poller->poll_interval_max);
    189}
    190
    191static DEVICE_ATTR(max, 0444, input_dev_get_poll_max, NULL);
    192
    193static ssize_t input_dev_get_poll_min(struct device *dev,
    194				     struct device_attribute *attr, char *buf)
    195{
    196	struct input_dev *input = to_input_dev(dev);
    197
    198	return sprintf(buf, "%d\n", input->poller->poll_interval_min);
    199}
    200
    201static DEVICE_ATTR(min, 0444, input_dev_get_poll_min, NULL);
    202
    203static umode_t input_poller_attrs_visible(struct kobject *kobj,
    204					  struct attribute *attr, int n)
    205{
    206	struct device *dev = kobj_to_dev(kobj);
    207	struct input_dev *input = to_input_dev(dev);
    208
    209	return input->poller ? attr->mode : 0;
    210}
    211
    212static struct attribute *input_poller_attrs[] = {
    213	&dev_attr_poll.attr,
    214	&dev_attr_max.attr,
    215	&dev_attr_min.attr,
    216	NULL
    217};
    218
    219struct attribute_group input_poller_attribute_group = {
    220	.is_visible	= input_poller_attrs_visible,
    221	.attrs		= input_poller_attrs,
    222};