Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d32af01 authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Merge branch 'next' into for-linus

Second round of input updates for 3.19.
parents f20c86cd 27a560ba
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -10,12 +10,13 @@ Optional properties:
Each button (key) is represented as a sub-node of "gpio-keys":
Each button (key) is represented as a sub-node of "gpio-keys":
Subnode properties:
Subnode properties:


	- gpios: OF device-tree gpio specification.
	- interrupts: the interrupt line for that input.
	- label: Descriptive name of the key.
	- label: Descriptive name of the key.
	- linux,code: Keycode to emit.
	- linux,code: Keycode to emit.


Required mutual exclusive subnode-properties:
Note that either "interrupts" or "gpios" properties can be omitted, but not
	- gpios: OF device-tree gpio specification.
both at the same time. Specifying both properties is allowed.
	- interrupts: the interrupt line for that input


Optional subnode-properties:
Optional subnode-properties:
	- linux,input-type: Specify event type this button/key generates.
	- linux,input-type: Specify event type this button/key generates.
@@ -23,6 +24,9 @@ Optional subnode-properties:
	- debounce-interval: Debouncing interval time in milliseconds.
	- debounce-interval: Debouncing interval time in milliseconds.
	  If not specified defaults to 5.
	  If not specified defaults to 5.
	- gpio-key,wakeup: Boolean, button can wake-up the system.
	- gpio-key,wakeup: Boolean, button can wake-up the system.
	- linux,can-disable: Boolean, indicates that button is connected
	  to dedicated (not shared) interrupt which can be disabled to
	  suppress events from the button.


Example nodes:
Example nodes:


+2 −0
Original line number Original line Diff line number Diff line
@@ -8,6 +8,8 @@ Optional properties:
 - debounce-interval        : Debouncing interval time in milliseconds
 - debounce-interval        : Debouncing interval time in milliseconds
 - st,scan-count            : Scanning cycles elapsed before key data is updated
 - st,scan-count            : Scanning cycles elapsed before key data is updated
 - st,no-autorepeat         : If specified device will not autorepeat
 - st,no-autorepeat         : If specified device will not autorepeat
 - keypad,num-rows          : See ./matrix-keymap.txt
 - keypad,num-columns       : See ./matrix-keymap.txt


Example:
Example:


+44 −16
Original line number Original line Diff line number Diff line
@@ -28,6 +28,13 @@
#include <linux/cdev.h>
#include <linux/cdev.h>
#include "input-compat.h"
#include "input-compat.h"


enum evdev_clock_type {
	EV_CLK_REAL = 0,
	EV_CLK_MONO,
	EV_CLK_BOOT,
	EV_CLK_MAX
};

