Skip to content

Commit 2043ae9

Browse files
committed
Merge tag 'hid-for-linus-2025060301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina: - support for Apple Magic Mouse 2 USB-C (Aditya Garg) - power management improvement for multitouch devices (Werner Sembach) - fix for ACPI initialization in intel-thc driver (Wentao Guan) - adaptation of HID drivers to use new gpio_chip's line setter callbacks (Bartosz Golaszewski) - fix potential OOB in usbhid_parse() (Terry Junge) - make it possible to set hid_mouse_ignore_list dynamically (the same way we handle other quirks) (Aditya Garg) - other small assorted fixes and device ID additions * tag 'hid-for-linus-2025060301' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: multitouch: Disable touchpad on firmware level while not in use HID: core: Add functions for HID drivers to react on first open and last close call HID: HID_APPLETB_BL should depend on X86 HID: HID_APPLETB_KBD should depend on X86 HID: appletb-kbd: Use secs_to_jiffies() instead of msecs_to_jiffies() HID: intel-thc-hid: intel-thc: make read-only arrays static const HID: magicmouse: Apple Magic Mouse 2 USB-C support HID: mcp2221: use new line value setter callbacks HID: mcp2200: use new line value setter callbacks HID: cp2112: use new line value setter callbacks HID: cp2112: use lock guards HID: cp2112: hold the lock for the entire direction_output() call HID: cp2112: destroy mutex on driver detach HID: intel-thc-hid: intel-quicki2c: pass correct arguments to acpi_evaluate_object HID: corsair-void: Use to_delayed_work() HID: hid-logitech: use sysfs_emit_at() instead of scnprintf() HID: quirks: Add HID_QUIRK_IGNORE_MOUSE quirk HID: usbhid: Eliminate recurrent out-of-bounds bug in usbhid_parse() HID: Kysona: Add periodic online check
2 parents efe19d3 + c48228c commit 2043ae9

File tree

19 files changed

+217
-111
lines changed

19 files changed

+217
-111
lines changed

drivers/hid/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ config HID_APPLEIR
151151
config HID_APPLETB_BL
152152
tristate "Apple Touch Bar Backlight"
153153
depends on BACKLIGHT_CLASS_DEVICE
154+
depends on X86 || COMPILE_TEST
154155
help
155156
Say Y here if you want support for the backlight of Touch Bars on x86
156157
MacBook Pros.
@@ -163,6 +164,7 @@ config HID_APPLETB_KBD
163164
depends on USB_HID
164165
depends on BACKLIGHT_CLASS_DEVICE
165166
depends on INPUT
167+
depends on X86 || COMPILE_TEST
166168
select INPUT_SPARSEKMAP
167169
select HID_APPLETB_BL
168170
help

drivers/hid/hid-appletb-kbd.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ static void appletb_inactivity_timer(struct timer_list *t)
172172
if (!kbd->has_dimmed) {
173173
backlight_device_set_brightness(kbd->backlight_dev, 1);
174174
kbd->has_dimmed = true;
175-
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_idle_timeout * 1000));
175+
mod_timer(&kbd->inactivity_timer,
176+
jiffies + secs_to_jiffies(appletb_tb_idle_timeout));
176177
} else if (!kbd->has_turned_off) {
177178
backlight_device_set_brightness(kbd->backlight_dev, 0);
178179
kbd->has_turned_off = true;
@@ -188,7 +189,8 @@ static void reset_inactivity_timer(struct appletb_kbd *kbd)
188189
kbd->has_dimmed = false;
189190
kbd->has_turned_off = false;
190191
}
191-
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
192+
mod_timer(&kbd->inactivity_timer,
193+
jiffies + secs_to_jiffies(appletb_tb_dim_timeout));
192194
}
193195
}
194196

@@ -407,7 +409,8 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
407409
} else {
408410
backlight_device_set_brightness(kbd->backlight_dev, 2);
409411
timer_setup(&kbd->inactivity_timer, appletb_inactivity_timer, 0);
410-
mod_timer(&kbd->inactivity_timer, jiffies + msecs_to_jiffies(appletb_tb_dim_timeout * 1000));
412+
mod_timer(&kbd->inactivity_timer,
413+
jiffies + secs_to_jiffies(appletb_tb_dim_timeout));
411414
}
412415

413416
kbd->inp_handler.event = appletb_kbd_inp_event;

drivers/hid/hid-core.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2396,6 +2396,9 @@ int hid_hw_open(struct hid_device *hdev)
23962396
ret = hdev->ll_driver->open(hdev);
23972397
if (ret)
23982398
hdev->ll_open_count--;
2399+
2400+
if (hdev->driver->on_hid_hw_open)
2401+
hdev->driver->on_hid_hw_open(hdev);
23992402
}
24002403

