Loading Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.yaml +12 −4 Original line number Diff line number Diff line Loading @@ -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 Loading Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml +2 −0 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ properties: - edt,edt-ft5406 - edt,edt-ft5506 - evervision,ev-ft5726 - focaltech,ft5452 - focaltech,ft6236 - focaltech,ft8719 reg: maxItems: 1 Loading drivers/input/ff-core.c +4 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); Loading drivers/input/input.c +89 −15 Original line number Diff line number Diff line Loading @@ -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-", Loading @@ -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, Loading @@ -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) Loading @@ -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); } Loading Loading @@ -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) { Loading @@ -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; Loading drivers/input/joystick/adafruit-seesaw.c +18 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 { Loading Loading @@ -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); Loading @@ -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)) Loading Loading @@ -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 Loading
Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.yaml +12 −4 Original line number Diff line number Diff line Loading @@ -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 Loading
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml +2 −0 Original line number Diff line number Diff line Loading @@ -39,7 +39,9 @@ properties: - edt,edt-ft5406 - edt,edt-ft5506 - evervision,ev-ft5726 - focaltech,ft5452 - focaltech,ft6236 - focaltech,ft8719 reg: maxItems: 1 Loading
drivers/input/ff-core.c +4 −3 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); Loading
drivers/input/input.c +89 −15 Original line number Diff line number Diff line Loading @@ -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-", Loading @@ -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, Loading @@ -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) Loading @@ -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); } Loading Loading @@ -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) { Loading @@ -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; Loading
drivers/input/joystick/adafruit-seesaw.c +18 −3 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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 { Loading Loading @@ -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); Loading @@ -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)) Loading Loading @@ -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