Commit 9ea370f3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull input updates from Dmitry Torokhov:

 - a change to input core to trim amount of keys data in modalias string
   in case when a device declares too many keys and they do not fit in
   uevent buffer instead of reporting an error which results in uevent
   not being generated at all

 - support for Machenike G5 Pro Controller added to xpad driver

 - support for FocalTech FT5452 and FT8719 added to edt-ft5x06

 - support for new SPMI vibrator added to pm8xxx-vibrator driver

 - missing locking added to cyapa touchpad driver

 - removal of unused fields in various driver structures

 - explicit initialization of i2c_device_id::driver_data to 0 dropped
   from input drivers

 - other assorted fixes and cleanups.

* tag 'input-for-v6.10-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (24 commits)
  Input: edt-ft5x06 - add support for FocalTech FT5452 and FT8719
  dt-bindings: input: touchscreen: edt-ft5x06: Document FT5452 and FT8719 support
  Input: xpad - add support for Machenike G5 Pro Controller
  Input: try trimming too long modalias strings
  Input: drop explicit initialization of struct i2c_device_id::driver_data to 0
  Input: zet6223 - remove an unused field in struct zet6223_ts
  Input: chipone_icn8505 - remove an unused field in struct icn8505_data
  Input: cros_ec_keyb - remove an unused field in struct cros_ec_keyb
  Input: lpc32xx-keys - remove an unused field in struct lpc32xx_kscan_drv
  Input: matrix_keypad - remove an unused field in struct matrix_keypad
  Input: tca6416-keypad - remove unused struct tca6416_drv_data
  Input: tca6416-keypad - remove an unused field in struct tca6416_keypad_chip
  Input: da7280 - remove an unused field in struct da7280_haptic
  Input: ff-core - prefer struct_size over open coded arithmetic
  Input: cyapa - add missing input core locking to suspend/resume functions
  input: pm8xxx-vibrator: add new SPMI vibrator support
  dt-bindings: input: qcom,pm8xxx-vib: add new SPMI vibrator module
  input: pm8xxx-vibrator: refactor to support new SPMI vibrator
  Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation
  Input: sur40 - convert le16 to cpu before use
  ...
parents 041c9f71 2ec0028a
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -11,10 +11,18 @@ maintainers:

properties:
  compatible:
    enum:
    oneOf:
      - enum:
          - qcom,pm8058-vib
          - qcom,pm8916-vib
          - qcom,pm8921-vib
          - qcom,pmi632-vib
      - items:
          - enum:
              - qcom,pm7250b-vib
              - qcom,pm7325b-vib
              - qcom,pm7550ba-vib
          - const: qcom,pmi632-vib

  reg:
    maxItems: 1
+2 −0
Original line number Diff line number Diff line
@@ -39,7 +39,9 @@ properties:
      - edt,edt-ft5406
      - edt,edt-ft5506
      - evervision,ev-ft5726
      - focaltech,ft5452
      - focaltech,ft6236
      - focaltech,ft8719

  reg:
    maxItems: 1
+4 −3
Original line number Diff line number Diff line
@@ -9,8 +9,10 @@
/* #define DEBUG */

#include <linux/input.h>
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/overflow.h>
#include <linux/sched.h>
#include <linux/slab.h>

@@ -315,9 +317,8 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects)
		return -EINVAL;
	}

	ff_dev_size = sizeof(struct ff_device) +
				max_effects * sizeof(struct file *);
	if (ff_dev_size < max_effects) /* overflow */
	ff_dev_size = struct_size(ff, effect_owners, max_effects);
	if (ff_dev_size == SIZE_MAX) /* overflow */
		return -EINVAL;

	ff = kzalloc(ff_dev_size, GFP_KERNEL);
+89 −15
Original line number Diff line number Diff line
@@ -1378,19 +1378,19 @@ static int input_print_modalias_bits(char *buf, int size,
				     char name, const unsigned long *bm,
				     unsigned int min_bit, unsigned int max_bit)
{
	int len = 0, i;
	int bit = min_bit;
	int len = 0;

	len += snprintf(buf, max(size, 0), "%c", name);
	for (i = min_bit; i < max_bit; i++)
		if (bm[BIT_WORD(i)] & BIT_MASK(i))
			len += snprintf(buf + len, max(size - len, 0), "%X,", i);
	for_each_set_bit_from(bit, bm, max_bit)
		len += snprintf(buf + len, max(size - len, 0), "%X,", bit);
	return len;
}

static int input_print_modalias(char *buf, int size, const struct input_dev *id,
				int add_cr)