24012404
mutex_unlock(&hdev->ll_open_lock);
@@ -2415,8 +2418,12 @@ EXPORT_SYMBOL_GPL(hid_hw_open);
24152418
void hid_hw_close(struct hid_device *hdev)
24162419
{
24172420
mutex_lock(&hdev->ll_open_lock);
2418-
if (!--hdev->ll_open_count)
2421+
if (!--hdev->ll_open_count) {
24192422
hdev->ll_driver->close(hdev);
2423+
2424+
if (hdev->driver->on_hid_hw_close)
2425+
hdev->driver->on_hid_hw_close(hdev);
2426+
}
24202427
mutex_unlock(&hdev->ll_open_lock);
24212428
}
24222429
EXPORT_SYMBOL_GPL(hid_hw_close);

drivers/hid/hid-corsair-void.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ static void corsair_void_status_work_handler(struct work_struct *work)
507507
struct delayed_work *delayed_work;
508508
int battery_ret;
509509

510-
delayed_work = container_of(work, struct delayed_work, work);
510+
delayed_work = to_delayed_work(work);
511511
drvdata = container_of(delayed_work, struct corsair_void_drvdata,
512512
delayed_status_work);
513513

@@ -525,7 +525,7 @@ static void corsair_void_firmware_work_handler(struct work_struct *work)
525525
struct delayed_work *delayed_work;
526526
int firmware_ret;
527527

528-
delayed_work = container_of(work, struct delayed_work, work);
528+
delayed_work = to_delayed_work(work);
529529
drvdata = container_of(delayed_work, struct corsair_void_drvdata,
530530
delayed_firmware_work);
531531

drivers/hid/hid-cp2112.c

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
*/
1818

1919
#include <linux/bitops.h>
20+
#include <linux/cleanup.h>
2021
#include <linux/gpio/driver.h>
2122
#include <linux/hid.h>
2223
#include <linux/hidraw.h>
2324
#include <linux/i2c.h>
2425
#include <linux/module.h>
26+
#include <linux/mutex.h>
2527
#include <linux/nls.h>
2628
#include <linux/string_choices.h>
2729
#include <linux/usb/ch9.h>
@@ -185,7 +187,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
185187
u8 *buf = dev->in_out_buffer;
186188
int ret;
187189

188-
mutex_lock(&dev->lock);
190+
guard(mutex)(&dev->lock);
189191

190192
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
191193
CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
@@ -194,7 +196,7 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
194196
hid_err(hdev, "error requesting GPIO config: %d\n", ret);
195197
if (ret >= 0)
196198
ret = -EIO;
197-
goto exit;
199+
return ret;
198200
}
199201

200202
buf[1] &= ~BIT(offset);
@@ -207,25 +209,19 @@ static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
207209
hid_err(hdev, "error setting GPIO config: %d\n", ret);
208210
if (ret >= 0)
209211
ret = -EIO;
210-
goto exit;
212+
return ret;
211213
}
212214

213-
ret = 0;
214-
215-
exit:
216-
mutex_unlock(&dev->lock);
217-
return ret;
215+
return 0;
218216
}
219217

220-
static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
218+
static int cp2112_gpio_set_unlocked(struct cp2112_device *dev,
219+
unsigned int offset, int value)
221220
{
222-
struct cp2112_device *dev = gpiochip_get_data(chip);
223221
struct hid_device *hdev = dev->hdev;
224222
u8 *buf = dev->in_out_buffer;
225223
int ret;
226224

227-
mutex_lock(&dev->lock);
228-
229225
buf[0] = CP2112_GPIO_SET;
230226
buf[1] = value ? CP2112_GPIO_ALL_GPIO_MASK : 0;
231227
buf[2] = BIT(offset);
@@ -236,7 +232,17 @@ static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
236232
if (ret < 0)
237233
hid_err(hdev, "error setting GPIO values: %d\n", ret);
238234

239-
mutex_unlock(&dev->lock);
235+
return ret;
236+
}
237+
238+
static int cp2112_gpio_set(struct gpio_chip *chip, unsigned int offset,
239+
int value)
240+
{
241+
struct cp2112_device *dev = gpiochip_get_data(chip);
242+
243+
guard(mutex)(&dev->lock);
244+
245+
return cp2112_gpio_set_unlocked(dev, offset, value);
240246
}
241247

242248
static int cp2112_gpio_get_all(struct gpio_chip *chip)
@@ -246,23 +252,17 @@ static int cp2112_gpio_get_all(struct gpio_chip *chip)
246252
u8 *buf = dev->in_out_buffer;
247253
int ret;
248254

249-
mutex_lock(&dev->lock);
255+
guard(mutex)(&dev->lock);
250256