struct evdev {
struct evdev {
	int open;
	int open;
	struct input_handle handle;
	struct input_handle handle;
@@ -49,12 +56,32 @@ struct evdev_client {
	struct fasync_struct *fasync;
	struct fasync_struct *fasync;
	struct evdev *evdev;
	struct evdev *evdev;
	struct list_head node;
	struct list_head node;
	int clkid;
	int clk_type;
	bool revoked;
	bool revoked;
	unsigned int bufsize;
	unsigned int bufsize;
	struct input_event buffer[];
	struct input_event buffer[];
};
};


static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
{
	switch (clkid) {

	case CLOCK_REALTIME:
		client->clk_type = EV_CLK_REAL;
		break;
	case CLOCK_MONOTONIC:
		client->clk_type = EV_CLK_MONO;
		break;
	case CLOCK_BOOTTIME:
		client->clk_type = EV_CLK_BOOT;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/* flush queued events of type @type, caller must hold client->buffer_lock */
/* flush queued events of type @type, caller must hold client->buffer_lock */
static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
{
{
@@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
	struct input_event ev;
	struct input_event ev;
	ktime_t time;
	ktime_t time;


	time = (client->clkid == CLOCK_MONOTONIC) ?
	time = client->clk_type == EV_CLK_REAL ?
		ktime_get() : ktime_get_real();
			ktime_get_real() :
			client->clk_type == EV_CLK_MONO ?
				ktime_get() :
				ktime_get_boottime();


	ev.time = ktime_to_timeval(time);
	ev.time = ktime_to_timeval(time);
	ev.type = EV_SYN;
	ev.type = EV_SYN;
@@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client,


static void evdev_pass_values(struct evdev_client *client,
static void evdev_pass_values(struct evdev_client *client,
			const struct input_value *vals, unsigned int count,
			const struct input_value *vals, unsigned int count,
			ktime_t mono, ktime_t real)
			ktime_t *ev_time)
{
{
	struct evdev *evdev = client->evdev;
	struct evdev *evdev = client->evdev;
	const struct input_value *v;
	const struct input_value *v;
@@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client,
	if (client->revoked)
	if (client->revoked)
		return;
		return;


	event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
	event.time = ktime_to_timeval(ev_time[client->clk_type]);
				      mono : real);


	/* Interrupts are disabled, just acquire the lock. */
	/* Interrupts are disabled, just acquire the lock. */
	spin_lock(&client->buffer_lock);
	spin_lock(&client->buffer_lock);
@@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle,
{
{
	struct evdev *evdev = handle->private;
	struct evdev *evdev = handle->private;
	struct evdev_client *client;
	struct evdev_client *client;
	ktime_t time_mono, time_real;
	ktime_t ev_time[EV_CLK_MAX];


	time_mono = ktime_get();
	ev_time[EV_CLK_MONO] = ktime_get();
	time_real = ktime_mono_to_real(time_mono);
	ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
	ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
						 TK_OFFS_BOOT);


	rcu_read_lock();
	rcu_read_lock();


	client = rcu_dereference(evdev->grab);
	client = rcu_dereference(evdev->grab);


	if (client)
	if (client)
		evdev_pass_values(client, vals, count, time_mono, time_real);
		evdev_pass_values(client, vals, count, ev_time);
	else
	else
		list_for_each_entry_rcu(client, &evdev->client_list, node)
		list_for_each_entry_rcu(client, &evdev->client_list, node)
			evdev_pass_values(client, vals, count,
			evdev_pass_values(client, vals, count, ev_time);
					  time_mono, time_real);


	rcu_read_unlock();
	rcu_read_unlock();
}
}
@@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
	case EVIOCSCLOCKID:
	case EVIOCSCLOCKID:
		if (copy_from_user(&i, p, sizeof(unsigned int)))
		if (copy_from_user(&i, p, sizeof(unsigned int)))
			return -EFAULT;
			return -EFAULT;
		if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)

			return -EINVAL;
		return evdev_set_clk_type(client, i);
		client->clkid = i;
		return 0;


	case EVIOCGKEYCODE:
	case EVIOCGKEYCODE:
		return evdev_handle_get_keycode(dev, p);
		return evdev_handle_get_keycode(dev, p);
+13 −9
Original line number Original line Diff line number Diff line
@@ -1974,6 +1974,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)


	events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
	events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */


	if (test_bit(EV_ABS, dev->evbit)) {
		for (i = 0; i < ABS_CNT; i++) {
		for (i = 0; i < ABS_CNT; i++) {
			if (test_bit(i, dev->absbit)) {
			if (test_bit(i, dev->absbit)) {
				if (input_is_mt_axis(i))
				if (input_is_mt_axis(i))
@@ -1982,10 +1983,13 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
					events++;
					events++;
			}
			}
		}
		}
	}


	if (test_bit(EV_REL, dev->evbit)) {
		for (i = 0; i < REL_CNT; i++)
		for (i = 0; i < REL_CNT; i++)
			if (test_bit(i, dev->relbit))
			if (test_bit(i, dev->relbit))
				events++;
				events++;
	}


	/* Make room for KEY and MSC events */
	/* Make room for KEY and MSC events */
	events += 7;
	events += 7;
+1 −0
Original line number Original line Diff line number Diff line
@@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC
config KEYBOARD_STMPE
config KEYBOARD_STMPE
	tristate "STMPE keypad support"
	tristate "STMPE keypad support"
	depends on MFD_STMPE
	depends on MFD_STMPE
	depends on OF
	select INPUT_MATRIXKMAP
	select INPUT_MATRIXKMAP
	help
	help
	  Say Y here if you want to use the keypad controller on STMPE I/O
	  Say Y here if you want to use the keypad controller on STMPE I/O
Loading