summaryrefslogtreecommitdiff
path: root/drivers/input/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-24 11:16:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-24 11:16:06 -0700
commite1611017870fa1582b5ff9ec0edc09542318daa6 (patch)
treefaff3dcc5bd72395f407a01922ac5366f9a76cea /drivers/input/misc
parentf0e6f20cb52b14c2c441f04e21cef0c95d498cac (diff)
parent7a0e692a0381254b2f77c54dec100cd3325a6fdf (diff)
Merge tag 'input-for-v7.2-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov: - A new driver for Wacom W9000-series penabled touchscreens - Updates to STM FTS driver adding support for reset line and preparing the driver for STMFTS5 support - Updates to RMI4 and IMS PCU drivers hardening the code - Support for half-duplex mode restored in ADS7846 driver - Updates to driver's device_id tables to use named initializers - Removal of no longer used PCAP keys and touchscreen drivers (support for the ezx series of phones was removed in 2022) - Removal of xilinx_ps2 driver which is no longer used either - Updates to userio to allow setting up additional serio port characteristics (such as id, extra and proto) - Assorted hardening and cleanup fixes for other drivers * tag 'input-for-v7.2-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (72 commits) Input: mms114 - fix touch indexing for MMS134S and MMS136 Input: elan_i2c - prevent division by zero and arithmetic underflow Input: stop force-feedback timer when unregistering input devices Input: iforce - bound the device-reported force-feedback effect index Input: goodix - clamp the device-reported contact count Input: mms114 - reject an oversized device packet size Input: touchwin - reset the packet index on every complete packet Input: rmi4 - update formatting in F12 Input: rmi4 - propagate proper error code in F12 sensor tuning Input: rmi4 - simplify size calculations in F12 Input: rmi4 - use sizeof(*ptr) and idiomatic checks in f12 allocators Input: rmi4 - use devm_kmalloc for F12 data packet buffer Input: rmi4 - use flexible array member for IRQ masks in F12 Input: rmi4 - use unaligned access helpers in F12 Input: rmi4 - change reg_size type to u32 Input: rmi4 - refactor F12 probe function Input: rmi4 - use kzalloc_flex() for struct rmi_function Input: rmi4 - refactor function allocation and registration Input: rmi4 - use local presence map in rmi_read_register_desc() Input: rmi4 - fix limit in rmi_register_desc_has_subpacket() ...
Diffstat (limited to 'drivers/input/misc')
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/ad714x-i2c.c10
-rw-r--r--drivers/input/misc/adxl34x-i2c.c2
-rw-r--r--drivers/input/misc/apanel.c2
-rw-r--r--drivers/input/misc/atlas_btns.c109
-rw-r--r--drivers/input/misc/atmel_captouch.c2
-rw-r--r--drivers/input/misc/bma150.c6
-rw-r--r--drivers/input/misc/cma3000_d0x_i2c.c2
-rw-r--r--drivers/input/misc/da7280.c2
-rw-r--r--drivers/input/misc/drv260x.c8
-rw-r--r--drivers/input/misc/drv2665.c2
-rw-r--r--drivers/input/misc/drv2667.c2
-rw-r--r--drivers/input/misc/ims-pcu.c131
-rw-r--r--drivers/input/misc/kxtj9.c2
-rw-r--r--drivers/input/misc/mma8450.c2
-rw-r--r--drivers/input/misc/pcap_keys.c125
-rw-r--r--drivers/input/misc/pcf8574_keypad.c2
-rw-r--r--drivers/input/misc/yealink.c9
19 files changed, 190 insertions, 239 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 94a753fcb64f..1f6c57dba030 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -745,16 +745,6 @@ config INPUT_WM831X_ON
To compile this driver as a module, choose M here: the module
will be called wm831x_on.
-config INPUT_PCAP
- tristate "Motorola EZX PCAP misc input events"
- depends on EZX_PCAP
- help
- Say Y here if you want to use Power key and Headphone button
- on Motorola EZX phones.
-
- To compile this driver as a module, choose M here: the
- module will be called pcap_keys.
-
config INPUT_ADXL34X
tristate "Analog Devices ADXL34x Three-Axis Digital Accelerometer"
default n
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 415fc4e2918b..2281d6803fce 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -60,7 +60,6 @@ obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
obj-$(CONFIG_INPUT_MMA8450) += mma8450.o
obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON) += palmas-pwrbutton.o
-obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_PF1550_ONKEY) += pf1550-onkey.o
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index 2adb7a058362..c3cb561512ed 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -72,11 +72,11 @@ static int ad714x_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id ad714x_id[] = {
- { "ad7142_captouch" },
- { "ad7143_captouch" },
- { "ad7147_captouch" },
- { "ad7147a_captouch" },
- { "ad7148_captouch" },
+ { .name = "ad7142_captouch" },
+ { .name = "ad7143_captouch" },
+ { .name = "ad7147_captouch" },
+ { .name = "ad7147a_captouch" },
+ { .name = "ad7148_captouch" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad714x_id);
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
index 5ea0ce42a507..84665c612f3c 100644
--- a/drivers/input/misc/adxl34x-i2c.c
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -96,7 +96,7 @@ static int adxl34x_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl34x_id[] = {
- { "adxl34x" },
+ { .name = "adxl34x" },
{ }
};
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c
index d43aebd785b7..3eb02a64acfb 100644
--- a/drivers/input/misc/apanel.c
+++ b/drivers/input/misc/apanel.c
@@ -192,7 +192,7 @@ static void apanel_shutdown(struct i2c_client *client)
}
static const struct i2c_device_id apanel_id[] = {
- { "fujitsu_apanel" },
+ { .name = "fujitsu_apanel" },
{ }
};
MODULE_DEVICE_TABLE(i2c, apanel_id);
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 835ad45a9d65..5805a1a3bb05 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -15,17 +15,18 @@
#include <linux/types.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
-#include <linux/uaccess.h>
#define ACPI_ATLAS_NAME "Atlas ACPI"
-#define ACPI_ATLAS_CLASS "Atlas"
-static unsigned short atlas_keymap[16];
-static struct input_dev *input_dev;
+struct atlas_btns {
+ struct input_dev *input_dev;
+ unsigned short keymap[16];
+};
/* button handling code */
static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
- u32 function, void *handler_context, void **return_context)
+ u32 function, void *handler_context,
+ void **return_context)
{
*return_context =
(function != ACPI_REGION_DEACTIVATE) ? handler_context : NULL;
@@ -34,33 +35,37 @@ static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
}
static acpi_status acpi_atlas_button_handler(u32 function,
- acpi_physical_address address,
- u32 bit_width, u64 *value,
- void *handler_context, void *region_context)
+ acpi_physical_address address,
+ u32 bit_width, u64 *value,
+ void *handler_context,
+ void *region_context)
{
- acpi_status status;
+ struct atlas_btns *atlas = region_context;
if (function == ACPI_WRITE) {
int code = address & 0x0f;
int key_down = !(address & 0x10);
- input_event(input_dev, EV_MSC, MSC_SCAN, code);
- input_report_key(input_dev, atlas_keymap[code], key_down);
- input_sync(input_dev);
+ input_event(atlas->input_dev, EV_MSC, MSC_SCAN, code);
+ input_report_key(atlas->input_dev, atlas->keymap[code],
+ key_down);
+ input_sync(atlas->input_dev);
- status = AE_OK;
- } else {
- pr_warn("shrugged on unexpected function: function=%x,address=%lx,value=%x\n",
- function, (unsigned long)address, (u32)*value);
- status = AE_BAD_PARAMETER;
+ return AE_OK;
}
- return status;
+ dev_warn(atlas->input_dev->dev.parent,
+ "unexpected function: function=%x,address=%lx,value=%x\n",
+ function, (unsigned long)address, (u32)*value);
+
+ return AE_BAD_PARAMETER;
}
static int atlas_acpi_button_probe(struct platform_device *pdev)
{
struct acpi_device *device;
+ struct atlas_btns *atlas;
+ struct input_dev *input_dev;
acpi_status status;
int i;
int err;
@@ -69,65 +74,62 @@ static int atlas_acpi_button_probe(struct platform_device *pdev)
if (!device)
return -ENODEV;
- input_dev = input_allocate_device();
- if (!input_dev) {
- pr_err("unable to allocate input device\n");
+ atlas = devm_kzalloc(&pdev->dev, sizeof(*atlas), GFP_KERNEL);
+ if (!atlas)
return -ENOMEM;
- }
+
+ input_dev = devm_input_allocate_device(&pdev->dev);
+ if (!input_dev)
+ return -ENOMEM;
+
+ atlas->input_dev = input_dev;
input_dev->name = "Atlas ACPI button driver";
input_dev->phys = "ASIM0000/atlas/input0";
input_dev->id.bustype = BUS_HOST;
- input_dev->keycode = atlas_keymap;
- input_dev->keycodesize = sizeof(unsigned short);
- input_dev->keycodemax = ARRAY_SIZE(atlas_keymap);
+ input_dev->keycode = atlas->keymap;
+ input_dev->keycodesize = sizeof(atlas->keymap[0]);
+ input_dev->keycodemax = ARRAY_SIZE(atlas->keymap);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
- __set_bit(EV_KEY, input_dev->evbit);
- for (i = 0; i < ARRAY_SIZE(atlas_keymap); i++) {
+ for (i = 0; i < ARRAY_SIZE(atlas->keymap); i++) {
if (i < 9) {
- atlas_keymap[i] = KEY_F1 + i;
- __set_bit(KEY_F1 + i, input_dev->keybit);
- } else
- atlas_keymap[i] = KEY_RESERVED;
+ atlas->keymap[i] = KEY_F1 + i;
+ input_set_capability(input_dev, EV_KEY, KEY_F1 + i);
+ } else {
+ atlas->keymap[i] = KEY_RESERVED;
+ }
}
err = input_register_device(input_dev);
- if (err) {
- pr_err("couldn't register input device\n");
- input_free_device(input_dev);
- return err;
- }
+ if (err)
+ return dev_err_probe(&pdev->dev, err,
+ "couldn't register input device\n");
/* hookup button handler */
status = acpi_install_address_space_handler(device->handle,
- 0x81, &acpi_atlas_button_handler,
- &acpi_atlas_button_setup, device);
- if (ACPI_FAILURE(status)) {
- pr_err("error installing addr spc handler\n");
- input_unregister_device(input_dev);
- err = -EINVAL;
- }
+ 0x81,
+ &acpi_atlas_button_handler,
+ &acpi_atlas_button_setup,
+ atlas);
+ if (ACPI_FAILURE(status))
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "error installing addr spc handler\n");
- return err;
+ return 0;
}
static void atlas_acpi_button_remove(struct platform_device *pdev)
{
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
- acpi_status status;
- status = acpi_remove_address_space_handler(device->handle,
- 0x81, &acpi_atlas_button_handler);
- if (ACPI_FAILURE(status))
- pr_err("error removing addr spc handler\n");
-
- input_unregister_device(input_dev);
+ acpi_remove_address_space_handler(device->handle, 0x81,
+ &acpi_atlas_button_handler);
}
static const struct acpi_device_id atlas_device_ids[] = {
- {"ASIM0000", 0},
- {"", 0},
+ { "ASIM0000" },
+ { "" }
};
MODULE_DEVICE_TABLE(acpi, atlas_device_ids);
@@ -144,4 +146,3 @@ module_platform_driver(atlas_acpi_driver);
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atlas button driver");
-
diff --git a/drivers/input/misc/atmel_captouch.c b/drivers/input/misc/atmel_captouch.c
index f9744cf0ca80..fc4abea68479 100644
--- a/drivers/input/misc/atmel_captouch.c
+++ b/drivers/input/misc/atmel_captouch.c
@@ -257,7 +257,7 @@ static const struct of_device_id atmel_captouch_of_id[] = {
MODULE_DEVICE_TABLE(of, atmel_captouch_of_id);
static const struct i2c_device_id atmel_captouch_id[] = {
- { "atmel_captouch" },
+ { .name = "atmel_captouch" },
{ }
};
MODULE_DEVICE_TABLE(i2c, atmel_captouch_id);
diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c
index 4cc2a0dcaa75..0ef282932095 100644
--- a/drivers/input/misc/bma150.c
+++ b/drivers/input/misc/bma150.c
@@ -536,9 +536,9 @@ static int __maybe_unused bma150_resume(struct device *dev)
static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
static const struct i2c_device_id bma150_id[] = {
- { "bma150" },
- { "smb380" },
- { "bma023" },
+ { .name = "bma150" },
+ { .name = "smb380" },
+ { .name = "bma023" },
{ }
};
diff --git a/drivers/input/misc/cma3000_d0x_i2c.c b/drivers/input/misc/cma3000_d0x_i2c.c
index f892c5b1e4bd..14be6d4682d0 100644
--- a/drivers/input/misc/cma3000_d0x_i2c.c
+++ b/drivers/input/misc/cma3000_d0x_i2c.c
@@ -90,7 +90,7 @@ static const struct dev_pm_ops cma3000_i2c_pm_ops = {
};
static const struct i2c_device_id cma3000_i2c_id[] = {
- { "cma3000_d01" },
+ { .name = "cma3000_d01" },
{ }
};
diff --git a/drivers/input/misc/da7280.c b/drivers/input/misc/da7280.c
index e4a605c6af15..77fcf868dca2 100644
--- a/drivers/input/misc/da7280.c
+++ b/drivers/input/misc/da7280.c
@@ -1305,7 +1305,7 @@ MODULE_DEVICE_TABLE(of, da7280_of_match);
#endif
static const struct i2c_device_id da7280_i2c_id[] = {
- { "da7280", },
+ { .name = "da7280" },
{ }
};
MODULE_DEVICE_TABLE(i2c, da7280_i2c_id);
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index e2089d6ac850..6c5c4c53753b 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -630,10 +630,10 @@ static int drv260x_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume);
static const struct i2c_device_id drv260x_id[] = {
- { "drv2604" },
- { "drv2604l" },
- { "drv2605" },
- { "drv2605l" },
+ { .name = "drv2604" },
+ { .name = "drv2604l" },
+ { .name = "drv2605" },
+ { .name = "drv2605l" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv260x_id);
diff --git a/drivers/input/misc/drv2665.c b/drivers/input/misc/drv2665.c
index 46842cb8ddd7..4f8c1f69aa63 100644
--- a/drivers/input/misc/drv2665.c
+++ b/drivers/input/misc/drv2665.c
@@ -281,7 +281,7 @@ static int drv2665_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(drv2665_pm_ops, drv2665_suspend, drv2665_resume);
static const struct i2c_device_id drv2665_id[] = {
- { "drv2665" },
+ { .name = "drv2665" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv2665_id);
diff --git a/drivers/input/misc/drv2667.c b/drivers/input/misc/drv2667.c
index f952a24ec595..97309984fa7c 100644
--- a/drivers/input/misc/drv2667.c
+++ b/drivers/input/misc/drv2667.c
@@ -458,7 +458,7 @@ static int drv2667_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume);
static const struct i2c_device_id drv2667_id[] = {
- { "drv2667" },
+ { .name = "drv2667" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv2667_id);
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 7a1cb9333f53..b1ff8c70877f 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -14,6 +14,7 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/usb/input.h>
#include <linux/usb/cdc.h>
@@ -406,7 +407,16 @@ static void ims_pcu_destroy_gamepad(struct ims_pcu *pcu)
static void ims_pcu_report_events(struct ims_pcu *pcu)
{
- u32 data = get_unaligned_be32(&pcu->read_buf[3]);
+ u32 data;
+
+ /* 6-axis setting (1 byte) + button data + checksum */
+ if (pcu->read_pos < IMS_PCU_DATA_OFFSET + 1 + sizeof(data) + 1) {
+ dev_warn(pcu->dev, "Short buttons report: %d bytes\n",
+ pcu->read_pos);
+ return;
+ }
+
+ data = get_unaligned_be32(&pcu->read_buf[IMS_PCU_DATA_OFFSET + 1]);
ims_pcu_buttons_report(pcu, data & ~IMS_PCU_GAMEPAD_MASK);
if (pcu->gamepad)
@@ -440,7 +450,7 @@ static void ims_pcu_handle_response(struct ims_pcu *pcu)
static void ims_pcu_reset_packet(struct ims_pcu *pcu)
{
- pcu->have_stx = true;
+ pcu->have_stx = false;
pcu->have_dle = false;
pcu->read_pos = 0;
pcu->check_sum = 0;
@@ -686,11 +696,19 @@ static int __ims_pcu_execute_bl_command(struct ims_pcu *pcu,
return error;
}
- if (expected_response && pcu->cmd_buf[2] != expected_response) {
- dev_err(pcu->dev,
- "Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n",
- pcu->cmd_buf[2], expected_response);
- return -EINVAL;
+ if (expected_response) {
+ if (pcu->cmd_buf_len < 3) {
+ dev_err(pcu->dev, "Short response from bootloader: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
+ if (pcu->cmd_buf[2] != expected_response) {
+ dev_err(pcu->dev,
+ "Unexpected response from bootloader: 0x%02x, wanted 0x%02x\n",
+ pcu->cmd_buf[2], expected_response);
+ return -EINVAL;
+ }
}
return 0;
@@ -718,6 +736,12 @@ static int ims_pcu_get_info(struct ims_pcu *pcu)
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + IMS_PCU_SET_INFO_SIZE + 1) {
+ dev_err(pcu->dev, "Short GET_INFO response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
memcpy(pcu->part_number,
&pcu->cmd_buf[IMS_PCU_INFO_PART_OFFSET],
sizeof(pcu->part_number));
@@ -815,6 +839,12 @@ static int ims_pcu_verify_block(struct ims_pcu *pcu,
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_BL_DATA_OFFSET + sizeof(*fragment) + len + 1) {
+ dev_err(pcu->dev, "Short READ_APP response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
fragment = (void *)&pcu->cmd_buf[IMS_PCU_BL_DATA_OFFSET];
if (get_unaligned_le32(&fragment->addr) != addr ||
fragment->len != len) {
@@ -934,9 +964,10 @@ out:
return retval;
}
-static void ims_pcu_process_async_firmware(const struct firmware *fw,
+static void ims_pcu_process_async_firmware(const struct firmware *_fw,
void *context)
{
+ const struct firmware *fw __free(firmware) = _fw;
struct ims_pcu *pcu = context;
int error;
@@ -956,8 +987,6 @@ static void ims_pcu_process_async_firmware(const struct firmware *fw,
scoped_guard(mutex, &pcu->cmd_mutex)
ims_pcu_handle_firmware_update(pcu, fw);
- release_firmware(fw);
-
out:
complete(&pcu->async_firmware_done);
}
@@ -1009,6 +1038,10 @@ ims_pcu_backlight_get_brightness(struct led_classdev *cdev)
error);
/* Assume the LED is OFF */
brightness = LED_OFF;
+ } else if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 2 + 1) {
+ dev_err(pcu->dev, "Short GET_BRIGHTNESS response: %d bytes\n",
+ pcu->cmd_buf_len);
+ brightness = LED_OFF;
} else {
brightness =
get_unaligned_le16(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET]);
@@ -1153,6 +1186,8 @@ static ssize_t ims_pcu_reset_device(struct device *dev,
dev_info(pcu->dev, "Attempting to reset device\n");
+ guard(mutex)(&pcu->cmd_mutex);
+
error = ims_pcu_execute_command(pcu, PCU_RESET, &reset_byte, 1);
if (error) {
dev_info(pcu->dev,
@@ -1249,6 +1284,9 @@ static umode_t ims_pcu_is_attr_visible(struct kobject *kobj,
struct ims_pcu *pcu = usb_get_intfdata(intf);
umode_t mode = attr->mode;
+ if (intf != pcu->ctrl_intf)
+ return 0;
+
if (pcu->bootloader_mode) {
if (attr != &dev_attr_update_firmware_status.attr &&
attr != &dev_attr_update_firmware.attr &&
@@ -1282,6 +1320,12 @@ static int ims_pcu_read_ofn_config(struct ims_pcu *pcu, u8 addr, u8 *data)
if (error)
return error;
+ if (pcu->cmd_buf_len < OFN_REG_RESULT_OFFSET + 2 + 1) {
+ dev_err(pcu->dev, "Short OFN_GET_CONFIG response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
result = (s16)get_unaligned_le16(pcu->cmd_buf + OFN_REG_RESULT_OFFSET);
if (result < 0)
return -EIO;
@@ -1302,6 +1346,12 @@ static int ims_pcu_write_ofn_config(struct ims_pcu *pcu, u8 addr, u8 data)
if (error)
return error;
+ if (pcu->cmd_buf_len < OFN_REG_RESULT_OFFSET + 2 + 1) {
+ dev_err(pcu->dev, "Short OFN_SET_CONFIG response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
result = (s16)get_unaligned_le16(pcu->cmd_buf + OFN_REG_RESULT_OFFSET);
if (result < 0)
return -EIO;
@@ -1488,6 +1538,9 @@ static umode_t ims_pcu_ofn_is_attr_visible(struct kobject *kobj,
struct ims_pcu *pcu = usb_get_intfdata(intf);
umode_t mode = attr->mode;
+ if (intf != pcu->ctrl_intf)
+ return SYSFS_GROUP_INVISIBLE;
+
/*
* PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor.
*/
@@ -1528,7 +1581,7 @@ static void ims_pcu_irq(struct urb *urb)
}
dev_dbg(pcu->dev, "%s: received %d: %*ph\n", __func__,
- urb->actual_length, urb->actual_length, pcu->urb_in_buf);
+ urb->actual_length, urb->actual_length, urb->transfer_buffer);
if (urb == pcu->urb_in)
ims_pcu_process_data(pcu, urb);
@@ -1656,8 +1709,9 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
while (buflen >= sizeof(*union_desc)) {
union_desc = (struct usb_cdc_union_desc *)buf;
- if (union_desc->bLength > buflen) {
- dev_err(&intf->dev, "Too large descriptor\n");
+ if (union_desc->bLength < 2 || union_desc->bLength > buflen) {
+ dev_err(&intf->dev, "Invalid descriptor length: %d\n",
+ union_desc->bLength);
return NULL;
}
@@ -1693,7 +1747,7 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev,
union_desc->bMasterInterface0);
- if (!pcu->ctrl_intf)
+ if (pcu->ctrl_intf != intf)
return -EINVAL;
alt = pcu->ctrl_intf->cur_altsetting;
@@ -1702,6 +1756,12 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
return -ENODEV;
pcu->ep_ctrl = &alt->endpoint[0].desc;
+ if (!usb_endpoint_is_int_in(pcu->ep_ctrl)) {
+ dev_err(pcu->dev,
+ "Control endpoint is not INTERRUPT IN\n");
+ return -EINVAL;
+ }
+
pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
pcu->data_intf = usb_ifnum_to_if(pcu->udev,
@@ -1783,11 +1843,16 @@ static void ims_pcu_stop_io(struct ims_pcu *pcu)
static int ims_pcu_line_setup(struct ims_pcu *pcu)
{
struct usb_host_interface *interface = pcu->ctrl_intf->cur_altsetting;
- struct usb_cdc_line_coding *line = (void *)pcu->cmd_buf;
+ struct usb_cdc_line_coding *line __free(kfree) =
+ kmalloc(sizeof(*line), GFP_KERNEL);
int error;
- memset(line, 0, sizeof(*line));
+ if (!line)
+ return -ENOMEM;
+
line->dwDTERate = cpu_to_le32(57600);
+ line->bCharFormat = USB_CDC_1_STOP_BITS;
+ line->bParityType = USB_CDC_NO_PARITY;
line->bDataBits = 8;
error = usb_control_msg(pcu->udev, usb_sndctrlpipe(pcu->udev, 0),
@@ -1831,6 +1896,12 @@ static int ims_pcu_get_device_info(struct ims_pcu *pcu)
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 6 + 1) {
+ dev_err(pcu->dev, "Short GET_FW_VERSION response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
snprintf(pcu->fw_version, sizeof(pcu->fw_version),
"%02d%02d%02d%02d.%c%c",
pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5],
@@ -1843,6 +1914,12 @@ static int ims_pcu_get_device_info(struct ims_pcu *pcu)
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 6 + 1) {
+ dev_err(pcu->dev, "Short GET_BL_VERSION response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
snprintf(pcu->bl_version, sizeof(pcu->bl_version),
"%02d%02d%02d%02d.%c%c",
pcu->cmd_buf[2], pcu->cmd_buf[3], pcu->cmd_buf[4], pcu->cmd_buf[5],
@@ -1855,6 +1932,12 @@ static int ims_pcu_get_device_info(struct ims_pcu *pcu)
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 1 + 1) {
+ dev_err(pcu->dev, "Short RESET_REASON response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
snprintf(pcu->reset_reason, sizeof(pcu->reset_reason),
"%02x", pcu->cmd_buf[IMS_PCU_DATA_OFFSET]);
@@ -1881,6 +1964,12 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 1 + 1) {
+ dev_err(pcu->dev, "Short GET_DEVICE_ID response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
*device_id = pcu->cmd_buf[IMS_PCU_DATA_OFFSET];
dev_dbg(pcu->dev, "Detected device ID: %d\n", *device_id);
@@ -1972,6 +2061,12 @@ static int ims_pcu_init_bootloader_mode(struct ims_pcu *pcu)
return error;
}
+ if (pcu->cmd_buf_len < IMS_PCU_DATA_OFFSET + 15 + 4 + 1) {
+ dev_err(pcu->dev, "Short QUERY_DEVICE response: %d bytes\n",
+ pcu->cmd_buf_len);
+ return -EIO;
+ }
+
pcu->fw_start_addr =
get_unaligned_le32(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET + 11]);
pcu->fw_end_addr =
@@ -2071,7 +2166,6 @@ err_free_mem:
static void ims_pcu_disconnect(struct usb_interface *intf)
{
struct ims_pcu *pcu = usb_get_intfdata(intf);
- struct usb_host_interface *alt = intf->cur_altsetting;
usb_set_intfdata(intf, NULL);
@@ -2079,7 +2173,7 @@ static void ims_pcu_disconnect(struct usb_interface *intf)
* See if we are dealing with control or data interface. The cleanup
* happens when we unbind primary (control) interface.
*/
- if (alt->desc.bInterfaceClass != USB_CLASS_COMM)
+ if (intf != pcu->ctrl_intf)
return;
ims_pcu_stop_io(pcu);
@@ -2090,6 +2184,7 @@ static void ims_pcu_disconnect(struct usb_interface *intf)
ims_pcu_destroy_application_mode(pcu);
ims_pcu_buffers_free(pcu);
+ usb_driver_release_interface(&ims_pcu_driver, pcu->data_intf);
kfree(pcu);
}
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c
index eb9788ea5215..6b3495ba5763 100644
--- a/drivers/input/misc/kxtj9.c
+++ b/drivers/input/misc/kxtj9.c
@@ -525,7 +525,7 @@ static int kxtj9_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume);
static const struct i2c_device_id kxtj9_id[] = {
- { NAME },
+ { .name = NAME },
{ }
};
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c
index 0c661140fb88..a2888d1ff58f 100644
--- a/drivers/input/misc/mma8450.c
+++ b/drivers/input/misc/mma8450.c
@@ -200,7 +200,7 @@ static int mma8450_probe(struct i2c_client *c)
}
static const struct i2c_device_id mma8450_id[] = {
- { MMA8450_DRV_NAME },
+ { .name = MMA8450_DRV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, mma8450_id);
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c
deleted file mode 100644
index b19899b50d0b..000000000000
--- a/drivers/input/misc/pcap_keys.c
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Input driver for PCAP events:
- * * Power key
- * * Headphone button
- *
- * Copyright (c) 2008,2009 Ilya Petrov <ilya.muromec@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/mfd/ezx-pcap.h>
-#include <linux/slab.h>
-
-struct pcap_keys {
- struct pcap_chip *pcap;
- struct input_dev *input;
-};
-
-/* PCAP2 interrupts us on keypress */
-static irqreturn_t pcap_keys_handler(int irq, void *_pcap_keys)
-{
- struct pcap_keys *pcap_keys = _pcap_keys;
- int pirq = irq_to_pcap(pcap_keys->pcap, irq);
- u32 pstat;
-
- ezx_pcap_read(pcap_keys->pcap, PCAP_REG_PSTAT, &pstat);
- pstat &= 1 << pirq;
-
- switch (pirq) {
- case PCAP_IRQ_ONOFF:
- input_report_key(pcap_keys->input, KEY_POWER, !pstat);
- break;
- case PCAP_IRQ_MIC:
- input_report_key(pcap_keys->input, KEY_HP, !pstat);
- break;
- }
-
- input_sync(pcap_keys->input);
-
- return IRQ_HANDLED;
-}
-
-static int pcap_keys_probe(struct platform_device *pdev)
-{
- int err = -ENOMEM;
- struct pcap_keys *pcap_keys;
- struct input_dev *input_dev;
-
- pcap_keys = kmalloc_obj(*pcap_keys);
- if (!pcap_keys)
- return err;
-
- pcap_keys->pcap = dev_get_drvdata(pdev->dev.parent);
-
- input_dev = input_allocate_device();
- if (!input_dev)
- goto fail;
-
- pcap_keys->input = input_dev;
-
- platform_set_drvdata(pdev, pcap_keys);
- input_dev->name = pdev->name;
- input_dev->phys = "pcap-keys/input0";
- input_dev->id.bustype = BUS_HOST;
- input_dev->dev.parent = &pdev->dev;
-
- __set_bit(EV_KEY, input_dev->evbit);
- __set_bit(KEY_POWER, input_dev->keybit);
- __set_bit(KEY_HP, input_dev->keybit);
-
- err = input_register_device(input_dev);
- if (err)
- goto fail_allocate;
-
- err = request_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF),
- pcap_keys_handler, 0, "Power key", pcap_keys);
- if (err)
- goto fail_register;
-
- err = request_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_MIC),
- pcap_keys_handler, 0, "Headphone button", pcap_keys);
- if (err)
- goto fail_pwrkey;
-
- return 0;
-
-fail_pwrkey:
- free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF), pcap_keys);
-fail_register:
- input_unregister_device(input_dev);
- goto fail;
-fail_allocate:
- input_free_device(input_dev);
-fail:
- kfree(pcap_keys);
- return err;
-}
-
-static void pcap_keys_remove(struct platform_device *pdev)
-{
- struct pcap_keys *pcap_keys = platform_get_drvdata(pdev);
-
- free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF), pcap_keys);
- free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_MIC), pcap_keys);
-
- input_unregister_device(pcap_keys->input);
- kfree(pcap_keys);
-}
-
-static struct platform_driver pcap_keys_device_driver = {
- .probe = pcap_keys_probe,
- .remove = pcap_keys_remove,
- .driver = {
- .name = "pcap-keys",
- }
-};
-module_platform_driver(pcap_keys_device_driver);
-
-MODULE_DESCRIPTION("Motorola PCAP2 input events driver");
-MODULE_AUTHOR("Ilya Petrov <ilya.muromec@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pcap_keys");
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c
index 14fc6c6cf699..a831fcc851f7 100644
--- a/drivers/input/misc/pcf8574_keypad.c
+++ b/drivers/input/misc/pcf8574_keypad.c
@@ -189,7 +189,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(pcf8574_kp_pm_ops,
pcf8574_kp_suspend, pcf8574_kp_resume);
static const struct i2c_device_id pcf8574_kp_id[] = {
- { DRV_NAME },
+ { .name = DRV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf8574_kp_id);
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index 8786ed8b3565..560f895a00cd 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -22,15 +22,6 @@
* - Olivier Vandorpe, for providing the usbb2k-api.
* - Martin Diehl, for spotting my memory allocation bug.
*
- * History:
- * 20050527 henk First version, functional keyboard. Keyboard events
- * will pop-up on the ../input/eventX bus.
- * 20050531 henk Added led, LCD, dialtone and sysfs interface.
- * 20050610 henk Cleanups, make it ready for public consumption.
- * 20050630 henk Cleanups, fixes in response to comments.
- * 20050701 henk sysfs write serialisation, fix potential unload races
- * 20050801 henk Added ringtone, restructure USB
- * 20050816 henk Merge 2.6.13-rc6
*/
#include <linux/kernel.h>