251257
ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf,
252258
CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT,
253259
HID_REQ_GET_REPORT);
254260
if (ret != CP2112_GPIO_GET_LENGTH) {
255261
hid_err(hdev, "error requesting GPIO values: %d\n", ret);
256-
ret = ret < 0 ? ret : -EIO;
257-
goto exit;
262+
return ret < 0 ? ret : -EIO;
258263
}
259264

260-
ret = buf[1];
261-
262-
exit:
263-
mutex_unlock(&dev->lock);
264-
265-
return ret;
265+
return buf[1];
266266
}
267267

268268
static int cp2112_gpio_get(struct gpio_chip *chip, unsigned int offset)
@@ -284,14 +284,14 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
284284
u8 *buf = dev->in_out_buffer;
285285
int ret;
286286

287-
mutex_lock(&dev->lock);
287+
guard(mutex)(&dev->lock);
288288

289289
ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
290290
CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
291291
HID_REQ_GET_REPORT);
292292
if (ret != CP2112_GPIO_CONFIG_LENGTH) {
293293
hid_err(hdev, "error requesting GPIO config: %d\n", ret);
294-
goto fail;
294+
return ret < 0 ? ret : -EIO;
295295
}
296296

297297
buf[1] |= 1 << offset;
@@ -302,22 +302,16 @@ static int cp2112_gpio_direction_output(struct gpio_chip *chip,
302302
HID_REQ_SET_REPORT);
303303
if (ret < 0) {
304304
hid_err(hdev, "error setting GPIO config: %d\n", ret);
305-
goto fail;
305+
return ret;
306306
}
307307

308-
mutex_unlock(&dev->lock);
309-
310308
/*
311309
* Set gpio value when output direction is already set,
312310
* as specified in AN495, Rev. 0.2, cpt. 4.4
313311
*/
314-
cp2112_gpio_set(chip, offset, value);
312+
cp2112_gpio_set_unlocked(dev, offset, value);
315313

316314
return 0;
317-
318-
fail:
319-
mutex_unlock(&dev->lock);
320-
return ret < 0 ? ret : -EIO;
321315
}
322316