static int input_print_modalias_parts(char *buf, int size, int full_len,
				      const struct input_dev *id)
{
	int len;
	int len, klen, remainder, space;

	len = snprintf(buf, max(size, 0),
		       "input:b%04Xv%04Xp%04Xe%04X-",
@@ -1399,8 +1399,48 @@ static int input_print_modalias(char *buf, int size, const struct input_dev *id,

	len += input_print_modalias_bits(buf + len, size - len,
				'e', id->evbit, 0, EV_MAX);
	len += input_print_modalias_bits(buf + len, size - len,

	/*
	 * Calculate the remaining space in the buffer making sure we
	 * have place for the terminating 0.
	 */
	space = max(size - (len + 1), 0);

	klen = input_print_modalias_bits(buf + len, size - len,
				'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
	len += klen;

	/*
	 * If we have more data than we can fit in the buffer, check
	 * if we can trim key data to fit in the rest. We will indicate
	 * that key data is incomplete by adding "+" sign at the end, like
	 * this: * "k1,2,3,45,+,".
	 *
	 * Note that we shortest key info (if present) is "k+," so we
	 * can only try to trim if key data is longer than that.
	 */
	if (full_len && size < full_len + 1 && klen > 3) {
		remainder = full_len - len;
		/*
		 * We can only trim if we have space for the remainder
		 * and also for at least "k+," which is 3 more characters.
		 */
		if (remainder <= space - 3) {
			/*
			 * We are guaranteed to have 'k' in the buffer, so
			 * we need at least 3 additional bytes for storing
			 * "+," in addition to the remainder.
			 */
			for (int i = size - 1 - remainder - 3; i >= 0; i--) {
				if (buf[i] == 'k' || buf[i] == ',') {
					strcpy(buf + i + 1, "+,");
					len = i + 3; /* Not counting '\0' */
					break;
				}
			}
		}
	}

	len += input_print_modalias_bits(buf + len, size - len,
				'r', id->relbit, 0, REL_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
@@ -1416,12 +1456,25 @@ static int input_print_modalias(char *buf, int size, const struct input_dev *id,
	len += input_print_modalias_bits(buf + len, size - len,
				'w', id->swbit, 0, SW_MAX);

	if (add_cr)
		len += snprintf(buf + len, max(size - len, 0), "\n");

	return len;
}

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

	/*
	 * Printing is done in 2 passes: first one figures out total length
	 * needed for the modalias string, second one will try to trim key
	 * data in case when buffer is too small for the entire modalias.
	 * If the buffer is too small regardless, it will fill as much as it
	 * can (without trimming key data) into the buffer and leave it to
	 * the caller to figure out what to do with the result.
	 */
	full_len = input_print_modalias_parts(NULL, 0, 0, id);
	return input_print_modalias_parts(buf, size, full_len, id);
}

static ssize_t input_dev_show_modalias(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
@@ -1429,7 +1482,9 @@ static ssize_t input_dev_show_modalias(struct device *dev,
	struct input_dev *id = to_input_dev(dev);
	ssize_t len;

	len = input_print_modalias(buf, PAGE_SIZE, id, 1);
	len = input_print_modalias(buf, PAGE_SIZE, id);
	if (len < PAGE_SIZE - 2)
		len += snprintf(buf + len, PAGE_SIZE - len, "\n");

	return min_t(int, len, PAGE_SIZE);
}
@@ -1641,6 +1696,23 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
	return 0;
}

/*
 * 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	96

static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
					 const struct input_dev *dev)
{
@@ -1650,9 +1722,11 @@ static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
		return -ENOMEM;

	len = input_print_modalias(&env->buf[env->buflen - 1],
				   sizeof(env->buf) - env->buflen,
				   dev, 0);
	if (len >= (sizeof(env->buf) - env->buflen))
				   (int)sizeof(env->buf) - env->buflen -
					UEVENT_ENV_EXTRA_LEN,
				   dev);
	if (len >= ((int)sizeof(env->buf) - env->buflen -
					UEVENT_ENV_EXTRA_LEN))
		return -ENOMEM;

	env->buflen += len;
+18 −3
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@
#define SEESAW_GAMEPAD_POLL_MIN		8
#define SEESAW_GAMEPAD_POLL_MAX		32

static const unsigned long SEESAW_BUTTON_MASK =
static const u32 SEESAW_BUTTON_MASK =
	BIT(SEESAW_BUTTON_A) | BIT(SEESAW_BUTTON_B) | BIT(SEESAW_BUTTON_X) |
	BIT(SEESAW_BUTTON_Y) | BIT(SEESAW_BUTTON_START) |
	BIT(SEESAW_BUTTON_SELECT);
@@ -64,6 +64,7 @@ static const unsigned long SEESAW_BUTTON_MASK =
struct seesaw_gamepad {
	struct input_dev *input_dev;
	struct i2c_client *i2c_client;
	u32 button_state;
};

struct seesaw_data {
@@ -178,10 +179,20 @@ static int seesaw_read_data(struct i2c_client *client, struct seesaw_data *data)
	return 0;
}

static int seesaw_open(struct input_dev *input)
{
	struct seesaw_gamepad *private = input_get_drvdata(input);

	private->button_state = 0;

	return 0;
}

static void seesaw_poll(struct input_dev *input)
{
	struct seesaw_gamepad *private = input_get_drvdata(input);
	struct seesaw_data data;
	unsigned long changed;
	int err, i;

	err = seesaw_read_data(private->i2c_client, &data);
@@ -194,8 +205,11 @@ static void seesaw_poll(struct input_dev *input)
	input_report_abs(input, ABS_X, data.x);
	input_report_abs(input, ABS_Y, data.y);

	for_each_set_bit(i, &SEESAW_BUTTON_MASK,
			 BITS_PER_TYPE(SEESAW_BUTTON_MASK)) {
	data.button_state &= SEESAW_BUTTON_MASK;
	changed = private->button_state ^ data.button_state;
	private->button_state = data.button_state;

	for_each_set_bit(i, &changed, fls(SEESAW_BUTTON_MASK)) {
		if (!sparse_keymap_report_event(input, i,
						data.button_state & BIT(i),
						false))
@@ -253,6 +267,7 @@ static int seesaw_probe(struct i2c_client *client)
	seesaw->input_dev->id.bustype = BUS_I2C;
	seesaw->input_dev->name = "Adafruit Seesaw Gamepad";
	seesaw->input_dev->phys = "i2c/" SEESAW_DEVICE_NAME;
	seesaw->input_dev->open = seesaw_open;
	input_set_drvdata(seesaw->input_dev, seesaw);
	input_set_abs_params(seesaw->input_dev, ABS_X,
			     0, SEESAW_JOYSTICK_MAX_AXIS,
Loading