323317
static int cp2112_hid_get(struct hid_device *hdev, unsigned char report_number,
@@ -1205,7 +1199,11 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
12051199
if (!dev->in_out_buffer)
12061200
return -ENOMEM;
12071201

1208-
mutex_init(&dev->lock);
1202+
ret = devm_mutex_init(&hdev->dev, &dev->lock);
1203+
if (ret) {
1204+
hid_err(hdev, "mutex init failed\n");
1205+
return ret;
1206+
}
12091207

12101208
ret = hid_parse(hdev);
12111209
if (ret) {
@@ -1290,7 +1288,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
12901288
dev->gc.label = "cp2112_gpio";
12911289
dev->gc.direction_input = cp2112_gpio_direction_input;
12921290
dev->gc.direction_output = cp2112_gpio_direction_output;
1293-
dev->gc.set = cp2112_gpio_set;
1291+
dev->gc.set_rv = cp2112_gpio_set;
12941292
dev->gc.get = cp2112_gpio_get;
12951293
dev->gc.base = -1;
12961294
dev->gc.ngpio = CP2112_GPIO_MAX_GPIO;

drivers/hid/hid-hyperv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
192192
goto cleanup;
193193

194194
input_device->report_desc_size = le16_to_cpu(
195-
desc->desc[0].wDescriptorLength);
195+
desc->rpt_desc.wDescriptorLength);
196196
if (input_device->report_desc_size == 0) {
197197
input_device->dev_info_status = -EINVAL;
198198
goto cleanup;
@@ -210,7 +210,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
210210

211211
memcpy(input_device->report_desc,
212212
((unsigned char *)desc) + desc->bLength,
213-
le16_to_cpu(desc->desc[0].wDescriptorLength));
213+
le16_to_cpu(desc->rpt_desc.wDescriptorLength));
214214

215215
/* Send the ack */
216216
memset(&ack, 0, sizeof(struct mousevsc_prt_msg));

drivers/hid/hid-ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
9797
#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
9898
#define USB_DEVICE_ID_APPLE_MAGICMOUSE2 0x0269
99+
#define USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC 0x0323
99100
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
100101
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
101102
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC 0x0324

drivers/hid/hid-kysona.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#define BATTERY_TIMEOUT_MS 5000
1616

17+
#define ONLINE_REPORT_ID 3
1718
#define BATTERY_REPORT_ID 4
1819

1920
struct kysona_drvdata {
@@ -80,11 +81,46 @@ static int kysona_battery_get_property(struct power_supply *psy,
8081
return ret;
8182
}
8283

84+
static const char kysona_online_request[] = {
85+
0x08, ONLINE_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a
87+
};
88+
8389
static const char kysona_battery_request[] = {
8490
0x08, BATTERY_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8591
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49
8692
};
8793

94+
static int kysona_m600_fetch_online(struct hid_device *hdev)
95+
{
96+
u8 *write_buf;
97+
int ret;
98+
99+
/* Request online information */
100+
write_buf = kmemdup(kysona_online_request, sizeof(kysona_online_request), GFP_KERNEL);
101+
if (!write_buf)
102+
return -ENOMEM;
103+
104+
ret = hid_hw_raw_request(hdev, kysona_online_request[0],
105+
write_buf, sizeof(kysona_online_request),
106+
HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
107+
if (ret < (int)sizeof(kysona_online_request)) {
108+
hid_err(hdev, "hid_hw_raw_request() failed with %d\n", ret);
109+
ret = -ENODATA;
110+
}
111+
kfree(write_buf);
112+
return ret;
113+
}
114+
115+
static void kysona_fetch_online(struct hid_device *hdev)
116+
{
117+
int ret = kysona_m600_fetch_online(hdev);
118+
119+
if (ret < 0)
120+
hid_dbg(hdev,
121+
"Online query failed (err: %d)\n", ret);
122+
}
123+
88124
static int kysona_m600_fetch_battery(struct hid_device *hdev)
89125
{
90126
u8 *write_buf;
@@ -121,6 +157,7 @@ static void kysona_battery_timer_tick(struct work_struct *work)
121157
struct kysona_drvdata, battery_work.work);
122158
struct hid_device *hdev = drv_data->hdev;
123159

160+
kysona_fetch_online(hdev);
124161
kysona_fetch_battery(hdev);
125162
schedule_delayed_work(&drv_data->battery_work,
126163
msecs_to_jiffies(BATTERY_TIMEOUT_MS));
@@ -160,6 +197,7 @@ static int kysona_battery_probe(struct hid_device *hdev)
160197
power_supply_powers(drv_data->battery, &hdev->dev);
161198

162199
INIT_DELAYED_WORK(&drv_data->battery_work, kysona_battery_timer_tick);
200+
kysona_fetch_online(hdev);
163201
kysona_fetch_battery(hdev);
164202
schedule_delayed_work(&drv_data->battery_work,
165203
msecs_to_jiffies(BATTERY_TIMEOUT_MS));
@@ -206,12 +244,16 @@ static int kysona_raw_event(struct hid_device *hdev,
206244
{
207245
struct kysona_drvdata *drv_data = hid_get_drvdata(hdev);
208246

209-
if (drv_data->battery && size == sizeof(kysona_battery_request) &&
247+
if (size == sizeof(kysona_online_request) &&
248+
data[0] == 8 && data[1] == ONLINE_REPORT_ID) {
249+
drv_data->online = data[6];
250+
}
251+
252+
if (size == sizeof(kysona_battery_request) &&
210253
data[0] == 8 && data[1] == BATTERY_REPORT_ID) {
211254
drv_data->battery_capacity = data[6];
212255
drv_data->battery_charging = data[7];
213256
drv_data->battery_voltage = (data[8] << 8) | data[9];
214-
drv_data->online = true;
215257
}
216258

217259
return 0;

drivers/hid/hid-lg4ff.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ static ssize_t lg4ff_alternate_modes_show(struct device *dev, struct device_attr
823823
for (i = 0; i < LG4FF_MODE_MAX_IDX; i++) {
824824
if (entry->wdata.alternate_modes & BIT(i)) {
825825
/* Print tag and full name */
826-
count += scnprintf(buf + count, PAGE_SIZE - count, "%s: %s",
826+
count += sysfs_emit_at(buf, count, "%s: %s",
827827
lg4ff_alternate_modes[i].tag,
828828
!lg4ff_alternate_modes[i].product_id ? entry->wdata.real_name : lg4ff_alternate_modes[i].name);
829829
if (count >= PAGE_SIZE - 1)
@@ -832,9 +832,9 @@ static ssize_t lg4ff_alternate_modes_show(struct device *dev, struct device_attr
832832
/* Mark the currently active mode with an asterisk */
833833
if (lg4ff_alternate_modes[i].product_id == entry->wdata.product_id ||
834834
(lg4ff_alternate_modes[i].product_id == 0 && entry->wdata.product_id == entry->wdata.real_product_id))
835-
count += scnprintf(buf + count, PAGE_SIZE - count, " *\n");
835+
count += sysfs_emit_at(buf, count, " *\n");
836836
else
837-
count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
837+
count += sysfs_emit_at(buf, count, "\n");
838838

839839
if (count >= PAGE_SIZE - 1)
840840
return count;

0 commit comments

Comments
 (0)