summaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2026-04-19 18:28:57 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2026-04-19 18:28:57 -0700
commitf4b369c6fe0ceaba2da2daff8c9eb415f85926dd (patch)
tree30465d0a429b2c224685b5d8e804bf053c4d129a /drivers/input
parentff14dafde15c11403fac61367a34fea08926e9ee (diff)
parent2ca45e57ea027fffe3350ae5e21ad9cecb0dce74 (diff)
Merge branch 'next' into for-linus
Prepare input updates for 7.1 merge window.
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/apm-power.c2
-rw-r--r--drivers/input/evdev.c4
-rw-r--r--drivers/input/ff-core.c5
-rw-r--r--drivers/input/ff-memless.c2
-rw-r--r--drivers/input/gameport/emu10k1-gp.c2
-rw-r--r--drivers/input/gameport/fm801-gp.c2
-rw-r--r--drivers/input/gameport/gameport.c2
-rw-r--r--drivers/input/gameport/ns558.c4
-rw-r--r--drivers/input/input-leds.c2
-rw-r--r--drivers/input/input-mt.c4
-rw-r--r--drivers/input/input-poller.c2
-rw-r--r--drivers/input/input.c29
-rw-r--r--drivers/input/joydev.c4
-rw-r--r--drivers/input/joystick/a3d.c2
-rw-r--r--drivers/input/joystick/adi.c2
-rw-r--r--drivers/input/joystick/analog.c2
-rw-r--r--drivers/input/joystick/as5011.c2
-rw-r--r--drivers/input/joystick/cobra.c2
-rw-r--r--drivers/input/joystick/db9.c2
-rw-r--r--drivers/input/joystick/fsia6b.c2
-rw-r--r--drivers/input/joystick/gamecon.c4
-rw-r--r--drivers/input/joystick/gf2k.c8
-rw-r--r--drivers/input/joystick/grip.c2
-rw-r--r--drivers/input/joystick/grip_mp.c2
-rw-r--r--drivers/input/joystick/guillemot.c2
-rw-r--r--drivers/input/joystick/iforce/iforce-serio.c2
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c2
-rw-r--r--drivers/input/joystick/interact.c2
-rw-r--r--drivers/input/joystick/joydump.c2
-rw-r--r--drivers/input/joystick/magellan.c2
-rw-r--r--drivers/input/joystick/maplecontrol.c2
-rw-r--r--drivers/input/joystick/n64joy.c2
-rw-r--r--drivers/input/joystick/sidewinder.c2
-rw-r--r--drivers/input/joystick/spaceball.c2
-rw-r--r--drivers/input/joystick/spaceorb.c2
-rw-r--r--drivers/input/joystick/stinger.c2
-rw-r--r--drivers/input/joystick/tmdc.c4
-rw-r--r--drivers/input/joystick/turbografx.c2
-rw-r--r--drivers/input/joystick/twidjoy.c2
-rw-r--r--drivers/input/joystick/warrior.c2
-rw-r--r--drivers/input/joystick/xpad.c39
-rw-r--r--drivers/input/joystick/zhenhua.c2
-rw-r--r--drivers/input/keyboard/Kconfig14
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/atkbd.c135
-rw-r--r--drivers/input/keyboard/charlieplex_keypad.c232
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c261
-rw-r--r--drivers/input/keyboard/hil_kbd.c2
-rw-r--r--drivers/input/keyboard/imx_keypad.c4
-rw-r--r--drivers/input/keyboard/lkkbd.c2
-rw-r--r--drivers/input/keyboard/locomokbd.c2
-rw-r--r--drivers/input/keyboard/maple_keyb.c2
-rw-r--r--drivers/input/keyboard/mpr121_touchkey.c8
-rw-r--r--drivers/input/keyboard/newtonkbd.c2
-rw-r--r--drivers/input/keyboard/omap-keypad.c2
-rw-r--r--drivers/input/keyboard/qt1050.c3
-rw-r--r--drivers/input/keyboard/qt1070.c3
-rw-r--r--drivers/input/keyboard/sh_keysc.c2
-rw-r--r--drivers/input/keyboard/stowaway.c2
-rw-r--r--drivers/input/keyboard/sunkbd.c2
-rw-r--r--drivers/input/keyboard/xtkbd.c2
-rw-r--r--drivers/input/misc/88pm80x_onkey.c2
-rw-r--r--drivers/input/misc/adxl34x-i2c.c5
-rw-r--r--drivers/input/misc/arizona-haptics.c14
-rw-r--r--drivers/input/misc/ati_remote2.c2
-rw-r--r--drivers/input/misc/atlas_btns.c22
-rw-r--r--drivers/input/misc/aw86927.c66
-rw-r--r--drivers/input/misc/cm109.c4
-rw-r--r--drivers/input/misc/cma3000_d0x.c2
-rw-r--r--drivers/input/misc/cs40l50-vibra.c4
-rw-r--r--drivers/input/misc/da9052_onkey.c2
-rw-r--r--drivers/input/misc/drv260x.c50
-rw-r--r--drivers/input/misc/ims-pcu.c36
-rw-r--r--drivers/input/misc/keyspan_remote.c24
-rw-r--r--drivers/input/misc/max8997_haptic.c2
-rw-r--r--drivers/input/misc/mc13783-pwrbutton.c2
-rw-r--r--drivers/input/misc/palmas-pwrbutton.c2
-rw-r--r--drivers/input/misc/pcap_keys.c2
-rw-r--r--drivers/input/misc/pcf8574_keypad.c2
-rw-r--r--drivers/input/misc/powermate.c4
-rw-r--r--drivers/input/misc/uinput.c2
-rw-r--r--drivers/input/misc/xen-kbdfront.c2
-rw-r--r--drivers/input/misc/yealink.c4
-rw-r--r--drivers/input/mouse/Kconfig36
-rw-r--r--drivers/input/mouse/Makefile3
-rw-r--r--drivers/input/mouse/alps.c13
-rw-r--r--drivers/input/mouse/alps.h4
-rw-r--r--drivers/input/mouse/appletouch.c23
-rw-r--r--drivers/input/mouse/bcm5974.c2
-rw-r--r--drivers/input/mouse/byd.c2
-rw-r--r--drivers/input/mouse/cypress_ps2.c2
-rw-r--r--drivers/input/mouse/elantech.c2
-rw-r--r--drivers/input/mouse/focaltech.c2
-rw-r--r--drivers/input/mouse/hgpk.c1063
-rw-r--r--drivers/input/mouse/hgpk.h61
-rw-r--r--drivers/input/mouse/inport.c177
-rw-r--r--drivers/input/mouse/lifebook.c2
-rw-r--r--drivers/input/mouse/logibm.c166
-rw-r--r--drivers/input/mouse/maplemouse.c2
-rw-r--r--drivers/input/mouse/psmouse-base.c53
-rw-r--r--drivers/input/mouse/psmouse-smbus.c2
-rw-r--r--drivers/input/mouse/psmouse.h6
-rw-r--r--drivers/input/mouse/sentelic.c2
-rw-r--r--drivers/input/mouse/sermouse.c2
-rw-r--r--drivers/input/mouse/synaptics.c4
-rw-r--r--drivers/input/mouse/synaptics_usb.c25
-rw-r--r--drivers/input/mouse/trackpoint.c2
-rw-r--r--drivers/input/mouse/vmmouse.c2
-rw-r--r--drivers/input/mouse/vsxxxaa.c2
-rw-r--r--drivers/input/mousedev.c4
-rw-r--r--drivers/input/rmi4/rmi_bus.c2
-rw-r--r--drivers/input/rmi4/rmi_f03.c2
-rw-r--r--drivers/input/serio/Kconfig13
-rw-r--r--drivers/input/serio/Makefile1
-rw-r--r--drivers/input/serio/altera_ps2.c2
-rw-r--r--drivers/input/serio/ambakmi.c4
-rw-r--r--drivers/input/serio/ams_delta_serio.c2
-rw-r--r--drivers/input/serio/apbps2.c2
-rw-r--r--drivers/input/serio/arc_ps2.c2
-rw-r--r--drivers/input/serio/ct82c710.c239
-rw-r--r--drivers/input/serio/gscps2.c4
-rw-r--r--drivers/input/serio/hil_mlc.c2
-rw-r--r--drivers/input/serio/hyperv-keyboard.c4
-rw-r--r--drivers/input/serio/i8042.c4
-rw-r--r--drivers/input/serio/ioc3kbd.c4
-rw-r--r--drivers/input/serio/libps2.c12
-rw-r--r--drivers/input/serio/maceps2.c2
-rw-r--r--drivers/input/serio/olpc_apsp.c4
-rw-r--r--drivers/input/serio/parkbd.c2
-rw-r--r--drivers/input/serio/pcips2.c4
-rw-r--r--drivers/input/serio/ps2-gpio.c2
-rw-r--r--drivers/input/serio/ps2mult.c4
-rw-r--r--drivers/input/serio/q40kbd.c4
-rw-r--r--drivers/input/serio/rpckbd.c4
-rw-r--r--drivers/input/serio/sa1111ps2.c4
-rw-r--r--drivers/input/serio/serio.c2
-rw-r--r--drivers/input/serio/serio_raw.c2
-rw-r--r--drivers/input/serio/serport.c4
-rw-r--r--drivers/input/serio/sun4i-ps2.c4
-rw-r--r--drivers/input/serio/userio.c4
-rw-r--r--drivers/input/serio/xilinx_ps2.c4
-rw-r--r--drivers/input/tablet/acecad.c2
-rw-r--r--drivers/input/tablet/aiptek.c22
-rw-r--r--drivers/input/tablet/hanwang.c2
-rw-r--r--drivers/input/tablet/kbtab.c2
-rw-r--r--drivers/input/tablet/pegasus_notetaker.c9
-rw-r--r--drivers/input/tablet/wacom_serial4.c2
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ad7877.c38
-rw-r--r--drivers/input/touchscreen/ad7879.c46
-rw-r--r--drivers/input/touchscreen/ads7846.c44
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c290
-rw-r--r--drivers/input/touchscreen/auo-pixcir-ts.c43
-rw-r--r--drivers/input/touchscreen/bu21029_ts.c8
-rw-r--r--drivers/input/touchscreen/chipone_icn8318.c8
-rw-r--r--drivers/input/touchscreen/cyttsp_core.c20
-rw-r--r--drivers/input/touchscreen/da9052_tsi.c2
-rw-r--r--drivers/input/touchscreen/dynapro.c2
-rw-r--r--drivers/input/touchscreen/edt-ft5x06.c90
-rw-r--r--drivers/input/touchscreen/eeti_ts.c27
-rw-r--r--drivers/input/touchscreen/egalax_ts_serial.c2
-rw-r--r--drivers/input/touchscreen/ektf2127.c8
-rw-r--r--drivers/input/touchscreen/elants_i2c.c91
-rw-r--r--drivers/input/touchscreen/elo.c34
-rw-r--r--drivers/input/touchscreen/exc3000.c31
-rw-r--r--drivers/input/touchscreen/fujitsu_ts.c2
-rw-r--r--drivers/input/touchscreen/goodix_berlin_core.c8
-rw-r--r--drivers/input/touchscreen/goodix_fwupload.c29
-rw-r--r--drivers/input/touchscreen/gunze.c2
-rw-r--r--drivers/input/touchscreen/hampshire.c2
-rw-r--r--drivers/input/touchscreen/hideep.c54
-rw-r--r--drivers/input/touchscreen/hycon-hy46xx.c31
-rw-r--r--drivers/input/touchscreen/imagis.c30
-rw-r--r--drivers/input/touchscreen/imx6ul_tsc.c19
-rw-r--r--drivers/input/touchscreen/inexio.c2
-rw-r--r--drivers/input/touchscreen/ipaq-micro-ts.c8
-rw-r--r--drivers/input/touchscreen/iqs5xx.c191
-rw-r--r--drivers/input/touchscreen/iqs7211.c24
-rw-r--r--drivers/input/touchscreen/lpc32xx_ts.c8
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c2
-rw-r--r--drivers/input/touchscreen/melfas_mip4.c121
-rw-r--r--drivers/input/touchscreen/migor_ts.c2
-rw-r--r--drivers/input/touchscreen/mk712.c215
-rw-r--r--drivers/input/touchscreen/mms114.c20
-rw-r--r--drivers/input/touchscreen/msg2638.c19
-rw-r--r--drivers/input/touchscreen/mtouch.c2
-rw-r--r--drivers/input/touchscreen/mxs-lradc-ts.c7
-rw-r--r--drivers/input/touchscreen/novatek-nvt-ts.c8
-rw-r--r--drivers/input/touchscreen/pcap_ts.c2
-rw-r--r--drivers/input/touchscreen/penmount.c2
-rw-r--r--drivers/input/touchscreen/pixcir_i2c_ts.c38
-rw-r--r--drivers/input/touchscreen/raydium_i2c_ts.c56
-rw-r--r--drivers/input/touchscreen/st1232.c67
-rw-r--r--drivers/input/touchscreen/stmfts.c63
-rw-r--r--drivers/input/touchscreen/sur40.c25
-rw-r--r--drivers/input/touchscreen/sx8654.c20
-rw-r--r--drivers/input/touchscreen/ti_am335x_tsc.c2
-rw-r--r--drivers/input/touchscreen/touchit213.c2
-rw-r--r--drivers/input/touchscreen/touchright.c2
-rw-r--r--drivers/input/touchscreen/touchwin.c2
-rw-r--r--drivers/input/touchscreen/tsc2007_core.c7
-rw-r--r--drivers/input/touchscreen/tsc2007_iio.c9
-rw-r--r--drivers/input/touchscreen/tsc40.c2
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c49
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c2
-rw-r--r--drivers/input/touchscreen/wdt87xx_i2c.c44
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c57
-rw-r--r--drivers/input/touchscreen/zinitix.c19
209 files changed, 1708 insertions, 3522 deletions
diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c
index 70a9e1dfba33..028fcaf4c142 100644
--- a/drivers/input/apm-power.c
+++ b/drivers/input/apm-power.c
@@ -52,7 +52,7 @@ static int apmpower_connect(struct input_handler *handler,
struct input_handle *handle;
int error;
- handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ handle = kzalloc_obj(struct input_handle);
if (!handle)
return -ENOMEM;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 90ff6be85cf4..c7325226cb86 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -465,7 +465,7 @@ static int evdev_open(struct inode *inode, struct file *file)
struct evdev_client *client;
int error;
- client = kvzalloc(struct_size(client, buffer, bufsize), GFP_KERNEL);
+ client = kvzalloc_flex(*client, buffer, bufsize);
if (!client)
return -ENOMEM;
@@ -1346,7 +1346,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
return error;
}
- evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
+ evdev = kzalloc_obj(struct evdev);
if (!evdev) {
error = -ENOMEM;
goto err_free_minor;
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 66f7ffe8c7e0..0e5d1d1ceb46 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -303,12 +303,11 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects)
}
struct ff_device *ff __free(kfree) =
- kzalloc(struct_size(ff, effect_owners, max_effects),
- GFP_KERNEL);
+ kzalloc_flex(*ff, effect_owners, max_effects);
if (!ff)
return -ENOMEM;
- ff->effects = kcalloc(max_effects, sizeof(*ff->effects), GFP_KERNEL);
+ ff->effects = kzalloc_objs(*ff->effects, max_effects);
if (!ff->effects)
return -ENOMEM;
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index e0c1c61aae71..937370d04928 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -508,7 +508,7 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
int error;
int i;
- struct ml_device *ml __free(kfree) = kzalloc(sizeof(*ml), GFP_KERNEL);
+ struct ml_device *ml __free(kfree) = kzalloc_obj(*ml);
if (!ml)
return -ENOMEM;
diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c
index 4f4583048f24..ee97621df59d 100644
--- a/drivers/input/gameport/emu10k1-gp.c
+++ b/drivers/input/gameport/emu10k1-gp.c
@@ -43,7 +43,7 @@ static int emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct gameport *port;
int error;
- emu = kzalloc(sizeof(*emu), GFP_KERNEL);
+ emu = kzalloc_obj(*emu);
port = gameport_allocate_port();
if (!emu || !port) {
printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n");
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c
index 7ae5009385cc..423cccdea34f 100644
--- a/drivers/input/gameport/fm801-gp.c
+++ b/drivers/input/gameport/fm801-gp.c
@@ -68,7 +68,7 @@ static int fm801_gp_probe(struct pci_dev *pci, const struct pci_device_id *id)
struct gameport *port;
int error;
- gp = kzalloc(sizeof(*gp), GFP_KERNEL);
+ gp = kzalloc_obj(*gp);
port = gameport_allocate_port();
if (!gp || !port) {
printk(KERN_ERR "fm801-gp: Memory allocation failed\n");
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index f4f12dd00fff..9707b155bc94 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -374,7 +374,7 @@ static int gameport_queue_event(void *object, struct module *owner,
}
}
- event = kmalloc(sizeof(*event), GFP_ATOMIC);
+ event = kmalloc_obj(*event, GFP_ATOMIC);
if (!event) {
pr_err("Not enough memory to queue event %d\n", event_type);
retval = -ENOMEM;
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
index 880e714b49bc..fdece6ec1df3 100644
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -120,7 +120,7 @@ static int ns558_isa_probe(int io)
return -EBUSY;
}
- ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL);
+ ns558 = kzalloc_obj(*ns558);
port = gameport_allocate_port();
if (!ns558 || !port) {
printk(KERN_ERR "ns558: Memory allocation failed.\n");
@@ -192,7 +192,7 @@ static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
if (!request_region(ioport, iolen, "ns558-pnp"))
return -EBUSY;
- ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL);
+ ns558 = kzalloc_obj(*ns558);
port = gameport_allocate_port();
if (!ns558 || !port) {
printk(KERN_ERR "ns558: Memory allocation failed\n");
diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c
index 6bbf3806ea37..b08d1d08d0b4 100644
--- a/drivers/input/input-leds.c
+++ b/drivers/input/input-leds.c
@@ -101,7 +101,7 @@ static int input_leds_connect(struct input_handler *handler,
if (!num_leds)
return -ENXIO;
- leds = kzalloc(struct_size(leds, leds, num_leds), GFP_KERNEL);
+ leds = kzalloc_flex(*leds, leds, num_leds);
if (!leds)
return -ENOMEM;
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 09f518897d4a..c06e98fbd77c 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -50,7 +50,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
return -EINVAL;
struct input_mt *mt __free(kfree) =
- kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL);
+ kzalloc_flex(*mt, slots, num_slots);
if (!mt)
return -ENOMEM;
@@ -84,7 +84,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
if (flags & INPUT_MT_TRACK) {
unsigned int n2 = num_slots * num_slots;
- mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL);
+ mt->red = kzalloc_objs(*mt->red, n2);
if (!mt->red)
return -ENOMEM;
}
diff --git a/drivers/input/input-poller.c b/drivers/input/input-poller.c
index 1ce83d6521bb..54dc07fcae0b 100644
--- a/drivers/input/input-poller.c
+++ b/drivers/input/input-poller.c
@@ -71,7 +71,7 @@ int input_setup_polling(struct input_dev *dev,
{
struct input_dev_poller *poller;
- poller = kzalloc(sizeof(*poller), GFP_KERNEL);
+ poller = kzalloc_obj(*poller);
if (!poller) {
/*
* We want to show message even though kzalloc() may have
diff --git a/drivers/input/input.c b/drivers/input/input.c
index a500e1e276c2..39d9d2b1e3ca 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -439,7 +439,7 @@ void input_alloc_absinfo(struct input_dev *dev)
if (dev->absinfo)
return;
- dev->absinfo = kcalloc(ABS_CNT, sizeof(*dev->absinfo), GFP_KERNEL);
+ dev->absinfo = kzalloc_objs(*dev->absinfo, ABS_CNT);
if (!dev->absinfo) {
dev_err(dev->dev.parent ?: &dev->dev,
"%s: unable to allocate memory\n", __func__);
@@ -800,14 +800,30 @@ static int input_default_getkeycode(struct input_dev *dev,
return 0;
}
-static int input_default_setkeycode(struct input_dev *dev,
- const struct input_keymap_entry *ke,
- unsigned int *old_keycode)
+/**
+ * input_default_setkeycode - default setkeycode method
+ * @dev: input device which keymap is being updated.
+ * @ke: new keymap entry.
+ * @old_keycode: pointer to the location where old keycode should be stored.
+ *
+ * This function is the default implementation of &input_dev.setkeycode()
+ * method. It is typically used when a driver does not provide its own
+ * implementation, but it is also exported so drivers can extend it.
+ *
+ * The function must be called with &input_dev.event_lock held.
+ *
+ * Return: 0 on success, or a negative error code on failure.
+ */
+int input_default_setkeycode(struct input_dev *dev,
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
{
unsigned int index;
int error;
int i;
+ lockdep_assert_held(&dev->event_lock);
+
if (!dev->keycodesize)
return -EINVAL;
@@ -861,6 +877,7 @@ static int input_default_setkeycode(struct input_dev *dev,
__set_bit(ke->keycode, dev->keybit);
return 0;
}
+EXPORT_SYMBOL(input_default_setkeycode);
/**
* input_get_keycode - retrieve keycode currently mapped to a given scancode
@@ -1887,7 +1904,7 @@ struct input_dev *input_allocate_device(void)
static atomic_t input_no = ATOMIC_INIT(-1);
struct input_dev *dev;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc_obj(*dev);
if (!dev)
return NULL;
@@ -1897,7 +1914,7 @@ struct input_dev *input_allocate_device(void)
* when we register the device.
*/
dev->max_vals = 10;
- dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL);
+ dev->vals = kzalloc_objs(*dev->vals, dev->max_vals);
if (!dev->vals) {
kfree(dev);
return NULL;
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index ba2b17288bcd..32459fd8a7c1 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -261,7 +261,7 @@ static int joydev_open(struct inode *inode, struct file *file)
struct joydev_client *client;
int error;
- client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
+ client = kzalloc_obj(struct joydev_client);
if (!client)
return -ENOMEM;
@@ -921,7 +921,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
return error;
}
- joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
+ joydev = kzalloc_obj(struct joydev);
if (!joydev) {
error = -ENOMEM;
goto err_free_minor;
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index 15182f16ed19..48a1457961ef 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -249,7 +249,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
int i;
int err;
- a3d = kzalloc(sizeof(*a3d), GFP_KERNEL);
+ a3d = kzalloc_obj(*a3d);
input_dev = input_allocate_device();
if (!a3d || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index 963250de24b7..e07b71978509 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -456,7 +456,7 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
int i;
int err;
- port = kzalloc(sizeof(*port), GFP_KERNEL);
+ port = kzalloc_obj(*port);
if (!port)
return -ENOMEM;
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index c709b58d770a..b6f7bce1c14f 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -582,7 +582,7 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv
int i;
int err;
- port = kzalloc(sizeof(*port), GFP_KERNEL);
+ port = kzalloc_obj(*port);
if (!port)
return -ENOMEM;
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c
index 49a0dfbbeb49..7b4d61626898 100644
--- a/drivers/input/joystick/as5011.c
+++ b/drivers/input/joystick/as5011.c
@@ -237,7 +237,7 @@ static int as5011_probe(struct i2c_client *client)
return -ENODEV;
}
- as5011 = kmalloc(sizeof(*as5011), GFP_KERNEL);
+ as5011 = kmalloc_obj(*as5011);
input_dev = input_allocate_device();
if (!as5011 || !input_dev) {
dev_err(&client->dev,
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index 5a0ea3ad5efa..ffa6d49c81fe 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -141,7 +141,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
int i, j;
int err;
- cobra = kzalloc(sizeof(*cobra), GFP_KERNEL);
+ cobra = kzalloc_obj(*cobra);
if (!cobra)
return -ENOMEM;
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index d5c67a927404..e5d9b71aab99 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -585,7 +585,7 @@ static void db9_attach(struct parport *pp)
return;
}
- db9 = kzalloc(sizeof(*db9), GFP_KERNEL);
+ db9 = kzalloc_obj(*db9);
if (!db9)
goto err_unreg_pardev;
diff --git a/drivers/input/joystick/fsia6b.c b/drivers/input/joystick/fsia6b.c
index 7e3bc99d766f..b0d73648477e 100644
--- a/drivers/input/joystick/fsia6b.c
+++ b/drivers/input/joystick/fsia6b.c
@@ -132,7 +132,7 @@ static int fsia6b_serio_connect(struct serio *serio, struct serio_driver *drv)
int i, j;
int sw_id = 0;
- fsia6b = kzalloc(sizeof(*fsia6b), GFP_KERNEL);
+ fsia6b = kzalloc_obj(*fsia6b);
if (!fsia6b)
return -ENOMEM;
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index ae95cb3d0ae9..d84d453b51af 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -291,7 +291,7 @@ static int gc_n64_init_ff(struct input_dev *dev, int i)
struct gc_subdev *sdev;
int err;
- sdev = kmalloc(sizeof(*sdev), GFP_KERNEL);
+ sdev = kmalloc_obj(*sdev);
if (!sdev)
return -ENOMEM;
@@ -948,7 +948,7 @@ static void gc_attach(struct parport *pp)
return;
}
- gc = kzalloc(sizeof(*gc), GFP_KERNEL);
+ gc = kzalloc_obj(*gc);
if (!gc) {
pr_err("Not enough memory\n");
goto err_unreg_pardev;
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index e7ff7bdb1a3a..1d843115d674 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -165,8 +165,10 @@ static void gf2k_read(struct gf2k *gf2k, unsigned char *data)
t = GB(40,4,0);
- for (i = 0; i < gf2k_hats[gf2k->id]; i++)
- input_report_abs(dev, ABS_HAT0X + i, gf2k_hat_to_axis[t][i]);
+ if (t < ARRAY_SIZE(gf2k_hat_to_axis))
+ for (i = 0; i < gf2k_hats[gf2k->id]; i++)
+ input_report_abs(dev, ABS_HAT0X + i,
+ gf2k_hat_to_axis[t][i]);
t = GB(44,2,0) | GB(32,8,2) | GB(78,2,10);
@@ -222,7 +224,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
unsigned char data[GF2K_LENGTH];
int i, err;
- gf2k = kzalloc(sizeof(*gf2k), GFP_KERNEL);
+ gf2k = kzalloc_obj(*gf2k);
input_dev = input_allocate_device();
if (!gf2k || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index f339ce2b7a33..2a3f768a7218 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -284,7 +284,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
int i, j, t;
int err;
- grip = kzalloc(sizeof(*grip), GFP_KERNEL);
+ grip = kzalloc_obj(*grip);
if (!grip)
return -ENOMEM;
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 5eadb5a3ca37..62fdd0831c83 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -632,7 +632,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
struct grip_mp *grip;
int err;
- grip = kzalloc(sizeof(*grip), GFP_KERNEL);
+ grip = kzalloc_obj(*grip);
if (!grip)
return -ENOMEM;
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index 1c5a76f72239..13f0fa4d3938 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -163,7 +163,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
int i, t;
int err;
- guillemot = kzalloc(sizeof(*guillemot), GFP_KERNEL);
+ guillemot = kzalloc_obj(*guillemot);
input_dev = input_allocate_device();
if (!guillemot || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 75b85c46dfa4..e235834888d2 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -185,7 +185,7 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
struct iforce_serio *iforce_serio;
int err;
- iforce_serio = kzalloc(sizeof(*iforce_serio), GFP_KERNEL);
+ iforce_serio = kzalloc_obj(*iforce_serio);
if (!iforce_serio)
return -ENOMEM;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 1f00f76b0174..0482eaaecf39 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -207,7 +207,7 @@ static int iforce_usb_probe(struct usb_interface *intf,
if (!usb_endpoint_is_int_out(epout))
return -ENODEV;
- iforce_usb = kzalloc(sizeof(*iforce_usb), GFP_KERNEL);
+ iforce_usb = kzalloc_obj(*iforce_usb);
if (!iforce_usb)
goto fail;
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index 262f022e5695..507cec36b220 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -192,7 +192,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
int i, t;
int err;
- interact = kzalloc(sizeof(*interact), GFP_KERNEL);
+ interact = kzalloc_obj(*interact);
input_dev = input_allocate_device();
if (!interact || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
index 865652a7821d..c9cbdcc7f31f 100644
--- a/drivers/input/joystick/joydump.c
+++ b/drivers/input/joystick/joydump.c
@@ -61,7 +61,7 @@ static int joydump_connect(struct gameport *gameport, struct gameport_driver *dr
timeout = gameport_time(gameport, 10000); /* 10 ms */
- buf = kmalloc_array(BUF_SIZE, sizeof(struct joydump), GFP_KERNEL);
+ buf = kmalloc_objs(struct joydump, BUF_SIZE);
if (!buf) {
printk(KERN_INFO "joydump: no memory for testing\n");
goto jd_end;
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
index 7622638e5bb8..201a049c8c06 100644
--- a/drivers/input/joystick/magellan.c
+++ b/drivers/input/joystick/magellan.c
@@ -132,7 +132,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- magellan = kzalloc(sizeof(*magellan), GFP_KERNEL);
+ magellan = kzalloc_obj(*magellan);
input_dev = input_allocate_device();
if (!magellan || !input_dev)
goto fail1;
diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c
index 8b54f9b18e7c..7f36f73844a9 100644
--- a/drivers/input/joystick/maplecontrol.c
+++ b/drivers/input/joystick/maplecontrol.c
@@ -102,7 +102,7 @@ static int probe_maple_controller(struct device *dev)
struct input_dev *idev;
unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);
- pad = kzalloc(sizeof(*pad), GFP_KERNEL);
+ pad = kzalloc_obj(*pad);
idev = input_allocate_device();
if (!pad || !idev) {
error = -ENOMEM;
diff --git a/drivers/input/joystick/n64joy.c b/drivers/input/joystick/n64joy.c
index 94d2f4e96fe6..43a02bb99fc2 100644
--- a/drivers/input/joystick/n64joy.c
+++ b/drivers/input/joystick/n64joy.c
@@ -243,7 +243,7 @@ static int __init n64joy_probe(struct platform_device *pdev)
int err = 0;
u32 i, j, found = 0;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
if (!priv)
return -ENOMEM;
mutex_init(&priv->n64joy_mutex);
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 3a5873e5fcb3..7f37d18c8477 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -578,7 +578,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
comment[0] = 0;
- sw = kzalloc(sizeof(*sw), GFP_KERNEL);
+ sw = kzalloc_obj(*sw);
buf = kmalloc(SW_LENGTH, GFP_KERNEL);
idbuf = kmalloc(SW_LENGTH, GFP_KERNEL);
if (!sw || !buf || !idbuf) {
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
index 4f2221001a95..1af299a41d13 100644
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -199,7 +199,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
if ((id = serio->id.id) > SPACEBALL_MAX_ID)
return -ENODEV;
- spaceball = kmalloc(sizeof(*spaceball), GFP_KERNEL);
+ spaceball = kmalloc_obj(*spaceball);
input_dev = input_allocate_device();
if (!spaceball || !input_dev)
goto fail1;
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
index 7250d74d62a1..ba5b318993ec 100644
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -147,7 +147,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- spaceorb = kzalloc(sizeof(*spaceorb), GFP_KERNEL);
+ spaceorb = kzalloc_obj(*spaceorb);
input_dev = input_allocate_device();
if (!spaceorb || !input_dev)
goto fail1;
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
index 1b24ea21aa30..011f9b137dca 100644
--- a/drivers/input/joystick/stinger.c
+++ b/drivers/input/joystick/stinger.c
@@ -118,7 +118,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err = -ENOMEM;
- stinger = kmalloc(sizeof(*stinger), GFP_KERNEL);
+ stinger = kmalloc_obj(*stinger);
input_dev = input_allocate_device();
if (!stinger || !input_dev)
goto fail1;
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 514b1026e379..d419f41e62ac 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -264,7 +264,7 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
int i, j, b = 0;
int err;
- tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL);
+ tmdc->port[idx] = port = kzalloc_obj(struct tmdc_port);
input_dev = input_allocate_device();
if (!port || !input_dev) {
err = -ENOMEM;
@@ -348,7 +348,7 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
int i;
int err;
- tmdc = kzalloc(sizeof(*tmdc), GFP_KERNEL);
+ tmdc = kzalloc_obj(*tmdc);
if (!tmdc)
return -ENOMEM;
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 5f69aef01791..4ee45f27290a 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -170,7 +170,7 @@ static void tgfx_attach(struct parport *pp)
return;
}
- tgfx = kzalloc(sizeof(*tgfx), GFP_KERNEL);
+ tgfx = kzalloc_obj(*tgfx);
if (!tgfx) {
printk(KERN_ERR "turbografx.c: Not enough memory\n");
goto err_unreg_pardev;
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index ab99d76e5d8d..fb452552ceb2 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -171,7 +171,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- twidjoy = kzalloc(sizeof(*twidjoy), GFP_KERNEL);
+ twidjoy = kzalloc_obj(*twidjoy);
input_dev = input_allocate_device();
if (!twidjoy || !input_dev)
goto fail1;
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
index ebeab441e9ec..2e1c6df98e24 100644
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -124,7 +124,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err = -ENOMEM;
- warrior = kzalloc(sizeof(*warrior), GFP_KERNEL);
+ warrior = kzalloc_obj(*warrior);
input_dev = input_allocate_device();
if (!warrior || !input_dev)
goto fail1;
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 627e8950e451..0549fdc5a985 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -25,40 +25,6 @@
* - Greg Kroah-Hartman - usb-skeleton driver
* - Xbox Linux project - extra USB IDs
* - Pekka Pöyry (quantus) - Xbox One controller reverse-engineering
- *
- * TODO:
- * - fine tune axes (especially trigger axes)
- * - fix "analog" buttons (reported as digital now)
- * - get rumble working
- * - need USB IDs for other dance pads
- *
- * History:
- *
- * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller"
- *
- * 2002-07-02 - 0.0.2 : basic working version
- * - all axes and 9 of the 10 buttons work (german InterAct device)
- * - the black button does not work
- *
- * 2002-07-14 - 0.0.3 : rework by Vojtech Pavlik
- * - indentation fixes
- * - usb + input init sequence fixes
- *
- * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3
- * - verified the lack of HID and report descriptors
- * - verified that ALL buttons WORK
- * - fixed d-pad to axes mapping
- *
- * 2002-07-17 - 0.0.5 : simplified d-pad handling
- *
- * 2004-10-02 - 0.0.6 : DDR pad support
- * - borrowed from the Xbox Linux kernel
- * - USB id's for commonly used dance pads are present
- * - dance pads will map D-PAD to buttons, not axes
- * - pass the module paramater 'dpad_to_buttons' to force
- * the D-PAD to map to buttons if your pad is not detected
- *
- * Later changes can be tracked in SCM.
*/
#include <linux/bits.h>
@@ -590,6 +556,7 @@ static const struct usb_device_id xpad_table[] = {
XPAD_XBOX360_VENDOR(0x3651), /* CRKD Controllers */
XPAD_XBOXONE_VENDOR(0x366c), /* ByoWave controllers */
XPAD_XBOX360_VENDOR(0x37d7), /* Flydigi Controllers */
+ XPAD_XBOX360_VENDOR(0x3958), /* RedOctane Games Controllers */
XPAD_XBOX360_VENDOR(0x413d), /* Black Shark Green Ghost Controller */
{ }
};
@@ -1749,7 +1716,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W)
return 0;
- xpad->led = led = kzalloc(sizeof(*led), GFP_KERNEL);
+ xpad->led = led = kzalloc_obj(*led);
if (!led)
return -ENOMEM;
@@ -2082,7 +2049,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
break;
}
- xpad = kzalloc(sizeof(*xpad), GFP_KERNEL);
+ xpad = kzalloc_obj(*xpad);
if (!xpad)
return -ENOMEM;
diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c
index cc0e2a77ac5e..8ca1896639de 100644
--- a/drivers/input/joystick/zhenhua.c
+++ b/drivers/input/joystick/zhenhua.c
@@ -131,7 +131,7 @@ static int zhenhua_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err = -ENOMEM;
- zhenhua = kzalloc(sizeof(*zhenhua), GFP_KERNEL);
+ zhenhua = kzalloc_obj(*zhenhua);
input_dev = input_allocate_device();
if (!zhenhua || !input_dev)
goto fail1;
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 2ff4fef322c2..9d1019ba0245 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -289,6 +289,20 @@ config KEYBOARD_MATRIX
To compile this driver as a module, choose M here: the
module will be called matrix_keypad.
+config KEYBOARD_CHARLIEPLEX
+ tristate "GPIO driven charlieplex keypad support"
+ depends on GPIOLIB || COMPILE_TEST
+ select INPUT_MATRIXKMAP
+ help
+ Enable support for GPIO driven charlieplex keypad. A charlieplex
+ keypad allows to use fewer GPIO lines to interface to key switches.
+ For example, an N lines charlieplex keypad can be used to interface
+ to N^2-N different key switches. However, this type of keypad
+ cannot detect more than one key press at a time.
+
+ To compile this driver as a module, choose M here: the
+ module will be called charlieplex_keypad.
+
config KEYBOARD_HIL_OLD
tristate "HP HIL keyboard support (simple driver)"
depends on GSC || HP300
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 2d906e14f3e2..60bb7baf802f 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
obj-$(CONFIG_KEYBOARD_BCM) += bcm-keypad.o
obj-$(CONFIG_KEYBOARD_CAP11XX) += cap11xx.o
+obj-$(CONFIG_KEYBOARD_CHARLIEPLEX) += charlieplex_keypad.o
obj-$(CONFIG_KEYBOARD_CLPS711X) += clps711x-keypad.o
obj-$(CONFIG_KEYBOARD_CROS_EC) += cros_ec_keyb.o
obj-$(CONFIG_KEYBOARD_CYPRESS_SF) += cypress-sf.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 422e28ad1e8e..c8ad55f26ea8 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -3,10 +3,7 @@
* AT and PS/2 keyboard driver
*
* Copyright (c) 1999-2002 Vojtech Pavlik
- */
-
-
-/*
+ *
* This driver can handle standard AT keyboards and PS/2 keyboards in
* Translated and Raw Set 2 and Set 3, as well as AT keyboards on dumb
* input-only controllers and AT keyboards connected over a one way RS232
@@ -65,8 +62,8 @@ static bool atkbd_terminal;
module_param_named(terminal, atkbd_terminal, bool, 0);
MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
-#define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF)
-#define KEYCODE(keymap) (keymap & 0xFFFF)
+#define SCANCODE(keymap) (((keymap) >> 16) & 0xFFFF)
+#define KEYCODE(keymap) ((keymap) & 0xFFFF)
/*
* Scancode to keycode tables. These are just the default setting, and
@@ -76,7 +73,6 @@ MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard conne
#define ATKBD_KEYMAP_SIZE 512
static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
-
#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
/* XXX: need a more general approach */
@@ -107,7 +103,6 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
};
static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
-
0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60,
131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62,
134, 46, 45, 32, 18, 5, 4, 63,135, 57, 47, 33, 20, 19, 6, 64,
@@ -122,15 +117,15 @@ static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
148,149,147,140
};
-static const unsigned short atkbd_unxlate_table[128] = {
- 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
- 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
- 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
- 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
- 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
- 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
- 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
- 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
+static const u8 atkbd_unxlate_table[128] = {
+ 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
+ 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
+ 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
+ 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
+ 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
+ 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
+ 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
+ 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
};
#define ATKBD_CMD_SETLEDS 0x10ed
@@ -184,7 +179,7 @@ static const unsigned short atkbd_unxlate_table[128] = {
static const struct {
unsigned short keycode;
- unsigned char set2;
+ u8 set2;
} atkbd_scroll_keys[] = {
{ ATKBD_SCR_1, 0xc5 },
{ ATKBD_SCR_2, 0x9d },
@@ -200,7 +195,6 @@ static const struct {
*/
struct atkbd {
-
struct ps2dev ps2dev;
struct input_dev *dev;
@@ -211,7 +205,7 @@ struct atkbd {
unsigned short id;
unsigned short keycode[ATKBD_KEYMAP_SIZE];
DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE);
- unsigned char set;
+ u8 set;
bool translated;
bool extra;
bool write;
@@ -221,7 +215,7 @@ struct atkbd {
bool enabled;
/* Accessed only from interrupt */
- unsigned char emul;
+ u8 emul;
bool resend;
bool release;
unsigned long xl_bit;
@@ -253,9 +247,9 @@ static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned in
static bool atkbd_skip_deactivate;
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct atkbd *, char *));
+ ssize_t (*handler)(struct atkbd *, char *));
static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct atkbd *, const char *, size_t));
+ ssize_t (*handler)(struct atkbd *, const char *, size_t));
#define ATKBD_DEFINE_ATTR(_name) \
static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \
@@ -270,7 +264,7 @@ static ssize_t atkbd_do_set_##_name(struct device *d, \
return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \
} \
static struct device_attribute atkbd_attr_##_name = \
- __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name);
+ __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name)
ATKBD_DEFINE_ATTR(extra);
ATKBD_DEFINE_ATTR(force_release);
@@ -287,7 +281,7 @@ static ssize_t atkbd_do_show_##_name(struct device *d, \
return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
} \
static struct device_attribute atkbd_attr_##_name = \
- __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
+ __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL)
ATKBD_DEFINE_RO_ATTR(err_count);
ATKBD_DEFINE_RO_ATTR(function_row_physmap);
@@ -317,7 +311,7 @@ static struct atkbd *atkbd_from_serio(struct serio *serio)
}
static umode_t atkbd_attr_is_visible(struct kobject *kobj,
- struct attribute *attr, int i)
+ struct attribute *attr, int i)
{
struct device *dev = kobj_to_dev(kobj);
struct serio *serio = to_serio_port(dev);
@@ -337,7 +331,7 @@ static const struct attribute_group atkbd_attribute_group = {
__ATTRIBUTE_GROUPS(atkbd_attribute);
-static const unsigned int xl_table[] = {
+static const u8 xl_table[] = {
ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK,
ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL,
};
@@ -346,7 +340,7 @@ static const unsigned int xl_table[] = {
* Checks if we should mangle the scancode to extract 'release' bit
* in translated mode.
*/
-static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
+static bool atkbd_need_xlate(unsigned long xl_bit, u8 code)
{
int i;
@@ -365,7 +359,7 @@ static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code)
* between make/break pair of scancodes for select keys and PS/2
* protocol responses.
*/
-static void atkbd_calculate_xl_bit(struct atkbd *atkbd, unsigned char code)
+static void atkbd_calculate_xl_bit(struct atkbd *atkbd, u8 code)
{
int i;
@@ -389,7 +383,7 @@ static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code
if (atkbd->set == 3) {
if (atkbd->emul == 1)
code |= 0x100;
- } else {
+ } else {
code = (code & 0x7f) | ((code & 0x80) << 1);
if (atkbd->emul == 1)
code |= 0x80;
@@ -431,7 +425,7 @@ static enum ps2_disposition atkbd_pre_receive_byte(struct ps2dev *ps2dev,
dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags);
-#if !defined(__i386__) && !defined (__x86_64__)
+#if !defined(__i386__) && !defined(__x86_64__)
if (atkbd_handle_frame_error(ps2dev, data, flags))
return PS2_IGNORE;
#endif
@@ -460,7 +454,6 @@ static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data)
code = atkbd_platform_scancode_fixup(atkbd, code);
if (atkbd->translated) {
-
if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) {
atkbd->release = code >> 7;
code &= 0x7f;
@@ -486,11 +479,9 @@ static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data)
return;
case ATKBD_RET_ACK:
case ATKBD_RET_NAK:
- if (printk_ratelimit())
- dev_warn(&serio->dev,
- "Spurious %s on %s. "
- "Some program might be trying to access hardware directly.\n",
- data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
+ dev_warn_ratelimited(&serio->dev,
+ "Spurious %s on %s. Some program might be trying to access hardware directly.\n",
+ data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
return;
case ATKBD_RET_ERR:
atkbd->err_count++;
@@ -582,14 +573,14 @@ static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data)
static int atkbd_set_repeat_rate(struct atkbd *atkbd)
{
- const short period[32] =
- { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125,
- 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
- const short delay[4] =
- { 250, 500, 750, 1000 };
+ const short period[32] = {
+ 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125,
+ 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500
+ };
+ const short delay[4] = { 250, 500, 750, 1000 };
struct input_dev *dev = atkbd->dev;
- unsigned char param;
+ u8 param;
int i = 0, j = 0;
while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD])
@@ -607,7 +598,7 @@ static int atkbd_set_repeat_rate(struct atkbd *atkbd)
static int atkbd_set_leds(struct atkbd *atkbd)
{
struct input_dev *dev = atkbd->dev;
- unsigned char param[2];
+ u8 param[2];
param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
| (test_bit(LED_NUML, dev->led) ? 2 : 0)
@@ -648,8 +639,7 @@ static void atkbd_event_work(struct work_struct *work)
* it may not be ready yet. In this case we need to keep
* rescheduling till reconnect completes.
*/
- schedule_delayed_work(&atkbd->event_work,
- msecs_to_jiffies(100));
+ schedule_delayed_work(&atkbd->event_work, msecs_to_jiffies(100));
} else {
if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
atkbd_set_leds(atkbd);
@@ -683,7 +673,7 @@ static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit)
*/
static int atkbd_event(struct input_dev *dev,
- unsigned int type, unsigned int code, int value)
+ unsigned int type, unsigned int code, int value)
{
struct atkbd *atkbd = input_get_drvdata(dev);
@@ -691,7 +681,6 @@ static int atkbd_event(struct input_dev *dev,
return -1;
switch (type) {
-
case EV_LED:
atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT);
return 0;
@@ -808,7 +797,7 @@ static inline bool atkbd_skip_getid(struct atkbd *atkbd) { return false; }
static int atkbd_probe(struct atkbd *atkbd)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
- unsigned char param[2];
+ u8 param[2];
/*
* Some systems, where the bit-twiddling when testing the io-lines of the
@@ -836,7 +825,6 @@ static int atkbd_probe(struct atkbd *atkbd)
param[0] = param[1] = 0xa5; /* initialize with invalid values */
if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) {
-
/*
* If the get ID command failed, we check if we can at least set
* the LEDs on the keyboard. This should work on every keyboard out there.
@@ -856,8 +844,7 @@ static int atkbd_probe(struct atkbd *atkbd)
if (atkbd->id == 0xaca1 && atkbd->translated) {
dev_err(&ps2dev->serio->dev,
- "NCD terminal keyboards are only supported on non-translating controllers. "
- "Use i8042.direct=1 to disable translation.\n");
+ "NCD terminal keyboards are only supported on non-translating controllers. Use i8042.direct=1 to disable translation.\n");
return -1;
}
@@ -881,7 +868,7 @@ deactivate_kbd:
static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra)
{
struct ps2dev *ps2dev = &atkbd->ps2dev;
- unsigned char param[2];
+ u8 param[2];
atkbd->extra = false;
/*
@@ -941,8 +928,8 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
static int atkbd_reset_state(struct atkbd *atkbd)
{
- struct ps2dev *ps2dev = &atkbd->ps2dev;
- unsigned char param[1];
+ struct ps2dev *ps2dev = &atkbd->ps2dev;
+ u8 param[1];
/*
* Set the LEDs to a predefined state (all off).
@@ -967,7 +954,6 @@ static int atkbd_reset_state(struct atkbd *atkbd)
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
* reboot.
*/
-
static void atkbd_cleanup(struct serio *serio)
{
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -976,11 +962,9 @@ static void atkbd_cleanup(struct serio *serio)
ps2_command(&atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF);
}
-
/*
* atkbd_disconnect() closes and frees.
*/
-
static void atkbd_disconnect(struct serio *serio)
{
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1005,8 +989,7 @@ static void atkbd_disconnect(struct serio *serio)
/*
* generate release events for the keycodes given in data
*/
-static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd,
- const void *data)
+static void atkbd_apply_forced_release_keylist(struct atkbd *atkbd, const void *data)
{
const unsigned int *keys = data;
unsigned int i;
@@ -1088,7 +1071,6 @@ static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
{
struct device *dev = &atkbd->ps2dev.serio->dev;
int i, n;
- u32 *ptr;
u16 scancode, keycode;
/* Parse "linux,keymap" property */
@@ -1096,13 +1078,12 @@ static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
if (n <= 0 || n > ATKBD_KEYMAP_SIZE)
return -ENXIO;
- ptr = kcalloc(n, sizeof(u32), GFP_KERNEL);
+ u32 *ptr __free(kfree) = kcalloc(n, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return -ENOMEM;
if (device_property_read_u32_array(dev, "linux,keymap", ptr, n)) {
dev_err(dev, "problem parsing FW keymap property\n");
- kfree(ptr);
return -EINVAL;
}
@@ -1110,10 +1091,14 @@ static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
for (i = 0; i < n; i++) {
scancode = SCANCODE(ptr[i]);
keycode = KEYCODE(ptr[i]);
+ if (scancode >= ATKBD_KEYMAP_SIZE) {
+ dev_warn(dev, "invalid scancode %#x in FW keymap entry %d\n",
+ scancode, i);
+ return -EINVAL;
+ }
atkbd->keycode[scancode] = keycode;
}
- kfree(ptr);
return 0;
}
@@ -1235,7 +1220,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
}
input_dev->keycode = atkbd->keycode;
- input_dev->keycodesize = sizeof(unsigned short);
+ input_dev->keycodesize = sizeof(atkbd->keycode[0]);
input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) {
@@ -1277,7 +1262,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *dev;
int err = -ENOMEM;
- atkbd = kzalloc(sizeof(*atkbd), GFP_KERNEL);
+ atkbd = kzalloc_obj(*atkbd);
dev = input_allocate_device();
if (!atkbd || !dev)
goto fail1;
@@ -1289,7 +1274,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
mutex_init(&atkbd->mutex);
switch (serio->id.type) {
-
case SERIO_8042_XL:
atkbd->translated = true;
fallthrough;
@@ -1314,7 +1298,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
goto fail2;
if (atkbd->write) {
-
if (atkbd_probe(atkbd)) {
err = -ENODEV;
goto fail3;
@@ -1354,7 +1337,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
* atkbd_reconnect() tries to restore keyboard into a sane state and is
* most likely called on resume.
*/
-
static int atkbd_reconnect(struct serio *serio)
{
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1389,7 +1371,6 @@ static int atkbd_reconnect(struct serio *serio)
atkbd_set_leds(atkbd);
if (!atkbd->softrepeat)
atkbd_set_repeat_rate(atkbd);
-
}
/*
@@ -1445,7 +1426,7 @@ static struct serio_driver atkbd_drv = {
};
static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct atkbd *, char *))
+ ssize_t (*handler)(struct atkbd *, char *))
{
struct serio *serio = to_serio_port(dev);
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1454,7 +1435,7 @@ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
}
static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct atkbd *, const char *, size_t))
+ ssize_t (*handler)(struct atkbd *, const char *, size_t))
{
struct serio *serio = to_serio_port(dev);
struct atkbd *atkbd = atkbd_from_serio(serio);
@@ -1482,7 +1463,7 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
unsigned int value;
int err;
bool old_extra;
- unsigned char old_set;
+ u8 old_set;
if (!atkbd->write)
return -EIO;
@@ -1527,8 +1508,8 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
return err;
}
input_unregister_device(old_dev);
-
}
+
return count;
}
@@ -1544,7 +1525,7 @@ static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
}
static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
/* 64 bytes on stack should be acceptable */
DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE);
@@ -1558,7 +1539,6 @@ static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
return count;
}
-
static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
{
return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0);
@@ -1617,7 +1597,7 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
struct input_dev *old_dev, *new_dev;
unsigned int value;
int err;
- unsigned char old_set;
+ u8 old_set;
bool old_extra;
if (!atkbd->write)
@@ -1715,7 +1695,6 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
return count;
}
-
static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf)
{
return sprintf(buf, "%d\n", atkbd->softraw ? 1 : 0);
diff --git a/drivers/input/keyboard/charlieplex_keypad.c b/drivers/input/keyboard/charlieplex_keypad.c
new file mode 100644
index 000000000000..6dbb5c183f02
--- /dev/null
+++ b/drivers/input/keyboard/charlieplex_keypad.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * GPIO driven charlieplex keypad driver
+ *
+ * Copyright (c) 2026 Hugo Villeneuve <hvilleneuve@dimonoff.com>
+ *
+ * Based on matrix_keyboard.c
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/device/devres.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/string_helpers.h>
+#include <linux/types.h>
+
+struct charlieplex_keypad {
+ struct input_dev *input_dev;
+ struct gpio_descs *line_gpios;
+ unsigned int nlines;
+ unsigned int settling_time_us;
+ unsigned int debounce_threshold;
+ unsigned int debounce_count;
+ int debounce_code;
+ int current_code;
+};
+
+static void charlieplex_keypad_report_key(struct input_dev *input)
+{
+ struct charlieplex_keypad *keypad = input_get_drvdata(input);
+ const unsigned short *keycodes = input->keycode;
+
+ if (keypad->current_code > 0) {
+ input_event(input, EV_MSC, MSC_SCAN, keypad->current_code);
+ input_report_key(input, keycodes[keypad->current_code], 0);
+ input_sync(input);
+ }
+
+ if (keypad->debounce_code) {
+ input_event(input, EV_MSC, MSC_SCAN, keypad->debounce_code);
+ input_report_key(input, keycodes[keypad->debounce_code], 1);
+ input_sync(input);
+ }
+
+ keypad->current_code = keypad->debounce_code;
+}
+
+static void charlieplex_keypad_check_switch_change(struct input_dev *input,
+ unsigned int code)
+{
+ struct charlieplex_keypad *keypad = input_get_drvdata(input);
+
+ if (code != keypad->debounce_code) {
+ keypad->debounce_count = 0;
+ keypad->debounce_code = code;
+ }
+
+ if (keypad->debounce_code != keypad->current_code) {
+ if (keypad->debounce_count++ >= keypad->debounce_threshold)
+ charlieplex_keypad_report_key(input);
+ }
+}
+
+static int charlieplex_keypad_scan_line(struct charlieplex_keypad *keypad,
+ unsigned int oline)
+{
+ struct gpio_descs *line_gpios = keypad->line_gpios;
+ DECLARE_BITMAP(values, MATRIX_MAX_ROWS);
+ int err;
+
+ /* Activate only one line as output at a time. */
+ gpiod_direction_output(line_gpios->desc[oline], 1);
+
+ if (keypad->settling_time_us)
+ fsleep(keypad->settling_time_us);
+
+ /* Read input on all other lines. */
+ err = gpiod_get_array_value_cansleep(line_gpios->ndescs, line_gpios->desc,
+ line_gpios->info, values);
+
+ gpiod_direction_input(line_gpios->desc[oline]);
+
+ if (err)
+ return err;
+
+ for (unsigned int iline = 0; iline < keypad->nlines; iline++) {
+ if (iline == oline)
+ continue; /* Do not read active output line. */
+
+ /* Check if GPIO is asserted. */
+ if (test_bit(iline, values))
+ return MATRIX_SCAN_CODE(oline, iline,
+ get_count_order(keypad->nlines));
+ }
+
+ return 0;
+}
+
+static void charlieplex_keypad_poll(struct input_dev *input)
+{
+ struct charlieplex_keypad *keypad = input_get_drvdata(input);
+ int code = 0;
+
+ for (unsigned int oline = 0; oline < keypad->nlines; oline++) {
+ code = charlieplex_keypad_scan_line(keypad, oline);
+ if (code != 0)
+ break;
+ }
+
+ if (code >= 0)
+ charlieplex_keypad_check_switch_change(input, code);
+}
+
+static int charlieplex_keypad_init_gpio(struct platform_device *pdev,
+ struct charlieplex_keypad *keypad)
+{
+ char **pin_names;
+ char label[32];
+
+ snprintf(label, sizeof(label), "%s-pin", pdev->name);
+
+ keypad->line_gpios = devm_gpiod_get_array(&pdev->dev, "line", GPIOD_IN);
+ if (IS_ERR(keypad->line_gpios))
+ return PTR_ERR(keypad->line_gpios);
+
+ keypad->nlines = keypad->line_gpios->ndescs;
+
+ if (keypad->nlines > MATRIX_MAX_ROWS)
+ return -EINVAL;
+
+ pin_names = devm_kasprintf_strarray(&pdev->dev, label, keypad->nlines);
+ if (IS_ERR(pin_names))
+ return PTR_ERR(pin_names);
+
+ for (unsigned int i = 0; i < keypad->line_gpios->ndescs; i++)
+ gpiod_set_consumer_name(keypad->line_gpios->desc[i], pin_names[i]);
+
+ return 0;
+}
+
+static int charlieplex_keypad_probe(struct platform_device *pdev)
+{
+ struct charlieplex_keypad *keypad;
+ struct input_dev *input_dev;
+ unsigned int debounce_interval_ms = 5;
+ unsigned int poll_interval_ms;
+ int err;
+
+ keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+ if (!keypad)
+ return -ENOMEM;
+
+ input_dev = devm_input_allocate_device(&pdev->dev);
+ if (!input_dev)
+ return -ENOMEM;
+
+ keypad->input_dev = input_dev;
+
+ err = device_property_read_u32(&pdev->dev, "poll-interval", &poll_interval_ms);
+ if (err)
+ return dev_err_probe(&pdev->dev, err,
+ "failed to parse 'poll-interval' property\n");
+
+ if (poll_interval_ms == 0)
+ return dev_err_probe(&pdev->dev, -EINVAL, "invalid 'poll-interval' value\n");
+
+ device_property_read_u32(&pdev->dev, "debounce-delay-ms", &debounce_interval_ms);
+ device_property_read_u32(&pdev->dev, "settling-time-us", &keypad->settling_time_us);
+
+ keypad->current_code = -1;
+ keypad->debounce_code = -1;
+ keypad->debounce_threshold = DIV_ROUND_UP(debounce_interval_ms, poll_interval_ms);
+
+ err = charlieplex_keypad_init_gpio(pdev, keypad);
+ if (err)
+ return err;
+
+ input_dev->name = pdev->name;
+ input_dev->id.bustype = BUS_HOST;
+
+ err = matrix_keypad_build_keymap(NULL, NULL, keypad->nlines,
+ keypad->nlines, NULL, input_dev);
+ if (err)
+ return dev_err_probe(&pdev->dev, err, "failed to build keymap\n");
+
+ if (device_property_read_bool(&pdev->dev, "autorepeat"))
+ __set_bit(EV_REP, input_dev->evbit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ err = input_setup_polling(input_dev, charlieplex_keypad_poll);
+ if (err)
+ return dev_err_probe(&pdev->dev, err, "unable to set up polling\n");
+
+ input_set_poll_interval(input_dev, poll_interval_ms);
+
+ input_set_drvdata(input_dev, keypad);
+
+ err = input_register_device(keypad->input_dev);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static const struct of_device_id charlieplex_keypad_dt_match[] = {
+ { .compatible = "gpio-charlieplex-keypad" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, charlieplex_keypad_dt_match);
+
+static struct platform_driver charlieplex_keypad_driver = {
+ .probe = charlieplex_keypad_probe,
+ .driver = {
+ .name = "charlieplex-keypad",
+ .of_match_table = charlieplex_keypad_dt_match,
+ },
+};
+module_platform_driver(charlieplex_keypad_driver);
+
+MODULE_AUTHOR("Hugo Villeneuve <hvilleneuve@dimonoff.com>");
+MODULE_DESCRIPTION("GPIO driven charlieplex keypad driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 2822c592880b..177e5d4a3382 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -29,6 +29,12 @@
#include <linux/unaligned.h>
+/*
+ * Maximum size of the normal key matrix, this is limited by the host command
+ * key_matrix field defined in ec_response_get_next_data_v3
+ */
+#define CROS_EC_KEYBOARD_COLS_MAX 18
+
/**
* struct cros_ec_keyb - Structure representing EC keyboard device
*
@@ -44,14 +50,17 @@
* @bs_idev: The input device for non-matrix buttons and switches (or NULL).
* @notifier: interrupt event notifier for transport devices
* @vdata: vivaldi function row data
+ * @has_fn_map: whether the driver uses an fn function-map layer
+ * @fn_active: tracks whether the function key is currently pressed
+ * @fn_combo_active: tracks whether another key was pressed while fn is active
*/
struct cros_ec_keyb {
unsigned int rows;
unsigned int cols;
int row_shift;
bool ghost_filter;
- uint8_t *valid_keys;
- uint8_t *old_kb_state;
+ u8 valid_keys[CROS_EC_KEYBOARD_COLS_MAX];
+ u8 old_kb_state[CROS_EC_KEYBOARD_COLS_MAX];
struct device *dev;
struct cros_ec_device *ec;
@@ -61,6 +70,10 @@ struct cros_ec_keyb {
struct notifier_block notifier;
struct vivaldi_data vdata;
+
+ bool has_fn_map;
+ bool fn_active;
+ bool fn_combo_active;
};
/**
@@ -132,11 +145,11 @@ static const struct cros_ec_bs_map cros_ec_keyb_bs[] = {
* Returns true when there is at least one combination of pressed keys that
* results in ghosting.
*/
-static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
+static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, u8 *buf)
{
int col1, col2, buf1, buf2;
struct device *dev = ckdev->dev;
- uint8_t *valid_keys = ckdev->valid_keys;
+ u8 *valid_keys = ckdev->valid_keys;
/*
* Ghosting happens if for any pressed key X there are other keys
@@ -166,20 +179,108 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
return false;
}
+static void cros_ec_emit_fn_key(struct input_dev *input, unsigned int pos)
+{
+ input_event(input, EV_MSC, MSC_SCAN, pos);
+ input_report_key(input, KEY_FN, true);
+ input_sync(input);
+
+ input_event(input, EV_MSC, MSC_SCAN, pos);
+ input_report_key(input, KEY_FN, false);
+}
+
+static void cros_ec_keyb_process_key_plain(struct cros_ec_keyb *ckdev,
+ int row, int col, bool state)
+{
+ struct input_dev *idev = ckdev->idev;
+ const unsigned short *keycodes = idev->keycode;
+ int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+
+ input_event(idev, EV_MSC, MSC_SCAN, pos);
+ input_report_key(idev, keycodes[pos], state);
+}
+
+static void cros_ec_keyb_process_key_fn_map(struct cros_ec_keyb *ckdev,
+ int row, int col, bool state)
+{
+ struct input_dev *idev = ckdev->idev;
+ const unsigned short *keycodes = idev->keycode;
+ unsigned int pos, fn_pos;
+ unsigned int code, fn_code;
+
+ pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+ code = keycodes[pos];
+
+ if (code == KEY_FN) {
+ ckdev->fn_active = state;
+ if (state) {
+ ckdev->fn_combo_active = false;
+ } else if (!ckdev->fn_combo_active) {
+ /*
+ * Send both Fn press and release events if nothing
+ * else has been pressed together with Fn.
+ */
+ cros_ec_emit_fn_key(idev, pos);
+ }
+ return;
+ }
+
+ fn_pos = MATRIX_SCAN_CODE(row + ckdev->rows, col, ckdev->row_shift);
+ fn_code = keycodes[fn_pos];
+
+ if (state) {
+ if (ckdev->fn_active) {
+ ckdev->fn_combo_active = true;
+ if (!fn_code)
+ return; /* Discard if no Fn mapping exists */
+
+ pos = fn_pos;
+ code = fn_code;
+ }
+ } else {
+ /*
+ * If the Fn-remapped code is currently pressed, release it.
+ * Otherwise, release the standard code (if it was pressed).
+ */
+ if (fn_code && test_bit(fn_code, idev->key)) {
+ pos = fn_pos;
+ code = fn_code;
+ } else if (!test_bit(code, idev->key)) {
+ return; /* Discard, key press code was not sent */
+ }
+ }
+
+ input_event(idev, EV_MSC, MSC_SCAN, pos);
+ input_report_key(idev, code, state);
+}
+
+static void cros_ec_keyb_process_col(struct cros_ec_keyb *ckdev, int col,
+ u8 col_state, u8 changed)
+{
+ for (int row = 0; row < ckdev->rows; row++) {
+ if (changed & BIT(row)) {
+ u8 key_state = col_state & BIT(row);
+
+ dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n",
+ row, col, key_state);
+
+ if (ckdev->has_fn_map)
+ cros_ec_keyb_process_key_fn_map(ckdev, row, col,
+ key_state);
+ else
+ cros_ec_keyb_process_key_plain(ckdev, row, col,
+ key_state);
+ }
+ }
+}
/*
* Compares the new keyboard state to the old one and produces key
- * press/release events accordingly. The keyboard state is 13 bytes (one byte
- * per column)
+ * press/release events accordingly. The keyboard state is one byte
+ * per column.
*/
-static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
- uint8_t *kb_state, int len)
+static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, u8 *kb_state, int len)
{
- struct input_dev *idev = ckdev->idev;
- int col, row;
- int new_state;
- int old_state;
-
if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
/*
* Simple-minded solution: ignore this state. The obvious
@@ -190,25 +291,15 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
return;
}
- for (col = 0; col < ckdev->cols; col++) {
- for (row = 0; row < ckdev->rows; row++) {
- int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
- const unsigned short *keycodes = idev->keycode;
-
- new_state = kb_state[col] & (1 << row);
- old_state = ckdev->old_kb_state[col] & (1 << row);
- if (new_state != old_state) {
- dev_dbg(ckdev->dev,
- "changed: [r%d c%d]: byte %02x\n",
- row, col, new_state);
-
- input_event(idev, EV_MSC, MSC_SCAN, pos);
- input_report_key(idev, keycodes[pos],
- new_state);
- }
- }
- ckdev->old_kb_state[col] = kb_state[col];
+ for (int col = 0; col < ckdev->cols; col++) {
+ u8 changed = kb_state[col] ^ ckdev->old_kb_state[col];
+
+ if (changed)
+ cros_ec_keyb_process_col(ckdev, col, kb_state[col],
+ changed);
}
+
+ memcpy(ckdev->old_kb_state, kb_state, sizeof(ckdev->old_kb_state));
input_sync(ckdev->idev);
}
@@ -246,8 +337,10 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
{
struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
notifier);
- u32 val;
+ struct ec_response_get_next_event_v3 *event_data;
+ unsigned int event_size;
unsigned int ev_type;
+ u32 val;
/*
* If not wake enabled, discard key state changes during
@@ -257,32 +350,32 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
if (queued_during_suspend && !device_may_wakeup(ckdev->dev))
return NOTIFY_OK;
- switch (ckdev->ec->event_data.event_type) {
+ event_data = &ckdev->ec->event_data;
+ event_size = ckdev->ec->event_size;
+
+ switch (event_data->event_type) {
case EC_MKBP_EVENT_KEY_MATRIX:
pm_wakeup_event(ckdev->dev, 0);
if (!ckdev->idev) {
- dev_warn_once(ckdev->dev,
- "Unexpected key matrix event\n");
+ dev_warn_once(ckdev->dev, "Unexpected key matrix event\n");
return NOTIFY_OK;
}
- if (ckdev->ec->event_size != ckdev->cols) {
+ if (event_size != ckdev->cols) {
dev_err(ckdev->dev,
"Discarded key matrix event, unexpected length: %d != %d\n",
ckdev->ec->event_size, ckdev->cols);
return NOTIFY_OK;
}
- cros_ec_keyb_process(ckdev,
- ckdev->ec->event_data.data.key_matrix,
- ckdev->ec->event_size);
+ cros_ec_keyb_process(ckdev, event_data->data.key_matrix, event_size);
break;
case EC_MKBP_EVENT_SYSRQ:
pm_wakeup_event(ckdev->dev, 0);
- val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq);
+ val = get_unaligned_le32(&event_data->data.sysrq);
dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val);
handle_sysrq(val);
break;
@@ -291,13 +384,11 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
case EC_MKBP_EVENT_SWITCH:
pm_wakeup_event(ckdev->dev, 0);
- if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) {
- val = get_unaligned_le32(
- &ckdev->ec->event_data.data.buttons);
+ if (event_data->event_type == EC_MKBP_EVENT_BUTTON) {
+ val = get_unaligned_le32(&event_data->data.buttons);
ev_type = EV_KEY;
} else {
- val = get_unaligned_le32(
- &ckdev->ec->event_data.data.switches);
+ val = get_unaligned_le32(&event_data->data.switches);
ev_type = EV_SW;
}
cros_ec_keyb_report_bs(ckdev, ev_type, val);
@@ -326,8 +417,8 @@ static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev)
for (col = 0; col < ckdev->cols; col++) {
for (row = 0; row < ckdev->rows; row++) {
code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)];
- if (code && (code != KEY_BATTERY))
- ckdev->valid_keys[col] |= 1 << row;
+ if (code != KEY_RESERVED && code != KEY_BATTERY)
+ ckdev->valid_keys[col] |= BIT(row);
}
dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n",
col, ckdev->valid_keys[col]);
@@ -583,6 +674,62 @@ static void cros_ec_keyb_parse_vivaldi_physmap(struct cros_ec_keyb *ckdev)
ckdev->vdata.num_function_row_keys = n_physmap;
}
+/* Returns true if there is a KEY_FN code defined in the normal keymap */
+static bool cros_ec_keyb_has_fn_key(struct cros_ec_keyb *ckdev)
+{
+ const unsigned short *keycodes = ckdev->idev->keycode;
+ int i;
+
+ for (i = 0; i < MATRIX_SCAN_CODE(ckdev->rows, 0, ckdev->row_shift); i++) {
+ if (keycodes[i] == KEY_FN)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Returns true if there is a KEY_FN defined and at least one key in the fn
+ * layer keymap
+ */
+static bool cros_ec_keyb_has_fn_map(struct cros_ec_keyb *ckdev)
+{
+ struct input_dev *idev = ckdev->idev;
+ const unsigned short *keycodes = ckdev->idev->keycode;
+ int i;
+
+ if (!cros_ec_keyb_has_fn_key(ckdev))
+ return false;
+
+ for (i = MATRIX_SCAN_CODE(ckdev->rows, 0, ckdev->row_shift);
+ i < idev->keycodemax; i++) {
+ if (keycodes[i] != KEY_RESERVED)
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * Custom handler for the set keycode ioctl, calls the default handler and
+ * recomputes has_fn_map.
+ */
+static int cros_ec_keyb_setkeycode(struct input_dev *idev,
+ const struct input_keymap_entry *ke,
+ unsigned int *old_keycode)
+{
+ struct cros_ec_keyb *ckdev = input_get_drvdata(idev);
+ int ret;
+
+ ret = input_default_setkeycode(idev, ke, old_keycode);
+ if (ret)
+ return ret;
+
+ ckdev->has_fn_map = cros_ec_keyb_has_fn_map(ckdev);
+
+ return 0;
+}
+
/**
* cros_ec_keyb_register_matrix - Register matrix keys
*
@@ -604,13 +751,11 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
if (err)
return err;
- ckdev->valid_keys = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL);
- if (!ckdev->valid_keys)
- return -ENOMEM;
-
- ckdev->old_kb_state = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL);
- if (!ckdev->old_kb_state)
- return -ENOMEM;
+ if (ckdev->cols > CROS_EC_KEYBOARD_COLS_MAX) {
+ dev_err(dev, "keypad,num-columns too large: %d (max: %d)\n",
+ ckdev->cols, CROS_EC_KEYBOARD_COLS_MAX);
+ return -EINVAL;
+ }
/*
* We call the keyboard matrix 'input0'. Allocate phys before input
@@ -632,11 +777,11 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
idev->id.version = 1;
idev->id.product = 0;
idev->dev.parent = dev;
+ idev->setkeycode = cros_ec_keyb_setkeycode;
- ckdev->ghost_filter = device_property_read_bool(dev,
- "google,needs-ghost-filter");
+ ckdev->ghost_filter = device_property_read_bool(dev, "google,needs-ghost-filter");
- err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
+ err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows * 2, ckdev->cols,
NULL, idev);
if (err) {
dev_err(dev, "cannot build key matrix\n");
@@ -651,6 +796,8 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
cros_ec_keyb_compute_valid_keys(ckdev);
cros_ec_keyb_parse_vivaldi_physmap(ckdev);
+ ckdev->has_fn_map = cros_ec_keyb_has_fn_map(ckdev);
+
err = input_register_device(ckdev->idev);
if (err) {
dev_err(dev, "cannot register input device\n");
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index 54afb38601b9..5ebde20df755 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -447,7 +447,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
uint8_t did, *idd;
int error;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc_obj(*dev);
input_dev = input_allocate_device();
if (!dev || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c
index 069c1d6376e1..ccde60cd6bb3 100644
--- a/drivers/input/keyboard/imx_keypad.c
+++ b/drivers/input/keyboard/imx_keypad.c
@@ -324,7 +324,7 @@ static void imx_keypad_config(struct imx_keypad *keypad)
reg_val |= (keypad->cols_en_mask & 0xff) << 8; /* cols */
writew(reg_val, keypad->mmio_base + KPCR);
- /* Write 0's to KPDR[15:8] (Colums) */
+ /* Write 0's to KPDR[15:8] (Columns) */
reg_val = readw(keypad->mmio_base + KPDR);
reg_val &= 0x00ff;
writew(reg_val, keypad->mmio_base + KPDR);
@@ -357,7 +357,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad)
reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD;
writew(reg_val, keypad->mmio_base + KPSR);
- /* Colums as open drain and disable all rows */
+ /* Columns as open drain and disable all rows */
reg_val = (keypad->cols_en_mask & 0xff) << 8;
writew(reg_val, keypad->mmio_base + KPCR);
}
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 2f130f819363..f5c2267a2c00 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -608,7 +608,7 @@ static int lkkbd_connect(struct serio *serio, struct serio_driver *drv)
int i;
int err;
- lk = kzalloc(sizeof(*lk), GFP_KERNEL);
+ lk = kzalloc_obj(*lk);
input_dev = input_allocate_device();
if (!lk || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index 58d4f2096cf9..6351562ebf8d 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -224,7 +224,7 @@ static int locomokbd_probe(struct locomo_dev *dev)
struct input_dev *input_dev;
int i, err;
- locomokbd = kzalloc(sizeof(*locomokbd), GFP_KERNEL);
+ locomokbd = kzalloc_obj(*locomokbd);
input_dev = input_allocate_device();
if (!locomokbd || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
index 1a8f1fa53fbb..80a5181313e1 100644
--- a/drivers/input/keyboard/maple_keyb.c
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -151,7 +151,7 @@ static int probe_maple_kbd(struct device *dev)
mdev = to_maple_dev(dev);
mdrv = to_maple_driver(dev->driver);
- kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
+ kbd = kzalloc_obj(*kbd);
if (!kbd) {
error = -ENOMEM;
goto fail;
diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c
index bd1a944ded46..47edc161ec77 100644
--- a/drivers/input/keyboard/mpr121_touchkey.c
+++ b/drivers/input/keyboard/mpr121_touchkey.c
@@ -295,8 +295,6 @@ static int mpr_touchkey_probe(struct i2c_client *client)
return error;
i2c_set_clientdata(client, mpr121);
- device_init_wakeup(dev,
- device_property_read_bool(dev, "wakeup-source"));
return 0;
}
@@ -305,9 +303,6 @@ static int mpr_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
- if (device_may_wakeup(&client->dev))
- enable_irq_wake(client->irq);
-
i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, 0x00);
return 0;
@@ -318,9 +313,6 @@ static int mpr_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
- if (device_may_wakeup(&client->dev))
- disable_irq_wake(client->irq);
-
i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
mpr121->keycount);
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
index 71e0a3f830dd..e60d1181dad0 100644
--- a/drivers/input/keyboard/newtonkbd.c
+++ b/drivers/input/keyboard/newtonkbd.c
@@ -68,7 +68,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- nkbd = kzalloc(sizeof(*nkbd), GFP_KERNEL);
+ nkbd = kzalloc_obj(*nkbd);
input_dev = input_allocate_device();
if (!nkbd || !input_dev)
goto fail1;
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 9e13f3f70a81..589f51d430c7 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -193,7 +193,7 @@ static int omap_kp_probe(struct platform_device *pdev)
row_shift = get_count_order(pdata->cols);
keycodemax = pdata->rows << row_shift;
- omap_kp = kzalloc(struct_size(omap_kp, keymap, keycodemax), GFP_KERNEL);
+ omap_kp = kzalloc_flex(*omap_kp, keymap, keycodemax);
input_dev = input_allocate_device();
if (!omap_kp || !input_dev) {
kfree(omap_kp);
diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c
index bce8157d1871..f9f480c91032 100644
--- a/drivers/input/keyboard/qt1050.c
+++ b/drivers/input/keyboard/qt1050.c
@@ -435,8 +435,7 @@ static int qt1050_probe(struct i2c_client *client)
int err;
/* Check basic functionality */
- err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
- if (!err) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "%s adapter not supported\n",
dev_driver_string(&client->adapter->dev));
return -ENODEV;
diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c
index b3db2c7d0957..b255b997e279 100644
--- a/drivers/input/keyboard/qt1070.c
+++ b/drivers/input/keyboard/qt1070.c
@@ -133,8 +133,7 @@ static int qt1070_probe(struct i2c_client *client)
int i;
int err;
- err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
- if (!err) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "%s adapter not supported\n",
dev_driver_string(&client->adapter->dev));
return -ENODEV;
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 159f41eedd41..6937f3576c05 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -184,7 +184,7 @@ static int sh_keysc_probe(struct platform_device *pdev)
if (irq < 0)
goto err0;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
if (priv == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
error = -ENOMEM;
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c
index 7ef0b3f4f549..eade05542ed6 100644
--- a/drivers/input/keyboard/stowaway.c
+++ b/drivers/input/keyboard/stowaway.c
@@ -72,7 +72,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- skbd = kzalloc(sizeof(*skbd), GFP_KERNEL);
+ skbd = kzalloc_obj(*skbd);
input_dev = input_allocate_device();
if (!skbd || !input_dev)
goto fail1;
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 3299e1919b37..5a0020827047 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -262,7 +262,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- sunkbd = kzalloc(sizeof(*sunkbd), GFP_KERNEL);
+ sunkbd = kzalloc_obj(*sunkbd);
input_dev = input_allocate_device();
if (!sunkbd || !input_dev)
goto fail1;
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
index befa713268ae..c0b4978a8cd5 100644
--- a/drivers/input/keyboard/xtkbd.c
+++ b/drivers/input/keyboard/xtkbd.c
@@ -70,7 +70,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
int err = -ENOMEM;
int i;
- xtkbd = kmalloc(sizeof(*xtkbd), GFP_KERNEL);
+ xtkbd = kmalloc_obj(*xtkbd);
input_dev = input_allocate_device();
if (!xtkbd || !input_dev)
goto fail1;
diff --git a/drivers/input/misc/88pm80x_onkey.c b/drivers/input/misc/88pm80x_onkey.c
index 9159b5fec129..fee28e537898 100644
--- a/drivers/input/misc/88pm80x_onkey.c
+++ b/drivers/input/misc/88pm80x_onkey.c
@@ -57,7 +57,7 @@ static int pm80x_onkey_probe(struct platform_device *pdev)
struct pm80x_onkey_info *info;
int err;
- info = kzalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc_obj(*info);
if (!info)
return -ENOMEM;
diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
index c05d898898e8..5ea0ce42a507 100644
--- a/drivers/input/misc/adxl34x-i2c.c
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -77,11 +77,8 @@ static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
static int adxl34x_i2c_probe(struct i2c_client *client)
{
struct adxl34x *ac;
- int error;
- error = i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_BYTE_DATA);
- if (!error) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
return -EIO;
}
diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c
index 5fa1c9438a85..bb1544d63c51 100644
--- a/drivers/input/misc/arizona-haptics.c
+++ b/drivers/input/misc/arizona-haptics.c
@@ -34,8 +34,6 @@ static void arizona_haptics_work(struct work_struct *work)
struct arizona_haptics,
work);
struct arizona *arizona = haptics->arizona;
- struct snd_soc_component *component =
- snd_soc_dapm_to_component(arizona->dapm);
int ret;
if (!haptics->arizona->dapm) {
@@ -65,7 +63,7 @@ static void arizona_haptics_work(struct work_struct *work)
return;
}
- ret = snd_soc_component_enable_pin(component, "HAPTICS");
+ ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS");
if (ret != 0) {
dev_err(arizona->dev, "Failed to start HAPTICS: %d\n",
ret);
@@ -80,7 +78,7 @@ static void arizona_haptics_work(struct work_struct *work)
}
} else {
/* This disable sequence will be a noop if already enabled */
- ret = snd_soc_component_disable_pin(component, "HAPTICS");
+ ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS");
if (ret != 0) {
dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n",
ret);
@@ -139,14 +137,12 @@ static int arizona_haptics_play(struct input_dev *input, void *data,
static void arizona_haptics_close(struct input_dev *input)
{
struct arizona_haptics *haptics = input_get_drvdata(input);
- struct snd_soc_component *component;
+ struct snd_soc_dapm_context *dapm = haptics->arizona->dapm;
cancel_work_sync(&haptics->work);
- if (haptics->arizona->dapm) {
- component = snd_soc_dapm_to_component(haptics->arizona->dapm);
- snd_soc_component_disable_pin(component, "HAPTICS");
- }
+ if (dapm)
+ snd_soc_dapm_disable_pin(dapm, "HAPTICS");
}
static int arizona_haptics_probe(struct platform_device *pdev)
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index e84649af801d..8db2dca84975 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -772,7 +772,7 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
if (alt->desc.bInterfaceNumber)
return -ENODEV;
- ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL);
+ ar2 = kzalloc_obj(struct ati_remote2);
if (!ar2)
return -ENOMEM;
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 5b9be2957746..47b31725e850 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -14,6 +14,7 @@
#include <linux/input.h>
#include <linux/types.h>
#include <linux/acpi.h>
+#include <linux/platform_device.h>
#include <linux/uaccess.h>
#define ACPI_ATLAS_NAME "Atlas ACPI"
@@ -57,8 +58,9 @@ static acpi_status acpi_atlas_button_handler(u32 function,
return status;
}
-static int atlas_acpi_button_add(struct acpi_device *device)
+static int atlas_acpi_button_probe(struct platform_device *pdev)
{
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
acpi_status status;
int i;
int err;
@@ -106,8 +108,9 @@ static int atlas_acpi_button_add(struct acpi_device *device)
return err;
}
-static void atlas_acpi_button_remove(struct acpi_device *device)
+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,
@@ -124,16 +127,15 @@ static const struct acpi_device_id atlas_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, atlas_device_ids);
-static struct acpi_driver atlas_acpi_driver = {
- .name = ACPI_ATLAS_NAME,
- .class = ACPI_ATLAS_CLASS,
- .ids = atlas_device_ids,
- .ops = {
- .add = atlas_acpi_button_add,
- .remove = atlas_acpi_button_remove,
+static struct platform_driver atlas_acpi_driver = {
+ .probe = atlas_acpi_button_probe,
+ .remove = atlas_acpi_button_remove,
+ .driver = {
+ .name = ACPI_ATLAS_NAME,
+ .acpi_match_table = atlas_device_ids,
},
};
-module_acpi_driver(atlas_acpi_driver);
+module_platform_driver(atlas_acpi_driver);
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/aw86927.c b/drivers/input/misc/aw86927.c
index 8ad361239cfe..f53b8f004cb3 100644
--- a/drivers/input/misc/aw86927.c
+++ b/drivers/input/misc/aw86927.c
@@ -43,6 +43,12 @@
#define AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK GENMASK(6, 0)
#define AW86927_PLAYCFG1_BST_8500MV 0x50
+#define AW86938_PLAYCFG1_REG 0x06
+#define AW86938_PLAYCFG1_BST_MODE_MASK GENMASK(5, 5)
+#define AW86938_PLAYCFG1_BST_MODE_BYPASS 0
+#define AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK GENMASK(4, 0)
+#define AW86938_PLAYCFG1_BST_7000MV 0x11
+
#define AW86927_PLAYCFG2_REG 0x07
#define AW86927_PLAYCFG3_REG 0x08
@@ -140,6 +146,7 @@
#define AW86927_CHIPIDH_REG 0x57
#define AW86927_CHIPIDL_REG 0x58
#define AW86927_CHIPID 0x9270
+#define AW86938_CHIPID 0x9380
#define AW86927_TMCFG_REG 0x5b
#define AW86927_TMCFG_UNLOCK 0x7d
@@ -173,14 +180,20 @@ enum aw86927_work_mode {
AW86927_RAM_MODE,
};
+enum aw86927_model {
+ AW86927,
+ AW86938,
+};
+
struct aw86927_data {
+ enum aw86927_model model;
struct work_struct play_work;
struct device *dev;
struct input_dev *input_dev;
struct i2c_client *client;
struct regmap *regmap;
struct gpio_desc *reset_gpio;
- bool running;
+ u16 level;
};
static const struct regmap_config aw86927_regmap_config = {
@@ -325,11 +338,12 @@ static int aw86927_haptics_play(struct input_dev *dev, void *data, struct ff_eff
if (!level)
level = effect->u.rumble.weak_magnitude;
- /* If already running, don't restart playback */
- if (haptics->running && level)
+ /* If level does not change, don't restart playback */
+ if (haptics->level == level)
return 0;
- haptics->running = level;
+ haptics->level = level;
+
schedule_work(&haptics->play_work);
return 0;
@@ -376,8 +390,7 @@ static int aw86927_play_sine(struct aw86927_data *haptics)
if (err)
return err;
- /* set gain to value lower than 0x80 to avoid distorted playback */
- err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x7c);
+ err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, haptics->level * 0x80 / 0xffff);
if (err)
return err;
@@ -409,7 +422,7 @@ static void aw86927_haptics_play_work(struct work_struct *work)
struct device *dev = &haptics->client->dev;
int err;
- if (haptics->running)
+ if (haptics->level)
err = aw86927_play_sine(haptics);
else
err = aw86927_stop(haptics);
@@ -565,13 +578,26 @@ static int aw86927_haptic_init(struct aw86927_data *haptics)
if (err)
return err;
- err = regmap_update_bits(haptics->regmap,
- AW86927_PLAYCFG1_REG,
- AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
- FIELD_PREP(AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
- AW86927_PLAYCFG1_BST_8500MV));
- if (err)
- return err;
+ switch (haptics->model) {
+ case AW86927:
+ err = regmap_update_bits(haptics->regmap,
+ AW86927_PLAYCFG1_REG,
+ AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ FIELD_PREP(AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ AW86927_PLAYCFG1_BST_8500MV));
+ if (err)
+ return err;
+ break;
+ case AW86938:
+ err = regmap_update_bits(haptics->regmap,
+ AW86938_PLAYCFG1_REG,
+ AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ FIELD_PREP(AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+ AW86938_PLAYCFG1_BST_7000MV));
+ if (err)
+ return err;
+ break;
+ }
err = regmap_update_bits(haptics->regmap,
AW86927_PLAYCFG3_REG,
@@ -599,6 +625,9 @@ static int aw86927_ram_init(struct aw86927_data *haptics)
FIELD_PREP(AW86927_SYSCTRL3_EN_RAMINIT_MASK,
AW86927_SYSCTRL3_EN_RAMINIT_ON));
+ /* AW86938 wants a 1ms delay here */
+ usleep_range(1000, 1500);
+
/* Set base address for the start of the SRAM waveforms */
err = regmap_write(haptics->regmap,
AW86927_BASEADDRH_REG, AW86927_BASEADDRH_VAL);
@@ -717,7 +746,14 @@ static int aw86927_detect(struct aw86927_data *haptics)
chip_id = be16_to_cpu(read_buf);
- if (chip_id != AW86927_CHIPID) {
+ switch (chip_id) {
+ case AW86927_CHIPID:
+ haptics->model = AW86927;
+ break;
+ case AW86938_CHIPID:
+ haptics->model = AW86938;
+ break;
+ default:
dev_err(haptics->dev, "Unexpected CHIPID value 0x%x\n", chip_id);
return -ENODEV;
}
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
index 0cfe5d4a573c..353d3c1d347d 100644
--- a/drivers/input/misc/cm109.c
+++ b/drivers/input/misc/cm109.c
@@ -696,7 +696,7 @@ static int cm109_usb_probe(struct usb_interface *intf,
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc_obj(*dev);
if (!dev)
return -ENOMEM;
@@ -721,7 +721,7 @@ static int cm109_usb_probe(struct usb_interface *intf,
if (!dev->ctl_data)
goto err_out;
- dev->ctl_req = kmalloc(sizeof(*(dev->ctl_req)), GFP_KERNEL);
+ dev->ctl_req = kmalloc_obj(*(dev->ctl_req));
if (!dev->ctl_req)
goto err_out;
diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c
index b4232b0a3957..a641453188d9 100644
--- a/drivers/input/misc/cma3000_d0x.c
+++ b/drivers/input/misc/cma3000_d0x.c
@@ -285,7 +285,7 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
goto err_out;
}
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ data = kzalloc_obj(*data);
input_dev = input_allocate_device();
if (!data || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/misc/cs40l50-vibra.c b/drivers/input/misc/cs40l50-vibra.c
index 90410025bbae..996d6c38cca4 100644
--- a/drivers/input/misc/cs40l50-vibra.c
+++ b/drivers/input/misc/cs40l50-vibra.c
@@ -276,7 +276,7 @@ static void cs40l50_add_worker(struct work_struct *work)
/* Update effect if already uploaded, otherwise create new effect */
effect = cs40l50_find_effect(work_data->effect->id, &vib->effect_head);
if (!effect) {
- effect = kzalloc(sizeof(*effect), GFP_KERNEL);
+ effect = kzalloc_obj(*effect);
if (!effect) {
error = -ENOMEM;
goto err_pm;
@@ -392,7 +392,7 @@ static int cs40l50_playback(struct input_dev *dev, int effect_id, int val)
struct cs40l50_vibra *vib = input_get_drvdata(dev);
struct cs40l50_work *work_data;
- work_data = kzalloc(sizeof(*work_data), GFP_ATOMIC);
+ work_data = kzalloc_obj(*work_data, GFP_ATOMIC);
if (!work_data)
return -ENOMEM;
diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c
index cc23625019e3..180b3bc76525 100644
--- a/drivers/input/misc/da9052_onkey.c
+++ b/drivers/input/misc/da9052_onkey.c
@@ -80,7 +80,7 @@ static int da9052_onkey_probe(struct platform_device *pdev)
return -EINVAL;
}
- onkey = kzalloc(sizeof(*onkey), GFP_KERNEL);
+ onkey = kzalloc_obj(*onkey);
input_dev = input_allocate_device();
if (!onkey || !input_dev) {
dev_err(&pdev->dev, "Failed to allocate memory\n");
diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
index 96cd6a078c8a..e2089d6ac850 100644
--- a/drivers/input/misc/drv260x.c
+++ b/drivers/input/misc/drv260x.c
@@ -7,14 +7,16 @@
* Copyright: (C) 2014 Texas Instruments, Inc.
*/
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/device/devres.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/regmap.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <dt-bindings/input/ti-drv260x.h>
@@ -165,6 +167,12 @@
#define DRV260X_AUTOCAL_TIME_500MS (2 << 4)
#define DRV260X_AUTOCAL_TIME_1000MS (3 << 4)
+/*
+ * Timeout for waiting for the GO status bit, in seconds. Should be reasonably
+ * large to wait for a auto-calibration cycle completion.
+ */
+#define DRV260X_GO_TIMEOUT_S 5
+
/**
* struct drv260x_data -
* @input_dev: Pointer to the input device
@@ -308,6 +316,7 @@ static int drv260x_init(struct drv260x_data *haptics)
{
int error;
unsigned int cal_buf;
+ unsigned long timeout;
error = regmap_write(haptics->regmap,
DRV260X_RATED_VOLT, haptics->rated_voltage);
@@ -397,6 +406,7 @@ static int drv260x_init(struct drv260x_data *haptics)
return error;
}
+ timeout = jiffies + DRV260X_GO_TIMEOUT_S * HZ;
do {
usleep_range(15000, 15500);
error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf);
@@ -406,6 +416,11 @@ static int drv260x_init(struct drv260x_data *haptics)
error);
return error;
}
+ if (time_after(jiffies, timeout)) {
+ dev_err(&haptics->client->dev,
+ "Calibration timeout. The device cannot be used.\n");
+ return -ETIMEDOUT;
+ }
} while (cal_buf == DRV260X_GO_BIT);
return 0;
@@ -419,6 +434,13 @@ static const struct regmap_config drv260x_regmap_config = {
.cache_type = REGCACHE_NONE,
};
+static void drv260x_power_off(void *data)
+{
+ struct drv260x_data *haptics = data;
+
+ regulator_disable(haptics->regulator);
+}
+
static int drv260x_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
@@ -484,6 +506,16 @@ static int drv260x_probe(struct i2c_client *client)
return error;
}
+ error = regulator_enable(haptics->regulator);
+ if (error) {
+ dev_err(dev, "Failed to enable regulator: %d\n", error);
+ return error;
+ }
+
+ error = devm_add_action_or_reset(dev, drv260x_power_off, haptics);
+ if (error)
+ return error;
+
haptics->enable_gpio = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_HIGH);
if (IS_ERR(haptics->enable_gpio))
@@ -598,11 +630,22 @@ 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" },
{ }
};
MODULE_DEVICE_TABLE(i2c, drv260x_id);
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id drv260x_acpi_match[] = {
+ { "DRV2604" },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, drv260x_acpi_match);
+#endif
+
static const struct of_device_id drv260x_of_match[] = {
{ .compatible = "ti,drv2604", },
{ .compatible = "ti,drv2604l", },
@@ -616,6 +659,7 @@ static struct i2c_driver drv260x_driver = {
.probe = drv260x_probe,
.driver = {
.name = "drv260x-haptics",
+ .acpi_match_table = ACPI_PTR(drv260x_acpi_match),
.of_match_table = drv260x_of_match,
.pm = pm_sleep_ptr(&drv260x_pm_ops),
},
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 4581f1c53644..4c022a36dbe8 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -286,7 +286,7 @@ static int ims_pcu_setup_gamepad(struct ims_pcu *pcu)
struct input_dev *input;
int error;
- gamepad = kzalloc(sizeof(*gamepad), GFP_KERNEL);
+ gamepad = kzalloc_obj(*gamepad);
input = input_allocate_device();
if (!gamepad || !input) {
dev_err(pcu->dev,
@@ -438,6 +438,14 @@ 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_dle = false;
+ pcu->read_pos = 0;
+ pcu->check_sum = 0;
+}
+
static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
{
int i;
@@ -450,6 +458,14 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
continue;
if (pcu->have_dle) {
+ if (pcu->read_pos >= IMS_PCU_BUF_SIZE) {
+ dev_warn(pcu->dev,
+ "Packet too long (%d bytes), discarding\n",
+ pcu->read_pos);
+ ims_pcu_reset_packet(pcu);
+ continue;
+ }
+
pcu->have_dle = false;
pcu->read_buf[pcu->read_pos++] = data;
pcu->check_sum += data;
@@ -462,10 +478,8 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
dev_warn(pcu->dev,
"Unexpected STX at byte %d, discarding old data\n",
pcu->read_pos);
+ ims_pcu_reset_packet(pcu);
pcu->have_stx = true;
- pcu->have_dle = false;
- pcu->read_pos = 0;
- pcu->check_sum = 0;
break;
case IMS_PCU_PROTOCOL_DLE:
@@ -485,12 +499,18 @@ static void ims_pcu_process_data(struct ims_pcu *pcu, struct urb *urb)
ims_pcu_handle_response(pcu);
}
- pcu->have_stx = false;
- pcu->have_dle = false;
- pcu->read_pos = 0;
+ ims_pcu_reset_packet(pcu);
break;
default:
+ if (pcu->read_pos >= IMS_PCU_BUF_SIZE) {
+ dev_warn(pcu->dev,
+ "Packet too long (%d bytes), discarding\n",
+ pcu->read_pos);
+ ims_pcu_reset_packet(pcu);
+ continue;
+ }
+
pcu->read_buf[pcu->read_pos++] = data;
pcu->check_sum += data;
break;
@@ -1991,7 +2011,7 @@ static int ims_pcu_probe(struct usb_interface *intf,
struct ims_pcu *pcu;
int error;
- pcu = kzalloc(sizeof(*pcu), GFP_KERNEL);
+ pcu = kzalloc_obj(*pcu);
if (!pcu)
return -ENOMEM;
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index bee4b1376491..70cd6586459e 100644
--- a/drivers/input/misc/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
@@ -420,24 +420,6 @@ static void keyspan_close(struct input_dev *dev)
usb_kill_urb(remote->irq_urb);
}
-static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface)
-{
-
- struct usb_endpoint_descriptor *endpoint;
- int i;
-
- for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
- endpoint = &iface->endpoint[i].desc;
-
- if (usb_endpoint_is_int_in(endpoint)) {
- /* we found our interrupt in endpoint */
- return endpoint;
- }
- }
-
- return NULL;
-}
-
/*
* Routine that sets up the driver to handle a specific USB device detected on the bus.
*/
@@ -449,11 +431,11 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
struct input_dev *input_dev;
int i, error;
- endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
- if (!endpoint)
+ error = usb_find_int_in_endpoint(interface->cur_altsetting, &endpoint);
+ if (error)
return -ENODEV;
- remote = kzalloc(sizeof(*remote), GFP_KERNEL);
+ remote = kzalloc_obj(*remote);
input_dev = input_allocate_device();
if (!remote || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c
index d5e051a25a74..975c3ba023f5 100644
--- a/drivers/input/misc/max8997_haptic.c
+++ b/drivers/input/misc/max8997_haptic.c
@@ -247,7 +247,7 @@ static int max8997_haptic_probe(struct platform_device *pdev)
return -EINVAL;
}
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
input_dev = input_allocate_device();
if (!chip || !input_dev) {
dev_err(&pdev->dev, "unable to allocate memory\n");
diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c
index b83d762ae2e9..cb781ce967ca 100644
--- a/drivers/input/misc/mc13783-pwrbutton.c
+++ b/drivers/input/misc/mc13783-pwrbutton.c
@@ -108,7 +108,7 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev)
return -ENOMEM;
}
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
if (!priv) {
err = -ENOMEM;
dev_dbg(&pdev->dev, "Can't allocate power button\n");
diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c
index d9c5aae143dc..f22083f44d91 100644
--- a/drivers/input/misc/palmas-pwrbutton.c
+++ b/drivers/input/misc/palmas-pwrbutton.c
@@ -164,7 +164,7 @@ static int palmas_pwron_probe(struct platform_device *pdev)
palmas_pwron_params_ofinit(dev, &config);
- pwron = kzalloc(sizeof(*pwron), GFP_KERNEL);
+ pwron = kzalloc_obj(*pwron);
if (!pwron)
return -ENOMEM;
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c
index fe43fd72ba7b..b19899b50d0b 100644
--- a/drivers/input/misc/pcap_keys.c
+++ b/drivers/input/misc/pcap_keys.c
@@ -49,7 +49,7 @@ static int pcap_keys_probe(struct platform_device *pdev)
struct pcap_keys *pcap_keys;
struct input_dev *input_dev;
- pcap_keys = kmalloc(sizeof(*pcap_keys), GFP_KERNEL);
+ pcap_keys = kmalloc_obj(*pcap_keys);
if (!pcap_keys)
return err;
diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c
index 3632cb206e34..14fc6c6cf699 100644
--- a/drivers/input/misc/pcf8574_keypad.c
+++ b/drivers/input/misc/pcf8574_keypad.c
@@ -91,7 +91,7 @@ static int pcf8574_kp_probe(struct i2c_client *client)
return -ENODEV;
}
- lp = kzalloc(sizeof(*lp), GFP_KERNEL);
+ lp = kzalloc_obj(*lp);
if (!lp)
return -ENOMEM;
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index ecb92ee5ebbc..754379d2625c 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -275,7 +275,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev
if (!pm->data)
return -1;
- pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL);
+ pm->configcr = kmalloc_obj(*(pm->configcr));
if (!pm->configcr)
return -ENOMEM;
@@ -313,7 +313,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
0, interface->desc.bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT);
- pm = kzalloc(sizeof(*pm), GFP_KERNEL);
+ pm = kzalloc_obj(*pm);
input_dev = input_allocate_device();
if (!pm || !input_dev)
goto fail1;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 0e9544a98e67..d32fa4b508fc 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -399,7 +399,7 @@ static int uinput_open(struct inode *inode, struct file *file)
{
struct uinput_device *newdev;
- newdev = kzalloc(sizeof(*newdev), GFP_KERNEL);
+ newdev = kzalloc_obj(*newdev);
if (!newdev)
return -ENOMEM;
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 67f1c7364c95..6471d836f6fe 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -205,7 +205,7 @@ static int xenkbd_probe(struct xenbus_device *dev,
struct xenkbd_info *info;
struct input_dev *kbd, *ptr, *mtouch;
- info = kzalloc(sizeof(*info), GFP_KERNEL);
+ info = kzalloc_obj(*info);
if (!info) {
xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
return -ENOMEM;
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index 08dc53ae1b3c..8786ed8b3565 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -831,7 +831,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
- yld = kzalloc(sizeof(*yld), GFP_KERNEL);
+ yld = kzalloc_obj(*yld);
if (!yld)
return -ENOMEM;
@@ -854,7 +854,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (!yld->ctl_data)
return usb_cleanup(yld, -ENOMEM);
- yld->ctl_req = kmalloc(sizeof(*(yld->ctl_req)), GFP_KERNEL);
+ yld->ctl_req = kmalloc_obj(*(yld->ctl_req));
if (yld->ctl_req == NULL)
return usb_cleanup(yld, -ENOMEM);
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 833b643f0616..04d56f40ecb6 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -164,16 +164,6 @@ config MOUSE_PS2_TOUCHKIT
If unsure, say N.
-config MOUSE_PS2_OLPC
- bool "OLPC PS/2 mouse protocol extension"
- depends on MOUSE_PS2 && OLPC
- help
- Say Y here if you have an OLPC XO-1 laptop (with built-in
- PS/2 touchpad/tablet device). The manufacturer calls the
- touchpad an HGPK.
-
- If unsure, say N.
-
config MOUSE_PS2_FOCALTECH
bool "FocalTech PS/2 mouse protocol extension" if EXPERT
default y
@@ -300,32 +290,6 @@ config MOUSE_ELAN_I2C_SMBUS
If unsure, say Y.
-config MOUSE_INPORT
- tristate "InPort/MS/ATIXL busmouse"
- depends on ISA
- help
- Say Y here if you have an InPort, Microsoft or ATI XL busmouse.
- They are rather rare these days.
-
- To compile this driver as a module, choose M here: the
- module will be called inport.
-
-config MOUSE_ATIXL
- bool "ATI XL variant"
- depends on MOUSE_INPORT
- help
- Say Y here if your mouse is of the ATI XL variety.
-
-config MOUSE_LOGIBM
- tristate "Logitech busmouse"
- depends on ISA
- help
- Say Y here if you have a Logitech busmouse.
- They are rather rare these days.
-
- To compile this driver as a module, choose M here: the
- module will be called logibm.
-
config MOUSE_PC110PAD
tristate "IBM PC110 touchpad"
depends on ISA
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index a1336d5bee6f..16d1cdf3182f 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -12,8 +12,6 @@ obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o
obj-$(CONFIG_MOUSE_CYAPA) += cyapatp.o
obj-$(CONFIG_MOUSE_ELAN_I2C) += elan_i2c.o
obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
-obj-$(CONFIG_MOUSE_INPORT) += inport.o
-obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o
obj-$(CONFIG_MOUSE_MAPLE) += maplemouse.o
obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
obj-$(CONFIG_MOUSE_PS2) += psmouse.o
@@ -29,7 +27,6 @@ psmouse-objs := psmouse-base.o synaptics.o focaltech.o
psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
psmouse-$(CONFIG_MOUSE_PS2_BYD) += byd.o
psmouse-$(CONFIG_MOUSE_PS2_ELANTECH) += elantech.o
-psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_SENTELIC) += sentelic.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index df8953a5196e..0ee1a30b9aaf 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -12,6 +12,7 @@
* tpconfig utility (by C. Scott Ananian and Bruce Kall).
*/
+#include "linux/workqueue.h"
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input/mt.h>
@@ -1452,7 +1453,7 @@ err_free_input:
static void alps_register_bare_ps2_mouse(struct work_struct *work)
{
struct alps_data *priv = container_of(work, struct alps_data,
- dev3_register_work.work);
+ dev3_register_work);
int error;
guard(mutex)(&alps_mutex);
@@ -1485,8 +1486,7 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
} else if (unlikely(IS_ERR_OR_NULL(priv->dev3))) {
/* Register dev3 mouse if we received PS/2 packet first time */
if (!IS_ERR(priv->dev3))
- psmouse_queue_work(psmouse, &priv->dev3_register_work,
- 0);
+ schedule_work(&priv->dev3_register_work);
return;
} else {
dev = priv->dev3;
@@ -2975,7 +2975,7 @@ static void alps_disconnect(struct psmouse *psmouse)
psmouse_reset(psmouse);
timer_shutdown_sync(&priv->timer);
- disable_delayed_work_sync(&priv->dev3_register_work);
+ disable_work_sync(&priv->dev3_register_work);
if (priv->dev2)
input_unregister_device(priv->dev2);
if (!IS_ERR_OR_NULL(priv->dev3))
@@ -3147,8 +3147,7 @@ int alps_init(struct psmouse *psmouse)
priv->psmouse = psmouse;
- INIT_DELAYED_WORK(&priv->dev3_register_work,
- alps_register_bare_ps2_mouse);
+ INIT_WORK(&priv->dev3_register_work, alps_register_bare_ps2_mouse);
psmouse->protocol_handler = alps_process_byte;
psmouse->poll = alps_poll;
@@ -3206,7 +3205,7 @@ int alps_detect(struct psmouse *psmouse, bool set_properties)
*/
psmouse_reset(psmouse);
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
if (!priv)
return -ENOMEM;
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 0a1048cf23f6..17bbf6cdba55 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -257,7 +257,7 @@ struct alps_fields {
* @dev3: Generic PS/2 mouse (can be NULL, delayed registering).
* @phys2: Physical path for the trackstick device.
* @phys3: Physical path for the generic PS/2 mouse.
- * @dev3_register_work: Delayed work for registering PS/2 mouse.
+ * @dev3_register_work: A work instance for registering PS/2 mouse.
* @nibble_commands: Command mapping used for touchpad register accesses.
* @addr_command: Command used to tell the touchpad that a register address
* follows.
@@ -289,7 +289,7 @@ struct alps_data {
struct input_dev *dev3;
char phys2[32];
char phys3[32];
- struct delayed_work dev3_register_work;
+ struct work_struct dev3_register_work;
/* these are autodetected when the device is identified */
const struct alps_nibble_commands *nibble_commands;
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 3ce63fb35992..eebeb57515e1 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -829,30 +829,21 @@ static int atp_probe(struct usb_interface *iface,
struct atp *dev;
struct input_dev *input_dev;
struct usb_device *udev = interface_to_usbdev(iface);
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int int_in_endpointAddr = 0;
- int i, error = -ENOMEM;
+ struct usb_endpoint_descriptor *ep;
+ int error;
const struct atp_info *info = (const struct atp_info *)id->driver_info;
/* set up the endpoint information */
/* use only the first interrupt-in endpoint */
- iface_desc = iface->cur_altsetting;
- for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (!int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) {
- /* we found an interrupt in endpoint */
- int_in_endpointAddr = endpoint->bEndpointAddress;
- break;
- }
- }
- if (!int_in_endpointAddr) {
+ error = usb_find_int_in_endpoint(iface->cur_altsetting, &ep);
+ if (error) {
dev_err(&iface->dev, "Could not find int-in endpoint\n");
return -EIO;
}
/* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ error = -ENOMEM;
+ dev = kzalloc_obj(*dev);
input_dev = input_allocate_device();
if (!dev || !input_dev) {
dev_err(&iface->dev, "Out of memory\n");
@@ -875,7 +866,7 @@ static int atp_probe(struct usb_interface *iface,
goto err_free_urb;
usb_fill_int_urb(dev->urb, udev,
- usb_rcvintpipe(udev, int_in_endpointAddr),
+ usb_rcvintpipe(udev, usb_endpoint_num(ep)),
dev->data, dev->info->datalen,
dev->info->callback, dev, 1);
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index fe52f15c0c10..e772bac3b64c 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -933,7 +933,7 @@ static int bcm5974_probe(struct usb_interface *iface,
cfg = bcm5974_get_config(udev);
/* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc_obj(*dev);
input_dev = input_allocate_device();
if (!dev || !input_dev) {
dev_err(&iface->dev, "out of memory\n");
diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c
index 7f85c7ab68c5..f5770a3af2f1 100644
--- a/drivers/input/mouse/byd.c
+++ b/drivers/input/mouse/byd.c
@@ -469,7 +469,7 @@ int byd_init(struct psmouse *psmouse)
if (byd_reset_touchpad(psmouse))
return -EIO;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
if (!priv)
return -ENOMEM;
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c
index 9446657a5f35..309063d07b4d 100644
--- a/drivers/input/mouse/cypress_ps2.c
+++ b/drivers/input/mouse/cypress_ps2.c
@@ -624,7 +624,7 @@ int cypress_init(struct psmouse *psmouse)
struct cytp_data *cytp;
int error;
- cytp = kzalloc(sizeof(*cytp), GFP_KERNEL);
+ cytp = kzalloc_obj(*cytp);
if (!cytp)
return -ENOMEM;
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 79ad98cc1e79..f8575b80d19d 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -2074,7 +2074,7 @@ static int elantech_setup_ps2(struct psmouse *psmouse,
int error = -EINVAL;
struct input_dev *tp_dev;
- psmouse->private = etd = kzalloc(sizeof(*etd), GFP_KERNEL);
+ psmouse->private = etd = kzalloc_obj(*etd);
if (!etd)
return -ENOMEM;
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
index 356b99d48544..43f9939b7c63 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -408,7 +408,7 @@ int focaltech_init(struct psmouse *psmouse)
struct focaltech_data *priv;
int error;
- psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ psmouse->private = priv = kzalloc_obj(*priv);
if (!priv)
return -ENOMEM;
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
deleted file mode 100644
index 6125652e5ad8..000000000000
--- a/drivers/input/mouse/hgpk.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
- *
- * Copyright (c) 2006-2008 One Laptop Per Child
- * Authors:
- * Zephaniah E. Hull
- * Andres Salomon <dilinger@debian.org>
- *
- * This driver is partly based on the ALPS driver, which is:
- *
- * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
- * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
- * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
- * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
- */
-
-/*
- * The spec from ALPS is available from
- * <http://wiki.laptop.org/go/Touch_Pad/Tablet>. It refers to this
- * device as HGPK (Hybrid GS, PT, and Keymatrix).
- *
- * The earliest versions of the device had simultaneous reporting; that
- * was removed. After that, the device used the Advanced Mode GS/PT streaming
- * stuff. That turned out to be too buggy to support, so we've finally
- * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad).
- */
-
-#define DEBUG
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/serio.h>
-#include <linux/libps2.h>
-#include <linux/delay.h>
-#include <asm/olpc.h>
-
-#include "psmouse.h"
-#include "hgpk.h"
-
-#define ILLEGAL_XY 999999
-
-static bool tpdebug;
-module_param(tpdebug, bool, 0644);
-MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
-
-static int recalib_delta = 100;
-module_param(recalib_delta, int, 0644);
-MODULE_PARM_DESC(recalib_delta,
- "packets containing a delta this large will be discarded, and a "
- "recalibration may be scheduled.");
-
-static int jumpy_delay = 20;
-module_param(jumpy_delay, int, 0644);
-MODULE_PARM_DESC(jumpy_delay,
- "delay (ms) before recal after jumpiness detected");
-
-static int spew_delay = 1;
-module_param(spew_delay, int, 0644);
-MODULE_PARM_DESC(spew_delay,
- "delay (ms) before recal after packet spew detected");
-
-static int recal_guard_time;
-module_param(recal_guard_time, int, 0644);
-MODULE_PARM_DESC(recal_guard_time,
- "interval (ms) during which recal will be restarted if packet received");
-
-static int post_interrupt_delay = 40;
-module_param(post_interrupt_delay, int, 0644);
-MODULE_PARM_DESC(post_interrupt_delay,
- "delay (ms) before recal after recal interrupt detected");
-
-static bool autorecal = true;
-module_param(autorecal, bool, 0644);
-MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
-
-static char hgpk_mode_name[16];
-module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644);
-MODULE_PARM_DESC(hgpk_mode,
- "default hgpk mode: mouse, glidesensor or pentablet");
-
-static int hgpk_default_mode = HGPK_MODE_MOUSE;
-
-static const char * const hgpk_mode_names[] = {
- [HGPK_MODE_MOUSE] = "Mouse",
- [HGPK_MODE_GLIDESENSOR] = "GlideSensor",
- [HGPK_MODE_PENTABLET] = "PenTablet",
-};
-
-static int hgpk_mode_from_name(const char *buf, int len)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) {
- const char *name = hgpk_mode_names[i];
- if (strlen(name) == len && !strncasecmp(name, buf, len))
- return i;
- }
-
- return HGPK_MODE_INVALID;
-}
-
-/*
- * see if new value is within 20% of half of old value
- */
-static int approx_half(int curr, int prev)
-{
- int belowhalf, abovehalf;
-
- if (curr < 5 || prev < 5)
- return 0;
-
- belowhalf = (prev * 8) / 20;
- abovehalf = (prev * 12) / 20;
-
- return belowhalf < curr && curr <= abovehalf;
-}
-
-/*
- * Throw out oddly large delta packets, and any that immediately follow whose
- * values are each approximately half of the previous. It seems that the ALPS
- * firmware emits errant packets, and they get averaged out slowly.
- */
-static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
-{
- struct hgpk_data *priv = psmouse->private;
- int avx, avy;
- bool do_recal = false;
-
- avx = abs(x);
- avy = abs(y);
-
- /* discard if too big, or half that but > 4 times the prev delta */
- if (avx > recalib_delta ||
- (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {
- psmouse_warn(psmouse, "detected %dpx jump in x\n", x);
- priv->xbigj = avx;
- } else if (approx_half(avx, priv->xbigj)) {
- psmouse_warn(psmouse, "detected secondary %dpx jump in x\n", x);
- priv->xbigj = avx;
- priv->xsaw_secondary++;
- } else {
- if (priv->xbigj && priv->xsaw_secondary > 1)
- do_recal = true;
- priv->xbigj = 0;
- priv->xsaw_secondary = 0;
- }
-
- if (avy > recalib_delta ||
- (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {
- psmouse_warn(psmouse, "detected %dpx jump in y\n", y);
- priv->ybigj = avy;
- } else if (approx_half(avy, priv->ybigj)) {
- psmouse_warn(psmouse, "detected secondary %dpx jump in y\n", y);
- priv->ybigj = avy;
- priv->ysaw_secondary++;
- } else {
- if (priv->ybigj && priv->ysaw_secondary > 1)
- do_recal = true;
- priv->ybigj = 0;
- priv->ysaw_secondary = 0;
- }
-
- priv->xlast = avx;
- priv->ylast = avy;
-
- if (do_recal && jumpy_delay) {
- psmouse_warn(psmouse, "scheduling recalibration\n");
- psmouse_queue_work(psmouse, &priv->recalib_wq,
- msecs_to_jiffies(jumpy_delay));
- }
-
- return priv->xbigj || priv->ybigj;
-}
-
-static void hgpk_reset_spew_detection(struct hgpk_data *priv)
-{
- priv->spew_count = 0;
- priv->dupe_count = 0;
- priv->x_tally = 0;
- priv->y_tally = 0;
- priv->spew_flag = NO_SPEW;
-}
-
-static void hgpk_reset_hack_state(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
-
- priv->abs_x = priv->abs_y = -1;
- priv->xlast = priv->ylast = ILLEGAL_XY;
- priv->xbigj = priv->ybigj = 0;
- priv->xsaw_secondary = priv->ysaw_secondary = 0;
- hgpk_reset_spew_detection(priv);
-}
-
-/*
- * We have no idea why this particular hardware bug occurs. The touchpad
- * will randomly start spewing packets without anything touching the
- * pad. This wouldn't necessarily be bad, but it's indicative of a
- * severely miscalibrated pad; attempting to use the touchpad while it's
- * spewing means the cursor will jump all over the place, and act "drunk".
- *
- * The packets that are spewed tend to all have deltas between -2 and 2, and
- * the cursor will move around without really going very far. It will
- * tend to end up in the same location; if we tally up the changes over
- * 100 packets, we end up w/ a final delta of close to 0. This happens
- * pretty regularly when the touchpad is spewing, and is pretty hard to
- * manually trigger (at least for *my* fingers). So, it makes a perfect
- * scheme for detecting spews.
- */
-static void hgpk_spewing_hack(struct psmouse *psmouse,
- int l, int r, int x, int y)
-{
- struct hgpk_data *priv = psmouse->private;
-
- /* ignore button press packets; many in a row could trigger
- * a false-positive! */
- if (l || r)
- return;
-
- /* don't track spew if the workaround feature has been turned off */
- if (!spew_delay)
- return;
-
- if (abs(x) > 3 || abs(y) > 3) {
- /* no spew, or spew ended */
- hgpk_reset_spew_detection(priv);
- return;
- }
-
- /* Keep a tally of the overall delta to the cursor position caused by
- * the spew */
- priv->x_tally += x;
- priv->y_tally += y;
-
- switch (priv->spew_flag) {
- case NO_SPEW:
- /* we're not spewing, but this packet might be the start */
- priv->spew_flag = MAYBE_SPEWING;
-
- fallthrough;
-
- case MAYBE_SPEWING:
- priv->spew_count++;
-
- if (priv->spew_count < SPEW_WATCH_COUNT)
- break;
-
- /* excessive spew detected, request recalibration */
- priv->spew_flag = SPEW_DETECTED;
-
- fallthrough;
-
- case SPEW_DETECTED:
- /* only recalibrate when the overall delta to the cursor
- * is really small. if the spew is causing significant cursor
- * movement, it is probably a case of the user moving the
- * cursor very slowly across the screen. */
- if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
- psmouse_warn(psmouse, "packet spew detected (%d,%d)\n",
- priv->x_tally, priv->y_tally);
- priv->spew_flag = RECALIBRATING;
- psmouse_queue_work(psmouse, &priv->recalib_wq,
- msecs_to_jiffies(spew_delay));
- }
-
- break;
- case RECALIBRATING:
- /* we already detected a spew and requested a recalibration,
- * just wait for the queue to kick into action. */
- break;
- }
-}
-
-/*
- * HGPK Mouse Mode format (standard mouse format, sans middle button)
- *
- * byte 0: y-over x-over y-neg x-neg 1 0 swr swl
- * byte 1: x7 x6 x5 x4 x3 x2 x1 x0
- * byte 2: y7 y6 y5 y4 y3 y2 y1 y0
- *
- * swr/swl are the left/right buttons.
- * x-neg/y-neg are the x and y delta negative bits
- * x-over/y-over are the x and y overflow bits
- *
- * ---
- *
- * HGPK Advanced Mode - single-mode format
- *
- * byte 0(PT): 1 1 0 0 1 1 1 1
- * byte 0(GS): 1 1 1 1 1 1 1 1
- * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
- * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw 0
- * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw
- * byte 3: 0 y9 y8 y7 1 0 swr swl
- * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
- * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
- *
- * ?'s are not defined in the protocol spec, may vary between models.
- *
- * swr/swl are the left/right buttons.
- *
- * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a
- * pen/finger
- */
-static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)
-{
- struct hgpk_data *priv = psmouse->private;
- int pktcnt = psmouse->pktcnt;
- bool valid;
-
- switch (priv->mode) {
- case HGPK_MODE_MOUSE:
- valid = (packet[0] & 0x0C) == 0x08;
- break;
-
- case HGPK_MODE_GLIDESENSOR:
- valid = pktcnt == 1 ?
- packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80);
- break;
-
- case HGPK_MODE_PENTABLET:
- valid = pktcnt == 1 ?
- packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80);
- break;
-
- default:
- valid = false;
- break;
- }
-
- if (!valid)
- psmouse_dbg(psmouse,
- "bad data, mode %d (%d) %*ph\n",
- priv->mode, pktcnt, 6, psmouse->packet);
-
- return valid;
-}
-
-static void hgpk_process_advanced_packet(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
- struct input_dev *idev = psmouse->dev;
- unsigned char *packet = psmouse->packet;
- int down = !!(packet[2] & 2);
- int left = !!(packet[3] & 1);
- int right = !!(packet[3] & 2);
- int x = packet[1] | ((packet[2] & 0x78) << 4);
- int y = packet[4] | ((packet[3] & 0x70) << 3);
-
- if (priv->mode == HGPK_MODE_GLIDESENSOR) {
- int pt_down = !!(packet[2] & 1);
- int finger_down = !!(packet[2] & 2);
- int z = packet[5];
-
- input_report_abs(idev, ABS_PRESSURE, z);
- if (tpdebug)
- psmouse_dbg(psmouse, "pd=%d fd=%d z=%d",
- pt_down, finger_down, z);
- } else {
- /*
- * PenTablet mode does not report pressure, so we don't
- * report it here
- */
- if (tpdebug)
- psmouse_dbg(psmouse, "pd=%d ", down);
- }
-
- if (tpdebug)
- psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
- left, right, x, y);
-
- input_report_key(idev, BTN_TOUCH, down);
- input_report_key(idev, BTN_LEFT, left);
- input_report_key(idev, BTN_RIGHT, right);
-
- /*
- * If this packet says that the finger was removed, reset our position
- * tracking so that we don't erroneously detect a jump on next press.
- */
- if (!down) {
- hgpk_reset_hack_state(psmouse);
- goto done;
- }
-
- /*
- * Weed out duplicate packets (we get quite a few, and they mess up
- * our jump detection)
- */
- if (x == priv->abs_x && y == priv->abs_y) {
- if (++priv->dupe_count > SPEW_WATCH_COUNT) {
- if (tpdebug)
- psmouse_dbg(psmouse, "hard spew detected\n");
- priv->spew_flag = RECALIBRATING;
- psmouse_queue_work(psmouse, &priv->recalib_wq,
- msecs_to_jiffies(spew_delay));
- }
- goto done;
- }
-
- /* not a duplicate, continue with position reporting */
- priv->dupe_count = 0;
-
- /* Don't apply hacks in PT mode, it seems reliable */
- if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) {
- int x_diff = priv->abs_x - x;
- int y_diff = priv->abs_y - y;
- if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {
- if (tpdebug)
- psmouse_dbg(psmouse, "discarding\n");
- goto done;
- }
- hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);
- }
-
- input_report_abs(idev, ABS_X, x);
- input_report_abs(idev, ABS_Y, y);
- priv->abs_x = x;
- priv->abs_y = y;
-
-done:
- input_sync(idev);
-}
-
-static void hgpk_process_simple_packet(struct psmouse *psmouse)
-{
- struct input_dev *dev = psmouse->dev;
- unsigned char *packet = psmouse->packet;
- int left = packet[0] & 1;
- int right = (packet[0] >> 1) & 1;
- int x = packet[1] - ((packet[0] << 4) & 0x100);
- int y = ((packet[0] << 3) & 0x100) - packet[2];
-
- if (packet[0] & 0xc0)
- psmouse_dbg(psmouse,
- "overflow -- 0x%02x 0x%02x 0x%02x\n",
- packet[0], packet[1], packet[2]);
-
- if (hgpk_discard_decay_hack(psmouse, x, y)) {
- if (tpdebug)
- psmouse_dbg(psmouse, "discarding\n");
- return;
- }
-
- hgpk_spewing_hack(psmouse, left, right, x, y);
-
- if (tpdebug)
- psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
- left, right, x, y);
-
- input_report_key(dev, BTN_LEFT, left);
- input_report_key(dev, BTN_RIGHT, right);
-
- input_report_rel(dev, REL_X, x);
- input_report_rel(dev, REL_Y, y);
-
- input_sync(dev);
-}
-
-static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
-
- if (!hgpk_is_byte_valid(psmouse, psmouse->packet))
- return PSMOUSE_BAD_DATA;
-
- if (psmouse->pktcnt >= psmouse->pktsize) {
- if (priv->mode == HGPK_MODE_MOUSE)
- hgpk_process_simple_packet(psmouse);
- else
- hgpk_process_advanced_packet(psmouse);
- return PSMOUSE_FULL_PACKET;
- }
-
- if (priv->recalib_window) {
- if (time_before(jiffies, priv->recalib_window)) {
- /*
- * ugh, got a packet inside our recalibration
- * window, schedule another recalibration.
- */
- psmouse_dbg(psmouse,
- "packet inside calibration window, queueing another recalibration\n");
- psmouse_queue_work(psmouse, &priv->recalib_wq,
- msecs_to_jiffies(post_interrupt_delay));
- }
- priv->recalib_window = 0;
- }
-
- return PSMOUSE_GOOD_DATA;
-}
-
-static int hgpk_select_mode(struct psmouse *psmouse)
-{
- struct ps2dev *ps2dev = &psmouse->ps2dev;
- struct hgpk_data *priv = psmouse->private;
- int i;
- int cmd;
-
- /*
- * 4 disables to enable advanced mode
- * then 3 0xf2 bytes as the preamble for GS/PT selection
- */
- const int advanced_init[] = {
- PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
- PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
- 0xf2, 0xf2, 0xf2,
- };
-
- switch (priv->mode) {
- case HGPK_MODE_MOUSE:
- psmouse->pktsize = 3;
- break;
-
- case HGPK_MODE_GLIDESENSOR:
- case HGPK_MODE_PENTABLET:
- psmouse->pktsize = 6;
-
- /* Switch to 'Advanced mode.', four disables in a row. */
- for (i = 0; i < ARRAY_SIZE(advanced_init); i++)
- if (ps2_command(ps2dev, NULL, advanced_init[i]))
- return -EIO;
-
- /* select between GlideSensor (mouse) or PenTablet */
- cmd = priv->mode == HGPK_MODE_GLIDESENSOR ?
- PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21;
-
- if (ps2_command(ps2dev, NULL, cmd))
- return -EIO;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void hgpk_setup_input_device(struct input_dev *input,
- struct input_dev *old_input,
- enum hgpk_mode mode)
-{
- if (old_input) {
- input->name = old_input->name;
- input->phys = old_input->phys;
- input->id = old_input->id;
- input->dev.parent = old_input->dev.parent;
- }
-
- memset(input->evbit, 0, sizeof(input->evbit));
- memset(input->relbit, 0, sizeof(input->relbit));
- memset(input->keybit, 0, sizeof(input->keybit));
-
- /* All modes report left and right buttons */
- __set_bit(EV_KEY, input->evbit);
- __set_bit(BTN_LEFT, input->keybit);
- __set_bit(BTN_RIGHT, input->keybit);
-
- switch (mode) {
- case HGPK_MODE_MOUSE:
- __set_bit(EV_REL, input->evbit);
- __set_bit(REL_X, input->relbit);
- __set_bit(REL_Y, input->relbit);
- break;
-
- case HGPK_MODE_GLIDESENSOR:
- __set_bit(BTN_TOUCH, input->keybit);
- __set_bit(BTN_TOOL_FINGER, input->keybit);
-
- __set_bit(EV_ABS, input->evbit);
-
- /* GlideSensor has pressure sensor, PenTablet does not */
- input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0);
-
- /* From device specs */
- input_set_abs_params(input, ABS_X, 0, 399, 0, 0);
- input_set_abs_params(input, ABS_Y, 0, 290, 0, 0);
-
- /* Calculated by hand based on usable size (52mm x 38mm) */
- input_abs_set_res(input, ABS_X, 8);
- input_abs_set_res(input, ABS_Y, 8);
- break;
-
- case HGPK_MODE_PENTABLET:
- __set_bit(BTN_TOUCH, input->keybit);
- __set_bit(BTN_TOOL_FINGER, input->keybit);
-
- __set_bit(EV_ABS, input->evbit);
-
- /* From device specs */
- input_set_abs_params(input, ABS_X, 0, 999, 0, 0);
- input_set_abs_params(input, ABS_Y, 5, 239, 0, 0);
-
- /* Calculated by hand based on usable size (156mm x 38mm) */
- input_abs_set_res(input, ABS_X, 6);
- input_abs_set_res(input, ABS_Y, 8);
- break;
-
- default:
- BUG();
- }
-}
-
-static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)
-{
- int err;
-
- psmouse_reset(psmouse);
-
- if (recalibrate) {
- struct ps2dev *ps2dev = &psmouse->ps2dev;
-
- /* send the recalibrate request */
- if (ps2_command(ps2dev, NULL, 0xf5) ||
- ps2_command(ps2dev, NULL, 0xf5) ||
- ps2_command(ps2dev, NULL, 0xe6) ||
- ps2_command(ps2dev, NULL, 0xf5)) {
- return -1;
- }
-
- /* according to ALPS, 150mS is required for recalibration */
- msleep(150);
- }
-
- err = hgpk_select_mode(psmouse);
- if (err) {
- psmouse_err(psmouse, "failed to select mode\n");
- return err;
- }
-
- hgpk_reset_hack_state(psmouse);
-
- return 0;
-}
-
-static int hgpk_force_recalibrate(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
- int err;
-
- /* C-series touchpads added the recalibrate command */
- if (psmouse->model < HGPK_MODEL_C)
- return 0;
-
- if (!autorecal) {
- psmouse_dbg(psmouse, "recalibration disabled, ignoring\n");
- return 0;
- }
-
- psmouse_dbg(psmouse, "recalibrating touchpad..\n");
-
- /* we don't want to race with the irq handler, nor with resyncs */
- psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
-
- /* start by resetting the device */
- err = hgpk_reset_device(psmouse, true);
- if (err)
- return err;
-
- /*
- * XXX: If a finger is down during this delay, recalibration will
- * detect capacitance incorrectly. This is a hardware bug, and
- * we don't have a good way to deal with it. The 2s window stuff
- * (below) is our best option for now.
- */
- if (psmouse_activate(psmouse))
- return -1;
-
- if (tpdebug)
- psmouse_dbg(psmouse, "touchpad reactivated\n");
-
- /*
- * If we get packets right away after recalibrating, it's likely
- * that a finger was on the touchpad. If so, it's probably
- * miscalibrated, so we optionally schedule another.
- */
- if (recal_guard_time)
- priv->recalib_window = jiffies +
- msecs_to_jiffies(recal_guard_time);
-
- return 0;
-}
-
-/*
- * This puts the touchpad in a power saving mode; according to ALPS, current
- * consumption goes down to 50uA after running this. To turn power back on,
- * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that
- * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this.
- *
- * We have no formal spec that details this operation -- the low-power
- * sequence came from a long-lost email trail.
- */
-static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
-{
- struct ps2dev *ps2dev = &psmouse->ps2dev;
- int timeo;
- int err;
-
- /* Added on D-series touchpads */
- if (psmouse->model < HGPK_MODEL_D)
- return 0;
-
- if (enable) {
- psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
-
- /*
- * Sending a byte will drive MS-DAT low; this will wake up
- * the controller. Once we get an ACK back from it, it
- * means we can continue with the touchpad re-init. ALPS
- * tells us that 1s should be long enough, so set that as
- * the upper bound. (in practice, it takes about 3 loops.)
- */
- for (timeo = 20; timeo > 0; timeo--) {
- if (!ps2_sendbyte(ps2dev, PSMOUSE_CMD_DISABLE, 20))
- break;
- msleep(25);
- }
-
- err = hgpk_reset_device(psmouse, false);
- if (err) {
- psmouse_err(psmouse, "Failed to reset device!\n");
- return err;
- }
-
- /* should be all set, enable the touchpad */
- psmouse_activate(psmouse);
- psmouse_dbg(psmouse, "Touchpad powered up.\n");
- } else {
- psmouse_dbg(psmouse, "Powering off touchpad.\n");
-
- if (ps2_command(ps2dev, NULL, 0xec) ||
- ps2_command(ps2dev, NULL, 0xec) ||
- ps2_command(ps2dev, NULL, 0xea)) {
- return -1;
- }
-
- psmouse_set_state(psmouse, PSMOUSE_IGNORE);
-
- /* probably won't see an ACK, the touchpad will be off */
- ps2_sendbyte(ps2dev, 0xec, 20);
- }
-
- return 0;
-}
-
-static int hgpk_poll(struct psmouse *psmouse)
-{
- /* We can't poll, so always return failure. */
- return -1;
-}
-
-static int hgpk_reconnect(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
-
- /*
- * During suspend/resume the ps2 rails remain powered. We don't want
- * to do a reset because it's flush data out of buffers; however,
- * earlier prototypes (B1) had some brokenness that required a reset.
- */
- if (olpc_board_at_least(olpc_board(0xb2)))
- if (psmouse->ps2dev.serio->dev.power.power_state.event !=
- PM_EVENT_ON)
- return 0;
-
- priv->powered = 1;
- return hgpk_reset_device(psmouse, false);
-}
-
-static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
-{
- struct hgpk_data *priv = psmouse->private;
-
- return sprintf(buf, "%d\n", priv->powered);
-}
-
-static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
- const char *buf, size_t count)
-{
- struct hgpk_data *priv = psmouse->private;
- unsigned int value;
- int err;
-
- err = kstrtouint(buf, 10, &value);
- if (err)
- return err;
-
- if (value > 1)
- return -EINVAL;
-
- if (value != priv->powered) {
- /*
- * hgpk_toggle_power will deal w/ state so
- * we're not racing w/ irq
- */
- err = hgpk_toggle_powersave(psmouse, value);
- if (!err)
- priv->powered = value;
- }
-
- return err ? err : count;
-}
-
-__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
- hgpk_show_powered, hgpk_set_powered, false);
-
-static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf)
-{
- struct hgpk_data *priv = psmouse->private;
-
- return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]);
-}
-
-static ssize_t attr_set_mode(struct psmouse *psmouse, void *data,
- const char *buf, size_t len)
-{
- struct hgpk_data *priv = psmouse->private;
- enum hgpk_mode old_mode = priv->mode;
- enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len);
- struct input_dev *old_dev = psmouse->dev;
- struct input_dev *new_dev;
- int err;
-
- if (new_mode == HGPK_MODE_INVALID)
- return -EINVAL;
-
- if (old_mode == new_mode)
- return len;
-
- new_dev = input_allocate_device();
- if (!new_dev)
- return -ENOMEM;
-
- psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
-
- /* Switch device into the new mode */
- priv->mode = new_mode;
- err = hgpk_reset_device(psmouse, false);
- if (err)
- goto err_try_restore;
-
- hgpk_setup_input_device(new_dev, old_dev, new_mode);
-
- psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
-
- err = input_register_device(new_dev);
- if (err)
- goto err_try_restore;
-
- psmouse->dev = new_dev;
- input_unregister_device(old_dev);
-
- return len;
-
-err_try_restore:
- input_free_device(new_dev);
- priv->mode = old_mode;
- hgpk_reset_device(psmouse, false);
-
- return err;
-}
-
-PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL,
- attr_show_mode, attr_set_mode);
-
-static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
- void *data, char *buf)
-{
- return -EINVAL;
-}
-
-static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
- const char *buf, size_t count)
-{
- struct hgpk_data *priv = psmouse->private;
- unsigned int value;
- int err;
-
- err = kstrtouint(buf, 10, &value);
- if (err)
- return err;
-
- if (value != 1)
- return -EINVAL;
-
- /*
- * We queue work instead of doing recalibration right here
- * to avoid adding locking to hgpk_force_recalibrate()
- * since workqueue provides serialization.
- */
- psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
- return count;
-}
-
-__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
- hgpk_trigger_recal_show, hgpk_trigger_recal, false);
-
-static void hgpk_disconnect(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
-
- device_remove_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_powered.dattr);
- device_remove_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_hgpk_mode.dattr);
-
- if (psmouse->model >= HGPK_MODEL_C)
- device_remove_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_recalibrate.dattr);
-
- psmouse_reset(psmouse);
- kfree(priv);
-}
-
-static void hgpk_recalib_work(struct work_struct *work)
-{
- struct delayed_work *w = to_delayed_work(work);
- struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
- struct psmouse *psmouse = priv->psmouse;
-
- if (hgpk_force_recalibrate(psmouse))
- psmouse_err(psmouse, "recalibration failed!\n");
-}
-
-static int hgpk_register(struct psmouse *psmouse)
-{
- struct hgpk_data *priv = psmouse->private;
- int err;
-
- /* register handlers */
- psmouse->protocol_handler = hgpk_process_byte;
- psmouse->poll = hgpk_poll;
- psmouse->disconnect = hgpk_disconnect;
- psmouse->reconnect = hgpk_reconnect;
-
- /* Disable the idle resync. */
- psmouse->resync_time = 0;
- /* Reset after a lot of bad bytes. */
- psmouse->resetafter = 1024;
-
- hgpk_setup_input_device(psmouse->dev, NULL, priv->mode);
-
- err = device_create_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_powered.dattr);
- if (err) {
- psmouse_err(psmouse, "Failed creating 'powered' sysfs node\n");
- return err;
- }
-
- err = device_create_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_hgpk_mode.dattr);
- if (err) {
- psmouse_err(psmouse,
- "Failed creating 'hgpk_mode' sysfs node\n");
- goto err_remove_powered;
- }
-
- /* C-series touchpads added the recalibrate command */
- if (psmouse->model >= HGPK_MODEL_C) {
- err = device_create_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_recalibrate.dattr);
- if (err) {
- psmouse_err(psmouse,
- "Failed creating 'recalibrate' sysfs node\n");
- goto err_remove_mode;
- }
- }
-
- return 0;
-
-err_remove_mode:
- device_remove_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_hgpk_mode.dattr);
-err_remove_powered:
- device_remove_file(&psmouse->ps2dev.serio->dev,
- &psmouse_attr_powered.dattr);
- return err;
-}
-
-int hgpk_init(struct psmouse *psmouse)
-{
- struct hgpk_data *priv;
- int err;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- err = -ENOMEM;
- goto alloc_fail;
- }
-
- psmouse->private = priv;
-
- priv->psmouse = psmouse;
- priv->powered = true;
- priv->mode = hgpk_default_mode;
- INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
-
- err = hgpk_reset_device(psmouse, false);
- if (err)
- goto init_fail;
-
- err = hgpk_register(psmouse);
- if (err)
- goto init_fail;
-
- return 0;
-
-init_fail:
- kfree(priv);
-alloc_fail:
- return err;
-}
-
-static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
-{
- struct ps2dev *ps2dev = &psmouse->ps2dev;
- unsigned char param[3];
-
- /* E7, E7, E7, E9 gets us a 3 byte identifier */
- if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
- ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
- ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
- ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
- return -EIO;
- }
-
- psmouse_dbg(psmouse, "ID: %*ph\n", 3, param);
-
- /* HGPK signature: 0x67, 0x00, 0x<model> */
- if (param[0] != 0x67 || param[1] != 0x00)
- return -ENODEV;
-
- psmouse_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
-
- return param[2];
-}
-
-int hgpk_detect(struct psmouse *psmouse, bool set_properties)
-{
- int version;
-
- version = hgpk_get_model(psmouse);
- if (version < 0)
- return version;
-
- if (set_properties) {
- psmouse->vendor = "ALPS";
- psmouse->name = "HGPK";
- psmouse->model = version;
- }
-
- return 0;
-}
-
-void hgpk_module_init(void)
-{
- hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name,
- strlen(hgpk_mode_name));
- if (hgpk_default_mode == HGPK_MODE_INVALID) {
- hgpk_default_mode = HGPK_MODE_MOUSE;
- strscpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE],
- sizeof(hgpk_mode_name));
- }
-}
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
deleted file mode 100644
index ce041591f1a8..000000000000
--- a/drivers/input/mouse/hgpk.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
- */
-
-#ifndef _HGPK_H
-#define _HGPK_H
-
-#define HGPK_GS 0xff /* The GlideSensor */
-#define HGPK_PT 0xcf /* The PenTablet */
-
-enum hgpk_model_t {
- HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
- HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
- HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */
- HGPK_MODEL_C = 0x3c,
- HGPK_MODEL_D = 0x50, /* C1, mass production */
-};
-
-enum hgpk_spew_flag {
- NO_SPEW,
- MAYBE_SPEWING,
- SPEW_DETECTED,
- RECALIBRATING,
-};
-
-#define SPEW_WATCH_COUNT 42 /* at 12ms/packet, this is 1/2 second */
-
-enum hgpk_mode {
- HGPK_MODE_MOUSE,
- HGPK_MODE_GLIDESENSOR,
- HGPK_MODE_PENTABLET,
- HGPK_MODE_INVALID
-};
-
-struct hgpk_data {
- struct psmouse *psmouse;
- enum hgpk_mode mode;
- bool powered;
- enum hgpk_spew_flag spew_flag;
- int spew_count, x_tally, y_tally; /* spew detection */
- unsigned long recalib_window;
- struct delayed_work recalib_wq;
- int abs_x, abs_y;
- int dupe_count;
- int xbigj, ybigj, xlast, ylast; /* jumpiness detection */
- int xsaw_secondary, ysaw_secondary; /* jumpiness detection */
-};
-
-int hgpk_detect(struct psmouse *psmouse, bool set_properties);
-int hgpk_init(struct psmouse *psmouse);
-
-#ifdef CONFIG_MOUSE_PS2_OLPC
-void hgpk_module_init(void);
-#else
-static inline void hgpk_module_init(void)
-{
-}
-#endif
-
-#endif
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
deleted file mode 100644
index 401d8bff8e84..000000000000
--- a/drivers/input/mouse/inport.c
+++ /dev/null
@@ -1,177 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) 1999-2001 Vojtech Pavlik
- *
- * Based on the work of:
- * Teemu Rantanen Derrick Cole
- * Peter Cervasio Christoph Niemann
- * Philip Blundell Russell King
- * Bob Harris
- */
-
-/*
- * Inport (ATI XL and Microsoft) busmouse driver for Linux
- */
-
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Inport (ATI XL and Microsoft) busmouse driver");
-MODULE_LICENSE("GPL");
-
-#define INPORT_BASE 0x23c
-#define INPORT_EXTENT 4
-
-#define INPORT_CONTROL_PORT INPORT_BASE + 0
-#define INPORT_DATA_PORT INPORT_BASE + 1
-#define INPORT_SIGNATURE_PORT INPORT_BASE + 2
-
-#define INPORT_REG_BTNS 0x00
-#define INPORT_REG_X 0x01
-#define INPORT_REG_Y 0x02
-#define INPORT_REG_MODE 0x07
-#define INPORT_RESET 0x80
-
-#ifdef CONFIG_MOUSE_ATIXL
-#define INPORT_NAME "ATI XL Mouse"
-#define INPORT_VENDOR 0x0002
-#define INPORT_SPEED_30HZ 0x01
-#define INPORT_SPEED_50HZ 0x02
-#define INPORT_SPEED_100HZ 0x03
-#define INPORT_SPEED_200HZ 0x04
-#define INPORT_MODE_BASE INPORT_SPEED_100HZ
-#define INPORT_MODE_IRQ 0x08
-#else
-#define INPORT_NAME "Microsoft InPort Mouse"
-#define INPORT_VENDOR 0x0001
-#define INPORT_MODE_BASE 0x10
-#define INPORT_MODE_IRQ 0x01
-#endif
-#define INPORT_MODE_HOLD 0x20
-
-#define INPORT_IRQ 5
-
-static int inport_irq = INPORT_IRQ;
-module_param_hw_named(irq, inport_irq, uint, irq, 0);
-MODULE_PARM_DESC(irq, "IRQ number (5=default)");
-
-static struct input_dev *inport_dev;
-
-static irqreturn_t inport_interrupt(int irq, void *dev_id)
-{
- unsigned char buttons;
-
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
- outb(INPORT_REG_X, INPORT_CONTROL_PORT);
- input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
-
- outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
- input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT));
-
- outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
- buttons = inb(INPORT_DATA_PORT);
-
- input_report_key(inport_dev, BTN_MIDDLE, buttons & 1);
- input_report_key(inport_dev, BTN_LEFT, buttons & 2);
- input_report_key(inport_dev, BTN_RIGHT, buttons & 4);
-
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
- input_sync(inport_dev);
- return IRQ_HANDLED;
-}
-
-static int inport_open(struct input_dev *dev)
-{
- if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
- return -EBUSY;
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
- return 0;
-}
-
-static void inport_close(struct input_dev *dev)
-{
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
- free_irq(inport_irq, NULL);
-}
-
-static int __init inport_init(void)
-{
- unsigned char a, b, c;
- int err;
-
- if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
- printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
- return -EBUSY;
- }
-
- a = inb(INPORT_SIGNATURE_PORT);
- b = inb(INPORT_SIGNATURE_PORT);
- c = inb(INPORT_SIGNATURE_PORT);
- if (a == b || a != c) {
- printk(KERN_INFO "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE);
- err = -ENODEV;
- goto err_release_region;
- }
-
- inport_dev = input_allocate_device();
- if (!inport_dev) {
- printk(KERN_ERR "inport.c: Not enough memory for input device\n");
- err = -ENOMEM;
- goto err_release_region;
- }
-
- inport_dev->name = INPORT_NAME;
- inport_dev->phys = "isa023c/input0";
- inport_dev->id.bustype = BUS_ISA;
- inport_dev->id.vendor = INPORT_VENDOR;
- inport_dev->id.product = 0x0001;
- inport_dev->id.version = 0x0100;
-
- inport_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
- inport_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
- BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
- inport_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-
- inport_dev->open = inport_open;
- inport_dev->close = inport_close;
-
- outb(INPORT_RESET, INPORT_CONTROL_PORT);
- outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
- outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
-
- err = input_register_device(inport_dev);
- if (err)
- goto err_free_dev;
-
- return 0;
-
- err_free_dev:
- input_free_device(inport_dev);
- err_release_region:
- release_region(INPORT_BASE, INPORT_EXTENT);
-
- return err;
-}
-
-static void __exit inport_exit(void)
-{
- input_unregister_device(inport_dev);
- release_region(INPORT_BASE, INPORT_EXTENT);
-}
-
-module_init(inport_init);
-module_exit(inport_exit);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 283ef46f039f..ef11b7b19833 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -273,7 +273,7 @@ static int lifebook_create_relative_device(struct psmouse *psmouse)
struct lifebook_data *priv;
int error = -ENOMEM;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
dev2 = input_allocate_device();
if (!priv || !dev2)
goto err_out;
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
deleted file mode 100644
index 0aab63dbc30a..000000000000
--- a/drivers/input/mouse/logibm.c
+++ /dev/null
@@ -1,166 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) 1999-2001 Vojtech Pavlik
- *
- * Based on the work of:
- * James Banks Matthew Dillon
- * David Giller Nathan Laredo
- * Linus Torvalds Johan Myreen
- * Cliff Matthews Philip Blundell
- * Russell King
- */
-
-/*
- * Logitech Bus Mouse Driver for Linux
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Logitech busmouse driver");
-MODULE_LICENSE("GPL");
-
-#define LOGIBM_BASE 0x23c
-#define LOGIBM_EXTENT 4
-
-#define LOGIBM_DATA_PORT LOGIBM_BASE + 0
-#define LOGIBM_SIGNATURE_PORT LOGIBM_BASE + 1
-#define LOGIBM_CONTROL_PORT LOGIBM_BASE + 2
-#define LOGIBM_CONFIG_PORT LOGIBM_BASE + 3
-
-#define LOGIBM_ENABLE_IRQ 0x00
-#define LOGIBM_DISABLE_IRQ 0x10
-#define LOGIBM_READ_X_LOW 0x80
-#define LOGIBM_READ_X_HIGH 0xa0
-#define LOGIBM_READ_Y_LOW 0xc0
-#define LOGIBM_READ_Y_HIGH 0xe0
-
-#define LOGIBM_DEFAULT_MODE 0x90
-#define LOGIBM_CONFIG_BYTE 0x91
-#define LOGIBM_SIGNATURE_BYTE 0xa5
-
-#define LOGIBM_IRQ 5
-
-static int logibm_irq = LOGIBM_IRQ;
-module_param_hw_named(irq, logibm_irq, uint, irq, 0);
-MODULE_PARM_DESC(irq, "IRQ number (5=default)");
-
-static struct input_dev *logibm_dev;
-
-static irqreturn_t logibm_interrupt(int irq, void *dev_id)
-{
- char dx, dy;
- unsigned char buttons;
-
- outb(LOGIBM_READ_X_LOW, LOGIBM_CONTROL_PORT);
- dx = (inb(LOGIBM_DATA_PORT) & 0xf);
- outb(LOGIBM_READ_X_HIGH, LOGIBM_CONTROL_PORT);
- dx |= (inb(LOGIBM_DATA_PORT) & 0xf) << 4;
- outb(LOGIBM_READ_Y_LOW, LOGIBM_CONTROL_PORT);
- dy = (inb(LOGIBM_DATA_PORT) & 0xf);
- outb(LOGIBM_READ_Y_HIGH, LOGIBM_CONTROL_PORT);
- buttons = inb(LOGIBM_DATA_PORT);
- dy |= (buttons & 0xf) << 4;
- buttons = ~buttons >> 5;
-
- input_report_rel(logibm_dev, REL_X, dx);
- input_report_rel(logibm_dev, REL_Y, dy);
- input_report_key(logibm_dev, BTN_RIGHT, buttons & 1);
- input_report_key(logibm_dev, BTN_MIDDLE, buttons & 2);
- input_report_key(logibm_dev, BTN_LEFT, buttons & 4);
- input_sync(logibm_dev);
-
- outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
- return IRQ_HANDLED;
-}
-
-static int logibm_open(struct input_dev *dev)
-{
- if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
- printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
- return -EBUSY;
- }
- outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
- return 0;
-}
-
-static void logibm_close(struct input_dev *dev)
-{
- outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
- free_irq(logibm_irq, NULL);
-}
-
-static int __init logibm_init(void)
-{
- int err;
-
- if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) {
- printk(KERN_ERR "logibm.c: Can't allocate ports at %#x\n", LOGIBM_BASE);
- return -EBUSY;
- }
-
- outb(LOGIBM_CONFIG_BYTE, LOGIBM_CONFIG_PORT);
- outb(LOGIBM_SIGNATURE_BYTE, LOGIBM_SIGNATURE_PORT);
- udelay(100);
-
- if (inb(LOGIBM_SIGNATURE_PORT) != LOGIBM_SIGNATURE_BYTE) {
- printk(KERN_INFO "logibm.c: Didn't find Logitech busmouse at %#x\n", LOGIBM_BASE);
- err = -ENODEV;
- goto err_release_region;
- }
-
- outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT);
- outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
-
- logibm_dev = input_allocate_device();
- if (!logibm_dev) {
- printk(KERN_ERR "logibm.c: Not enough memory for input device\n");
- err = -ENOMEM;
- goto err_release_region;
- }
-
- logibm_dev->name = "Logitech bus mouse";
- logibm_dev->phys = "isa023c/input0";
- logibm_dev->id.bustype = BUS_ISA;
- logibm_dev->id.vendor = 0x0003;
- logibm_dev->id.product = 0x0001;
- logibm_dev->id.version = 0x0100;
-
- logibm_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
- logibm_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
- BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
- logibm_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
-
- logibm_dev->open = logibm_open;
- logibm_dev->close = logibm_close;
-
- err = input_register_device(logibm_dev);
- if (err)
- goto err_free_dev;
-
- return 0;
-
- err_free_dev:
- input_free_device(logibm_dev);
- err_release_region:
- release_region(LOGIBM_BASE, LOGIBM_EXTENT);
-
- return err;
-}
-
-static void __exit logibm_exit(void)
-{
- input_unregister_device(logibm_dev);
- release_region(LOGIBM_BASE, LOGIBM_EXTENT);
-}
-
-module_init(logibm_init);
-module_exit(logibm_exit);
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
index baef4be14b54..c99f7e234219 100644
--- a/drivers/input/mouse/maplemouse.c
+++ b/drivers/input/mouse/maplemouse.c
@@ -73,7 +73,7 @@ static int probe_maple_mouse(struct device *dev)
struct input_dev *input_dev;
struct dc_mouse *mse;
- mse = kzalloc(sizeof(*mse), GFP_KERNEL);
+ mse = kzalloc_obj(*mse);
if (!mse) {
error = -ENOMEM;
goto fail;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 77ea7da3b1c5..6ab5f1d96eae 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -26,7 +26,6 @@
#include "synaptics.h"
#include "logips2pp.h"
#include "alps.h"
-#include "hgpk.h"
#include "lifebook.h"
#include "trackpoint.h"
#include "touchkit_ps2.h"
@@ -114,8 +113,6 @@ ATTRIBUTE_GROUPS(psmouse_dev);
*/
static DEFINE_MUTEX(psmouse_mutex);
-static struct workqueue_struct *kpsmoused_wq;
-
struct psmouse *psmouse_from_serio(struct serio *serio)
{
struct ps2dev *ps2dev = serio_get_drvdata(serio);
@@ -241,12 +238,6 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
return PSMOUSE_FULL_PACKET;
}
-void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
- unsigned long delay)
-{
- queue_delayed_work(kpsmoused_wq, work, delay);
-}
-
/*
* __psmouse_set_state() sets new psmouse state and resets all flags.
*/
@@ -380,7 +371,7 @@ static void psmouse_receive_byte(struct ps2dev *ps2dev, u8 data)
psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
- psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
+ schedule_work(&psmouse->resync_work);
return;
}
@@ -393,9 +384,7 @@ static void psmouse_receive_byte(struct ps2dev *ps2dev, u8 data)
return;
}
- if (psmouse->packet[1] == PSMOUSE_RET_ID ||
- (psmouse->protocol->type == PSMOUSE_HGPK &&
- psmouse->packet[1] == PSMOUSE_RET_BAT)) {
+ if (psmouse->packet[1] == PSMOUSE_RET_ID) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
serio_reconnect(ps2dev->serio);
return;
@@ -418,7 +407,7 @@ static void psmouse_receive_byte(struct ps2dev *ps2dev, u8 data)
time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
- psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
+ schedule_work(&psmouse->resync_work);
return;
}
@@ -837,14 +826,6 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.detect = touchkit_ps2_detect,
},
#endif
-#ifdef CONFIG_MOUSE_PS2_OLPC
- {
- .type = PSMOUSE_HGPK,
- .name = "OLPC HGPK",
- .alias = "hgpk",
- .detect = hgpk_detect,
- },
-#endif
#ifdef CONFIG_MOUSE_PS2_ELANTECH
{
.type = PSMOUSE_ELANTECH,
@@ -1153,13 +1134,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
return PSMOUSE_ALPS;
}
- /* Try OLPC HGPK touchpad */
- if (max_proto > PSMOUSE_IMEX &&
- psmouse_try_protocol(psmouse, PSMOUSE_HGPK, &max_proto,
- set_properties, true)) {
- return PSMOUSE_HGPK;
- }
-
/* Try Elantech touchpad */
if (max_proto > PSMOUSE_IMEX &&
psmouse_try_protocol(psmouse, PSMOUSE_ELANTECH,
@@ -1331,7 +1305,7 @@ int psmouse_deactivate(struct psmouse *psmouse)
static void psmouse_resync(struct work_struct *work)
{
struct psmouse *parent = NULL, *psmouse =
- container_of(work, struct psmouse, resync_work.work);
+ container_of(work, struct psmouse, resync_work);
struct serio *serio = psmouse->ps2dev.serio;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
bool failed = false, enabled = false;
@@ -1484,7 +1458,7 @@ static void psmouse_disconnect(struct serio *serio)
/* make sure we don't have a resync in progress */
mutex_unlock(&psmouse_mutex);
- flush_workqueue(kpsmoused_wq);
+ disable_work_sync(&psmouse->resync_work);
mutex_lock(&psmouse_mutex);
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
@@ -1591,14 +1565,14 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
psmouse_deactivate(parent);
}
- psmouse = kzalloc(sizeof(*psmouse), GFP_KERNEL);
+ psmouse = kzalloc_obj(*psmouse);
input_dev = input_allocate_device();
if (!psmouse || !input_dev)
goto err_free;
ps2_init(&psmouse->ps2dev, serio,
psmouse_pre_receive_byte, psmouse_receive_byte);
- INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
+ INIT_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
scnprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
@@ -2035,27 +2009,17 @@ static int __init psmouse_init(void)
lifebook_module_init();
synaptics_module_init();
- hgpk_module_init();
err = psmouse_smbus_module_init();
if (err)
return err;
- kpsmoused_wq = alloc_ordered_workqueue("kpsmoused", 0);
- if (!kpsmoused_wq) {
- pr_err("failed to create kpsmoused workqueue\n");
- err = -ENOMEM;
- goto err_smbus_exit;
- }
-
err = serio_register_driver(&psmouse_drv);
if (err)
- goto err_destroy_wq;
+ goto err_smbus_exit;
return 0;
-err_destroy_wq:
- destroy_workqueue(kpsmoused_wq);
err_smbus_exit:
psmouse_smbus_module_exit();
return err;
@@ -2064,7 +2028,6 @@ err_smbus_exit:
static void __exit psmouse_exit(void)
{
serio_unregister_driver(&psmouse_drv);
- destroy_workqueue(kpsmoused_wq);
psmouse_smbus_module_exit();
}
diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c
index 15bd49ccad22..7fb4cbb2aca2 100644
--- a/drivers/input/mouse/psmouse-smbus.c
+++ b/drivers/input/mouse/psmouse-smbus.c
@@ -154,7 +154,7 @@ static void psmouse_smbus_schedule_remove(struct i2c_client *client)
{
struct psmouse_smbus_removal_work *rwork;
- rwork = kzalloc(sizeof(*rwork), GFP_KERNEL);
+ rwork = kzalloc_obj(*rwork);
if (rwork) {
INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device);
rwork->client = client;
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 4d8acfe0d82a..90ed8cd15d85 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -59,7 +59,7 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON,
- PSMOUSE_HGPK,
+ PSMOUSE_HGPK, /* No longer used */
PSMOUSE_ELANTECH,
PSMOUSE_FSP,
PSMOUSE_SYNAPTICS_RELATIVE,
@@ -90,7 +90,7 @@ struct psmouse {
void *private;
struct input_dev *dev;
struct ps2dev ps2dev;
- struct delayed_work resync_work;
+ struct work_struct resync_work;
const char *vendor;
const char *name;
const struct psmouse_protocol *protocol;
@@ -132,8 +132,6 @@ struct psmouse {
struct psmouse *psmouse_from_serio(struct serio *serio);
-void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
- unsigned long delay);
int psmouse_reset(struct psmouse *psmouse);
void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
index 44b136fc29aa..cda6febe3faf 100644
--- a/drivers/input/mouse/sentelic.c
+++ b/drivers/input/mouse/sentelic.c
@@ -1028,7 +1028,7 @@ int fsp_init(struct psmouse *psmouse)
"Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n",
ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver);
- psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ psmouse->private = priv = kzalloc_obj(*priv);
if (!priv)
return -ENOMEM;
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index 218c8432a13b..c334a488700f 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -231,7 +231,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
unsigned char c = serio->id.extra;
int err = -ENOMEM;
- sermouse = kzalloc(sizeof(*sermouse), GFP_KERNEL);
+ sermouse = kzalloc_obj(*sermouse);
input_dev = input_allocate_device();
if (!sermouse || !input_dev)
goto fail1;
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index c5c88a75a019..26071128f43a 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -741,7 +741,7 @@ static void synaptics_pt_create(struct psmouse *psmouse)
{
struct serio *serio;
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!serio) {
psmouse_err(psmouse,
"not enough memory for pass-through port\n");
@@ -1597,7 +1597,7 @@ static int synaptics_init_ps2(struct psmouse *psmouse,
synaptics_apply_quirks(psmouse, info);
- psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ psmouse->private = priv = kzalloc_obj(*priv);
if (!priv)
return -ENOMEM;
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c
index 75e45f3ae675..880a0c79148c 100644
--- a/drivers/input/mouse/synaptics_usb.c
+++ b/drivers/input/mouse/synaptics_usb.c
@@ -220,25 +220,6 @@ resubmit:
__func__, error);
}
-static struct usb_endpoint_descriptor *
-synusb_get_in_endpoint(struct usb_host_interface *iface)
-{
-
- struct usb_endpoint_descriptor *endpoint;
- int i;
-
- for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
- endpoint = &iface->endpoint[i].desc;
-
- if (usb_endpoint_is_int_in(endpoint)) {
- /* we found our interrupt in endpoint */
- return endpoint;
- }
- }
-
- return NULL;
-}
-
static int synusb_open(struct input_dev *dev)
{
struct synusb *synusb = input_get_drvdata(dev);
@@ -307,11 +288,11 @@ static int synusb_probe(struct usb_interface *intf,
return error;
}
- ep = synusb_get_in_endpoint(intf->cur_altsetting);
- if (!ep)
+ error = usb_find_int_in_endpoint(intf->cur_altsetting, &ep);
+ if (error)
return -ENODEV;
- synusb = kzalloc(sizeof(*synusb), GFP_KERNEL);
+ synusb = kzalloc_obj(*synusb);
input_dev = input_allocate_device();
if (!synusb || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 5f6643b69a2c..b06c7ad721fe 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -409,7 +409,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
if (!set_properties)
return 0;
- tp = kzalloc(sizeof(*tp), GFP_KERNEL);
+ tp = kzalloc_obj(*tp);
if (!tp)
return -ENOMEM;
diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
index fb1d986a6895..aaecdd3d50b6 100644
--- a/drivers/input/mouse/vmmouse.c
+++ b/drivers/input/mouse/vmmouse.c
@@ -409,7 +409,7 @@ int vmmouse_init(struct psmouse *psmouse)
if (error)
return error;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
abs_dev = input_allocate_device();
if (!priv || !abs_dev) {
error = -ENOMEM;
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 707cd28f4ba6..042a17fe81db 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -456,7 +456,7 @@ static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err = -ENOMEM;
- mouse = kzalloc(sizeof(*mouse), GFP_KERNEL);
+ mouse = kzalloc_obj(*mouse);
input_dev = input_allocate_device();
if (!mouse || !input_dev)
goto fail1;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 505c562a5daa..d5c9b0a09fcf 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -543,7 +543,7 @@ static int mousedev_open(struct inode *inode, struct file *file)
#endif
mousedev = container_of(inode->i_cdev, struct mousedev, cdev);
- client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
+ client = kzalloc_obj(struct mousedev_client);
if (!client)
return -ENOMEM;
@@ -853,7 +853,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
goto err_out;
}
- mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
+ mousedev = kzalloc_obj(struct mousedev);
if (!mousedev) {
error = -ENOMEM;
goto err_free_minor;
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index b85ee9db87b0..687cb987bc13 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -78,7 +78,7 @@ int rmi_register_transport_device(struct rmi_transport_dev *xport)
struct rmi_device *rmi_dev;
int error;
- rmi_dev = kzalloc(sizeof(struct rmi_device), GFP_KERNEL);
+ rmi_dev = kzalloc_obj(struct rmi_device);
if (!rmi_dev)
return -ENOMEM;
diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
index e1157ff0f00a..04f0e5578861 100644
--- a/drivers/input/rmi4/rmi_f03.c
+++ b/drivers/input/rmi4/rmi_f03.c
@@ -171,7 +171,7 @@ static int rmi_f03_register_pt(struct f03_data *f03)
{
struct serio *serio;
- serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ serio = kzalloc_obj(struct serio);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index c7ef347a4dff..5f15a6462056 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -55,19 +55,6 @@ config SERIO_SERPORT
To compile this driver as a module, choose M here: the
module will be called serport.
-config SERIO_CT82C710
- tristate "ct82c710 Aux port controller"
- depends on X86
- help
- Say Y here if you have a Texas Instruments TravelMate notebook
- equipped with the ct82c710 chip and want to use a mouse connected
- to the "QuickPort".
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called ct82c710.
-
config SERIO_Q40KBD
tristate "Q40 keyboard controller"
depends on Q40
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 6d97bad7b844..8ab98f4aa28d 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_SERIO) += serio.o
obj-$(CONFIG_SERIO_I8042) += i8042.o
obj-$(CONFIG_SERIO_PARKBD) += parkbd.o
obj-$(CONFIG_SERIO_SERPORT) += serport.o
-obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o
obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o
obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o
obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c
index 761aaaa3e571..4bf37db65b76 100644
--- a/drivers/input/serio/altera_ps2.c
+++ b/drivers/input/serio/altera_ps2.c
@@ -100,7 +100,7 @@ static int altera_ps2_probe(struct platform_device *pdev)
return error;
}
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index de4b3915c37d..046b8f388eb6 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -114,8 +114,8 @@ static int amba_kmi_probe(struct amba_device *dev,
if (ret)
return ret;
- kmi = kzalloc(sizeof(*kmi), GFP_KERNEL);
- io = kzalloc(sizeof(*io), GFP_KERNEL);
+ kmi = kzalloc_obj(*kmi);
+ io = kzalloc_obj(*io);
if (!kmi || !io) {
ret = -ENOMEM;
goto out;
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index 81b3a053df81..e346bf53eb16 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -150,7 +150,7 @@ static int ams_delta_serio_init(struct platform_device *pdev)
return err;
}
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c
index a5fbb27088be..0aa4ab00af35 100644
--- a/drivers/input/serio/apbps2.c
+++ b/drivers/input/serio/apbps2.c
@@ -165,7 +165,7 @@ static int apbps2_of_probe(struct platform_device *ofdev)
/* Set reload register to core freq in kHz/10 */
iowrite32be(freq_hz / 10000, &priv->regs->reload);
- priv->io = kzalloc(sizeof(*priv->io), GFP_KERNEL);
+ priv->io = kzalloc_obj(*priv->io);
if (!priv->io)
return -ENOMEM;
diff --git a/drivers/input/serio/arc_ps2.c b/drivers/input/serio/arc_ps2.c
index 29095d8804d2..2eb069a0f054 100644
--- a/drivers/input/serio/arc_ps2.c
+++ b/drivers/input/serio/arc_ps2.c
@@ -155,7 +155,7 @@ static int arc_ps2_create_port(struct platform_device *pdev,
struct arc_ps2_port *port = &arc_ps2->port[index];
struct serio *io;
- io = kzalloc(sizeof(*io), GFP_KERNEL);
+ io = kzalloc_obj(*io);
if (!io)
return -ENOMEM;
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
deleted file mode 100644
index 053a15988c45..000000000000
--- a/drivers/input/serio/ct82c710.c
+++ /dev/null
@@ -1,239 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) 1999-2001 Vojtech Pavlik
- */
-
-/*
- * 82C710 C&T mouse port chip driver for Linux
- */
-
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/serio.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("82C710 C&T mouse port chip driver");
-MODULE_LICENSE("GPL");
-
-/*
- * ct82c710 interface
- */
-
-#define CT82C710_DEV_IDLE 0x01 /* Device Idle */
-#define CT82C710_RX_FULL 0x02 /* Device Char received */
-#define CT82C710_TX_IDLE 0x04 /* Device XMIT Idle */
-#define CT82C710_RESET 0x08 /* Device Reset */
-#define CT82C710_INTS_ON 0x10 /* Device Interrupt On */
-#define CT82C710_ERROR_FLAG 0x20 /* Device Error */
-#define CT82C710_CLEAR 0x40 /* Device Clear */
-#define CT82C710_ENABLE 0x80 /* Device Enable */
-
-#define CT82C710_IRQ 12
-
-#define CT82C710_DATA ct82c710_iores.start
-#define CT82C710_STATUS (ct82c710_iores.start + 1)
-
-static struct serio *ct82c710_port;
-static struct platform_device *ct82c710_device;
-static struct resource ct82c710_iores;
-
-/*
- * Interrupt handler for the 82C710 mouse port. A character
- * is waiting in the 82C710.
- */
-
-static irqreturn_t ct82c710_interrupt(int cpl, void *dev_id)
-{
- return serio_interrupt(ct82c710_port, inb(CT82C710_DATA), 0);
-}
-
-/*
- * Wait for device to send output char and flush any input char.
- */
-
-static int ct82c170_wait(void)
-{
- int timeout = 60000;
-
- while ((inb(CT82C710_STATUS) & (CT82C710_RX_FULL | CT82C710_TX_IDLE | CT82C710_DEV_IDLE))
- != (CT82C710_DEV_IDLE | CT82C710_TX_IDLE) && timeout) {
-
- if (inb_p(CT82C710_STATUS) & CT82C710_RX_FULL) inb_p(CT82C710_DATA);
-
- udelay(1);
- timeout--;
- }
-
- return !timeout;
-}
-
-static void ct82c710_close(struct serio *serio)
-{
- if (ct82c170_wait())
- printk(KERN_WARNING "ct82c710.c: Device busy in close()\n");
-
- outb_p(inb_p(CT82C710_STATUS) & ~(CT82C710_ENABLE | CT82C710_INTS_ON), CT82C710_STATUS);
-
- if (ct82c170_wait())
- printk(KERN_WARNING "ct82c710.c: Device busy in close()\n");
-
- free_irq(CT82C710_IRQ, NULL);
-}
-
-static int ct82c710_open(struct serio *serio)
-{
- unsigned char status;
- int err;
-
- err = request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL);
- if (err)
- return err;
-
- status = inb_p(CT82C710_STATUS);
-
- status |= (CT82C710_ENABLE | CT82C710_RESET);
- outb_p(status, CT82C710_STATUS);
-
- status &= ~(CT82C710_RESET);
- outb_p(status, CT82C710_STATUS);
-
- status |= CT82C710_INTS_ON;
- outb_p(status, CT82C710_STATUS); /* Enable interrupts */
-
- while (ct82c170_wait()) {
- printk(KERN_ERR "ct82c710: Device busy in open()\n");
- status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON);
- outb_p(status, CT82C710_STATUS);
- free_irq(CT82C710_IRQ, NULL);
- return -EBUSY;
- }
-
- return 0;
-}
-
-/*
- * Write to the 82C710 mouse device.
- */
-
-static int ct82c710_write(struct serio *port, unsigned char c)
-{
- if (ct82c170_wait()) return -1;
- outb_p(c, CT82C710_DATA);
- return 0;
-}
-
-/*
- * See if we can find a 82C710 device. Read mouse address.
- */
-
-static int __init ct82c710_detect(void)
-{
- outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */
- outb_p(0xaa, 0x3fa); /* Inverse of 55 */
- outb_p(0x36, 0x3fa); /* Address the chip */
- outb_p(0xe4, 0x3fa); /* 390/4; 390 = config address */
- outb_p(0x1b, 0x2fa); /* Inverse of e4 */
- outb_p(0x0f, 0x390); /* Write index */
- if (inb_p(0x391) != 0xe4) /* Config address found? */
- return -ENODEV; /* No: no 82C710 here */
-
- outb_p(0x0d, 0x390); /* Write index */
- ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */
- ct82c710_iores.end = ct82c710_iores.start + 1;
- ct82c710_iores.flags = IORESOURCE_IO;
- outb_p(0x0f, 0x390);
- outb_p(0x0f, 0x391); /* Close config mode */
-
- return 0;
-}
-
-static int ct82c710_probe(struct platform_device *dev)
-{
- ct82c710_port = kzalloc(sizeof(*ct82c710_port), GFP_KERNEL);
- if (!ct82c710_port)
- return -ENOMEM;
-
- ct82c710_port->id.type = SERIO_8042;
- ct82c710_port->dev.parent = &dev->dev;
- ct82c710_port->open = ct82c710_open;
- ct82c710_port->close = ct82c710_close;
- ct82c710_port->write = ct82c710_write;
- strscpy(ct82c710_port->name, "C&T 82c710 mouse port",
- sizeof(ct82c710_port->name));
- snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys),
- "isa%16llx/serio0", (unsigned long long)CT82C710_DATA);
-
- serio_register_port(ct82c710_port);
-
- printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n",
- (unsigned long long)CT82C710_DATA, CT82C710_IRQ);
-
- return 0;
-}
-
-static void ct82c710_remove(struct platform_device *dev)
-{
- serio_unregister_port(ct82c710_port);
-}
-
-static struct platform_driver ct82c710_driver = {
- .driver = {
- .name = "ct82c710",
- },
- .probe = ct82c710_probe,
- .remove = ct82c710_remove,
-};
-
-
-static int __init ct82c710_init(void)
-{
- int error;
-
- error = ct82c710_detect();
- if (error)
- return error;
-
- error = platform_driver_register(&ct82c710_driver);
- if (error)
- return error;
-
- ct82c710_device = platform_device_alloc("ct82c710", -1);
- if (!ct82c710_device) {
- error = -ENOMEM;
- goto err_unregister_driver;
- }
-
- error = platform_device_add_resources(ct82c710_device, &ct82c710_iores, 1);
- if (error)
- goto err_free_device;
-
- error = platform_device_add(ct82c710_device);
- if (error)
- goto err_free_device;
-
- return 0;
-
- err_free_device:
- platform_device_put(ct82c710_device);
- err_unregister_driver:
- platform_driver_unregister(&ct82c710_driver);
- return error;
-}
-
-static void __exit ct82c710_exit(void)
-{
- platform_device_unregister(ct82c710_device);
- platform_driver_unregister(&ct82c710_driver);
-}
-
-module_init(ct82c710_init);
-module_exit(ct82c710_exit);
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 9c6ff04c46cf..22b2f57fd91f 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -350,8 +350,8 @@ static int __init gscps2_probe(struct parisc_device *dev)
if (dev->id.sversion == 0x96)
hpa += GSC_DINO_OFFSET;
- ps2port = kzalloc(sizeof(*ps2port), GFP_KERNEL);
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ ps2port = kzalloc_obj(*ps2port);
+ serio = kzalloc_obj(*serio);
if (!ps2port || !serio) {
ret = -ENOMEM;
goto fail_nomem;
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c
index 3fedfc5abc73..2680a816c393 100644
--- a/drivers/input/serio/hil_mlc.c
+++ b/drivers/input/serio/hil_mlc.c
@@ -939,7 +939,7 @@ int hil_mlc_register(hil_mlc *mlc)
for (i = 0; i < HIL_MLC_DEVMEM; i++) {
struct serio *mlc_serio;
hil_mlc_copy_di_scratch(mlc, i);
- mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL);
+ mlc_serio = kzalloc_obj(*mlc_serio);
mlc->serio[i] = mlc_serio;
if (!mlc->serio[i]) {
for (; i >= 0; i--)
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index 0ee7505427ac..13434b9330c8 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -316,8 +316,8 @@ static int hv_kbd_probe(struct hv_device *hv_dev,
struct serio *hv_serio;
int error;
- kbd_dev = kzalloc(sizeof(*kbd_dev), GFP_KERNEL);
- hv_serio = kzalloc(sizeof(*hv_serio), GFP_KERNEL);
+ kbd_dev = kzalloc_obj(*kbd_dev);
+ hv_serio = kzalloc_obj(*hv_serio);
if (!kbd_dev || !hv_serio) {
error = -ENOMEM;
goto err_free_mem;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c135254665b6..8bcce11cb7ce 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1324,7 +1324,7 @@ static int i8042_create_kbd_port(void)
struct serio *serio;
struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!serio)
return -ENOMEM;
@@ -1354,7 +1354,7 @@ static int i8042_create_aux_port(int idx)
int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
struct i8042_port *port = &i8042_ports[port_no];
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/ioc3kbd.c b/drivers/input/serio/ioc3kbd.c
index d2c7ffb9a946..4ef60c24e788 100644
--- a/drivers/input/serio/ioc3kbd.c
+++ b/drivers/input/serio/ioc3kbd.c
@@ -139,11 +139,11 @@ static int ioc3kbd_probe(struct platform_device *pdev)
if (!d)
return -ENOMEM;
- sk = kzalloc(sizeof(*sk), GFP_KERNEL);
+ sk = kzalloc_obj(*sk);
if (!sk)
return -ENOMEM;
- sa = kzalloc(sizeof(*sa), GFP_KERNEL);
+ sa = kzalloc_obj(*sa);
if (!sa) {
kfree(sk);
return -ENOMEM;
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 269df83a167d..05b64277aecd 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -154,10 +154,8 @@ EXPORT_SYMBOL(ps2_end_command);
*/
void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
{
- if (maxbytes > sizeof(ps2dev->cmdbuf)) {
- WARN_ON(1);
+ if (WARN_ON(maxbytes > sizeof(ps2dev->cmdbuf)))
maxbytes = sizeof(ps2dev->cmdbuf);
- }
ps2_begin_command(ps2dev);
@@ -270,15 +268,11 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
int i;
u8 send_param[16];
- if (receive > sizeof(ps2dev->cmdbuf)) {
- WARN_ON(1);
+ if (WARN_ON(receive > sizeof(ps2dev->cmdbuf)))
return -EINVAL;
- }
- if (send && !param) {
- WARN_ON(1);
+ if (WARN_ON(send && !param))
return -EINVAL;
- }
memcpy(send_param, param, send);
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index 3d28a5cddd61..fb41e7f5af46 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -117,7 +117,7 @@ static struct serio *maceps2_allocate_port(int idx)
{
struct serio *serio;
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (serio) {
serio->id.type = SERIO_8042;
serio->write = maceps2_write;
diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c
index c07fb8a1799d..ccc40634f582 100644
--- a/drivers/input/serio/olpc_apsp.c
+++ b/drivers/input/serio/olpc_apsp.c
@@ -188,7 +188,7 @@ static int olpc_apsp_probe(struct platform_device *pdev)
return priv->irq;
/* KEYBOARD */
- kb_serio = kzalloc(sizeof(*kb_serio), GFP_KERNEL);
+ kb_serio = kzalloc_obj(*kb_serio);
if (!kb_serio)
return -ENOMEM;
kb_serio->id.type = SERIO_8042_XL;
@@ -203,7 +203,7 @@ static int olpc_apsp_probe(struct platform_device *pdev)
serio_register_port(kb_serio);
/* TOUCHPAD */
- pad_serio = kzalloc(sizeof(*pad_serio), GFP_KERNEL);
+ pad_serio = kzalloc_obj(*pad_serio);
if (!pad_serio) {
error = -ENOMEM;
goto err_pad;
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
index 22fe55490572..09a24413d940 100644
--- a/drivers/input/serio/parkbd.c
+++ b/drivers/input/serio/parkbd.c
@@ -165,7 +165,7 @@ static struct serio *parkbd_allocate_serio(void)
{
struct serio *serio;
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (serio) {
serio->id.type = parkbd_mode;
serio->write = parkbd_write;
diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index 6b9abb2e18c9..78f47b0ca125 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -137,8 +137,8 @@ static int pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (ret)
goto disable;
- ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL);
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ ps2if = kzalloc_obj(*ps2if);
+ serio = kzalloc_obj(*serio);
if (!ps2if || !serio) {
ret = -ENOMEM;
goto release;
diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c
index 46fb7667b244..6cde0d88c6f4 100644
--- a/drivers/input/serio/ps2-gpio.c
+++ b/drivers/input/serio/ps2-gpio.c
@@ -405,7 +405,7 @@ static int ps2_gpio_probe(struct platform_device *pdev)
int error;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!drvdata || !serio) {
error = -ENOMEM;
goto err_free_serio;
diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c
index b96cee52fc52..27d554b59658 100644
--- a/drivers/input/serio/ps2mult.c
+++ b/drivers/input/serio/ps2mult.c
@@ -122,7 +122,7 @@ static int ps2mult_create_port(struct ps2mult *psm, int i)
struct serio *mx_serio = psm->mx_serio;
struct serio *serio;
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
if (!serio)
return -ENOMEM;
@@ -160,7 +160,7 @@ static int ps2mult_connect(struct serio *serio, struct serio_driver *drv)
if (!serio->write)
return -EINVAL;
- psm = kzalloc(sizeof(*psm), GFP_KERNEL);
+ psm = kzalloc_obj(*psm);
if (!psm)
return -ENOMEM;
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index ae55c4de092f..2f553efbe649 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -102,8 +102,8 @@ static int q40kbd_probe(struct platform_device *pdev)
struct serio *port;
int error;
- q40kbd = kzalloc(sizeof(*q40kbd), GFP_KERNEL);
- port = kzalloc(sizeof(*port), GFP_KERNEL);
+ q40kbd = kzalloc_obj(*q40kbd);
+ port = kzalloc_obj(*port);
if (!q40kbd || !port) {
error = -ENOMEM;
goto err_free_mem;
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index c65c552b0c45..4d817850ba3b 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -108,8 +108,8 @@ static int rpckbd_probe(struct platform_device *dev)
if (tx_irq < 0)
return tx_irq;
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
- rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
+ serio = kzalloc_obj(*serio);
+ rpckbd = kzalloc_obj(*rpckbd);
if (!serio || !rpckbd) {
kfree(rpckbd);
kfree(serio);
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 375c6f5f905c..e3a463c157d1 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -254,8 +254,8 @@ static int ps2_probe(struct sa1111_dev *dev)
struct serio *serio;
int ret;
- ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL);
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ ps2if = kzalloc_obj(*ps2if);
+ serio = kzalloc_obj(*serio);
if (!ps2if || !serio) {
ret = -ENOMEM;
goto free;
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 2b5ddc5dac19..54dd26249b02 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -244,7 +244,7 @@ static int serio_queue_event(void *object, struct module *owner,
}
}
- event = kmalloc(sizeof(*event), GFP_ATOMIC);
+ event = kmalloc_obj(*event, GFP_ATOMIC);
if (!event) {
pr_err("Not enough memory to queue event %d\n", event_type);
return -ENOMEM;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 4d6395088986..a7ccedfa459c 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -270,7 +270,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
struct serio_raw *serio_raw;
int err;
- serio_raw = kzalloc(sizeof(*serio_raw), GFP_KERNEL);
+ serio_raw = kzalloc_obj(*serio_raw);
if (!serio_raw) {
dev_dbg(&serio->dev, "can't allocate memory for a device\n");
return -ENOMEM;
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 74ac88796187..cabe3876c168 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -78,7 +78,7 @@ static int serport_ldisc_open(struct tty_struct *tty)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- serport = kzalloc(sizeof(*serport), GFP_KERNEL);
+ serport = kzalloc_obj(*serport);
if (!serport)
return -ENOMEM;
@@ -159,7 +159,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file,
if (test_and_set_bit(SERPORT_BUSY, &serport->flags))
return -EBUSY;
- serport->serio = serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ serport->serio = serio = kzalloc_obj(*serio);
if (!serio)
return -ENOMEM;
diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c
index 524929ce1cae..a9812789771c 100644
--- a/drivers/input/serio/sun4i-ps2.c
+++ b/drivers/input/serio/sun4i-ps2.c
@@ -209,8 +209,8 @@ static int sun4i_ps2_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
int error;
- drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ drvdata = kzalloc_obj(*drvdata);
+ serio = kzalloc_obj(*serio);
if (!drvdata || !serio) {
error = -ENOMEM;
goto err_free_mem;
diff --git a/drivers/input/serio/userio.c b/drivers/input/serio/userio.c
index 7f627b08055e..91cb7a177b2d 100644
--- a/drivers/input/serio/userio.c
+++ b/drivers/input/serio/userio.c
@@ -73,7 +73,7 @@ static int userio_device_write(struct serio *id, unsigned char val)
static int userio_char_open(struct inode *inode, struct file *file)
{
struct userio_device *userio __free(kfree) =
- kzalloc(sizeof(*userio), GFP_KERNEL);
+ kzalloc_obj(*userio);
if (!userio)
return -ENOMEM;
@@ -81,7 +81,7 @@ static int userio_char_open(struct inode *inode, struct file *file)
spin_lock_init(&userio->buf_lock);
init_waitqueue_head(&userio->waitq);
- userio->serio = kzalloc(sizeof(*userio->serio), GFP_KERNEL);
+ userio->serio = kzalloc_obj(*userio->serio);
if (!userio->serio)
return -ENOMEM;
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 01433f0b48f1..411d55ca1a66 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -247,8 +247,8 @@ static int xps2_of_probe(struct platform_device *ofdev)
return -ENODEV;
}
- drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
- serio = kzalloc(sizeof(*serio), GFP_KERNEL);
+ drvdata = kzalloc_obj(*drvdata);
+ serio = kzalloc_obj(*serio);
if (!drvdata || !serio) {
error = -ENOMEM;
goto failed1;
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
index 0ac16f32b31f..ba79dff21aac 100644
--- a/drivers/input/tablet/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -129,7 +129,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe);
- acecad = kzalloc(sizeof(*acecad), GFP_KERNEL);
+ acecad = kzalloc_obj(*acecad);
input_dev = input_allocate_device();
if (!acecad || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 2b3fbb0455d5..c850b5890070 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -57,6 +57,7 @@
* http://aiptektablet.sourceforge.net.
*/
+#include <linux/hid.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -164,8 +165,6 @@
#define USB_VENDOR_ID_AIPTEK 0x08ca
#define USB_VENDOR_ID_KYE 0x0458
-#define USB_REQ_GET_REPORT 0x01
-#define USB_REQ_SET_REPORT 0x09
/* PointerMode codes
*/
@@ -658,6 +657,8 @@ static void aiptek_irq(struct urb *urb)
pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1;
+ if (macro >= ARRAY_SIZE(macroKeyEvents))
+ macro = -1;
z = get_unaligned_le16(data + 4);
if (dv) {
@@ -699,7 +700,9 @@ static void aiptek_irq(struct urb *urb)
left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
- macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0;
+ macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : -1;
+ if (macro >= ARRAY_SIZE(macroKeyEvents))
+ macro = -1;
if (dv) {
/* If the selected tool changed, reset the old
@@ -737,11 +740,11 @@ static void aiptek_irq(struct urb *urb)
*/
else if (data[0] == 6) {
macro = get_unaligned_le16(data + 1);
- if (macro > 0) {
+ if (macro > 0 && macro - 1 < ARRAY_SIZE(macroKeyEvents)) {
input_report_key(inputdev, macroKeyEvents[macro - 1],
0);
}
- if (macro < 25) {
+ if (macro + 1 < ARRAY_SIZE(macroKeyEvents)) {
input_report_key(inputdev, macroKeyEvents[macro + 1],
0);
}
@@ -760,7 +763,8 @@ static void aiptek_irq(struct urb *urb)
aiptek->curSetting.toolMode;
}
- input_report_key(inputdev, macroKeyEvents[macro], 1);
+ if (macro < ARRAY_SIZE(macroKeyEvents))
+ input_report_key(inputdev, macroKeyEvents[macro], 1);
input_report_abs(inputdev, ABS_MISC,
1 | AIPTEK_REPORT_TOOL_UNKNOWN);
input_sync(inputdev);
@@ -856,7 +860,7 @@ aiptek_set_report(struct aiptek *aiptek,
return usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
- USB_REQ_SET_REPORT,
+ HID_REQ_SET_REPORT,
USB_TYPE_CLASS | USB_RECIP_INTERFACE |
USB_DIR_OUT, (report_type << 8) + report_id,
aiptek->ifnum, buffer, size, 5000);
@@ -871,7 +875,7 @@ aiptek_get_report(struct aiptek *aiptek,
return usb_control_msg(udev,
usb_rcvctrlpipe(udev, 0),
- USB_REQ_GET_REPORT,
+ HID_REQ_GET_REPORT,
USB_TYPE_CLASS | USB_RECIP_INTERFACE |
USB_DIR_IN, (report_type << 8) + report_id,
aiptek->ifnum, buffer, size, 5000);
@@ -1673,7 +1677,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
*/
speeds[0] = programmableDelay;
- aiptek = kzalloc(sizeof(*aiptek), GFP_KERNEL);
+ aiptek = kzalloc_obj(*aiptek);
inputdev = input_allocate_device();
if (!aiptek || !inputdev) {
dev_warn(&intf->dev,
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c
index 42c1e5eaddd5..fd5a7e761dcc 100644
--- a/drivers/input/tablet/hanwang.c
+++ b/drivers/input/tablet/hanwang.c
@@ -322,7 +322,7 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
return -ENODEV;
- hanwang = kzalloc(sizeof(*hanwang), GFP_KERNEL);
+ hanwang = kzalloc_obj(*hanwang);
input_dev = input_allocate_device();
if (!hanwang || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index 794caa102909..6ce70c8e2d7c 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -121,7 +121,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
if (!usb_endpoint_is_int_in(endpoint))
return -ENODEV;
- kbtab = kzalloc(sizeof(*kbtab), GFP_KERNEL);
+ kbtab = kzalloc_obj(*kbtab);
input_dev = input_allocate_device();
if (!kbtab || !input_dev)
goto fail1;
diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c
index eabb4a0b8a0d..85390ae42307 100644
--- a/drivers/input/tablet/pegasus_notetaker.c
+++ b/drivers/input/tablet/pegasus_notetaker.c
@@ -36,6 +36,7 @@
* T Tip
*/
+#include <linux/hid.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
@@ -44,10 +45,6 @@
#include <linux/workqueue.h>
#include <linux/mutex.h>
-/* USB HID defines */
-#define USB_REQ_GET_REPORT 0x01
-#define USB_REQ_SET_REPORT 0x09
-
#define USB_VENDOR_ID_PEGASUSTECH 0x0e20
#define USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100 0x0101
@@ -108,7 +105,7 @@ static int pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
result = usb_control_msg(pegasus->usbdev,
usb_sndctrlpipe(pegasus->usbdev, 0),
- USB_REQ_SET_REPORT,
+ HID_REQ_SET_REPORT,
USB_TYPE_VENDOR | USB_DIR_OUT,
0, 0, cmd_buf, sizeof_buf,
USB_CTRL_SET_TIMEOUT);
@@ -293,7 +290,7 @@ static int pegasus_probe(struct usb_interface *intf,
endpoint = &intf->cur_altsetting->endpoint[0].desc;
- pegasus = kzalloc(sizeof(*pegasus), GFP_KERNEL);
+ pegasus = kzalloc_obj(*pegasus);
input_dev = input_allocate_device();
if (!pegasus || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/tablet/wacom_serial4.c b/drivers/input/tablet/wacom_serial4.c
index cf7cea77dabc..bc0c77e5487f 100644
--- a/drivers/input/tablet/wacom_serial4.c
+++ b/drivers/input/tablet/wacom_serial4.c
@@ -521,7 +521,7 @@ static int wacom_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err = -ENOMEM;
- wacom = kzalloc(sizeof(*wacom), GFP_KERNEL);
+ wacom = kzalloc_obj(*wacom);
input_dev = input_allocate_device();
if (!wacom || !input_dev)
goto free_device;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 7d5b72ee07fa..aeaf9a9cbb41 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -723,18 +723,6 @@ config TOUCHSCREEN_INEXIO
To compile this driver as a module, choose M here: the
module will be called inexio.
-config TOUCHSCREEN_MK712
- tristate "ICS MicroClock MK712 touchscreen"
- depends on ISA
- help
- Say Y here if you have the ICS MicroClock MK712 touchscreen
- controller chip in your system.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called mk712.
-
config TOUCHSCREEN_HP600
tristate "HP Jornada 6xx touchscreen"
depends on SH_HP6XX && SH_ADC
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index ab9abd151078..f2b002abebe8 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -68,7 +68,6 @@ obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
obj-$(CONFIG_TOUCHSCREEN_MMS114) += mms114.o
obj-$(CONFIG_TOUCHSCREEN_MSG2638) += msg2638.o
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
-obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
obj-$(CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS) += novatek-nvt-ts.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c
index c9aa1847265a..cc39057d0117 100644
--- a/drivers/input/touchscreen/ad7877.c
+++ b/drivers/input/touchscreen/ad7877.c
@@ -201,7 +201,7 @@ static int ad7877_read(struct spi_device *spi, u16 reg)
struct ser_req *req;
int status, ret;
- req = kzalloc(sizeof *req, GFP_KERNEL);
+ req = kzalloc_obj(*req);
if (!req)
return -ENOMEM;
@@ -232,7 +232,7 @@ static int ad7877_write(struct spi_device *spi, u16 reg, u16 val)
struct ser_req *req;
int status;
- req = kzalloc(sizeof *req, GFP_KERNEL);
+ req = kzalloc_obj(*req);
if (!req)
return -ENOMEM;
@@ -259,7 +259,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command)
int sample;
int i;
- req = kzalloc(sizeof *req, GFP_KERNEL);
+ req = kzalloc_obj(*req);
if (!req)
return -ENOMEM;
@@ -376,17 +376,14 @@ static inline void ad7877_ts_event_release(struct ad7877 *ts)
static void ad7877_timer(struct timer_list *t)
{
struct ad7877 *ts = timer_container_of(ts, t, timer);
- unsigned long flags;
- spin_lock_irqsave(&ts->lock, flags);
+ guard(spinlock_irqsave)(&ts->lock);
ad7877_ts_event_release(ts);
- spin_unlock_irqrestore(&ts->lock, flags);
}
static irqreturn_t ad7877_irq(int irq, void *handle)
{
struct ad7877 *ts = handle;
- unsigned long flags;
int error;
error = spi_sync(ts->spi, &ts->msg);
@@ -395,11 +392,13 @@ static irqreturn_t ad7877_irq(int irq, void *handle)
goto out;
}
- spin_lock_irqsave(&ts->lock, flags);
- error = ad7877_process_data(ts);
- if (!error)
+ scoped_guard(spinlock_irqsave, &ts->lock) {
+ error = ad7877_process_data(ts);
+ if (error)
+ goto out;
+
mod_timer(&ts->timer, jiffies + TS_PEN_UP_TIMEOUT);
- spin_unlock_irqrestore(&ts->lock, flags);
+ }
out:
return IRQ_HANDLED;
@@ -409,7 +408,7 @@ static void ad7877_disable(void *data)
{
struct ad7877 *ts = data;
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
if (!ts->disabled) {
ts->disabled = true;
@@ -423,20 +422,16 @@ static void ad7877_disable(void *data)
* We know the chip's in lowpower mode since we always
* leave it that way after every request
*/
-
- mutex_unlock(&ts->mutex);
}
static void ad7877_enable(struct ad7877 *ts)
{
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
if (ts->disabled) {
ts->disabled = false;
enable_irq(ts->spi->irq);
}
-
- mutex_unlock(&ts->mutex);
}
#define SHOW(name) static ssize_t \
@@ -509,10 +504,9 @@ static ssize_t ad7877_dac_store(struct device *dev,
if (error)
return error;
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
ts->dac = val & 0xFF;
ad7877_write(ts->spi, AD7877_REG_DAC, (ts->dac << 4) | AD7877_DAC_CONF);
- mutex_unlock(&ts->mutex);
return count;
}
@@ -539,11 +533,10 @@ static ssize_t ad7877_gpio3_store(struct device *dev,
if (error)
return error;
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
ts->gpio3 = !!val;
ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
(ts->gpio4 << 4) | (ts->gpio3 << 5));
- mutex_unlock(&ts->mutex);
return count;
}
@@ -570,11 +563,10 @@ static ssize_t ad7877_gpio4_store(struct device *dev,
if (error)
return error;
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
ts->gpio4 = !!val;
ad7877_write(ts->spi, AD7877_REG_EXTWRITE, AD7877_EXTW_GPIO_DATA |
(ts->gpio4 << 4) | (ts->gpio3 << 5));
- mutex_unlock(&ts->mutex);
return count;
}
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index 4c448f39bf57..31d2a3029d5f 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -305,15 +305,13 @@ static int __maybe_unused ad7879_suspend(struct device *dev)
{
struct ad7879 *ts = dev_get_drvdata(dev);
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
if (!ts->suspended && !ts->disabled && input_device_enabled(ts->input))
__ad7879_disable(ts);
ts->suspended = true;
- mutex_unlock(&ts->input->mutex);
-
return 0;
}
@@ -321,15 +319,13 @@ static int __maybe_unused ad7879_resume(struct device *dev)
{
struct ad7879 *ts = dev_get_drvdata(dev);
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
if (ts->suspended && !ts->disabled && input_device_enabled(ts->input))
__ad7879_enable(ts);
ts->suspended = false;
- mutex_unlock(&ts->input->mutex);
-
return 0;
}
@@ -338,7 +334,7 @@ EXPORT_SYMBOL(ad7879_pm_ops);
static void ad7879_toggle(struct ad7879 *ts, bool disable)
{
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
if (!ts->suspended && input_device_enabled(ts->input)) {
@@ -352,8 +348,6 @@ static void ad7879_toggle(struct ad7879 *ts, bool disable)
}
ts->disabled = disable;
-
- mutex_unlock(&ts->input->mutex);
}
static ssize_t ad7879_disable_show(struct device *dev,
@@ -403,23 +397,20 @@ static int ad7879_gpio_direction_input(struct gpio_chip *chip,
unsigned gpio)
{
struct ad7879 *ts = gpiochip_get_data(chip);
- int err;
- mutex_lock(&ts->mutex);
- ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL;
- err = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
- mutex_unlock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
- return err;
+ ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIODIR | AD7879_GPIOPOL;
+ return ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
}
static int ad7879_gpio_direction_output(struct gpio_chip *chip,
unsigned gpio, int level)
{
struct ad7879 *ts = gpiochip_get_data(chip);
- int err;
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
+
ts->cmd_crtl2 &= ~AD7879_GPIODIR;
ts->cmd_crtl2 |= AD7879_GPIO_EN | AD7879_GPIOPOL;
if (level)
@@ -427,21 +418,17 @@ static int ad7879_gpio_direction_output(struct gpio_chip *chip,
else
ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
- err = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
- mutex_unlock(&ts->mutex);
-
- return err;
+ return ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
}
-static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+static int ad7879_gpio_get_value(struct gpio_chip *chip, unsigned int gpio)
{
struct ad7879 *ts = gpiochip_get_data(chip);
u16 val;
- mutex_lock(&ts->mutex);
- val = ad7879_read(ts, AD7879_REG_CTRL2);
- mutex_unlock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
+ val = ad7879_read(ts, AD7879_REG_CTRL2);
return !!(val & AD7879_GPIO_DATA);
}
@@ -449,18 +436,15 @@ static int ad7879_gpio_set_value(struct gpio_chip *chip, unsigned int gpio,
int value)
{
struct ad7879 *ts = gpiochip_get_data(chip);
- int ret;
- mutex_lock(&ts->mutex);
+ guard(mutex)(&ts->mutex);
+
if (value)
ts->cmd_crtl2 |= AD7879_GPIO_DATA;
else
ts->cmd_crtl2 &= ~AD7879_GPIO_DATA;
- ret = ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
- mutex_unlock(&ts->mutex);
-
- return ret;
+ return ad7879_write(ts, AD7879_REG_CTRL2, ts->cmd_crtl2);
}
static int ad7879_gpio_add(struct ad7879 *ts)
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 67264c5b49cb..4b39f7212d35 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -289,7 +289,7 @@ static void __ads7846_enable(struct ads7846 *ts)
static void ads7846_disable(struct ads7846 *ts)
{
- mutex_lock(&ts->lock);
+ guard(mutex)(&ts->lock);
if (!ts->disabled) {
@@ -298,13 +298,11 @@ static void ads7846_disable(struct ads7846 *ts)
ts->disabled = true;
}
-
- mutex_unlock(&ts->lock);
}
static void ads7846_enable(struct ads7846 *ts)
{
- mutex_lock(&ts->lock);
+ guard(mutex)(&ts->lock);
if (ts->disabled) {
@@ -313,8 +311,6 @@ static void ads7846_enable(struct ads7846 *ts)
if (!ts->suspended)
__ads7846_enable(ts);
}
-
- mutex_unlock(&ts->lock);
}
/*--------------------------------------------------------------------------*/
@@ -354,10 +350,9 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
{
struct spi_device *spi = to_spi_device(dev);
struct ads7846 *ts = dev_get_drvdata(dev);
- struct ser_req *req;
int status;
- req = kzalloc(sizeof *req, GFP_KERNEL);
+ struct ser_req *req __free(kfree) = kzalloc_obj(*req);
if (!req)
return -ENOMEM;
@@ -418,11 +413,11 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
CS_CHANGE(req->xfer[7]);
spi_message_add_tail(&req->xfer[7], &req->msg);
- mutex_lock(&ts->lock);
- ads7846_stop(ts);
- status = spi_sync(spi, &req->msg);
- ads7846_restart(ts);
- mutex_unlock(&ts->lock);
+ scoped_guard(mutex, &ts->lock) {
+ ads7846_stop(ts);
+ status = spi_sync(spi, &req->msg);
+ ads7846_restart(ts);
+ }
if (status == 0) {
/* on-wire is a must-ignore bit, a BE12 value, then padding */
@@ -431,7 +426,6 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
status &= 0x0fff;
}
- kfree(req);
return status;
}
@@ -439,10 +433,9 @@ static int ads7845_read12_ser(struct device *dev, unsigned command)
{
struct spi_device *spi = to_spi_device(dev);
struct ads7846 *ts = dev_get_drvdata(dev);
- struct ads7845_ser_req *req;
int status;
- req = kzalloc(sizeof *req, GFP_KERNEL);
+ struct ads7845_ser_req *req __free(kfree) = kzalloc_obj(*req);
if (!req)
return -ENOMEM;
@@ -454,11 +447,11 @@ static int ads7845_read12_ser(struct device *dev, unsigned command)
req->xfer[0].len = 3;
spi_message_add_tail(&req->xfer[0], &req->msg);
- mutex_lock(&ts->lock);
- ads7846_stop(ts);
- status = spi_sync(spi, &req->msg);
- ads7846_restart(ts);
- mutex_unlock(&ts->lock);
+ scoped_guard(mutex, &ts->lock) {
+ ads7846_stop(ts);
+ status = spi_sync(spi, &req->msg);
+ ads7846_restart(ts);
+ }
if (status == 0) {
/* BE12 value, then padding */
@@ -467,7 +460,6 @@ static int ads7845_read12_ser(struct device *dev, unsigned command)
status &= 0x0fff;
}
- kfree(req);
return status;
}
@@ -966,7 +958,7 @@ static int ads7846_suspend(struct device *dev)
{
struct ads7846 *ts = dev_get_drvdata(dev);
- mutex_lock(&ts->lock);
+ guard(mutex)(&ts->lock);
if (!ts->suspended) {
@@ -979,8 +971,6 @@ static int ads7846_suspend(struct device *dev)
ts->suspended = true;
}
- mutex_unlock(&ts->lock);
-
return 0;
}
@@ -988,7 +978,7 @@ static int ads7846_resume(struct device *dev)
{
struct ads7846 *ts = dev_get_drvdata(dev);
- mutex_lock(&ts->lock);
+ guard(mutex)(&ts->lock);
if (ts->suspended) {
@@ -1001,8 +991,6 @@ static int ads7846_resume(struct device *dev)
__ads7846_enable(ts);
}
- mutex_unlock(&ts->lock);
-
return 0;
}
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index dd0544cc1bc1..87c6a10381f2 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -713,12 +713,11 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
const void *val)
{
bool retried = false;
- u8 *buf;
- size_t count;
+ size_t count = len + 2;
+ int error;
int ret;
- count = len + 2;
- buf = kmalloc(count, GFP_KERNEL);
+ u8 *buf __free(kfree) = kmalloc(count, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -728,20 +727,17 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
retry:
ret = i2c_master_send(client, buf, count);
- if (ret == count) {
- ret = 0;
- } else if (!retried && mxt_wakeup_toggle(client, true, true)) {
+ if (ret == count)
+ return 0;
+
+ if (!retried && mxt_wakeup_toggle(client, true, true)) {
retried = true;
goto retry;
- } else {
- if (ret >= 0)
- ret = -EIO;
- dev_err(&client->dev, "%s: i2c send failed (%d)\n",
- __func__, ret);
}
- kfree(buf);
- return ret;
+ error = ret < 0 ? ret : -EIO;
+ dev_err(&client->dev, "%s: i2c send failed (%d)\n", __func__, error);
+ return error;
}
static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
@@ -1547,14 +1543,15 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
{
struct device *dev = &data->client->dev;
struct mxt_cfg cfg;
- int ret;
+ int error;
int offset;
int i;
u32 info_crc, config_crc, calculated_crc;
u16 crc_start = 0;
/* Make zero terminated copy of the OBP_RAW file */
- cfg.raw = kmemdup_nul(fw->data, fw->size, GFP_KERNEL);
+ u8 *raw_buf __free(kfree) = cfg.raw = kmemdup_nul(fw->data, fw->size,
+ GFP_KERNEL);
if (!cfg.raw)
return -ENOMEM;
@@ -1564,21 +1561,17 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
if (strncmp(cfg.raw, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
dev_err(dev, "Unrecognised config file\n");
- ret = -EINVAL;
- goto release_raw;
+ return -EINVAL;
}
cfg.raw_pos = strlen(MXT_CFG_MAGIC);
/* Load information block and check */
for (i = 0; i < sizeof(struct mxt_info); i++) {
- ret = sscanf(cfg.raw + cfg.raw_pos, "%hhx%n",
- (unsigned char *)&cfg.info + i,
- &offset);
- if (ret != 1) {
+ if (sscanf(cfg.raw + cfg.raw_pos, "%hhx%n",
+ (unsigned char *)&cfg.info + i, &offset) != 1) {
dev_err(dev, "Bad format\n");
- ret = -EINVAL;
- goto release_raw;
+ return -EINVAL;
}
cfg.raw_pos += offset;
@@ -1586,30 +1579,24 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
if (cfg.info.family_id != data->info->family_id) {
dev_err(dev, "Family ID mismatch!\n");
- ret = -EINVAL;
- goto release_raw;
+ return -EINVAL;
}
if (cfg.info.variant_id != data->info->variant_id) {
dev_err(dev, "Variant ID mismatch!\n");
- ret = -EINVAL;
- goto release_raw;
+ return -EINVAL;
}
/* Read CRCs */
- ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &info_crc, &offset);
- if (ret != 1) {
+ if (sscanf(cfg.raw + cfg.raw_pos, "%x%n", &info_crc, &offset) != 1) {
dev_err(dev, "Bad format: failed to parse Info CRC\n");
- ret = -EINVAL;
- goto release_raw;
+ return -EINVAL;
}
cfg.raw_pos += offset;
- ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &config_crc, &offset);
- if (ret != 1) {
+ if (sscanf(cfg.raw + cfg.raw_pos, "%x%n", &config_crc, &offset) != 1) {
dev_err(dev, "Bad format: failed to parse Config CRC\n");
- ret = -EINVAL;
- goto release_raw;
+ return -EINVAL;
}
cfg.raw_pos += offset;
@@ -1625,8 +1612,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
} else if (config_crc == data->config_crc) {
dev_dbg(dev, "Config CRC 0x%06X: OK\n",
data->config_crc);
- ret = 0;
- goto release_raw;
+ return 0;
} else {
dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n",
data->config_crc, config_crc);
@@ -1642,15 +1628,14 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
data->info->object_num * sizeof(struct mxt_object) +
MXT_INFO_CHECKSUM_SIZE;
cfg.mem_size = data->mem_size - cfg.start_ofs;
- cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL);
- if (!cfg.mem) {
- ret = -ENOMEM;
- goto release_raw;
- }
- ret = mxt_prepare_cfg_mem(data, &cfg);
- if (ret)
- goto release_mem;
+ u8 *mem_buf __free(kfree) = cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL);
+ if (!cfg.mem)
+ return -ENOMEM;
+
+ error = mxt_prepare_cfg_mem(data, &cfg);
+ if (error)
+ return error;
/* Calculate crc of the received configs (not the raw config file) */
if (data->T71_address)
@@ -1670,30 +1655,26 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
calculated_crc, config_crc);
}
- ret = mxt_upload_cfg_mem(data, &cfg);
- if (ret)
- goto release_mem;
+ error = mxt_upload_cfg_mem(data, &cfg);
+ if (error)
+ return error;
mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
- ret = mxt_check_retrigen(data);
- if (ret)
- goto release_mem;
+ error = mxt_check_retrigen(data);
+ if (error)
+ return error;
- ret = mxt_soft_reset(data);
- if (ret)
- goto release_mem;
+ error = mxt_soft_reset(data);
+ if (error)
+ return error;
dev_info(dev, "Config successfully updated\n");
/* T7 config may have changed */
mxt_init_t7_power_cfg(data);
-release_mem:
- kfree(cfg.mem);
-release_raw:
- kfree(cfg.raw);
- return ret;
+ return 0;
}
static void mxt_free_input_device(struct mxt_data *data)
@@ -1857,7 +1838,6 @@ static int mxt_read_info_block(struct mxt_data *data)
struct i2c_client *client = data->client;
int error;
size_t size;
- void *id_buf, *buf;
uint8_t num_objects;
u32 calculated_crc;
u8 *crc_ptr;
@@ -1868,24 +1848,23 @@ static int mxt_read_info_block(struct mxt_data *data)
/* Read 7-byte ID information block starting at address 0 */
size = sizeof(struct mxt_info);
- id_buf = kzalloc(size, GFP_KERNEL);
+ void *id_buf __free(kfree) = kzalloc(size, GFP_KERNEL);
if (!id_buf)
return -ENOMEM;
error = __mxt_read_reg(client, 0, size, id_buf);
if (error)
- goto err_free_mem;
+ return error;
/* Resize buffer to give space for rest of info block */
num_objects = ((struct mxt_info *)id_buf)->object_num;
size += (num_objects * sizeof(struct mxt_object))
+ MXT_INFO_CHECKSUM_SIZE;
- buf = krealloc(id_buf, size, GFP_KERNEL);
- if (!buf) {
- error = -ENOMEM;
- goto err_free_mem;
- }
+ void *buf = krealloc(id_buf, size, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
id_buf = buf;
/* Read rest of info block */
@@ -1893,7 +1872,7 @@ static int mxt_read_info_block(struct mxt_data *data)
size - MXT_OBJECT_START,
id_buf + MXT_OBJECT_START);
if (error)
- goto err_free_mem;
+ return error;
/* Extract & calculate checksum */
crc_ptr = id_buf + size - MXT_INFO_CHECKSUM_SIZE;
@@ -1910,12 +1889,11 @@ static int mxt_read_info_block(struct mxt_data *data)
dev_err(&client->dev,
"Info Block CRC error calculated=0x%06X read=0x%06X\n",
calculated_crc, data->info_crc);
- error = -EIO;
- goto err_free_mem;
+ return -EIO;
}
- data->raw_info_block = id_buf;
- data->info = (struct mxt_info *)id_buf;
+ data->raw_info_block = no_free_ptr(id_buf);
+ data->info = (struct mxt_info *)data->raw_info_block;
dev_info(&client->dev,
"Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
@@ -1924,20 +1902,18 @@ static int mxt_read_info_block(struct mxt_data *data)
data->info->build, data->info->object_num);
/* Parse object table information */
- error = mxt_parse_object_table(data, id_buf + MXT_OBJECT_START);
+ error = mxt_parse_object_table(data,
+ data->raw_info_block + MXT_OBJECT_START);
if (error) {
dev_err(&client->dev, "Error %d parsing object table\n", error);
mxt_free_object_table(data);
return error;
}
- data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START);
+ data->object_table =
+ (struct mxt_object *)(data->raw_info_block + MXT_OBJECT_START);
return 0;
-
-err_free_mem:
- kfree(id_buf);
- return error;
}
static int mxt_read_t9_resolution(struct mxt_data *data)
@@ -2914,70 +2890,38 @@ static int mxt_check_firmware_format(struct device *dev,
return -EINVAL;
}
-static int mxt_load_fw(struct device *dev, const char *fn)
+static int mxt_flash_fw(struct mxt_data *data, const struct firmware *fw)
{
- struct mxt_data *data = dev_get_drvdata(dev);
- const struct firmware *fw = NULL;
+ struct device *dev = &data->client->dev;
unsigned int frame_size;
unsigned int pos = 0;
unsigned int retry = 0;
unsigned int frame = 0;
- int ret;
-
- ret = request_firmware(&fw, fn, dev);
- if (ret) {
- dev_err(dev, "Unable to open firmware %s\n", fn);
- return ret;
- }
-
- /* Check for incorrect enc file */
- ret = mxt_check_firmware_format(dev, fw);
- if (ret)
- goto release_firmware;
-
- if (!data->in_bootloader) {
- /* Change to the bootloader mode */
- data->in_bootloader = true;
-
- ret = mxt_t6_command(data, MXT_COMMAND_RESET,
- MXT_BOOT_VALUE, false);
- if (ret)
- goto release_firmware;
-
- msleep(MXT_RESET_TIME);
-
- /* Do not need to scan since we know family ID */
- ret = mxt_lookup_bootloader_address(data, 0);
- if (ret)
- goto release_firmware;
-
- mxt_free_input_device(data);
- mxt_free_object_table(data);
- } else {
- enable_irq(data->irq);
- }
+ int error;
reinit_completion(&data->bl_completion);
- ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
- if (ret) {
+ error = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
+ if (error) {
/* Bootloader may still be unlocked from previous attempt */
- ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, false);
- if (ret)
- goto disable_irq;
+ error = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA,
+ false);
+ if (error)
+ return error;
} else {
dev_info(dev, "Unlocking bootloader\n");
/* Unlock bootloader */
- ret = mxt_send_bootloader_cmd(data, true);
- if (ret)
- goto disable_irq;
+ error = mxt_send_bootloader_cmd(data, true);
+ if (error)
+ return error;
}
while (pos < fw->size) {
- ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, true);
- if (ret)
- goto disable_irq;
+ error = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA,
+ true);
+ if (error)
+ return error;
frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
@@ -2985,12 +2929,12 @@ static int mxt_load_fw(struct device *dev, const char *fn)
frame_size += 2;
/* Write one frame to device */
- ret = mxt_bootloader_write(data, fw->data + pos, frame_size);
- if (ret)
- goto disable_irq;
+ error = mxt_bootloader_write(data, fw->data + pos, frame_size);
+ if (error)
+ return error;
- ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS, true);
- if (ret) {
+ error = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS, true);
+ if (error) {
retry++;
/* Back off by 20ms per retry */
@@ -2998,7 +2942,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
if (retry > 20) {
dev_err(dev, "Retry count exceeded\n");
- goto disable_irq;
+ return error;
}
} else {
retry = 0;
@@ -3012,10 +2956,10 @@ static int mxt_load_fw(struct device *dev, const char *fn)
}
/* Wait for flash. */
- ret = mxt_wait_for_completion(data, &data->bl_completion,
- MXT_FW_RESET_TIME);
- if (ret)
- goto disable_irq;
+ error = mxt_wait_for_completion(data, &data->bl_completion,
+ MXT_FW_RESET_TIME);
+ if (error)
+ return error;
dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos);
@@ -3025,14 +2969,56 @@ static int mxt_load_fw(struct device *dev, const char *fn)
* errors.
*/
mxt_wait_for_completion(data, &data->bl_completion, MXT_FW_RESET_TIME);
-
data->in_bootloader = false;
-disable_irq:
+ return 0;
+}
+
+static int mxt_load_fw(struct device *dev, const char *fn)
+{
+ struct mxt_data *data = dev_get_drvdata(dev);
+ int retval;
+ int error;
+
+ const struct firmware *fw __free(firmware) = NULL;
+ error = request_firmware(&fw, fn, dev);
+ if (error) {
+ dev_err(dev, "Unable to open firmware %s\n", fn);
+ return error;
+ }
+
+ /* Check for incorrect enc file */
+ error = mxt_check_firmware_format(dev, fw);
+ if (error)
+ return error;
+
+ if (!data->in_bootloader) {
+ /* Change to the bootloader mode */
+ data->in_bootloader = true;
+
+ error = mxt_t6_command(data, MXT_COMMAND_RESET,
+ MXT_BOOT_VALUE, false);
+ if (error)
+ return error;
+
+ msleep(MXT_RESET_TIME);
+
+ /* Do not need to scan since we know family ID */
+ error = mxt_lookup_bootloader_address(data, 0);
+ if (error)
+ return error;
+
+ mxt_free_input_device(data);
+ mxt_free_object_table(data);
+ } else {
+ enable_irq(data->irq);
+ }
+
+ retval = mxt_flash_fw(data, fw);
+
disable_irq(data->irq);
-release_firmware:
- release_firmware(fw);
- return ret;
+
+ return retval;
}
static ssize_t mxt_update_fw_store(struct device *dev,
@@ -3375,12 +3361,10 @@ static int mxt_suspend(struct device *dev)
if (!input_dev)
return 0;
- mutex_lock(&input_dev->mutex);
-
- if (input_device_enabled(input_dev))
- mxt_stop(data);
-
- mutex_unlock(&input_dev->mutex);
+ scoped_guard(mutex, &input_dev->mutex) {
+ if (input_device_enabled(input_dev))
+ mxt_stop(data);
+ }
disable_irq(data->irq);
@@ -3398,12 +3382,10 @@ static int mxt_resume(struct device *dev)
enable_irq(data->irq);
- mutex_lock(&input_dev->mutex);
-
- if (input_device_enabled(input_dev))
- mxt_start(data);
-
- mutex_unlock(&input_dev->mutex);
+ scoped_guard(mutex, &input_dev->mutex) {
+ if (input_device_enabled(input_dev))
+ mxt_start(data);
+ }
return 0;
}
diff --git a/drivers/input/touchscreen/auo-pixcir-ts.c b/drivers/input/touchscreen/auo-pixcir-ts.c
index 363a4a1f1560..401b2264f585 100644
--- a/drivers/input/touchscreen/auo-pixcir-ts.c
+++ b/drivers/input/touchscreen/auo-pixcir-ts.c
@@ -415,9 +415,9 @@ static int auo_pixcir_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
struct input_dev *input = ts->input;
- int ret = 0;
+ int error;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
/* when configured as wakeup source, device should always wake system
* therefore start device if necessary
@@ -425,21 +425,23 @@ static int auo_pixcir_suspend(struct device *dev)
if (device_may_wakeup(&client->dev)) {
/* need to start device if not open, to be wakeup source */
if (!input_device_enabled(input)) {
- ret = auo_pixcir_start(ts);
- if (ret)
- goto unlock;
+ error = auo_pixcir_start(ts);
+ if (error)
+ return error;
}
enable_irq_wake(client->irq);
- ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP);
+ error = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP);
+ if (error)
+ return error;
+
} else if (input_device_enabled(input)) {
- ret = auo_pixcir_stop(ts);
+ error = auo_pixcir_stop(ts);
+ if (error)
+ return error;
}
-unlock:
- mutex_unlock(&input->mutex);
-
- return ret;
+ return 0;
}
static int auo_pixcir_resume(struct device *dev)
@@ -447,29 +449,28 @@ static int auo_pixcir_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct auo_pixcir_ts *ts = i2c_get_clientdata(client);
struct input_dev *input = ts->input;
- int ret = 0;
+ int error;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (device_may_wakeup(&client->dev)) {
disable_irq_wake(client->irq);
/* need to stop device if it was not open on suspend */
if (!input_device_enabled(input)) {
- ret = auo_pixcir_stop(ts);
- if (ret)
- goto unlock;
+ error = auo_pixcir_stop(ts);
+ if (error)
+ return error;
}
/* device wakes automatically from SLEEP */
} else if (input_device_enabled(input)) {
- ret = auo_pixcir_start(ts);
+ error = auo_pixcir_start(ts);
+ if (error)
+ return error;
}
-unlock:
- mutex_unlock(&input->mutex);
-
- return ret;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops,
diff --git a/drivers/input/touchscreen/bu21029_ts.c b/drivers/input/touchscreen/bu21029_ts.c
index 64f474e67312..68d9cd55ceeb 100644
--- a/drivers/input/touchscreen/bu21029_ts.c
+++ b/drivers/input/touchscreen/bu21029_ts.c
@@ -416,10 +416,10 @@ static int bu21029_suspend(struct device *dev)
struct bu21029_ts_data *bu21029 = i2c_get_clientdata(i2c);
if (!device_may_wakeup(dev)) {
- mutex_lock(&bu21029->in_dev->mutex);
+ guard(mutex)(&bu21029->in_dev->mutex);
+
if (input_device_enabled(bu21029->in_dev))
bu21029_stop_chip(bu21029->in_dev);
- mutex_unlock(&bu21029->in_dev->mutex);
}
return 0;
@@ -431,10 +431,10 @@ static int bu21029_resume(struct device *dev)
struct bu21029_ts_data *bu21029 = i2c_get_clientdata(i2c);
if (!device_may_wakeup(dev)) {
- mutex_lock(&bu21029->in_dev->mutex);
+ guard(mutex)(&bu21029->in_dev->mutex);
+
if (input_device_enabled(bu21029->in_dev))
bu21029_start_chip(bu21029->in_dev);
- mutex_unlock(&bu21029->in_dev->mutex);
}
return 0;
diff --git a/drivers/input/touchscreen/chipone_icn8318.c b/drivers/input/touchscreen/chipone_icn8318.c
index d6876d10b252..1b10a757313c 100644
--- a/drivers/input/touchscreen/chipone_icn8318.c
+++ b/drivers/input/touchscreen/chipone_icn8318.c
@@ -152,10 +152,10 @@ static int icn8318_suspend(struct device *dev)
{
struct icn8318_data *data = i2c_get_clientdata(to_i2c_client(dev));
- mutex_lock(&data->input->mutex);
+ guard(mutex)(&data->input->mutex);
+
if (input_device_enabled(data->input))
icn8318_stop(data->input);
- mutex_unlock(&data->input->mutex);
return 0;
}
@@ -164,10 +164,10 @@ static int icn8318_resume(struct device *dev)
{
struct icn8318_data *data = i2c_get_clientdata(to_i2c_client(dev));
- mutex_lock(&data->input->mutex);
+ guard(mutex)(&data->input->mutex);
+
if (input_device_enabled(data->input))
icn8318_start(data->input);
- mutex_unlock(&data->input->mutex);
return 0;
}
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
index 9e729910fbc8..012dfcae01cc 100644
--- a/drivers/input/touchscreen/cyttsp_core.c
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -494,34 +494,30 @@ static int cyttsp_disable(struct cyttsp *ts)
static int cyttsp_suspend(struct device *dev)
{
struct cyttsp *ts = dev_get_drvdata(dev);
- int retval = 0;
+ int error;
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
if (input_device_enabled(ts->input)) {
- retval = cyttsp_disable(ts);
- if (retval == 0)
- ts->suspended = true;
+ error = cyttsp_disable(ts);
+ if (error)
+ return error;
}
- mutex_unlock(&ts->input->mutex);
-
- return retval;
+ ts->suspended = true;
+ return 0;
}
static int cyttsp_resume(struct device *dev)
{
struct cyttsp *ts = dev_get_drvdata(dev);
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
if (input_device_enabled(ts->input))
cyttsp_enable(ts);
ts->suspended = false;
-
- mutex_unlock(&ts->input->mutex);
-
return 0;
}
diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c
index c2d3252f8466..a8e3d85eece7 100644
--- a/drivers/input/touchscreen/da9052_tsi.c
+++ b/drivers/input/touchscreen/da9052_tsi.c
@@ -232,7 +232,7 @@ static int da9052_ts_probe(struct platform_device *pdev)
if (!da9052)
return -EINVAL;
- tsi = kzalloc(sizeof(*tsi), GFP_KERNEL);
+ tsi = kzalloc_obj(*tsi);
input_dev = input_allocate_device();
if (!tsi || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c
index 998d5ca8071e..943ba8c2fb6c 100644
--- a/drivers/input/touchscreen/dynapro.c
+++ b/drivers/input/touchscreen/dynapro.c
@@ -110,7 +110,7 @@ static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- pdynapro = kzalloc(sizeof(*pdynapro), GFP_KERNEL);
+ pdynapro = kzalloc_obj(*pdynapro);
input_dev = input_allocate_device();
if (!pdynapro || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index d0ab644be006..d3b1177185a3 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -380,16 +380,13 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
container_of(dattr, struct edt_ft5x06_attribute, dattr);
u8 *field = (u8 *)tsdata + attr->field_offset;
unsigned int val;
- size_t count = 0;
- int error = 0;
+ int error;
u8 addr;
- mutex_lock(&tsdata->mutex);
+ guard(mutex)(&tsdata->mutex);
- if (tsdata->factory_mode) {
- error = -EIO;
- goto out;
- }
+ if (tsdata->factory_mode)
+ return -EIO;
switch (tsdata->version) {
case EDT_M06:
@@ -407,8 +404,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
break;
default:
- error = -ENODEV;
- goto out;
+ return -ENODEV;
}
if (addr != NO_REGISTER) {
@@ -417,7 +413,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
dev_err(&tsdata->client->dev,
"Failed to fetch attribute %s, error %d\n",
dattr->attr.name, error);
- goto out;
+ return error;
}
} else {
val = *field;
@@ -430,10 +426,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
*field = val;
}
- count = sysfs_emit(buf, "%d\n", val);
-out:
- mutex_unlock(&tsdata->mutex);
- return error ?: count;
+ return sysfs_emit(buf, "%d\n", val);
}
static ssize_t edt_ft5x06_setting_store(struct device *dev,
@@ -449,21 +442,17 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
int error;
u8 addr;
- mutex_lock(&tsdata->mutex);
+ guard(mutex)(&tsdata->mutex);
- if (tsdata->factory_mode) {
- error = -EIO;
- goto out;
- }
+ if (tsdata->factory_mode)
+ return -EIO;
error = kstrtouint(buf, 0, &val);
if (error)
- goto out;
+ return error;
- if (val < attr->limit_low || val > attr->limit_high) {
- error = -ERANGE;
- goto out;
- }
+ if (val < attr->limit_low || val > attr->limit_high)
+ return -ERANGE;
switch (tsdata->version) {
case EDT_M06:
@@ -481,8 +470,7 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
break;
default:
- error = -ENODEV;
- goto out;
+ return -ENODEV;
}
if (addr != NO_REGISTER) {
@@ -491,14 +479,12 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
dev_err(&tsdata->client->dev,
"Failed to update attribute %s, error: %d\n",
dattr->attr.name, error);
- goto out;
+ return error;
}
}
*field = val;
-out:
- mutex_unlock(&tsdata->mutex);
- return error ?: count;
+ return count;
}
/* m06, m09: range 0-31, m12: range 0-5 */
@@ -714,21 +700,17 @@ static int edt_ft5x06_debugfs_mode_get(void *data, u64 *mode)
static int edt_ft5x06_debugfs_mode_set(void *data, u64 mode)
{
struct edt_ft5x06_ts_data *tsdata = data;
- int retval = 0;
if (mode > 1)
return -ERANGE;
- mutex_lock(&tsdata->mutex);
-
- if (mode != tsdata->factory_mode) {
- retval = mode ? edt_ft5x06_factory_mode(tsdata) :
- edt_ft5x06_work_mode(tsdata);
- }
+ guard(mutex)(&tsdata->mutex);
- mutex_unlock(&tsdata->mutex);
+ if (mode == tsdata->factory_mode)
+ return 0;
- return retval;
+ return mode ? edt_ft5x06_factory_mode(tsdata) :
+ edt_ft5x06_work_mode(tsdata);
};
DEFINE_SIMPLE_ATTRIBUTE(debugfs_mode_fops, edt_ft5x06_debugfs_mode_get,
@@ -750,18 +732,16 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
if (*off < 0 || *off >= tsdata->raw_bufsize)
return 0;
- mutex_lock(&tsdata->mutex);
+ guard(mutex)(&tsdata->mutex);
- if (!tsdata->factory_mode || !tsdata->raw_buffer) {
- error = -EIO;
- goto out;
- }
+ if (!tsdata->factory_mode || !tsdata->raw_buffer)
+ return -EIO;
error = regmap_write(tsdata->regmap, 0x08, 0x01);
if (error) {
dev_err(&client->dev,
"failed to write 0x08 register, error %d\n", error);
- goto out;
+ return error;
}
do {
@@ -771,7 +751,7 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
dev_err(&client->dev,
"failed to read 0x08 register, error %d\n",
error);
- goto out;
+ return error;
}
if (val == 1)
@@ -781,8 +761,7 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
if (retries == 0) {
dev_err(&client->dev,
"timed out waiting for register to settle\n");
- error = -ETIMEDOUT;
- goto out;
+ return -ETIMEDOUT;
}
rdbuf = tsdata->raw_buffer;
@@ -792,21 +771,17 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
rdbuf[0] = i; /* column index */
error = regmap_bulk_read(tsdata->regmap, 0xf5, rdbuf, colbytes);
if (error)
- goto out;
+ return error;
rdbuf += colbytes;
}
read = min_t(size_t, count, tsdata->raw_bufsize - *off);
- if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) {
- error = -EFAULT;
- goto out;
- }
+ if (copy_to_user(buf, tsdata->raw_buffer + *off, read))
+ return -EFAULT;
*off += read;
-out:
- mutex_unlock(&tsdata->mutex);
- return error ?: read;
+ return read;
};
static const struct file_operations debugfs_raw_data_fops = {
@@ -829,7 +804,10 @@ static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata)
static void edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata)
{
+ guard(mutex)(&tsdata->mutex);
+
kfree(tsdata->raw_buffer);
+ tsdata->raw_buffer = NULL;
}
#else
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 87eb18977b71..492e19a28a74 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -89,7 +89,7 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
struct eeti_ts *eeti = dev_id;
int error;
- mutex_lock(&eeti->mutex);
+ guard(mutex)(&eeti->mutex);
do {
/*
@@ -109,13 +109,12 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
} while (eeti->running && eeti->attn_gpio);
- mutex_unlock(&eeti->mutex);
return IRQ_HANDLED;
}
static void eeti_ts_start(struct eeti_ts *eeti)
{
- mutex_lock(&eeti->mutex);
+ guard(mutex)(&eeti->mutex);
eeti->running = true;
enable_irq(eeti->client->irq);
@@ -127,8 +126,6 @@ static void eeti_ts_start(struct eeti_ts *eeti)
*/
if (eeti->attn_gpio && gpiod_get_value_cansleep(eeti->attn_gpio))
eeti_ts_read(eeti);
-
- mutex_unlock(&eeti->mutex);
}
static void eeti_ts_stop(struct eeti_ts *eeti)
@@ -238,12 +235,10 @@ static int eeti_ts_suspend(struct device *dev)
struct eeti_ts *eeti = i2c_get_clientdata(client);
struct input_dev *input_dev = eeti->input;
- mutex_lock(&input_dev->mutex);
-
- if (input_device_enabled(input_dev))
- eeti_ts_stop(eeti);
-
- mutex_unlock(&input_dev->mutex);
+ scoped_guard(mutex, &input_dev->mutex) {
+ if (input_device_enabled(input_dev))
+ eeti_ts_stop(eeti);
+ }
if (device_may_wakeup(&client->dev))
enable_irq_wake(client->irq);
@@ -260,12 +255,10 @@ static int eeti_ts_resume(struct device *dev)
if (device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
- mutex_lock(&input_dev->mutex);
-
- if (input_device_enabled(input_dev))
- eeti_ts_start(eeti);
-
- mutex_unlock(&input_dev->mutex);
+ scoped_guard(mutex, &input_dev->mutex) {
+ if (input_device_enabled(input_dev))
+ eeti_ts_start(eeti);
+ }
return 0;
}
diff --git a/drivers/input/touchscreen/egalax_ts_serial.c b/drivers/input/touchscreen/egalax_ts_serial.c
index 5f284490a298..e04ea1fea4ad 100644
--- a/drivers/input/touchscreen/egalax_ts_serial.c
+++ b/drivers/input/touchscreen/egalax_ts_serial.c
@@ -99,7 +99,7 @@ static int egalax_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int error;
- egalax = kzalloc(sizeof(*egalax), GFP_KERNEL);
+ egalax = kzalloc_obj(*egalax);
input_dev = input_allocate_device();
if (!egalax || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c
index 46a0611fac82..572a37d4e0aa 100644
--- a/drivers/input/touchscreen/ektf2127.c
+++ b/drivers/input/touchscreen/ektf2127.c
@@ -187,10 +187,10 @@ static int ektf2127_suspend(struct device *dev)
{
struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
+
if (input_device_enabled(ts->input))
ektf2127_stop(ts->input);
- mutex_unlock(&ts->input->mutex);
return 0;
}
@@ -199,10 +199,10 @@ static int ektf2127_resume(struct device *dev)
{
struct ektf2127_ts *ts = i2c_get_clientdata(to_i2c_client(dev));
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
+
if (input_device_enabled(ts->input))
ektf2127_start(ts->input);
- mutex_unlock(&ts->input->mutex);
return 0;
}
diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
index 3fd170f75b4a..835d91dff0a4 100644
--- a/drivers/input/touchscreen/elants_i2c.c
+++ b/drivers/input/touchscreen/elants_i2c.c
@@ -303,15 +303,13 @@ static int elants_i2c_calibrate(struct elants_data *ts)
static const u8 rek[] = { CMD_HEADER_WRITE, 0x29, 0x00, 0x01 };
static const u8 rek_resp[] = { CMD_HEADER_REK, 0x66, 0x66, 0x66 };
- disable_irq(client->irq);
-
- ts->state = ELAN_WAIT_RECALIBRATION;
- reinit_completion(&ts->cmd_done);
-
- elants_i2c_send(client, w_flashkey, sizeof(w_flashkey));
- elants_i2c_send(client, rek, sizeof(rek));
+ scoped_guard(disable_irq, &client->irq) {
+ ts->state = ELAN_WAIT_RECALIBRATION;
+ reinit_completion(&ts->cmd_done);
- enable_irq(client->irq);
+ elants_i2c_send(client, w_flashkey, sizeof(w_flashkey));
+ elants_i2c_send(client, rek, sizeof(rek));
+ }
ret = wait_for_completion_interruptible_timeout(&ts->cmd_done,
msecs_to_jiffies(ELAN_CALI_TIMEOUT_MSEC));
@@ -906,17 +904,17 @@ static int elants_i2c_do_update_firmware(struct i2c_client *client,
static int elants_i2c_fw_update(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
- const struct firmware *fw;
- char *fw_name;
int error;
- fw_name = kasprintf(GFP_KERNEL, "elants_i2c_%04x.bin", ts->hw_version);
+ const char *fw_name __free(kfree) =
+ kasprintf(GFP_KERNEL, "elants_i2c_%04x.bin", ts->hw_version);
if (!fw_name)
return -ENOMEM;
dev_info(&client->dev, "requesting fw name = %s\n", fw_name);
+
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, fw_name, &client->dev);
- kfree(fw_name);
if (error) {
dev_err(&client->dev, "failed to request firmware: %d\n",
error);
@@ -926,40 +924,32 @@ static int elants_i2c_fw_update(struct elants_data *ts)
if (fw->size % ELAN_FW_PAGESIZE) {
dev_err(&client->dev, "invalid firmware length: %zu\n",
fw->size);
- error = -EINVAL;
- goto out;
+ return -EINVAL;
}
- disable_irq(client->irq);
+ scoped_guard(disable_irq, &client->irq) {
+ bool force_update = ts->iap_mode == ELAN_IAP_RECOVERY;
- error = elants_i2c_do_update_firmware(client, fw,
- ts->iap_mode == ELAN_IAP_RECOVERY);
- if (error) {
- dev_err(&client->dev, "firmware update failed: %d\n", error);
- ts->iap_mode = ELAN_IAP_RECOVERY;
- goto out_enable_irq;
- }
+ error = elants_i2c_do_update_firmware(client, fw, force_update);
+ if (error) {
+ dev_err(&client->dev, "firmware update failed: %d\n",
+ error);
+ } else {
+ error = elants_i2c_initialize(ts);
+ if (error)
+ dev_err(&client->dev,
+ "failed to initialize device after firmware update: %d\n",
+ error);
+ }
- error = elants_i2c_initialize(ts);
- if (error) {
- dev_err(&client->dev,
- "failed to initialize device after firmware update: %d\n",
- error);
- ts->iap_mode = ELAN_IAP_RECOVERY;
- goto out_enable_irq;
+ ts->iap_mode = error ? ELAN_IAP_RECOVERY : ELAN_IAP_OPERATIONAL;
+ ts->state = ELAN_STATE_NORMAL;
}
-
- ts->iap_mode = ELAN_IAP_OPERATIONAL;
-
-out_enable_irq:
- ts->state = ELAN_STATE_NORMAL;
- enable_irq(client->irq);
msleep(100);
if (!error)
elants_i2c_calibrate(ts);
-out:
- release_firmware(fw);
+
return error;
}
@@ -1186,14 +1176,13 @@ static ssize_t calibrate_store(struct device *dev,
struct elants_data *ts = i2c_get_clientdata(client);
int error;
- error = mutex_lock_interruptible(&ts->sysfs_mutex);
- if (error)
- return error;
-
- error = elants_i2c_calibrate(ts);
+ scoped_cond_guard(mutex_intr, return -EINTR, &ts->sysfs_mutex) {
+ error = elants_i2c_calibrate(ts);
+ if (error)
+ return error;
+ }
- mutex_unlock(&ts->sysfs_mutex);
- return error ?: count;
+ return count;
}
static ssize_t write_update_fw(struct device *dev,
@@ -1204,15 +1193,13 @@ static ssize_t write_update_fw(struct device *dev,
struct elants_data *ts = i2c_get_clientdata(client);
int error;
- error = mutex_lock_interruptible(&ts->sysfs_mutex);
- if (error)
- return error;
-
- error = elants_i2c_fw_update(ts);
- dev_dbg(dev, "firmware update result: %d\n", error);
+ scoped_cond_guard(mutex_intr, return -EINTR, &ts->sysfs_mutex) {
+ error = elants_i2c_fw_update(ts);
+ if (error)
+ return error;
+ }
- mutex_unlock(&ts->sysfs_mutex);
- return error ?: count;
+ return count;
}
static ssize_t show_iap_mode(struct device *dev,
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 137a5f69b83e..6814d5789b6f 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -219,40 +219,40 @@ static irqreturn_t elo_interrupt(struct serio *serio,
static int elo_command_10(struct elo *elo, unsigned char *packet)
{
- int rc = -1;
+ int error;
int i;
unsigned char csum = 0xaa + ELO10_LEAD_BYTE;
- mutex_lock(&elo->cmd_mutex);
+ guard(mutex)(&elo->cmd_mutex);
scoped_guard(serio_pause_rx, elo->serio) {
elo->expected_packet = toupper(packet[0]);
init_completion(&elo->cmd_done);
}
- if (serio_write(elo->serio, ELO10_LEAD_BYTE))
- goto out;
+ error = serio_write(elo->serio, ELO10_LEAD_BYTE);
+ if (error)
+ return error;
for (i = 0; i < ELO10_PACKET_LEN; i++) {
csum += packet[i];
- if (serio_write(elo->serio, packet[i]))
- goto out;
+ error = serio_write(elo->serio, packet[i]);
+ if (error)
+ return error;
}
- if (serio_write(elo->serio, csum))
- goto out;
+ error = serio_write(elo->serio, csum);
+ if (error)
+ return error;
wait_for_completion_timeout(&elo->cmd_done, HZ);
- if (elo->expected_packet == ELO10_TOUCH_PACKET) {
- /* We are back in reporting mode, the command was ACKed */
- memcpy(packet, elo->response, ELO10_PACKET_LEN);
- rc = 0;
- }
+ if (elo->expected_packet != ELO10_TOUCH_PACKET)
+ return -EIO;
- out:
- mutex_unlock(&elo->cmd_mutex);
- return rc;
+ /* We are back in reporting mode, the command was ACKed */
+ memcpy(packet, elo->response, ELO10_PACKET_LEN);
+ return 0;
}
static int elo_setup_10(struct elo *elo)
@@ -307,7 +307,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- elo = kzalloc(sizeof(*elo), GFP_KERNEL);
+ elo = kzalloc_obj(*elo);
input_dev = input_allocate_device();
if (!elo || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c
index 28da7ba55a4b..78c0911ba6e2 100644
--- a/drivers/input/touchscreen/exc3000.c
+++ b/drivers/input/touchscreen/exc3000.c
@@ -234,7 +234,7 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
int ret;
unsigned long time_left;
- mutex_lock(&data->query_lock);
+ guard(mutex)(&data->query_lock);
reinit_completion(&data->wait_event);
@@ -243,29 +243,18 @@ static int exc3000_vendor_data_request(struct exc3000_data *data, u8 *request,
ret = i2c_master_send(data->client, buf, EXC3000_LEN_VENDOR_REQUEST);
if (ret < 0)
- goto out_unlock;
-
- if (response) {
- time_left = wait_for_completion_timeout(&data->wait_event,
- timeout * HZ);
- if (time_left == 0) {
- ret = -ETIMEDOUT;
- goto out_unlock;
- }
-
- if (data->buf[3] >= EXC3000_LEN_FRAME) {
- ret = -ENOSPC;
- goto out_unlock;
- }
+ return ret;
- memcpy(response, &data->buf[4], data->buf[3]);
- ret = data->buf[3];
- }
+ time_left = wait_for_completion_timeout(&data->wait_event,
+ timeout * HZ);
+ if (time_left == 0)
+ return -ETIMEDOUT;
-out_unlock:
- mutex_unlock(&data->query_lock);
+ if (data->buf[3] >= EXC3000_LEN_FRAME)
+ return -ENOSPC;
- return ret;
+ memcpy(response, &data->buf[4], data->buf[3]);
+ return data->buf[3];
}
static ssize_t fw_version_show(struct device *dev,
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c
index cef2e93c17bc..8ed592294b17 100644
--- a/drivers/input/touchscreen/fujitsu_ts.c
+++ b/drivers/input/touchscreen/fujitsu_ts.c
@@ -99,7 +99,7 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- fujitsu = kzalloc(sizeof(*fujitsu), GFP_KERNEL);
+ fujitsu = kzalloc_obj(*fujitsu);
input_dev = input_allocate_device();
if (!fujitsu || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/goodix_berlin_core.c b/drivers/input/touchscreen/goodix_berlin_core.c
index 83f28b870531..b0938a4f3fec 100644
--- a/drivers/input/touchscreen/goodix_berlin_core.c
+++ b/drivers/input/touchscreen/goodix_berlin_core.c
@@ -628,6 +628,14 @@ static int goodix_berlin_input_dev_config(struct goodix_berlin_core *cd,
touchscreen_parse_properties(cd->input_dev, true, &cd->props);
+ /*
+ * The resolution of these touchscreens is about 10 units/mm, the actual
+ * resolution does not matter much since we set INPUT_PROP_DIRECT.
+ * Set it to 10 to ensure userspace isn't off by an order of magnitude.
+ */
+ input_abs_set_res(cd->input_dev, ABS_MT_POSITION_X, 10);
+ input_abs_set_res(cd->input_dev, ABS_MT_POSITION_Y, 10);
+
error = input_mt_init_slots(cd->input_dev, GOODIX_BERLIN_MAX_TOUCH,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
if (error)
diff --git a/drivers/input/touchscreen/goodix_fwupload.c b/drivers/input/touchscreen/goodix_fwupload.c
index 191d4f38d991..5ae9a109ba0d 100644
--- a/drivers/input/touchscreen/goodix_fwupload.c
+++ b/drivers/input/touchscreen/goodix_fwupload.c
@@ -188,13 +188,13 @@ static int goodix_start_firmware(struct i2c_client *client)
static int goodix_firmware_upload(struct goodix_ts_data *ts)
{
- const struct firmware *fw;
char fw_name[64];
const u8 *data;
int error;
snprintf(fw_name, sizeof(fw_name), "goodix/%s", ts->firmware_name);
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, fw_name, &ts->client->dev);
if (error) {
dev_err(&ts->client->dev, "Firmware request error %d\n", error);
@@ -203,60 +203,61 @@ static int goodix_firmware_upload(struct goodix_ts_data *ts)
error = goodix_firmware_verify(&ts->client->dev, fw);
if (error)
- goto release;
+ return error;
error = goodix_reset_no_int_sync(ts);
if (error)
- goto release;
+ return error;
error = goodix_enter_upload_mode(ts->client);
if (error)
- goto release;
+ return error;
/* Select SRAM bank 0 and upload section 1 & 2 */
error = goodix_i2c_write_u8(ts->client,
GOODIX_REG_MISCTL_SRAM_BANK, 0x00);
if (error)
- goto release;
+ return error;
data = fw->data + GOODIX_FW_HEADER_LENGTH;
error = goodix_i2c_write(ts->client, GOODIX_FW_UPLOAD_ADDRESS,
data, 2 * GOODIX_FW_SECTION_LENGTH);
if (error)
- goto release;
+ return error;
/* Select SRAM bank 1 and upload section 3 & 4 */
error = goodix_i2c_write_u8(ts->client,
GOODIX_REG_MISCTL_SRAM_BANK, 0x01);
if (error)
- goto release;
+ return error;
data += 2 * GOODIX_FW_SECTION_LENGTH;
error = goodix_i2c_write(ts->client, GOODIX_FW_UPLOAD_ADDRESS,
data, 2 * GOODIX_FW_SECTION_LENGTH);
if (error)
- goto release;
+ return error;
/* Select SRAM bank 2 and upload the DSP firmware */
error = goodix_i2c_write_u8(ts->client,
GOODIX_REG_MISCTL_SRAM_BANK, 0x02);
if (error)
- goto release;
+ return error;
data += 2 * GOODIX_FW_SECTION_LENGTH;
error = goodix_i2c_write(ts->client, GOODIX_FW_UPLOAD_ADDRESS,
data, GOODIX_FW_DSP_LENGTH);
if (error)
- goto release;
+ return error;
error = goodix_start_firmware(ts->client);
if (error)
- goto release;
+ return error;
error = goodix_int_sync(ts);
-release:
- release_firmware(fw);
- return error;
+ if (error)
+ return error;
+
+ return 0;
}
static int goodix_prepare_bak_ref(struct goodix_ts_data *ts)
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index 426d2bc80a93..2baeb4f3b941 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -97,7 +97,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- gunze = kzalloc(sizeof(*gunze), GFP_KERNEL);
+ gunze = kzalloc_obj(*gunze);
input_dev = input_allocate_device();
if (!gunze || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c
index 0a9af8d0218c..394ae8c88d50 100644
--- a/drivers/input/touchscreen/hampshire.c
+++ b/drivers/input/touchscreen/hampshire.c
@@ -109,7 +109,7 @@ static int hampshire_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- phampshire = kzalloc(sizeof(*phampshire), GFP_KERNEL);
+ phampshire = kzalloc_obj(*phampshire);
input_dev = input_allocate_device();
if (!phampshire || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/hideep.c b/drivers/input/touchscreen/hideep.c
index a73369e15dda..62041bcca83d 100644
--- a/drivers/input/touchscreen/hideep.c
+++ b/drivers/input/touchscreen/hideep.c
@@ -869,8 +869,6 @@ static ssize_t hideep_update_fw(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct hideep_ts *ts = i2c_get_clientdata(client);
- const struct firmware *fw_entry;
- char *fw_name;
int mode;
int error;
@@ -878,46 +876,42 @@ static ssize_t hideep_update_fw(struct device *dev,
if (error)
return error;
- fw_name = kasprintf(GFP_KERNEL, "hideep_ts_%04x.bin",
- be16_to_cpu(ts->dwz_info.product_id));
+ const char *fw_name __free(kfree) =
+ kasprintf(GFP_KERNEL, "hideep_ts_%04x.bin",
+ be16_to_cpu(ts->dwz_info.product_id));
if (!fw_name)
return -ENOMEM;
+ const struct firmware *fw_entry __free(firmware) = NULL;
error = request_firmware(&fw_entry, fw_name, dev);
if (error) {
dev_err(dev, "failed to request firmware %s: %d",
fw_name, error);
- goto out_free_fw_name;
+ return error;
}
if (fw_entry->size % sizeof(__be32)) {
dev_err(dev, "invalid firmware size %zu\n", fw_entry->size);
- error = -EINVAL;
- goto out_release_fw;
+ return -EINVAL;
}
if (fw_entry->size > ts->fw_size) {
dev_err(dev, "fw size (%zu) is too big (memory size %d)\n",
fw_entry->size, ts->fw_size);
- error = -EFBIG;
- goto out_release_fw;
+ return -EFBIG;
}
- mutex_lock(&ts->dev_mutex);
- disable_irq(client->irq);
-
- error = hideep_update_firmware(ts, (const __be32 *)fw_entry->data,
- fw_entry->size);
-
- enable_irq(client->irq);
- mutex_unlock(&ts->dev_mutex);
+ scoped_guard(mutex, &ts->dev_mutex) {
+ guard(disable_irq)(&client->irq);
-out_release_fw:
- release_firmware(fw_entry);
-out_free_fw_name:
- kfree(fw_name);
+ error = hideep_update_firmware(ts,
+ (const __be32 *)fw_entry->data,
+ fw_entry->size);
+ if (error)
+ return error;
+ }
- return error ?: count;
+ return count;
}
static ssize_t hideep_fw_version_show(struct device *dev,
@@ -925,13 +919,9 @@ static ssize_t hideep_fw_version_show(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct hideep_ts *ts = i2c_get_clientdata(client);
- ssize_t len;
- mutex_lock(&ts->dev_mutex);
- len = sysfs_emit(buf, "%04x\n", be16_to_cpu(ts->dwz_info.release_ver));
- mutex_unlock(&ts->dev_mutex);
-
- return len;
+ guard(mutex)(&ts->dev_mutex);
+ return sysfs_emit(buf, "%04x\n", be16_to_cpu(ts->dwz_info.release_ver));
}
static ssize_t hideep_product_id_show(struct device *dev,
@@ -939,13 +929,9 @@ static ssize_t hideep_product_id_show(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct hideep_ts *ts = i2c_get_clientdata(client);
- ssize_t len;
-
- mutex_lock(&ts->dev_mutex);
- len = sysfs_emit(buf, "%04x\n", be16_to_cpu(ts->dwz_info.product_id));
- mutex_unlock(&ts->dev_mutex);
- return len;
+ guard(mutex)(&ts->dev_mutex);
+ return sysfs_emit(buf, "%04x\n", be16_to_cpu(ts->dwz_info.product_id));
}
static DEVICE_ATTR(version, 0664, hideep_fw_version_show, NULL);
diff --git a/drivers/input/touchscreen/hycon-hy46xx.c b/drivers/input/touchscreen/hycon-hy46xx.c
index b2ff7a45b908..1513f20cbf51 100644
--- a/drivers/input/touchscreen/hycon-hy46xx.c
+++ b/drivers/input/touchscreen/hycon-hy46xx.c
@@ -181,18 +181,17 @@ static ssize_t hycon_hy46xx_setting_show(struct device *dev,
struct hycon_hy46xx_attribute *attr =
container_of(dattr, struct hycon_hy46xx_attribute, dattr);
u8 *field = (u8 *)tsdata + attr->field_offset;
- size_t count = 0;
int error = 0;
int val;
- mutex_lock(&tsdata->mutex);
+ guard(mutex)(&tsdata->mutex);
error = regmap_read(tsdata->regmap, attr->address, &val);
- if (error < 0) {
+ if (error) {
dev_err(&tsdata->client->dev,
"Failed to fetch attribute %s, error %d\n",
dattr->attr.name, error);
- goto out;
+ return error;
}
if (val != *field) {
@@ -202,11 +201,7 @@ static ssize_t hycon_hy46xx_setting_show(struct device *dev,
*field = val;
}
- count = sysfs_emit(buf, "%d\n", val);
-
-out:
- mutex_unlock(&tsdata->mutex);
- return error ?: count;
+ return sysfs_emit(buf, "%d\n", val);
}
static ssize_t hycon_hy46xx_setting_store(struct device *dev,
@@ -221,29 +216,25 @@ static ssize_t hycon_hy46xx_setting_store(struct device *dev,
unsigned int val;
int error;
- mutex_lock(&tsdata->mutex);
+ guard(mutex)(&tsdata->mutex);
error = kstrtouint(buf, 0, &val);
if (error)
- goto out;
+ return error;
- if (val < attr->limit_low || val > attr->limit_high) {
- error = -ERANGE;
- goto out;
- }
+ if (val < attr->limit_low || val > attr->limit_high)
+ return -ERANGE;
error = regmap_write(tsdata->regmap, attr->address, val);
- if (error < 0) {
+ if (error) {
dev_err(&tsdata->client->dev,
"Failed to update attribute %s, error: %d\n",
dattr->attr.name, error);
- goto out;
+ return error;
}
*field = val;
-out:
- mutex_unlock(&tsdata->mutex);
- return error ?: count;
+ return count;
}
static HYCON_ATTR_U8(threshold, 0644, HY46XX_THRESHOLD, 0, 255);
diff --git a/drivers/input/touchscreen/imagis.c b/drivers/input/touchscreen/imagis.c
index 3c8bbe284b73..7bbb00beec3b 100644
--- a/drivers/input/touchscreen/imagis.c
+++ b/drivers/input/touchscreen/imagis.c
@@ -366,32 +366,34 @@ static int imagis_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct imagis_ts *ts = i2c_get_clientdata(client);
- int retval = 0;
-
- mutex_lock(&ts->input_dev->mutex);
+ int error;
- if (input_device_enabled(ts->input_dev))
- retval = imagis_stop(ts);
+ guard(mutex)(&ts->input_dev->mutex);
- mutex_unlock(&ts->input_dev->mutex);
+ if (input_device_enabled(ts->input_dev)) {
+ error = imagis_stop(ts);
+ if (error)
+ return error;
+ }
- return retval;
+ return 0;
}
static int imagis_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct imagis_ts *ts = i2c_get_clientdata(client);
- int retval = 0;
-
- mutex_lock(&ts->input_dev->mutex);
+ int error;
- if (input_device_enabled(ts->input_dev))
- retval = imagis_start(ts);
+ guard(mutex)(&ts->input_dev->mutex);
- mutex_unlock(&ts->input_dev->mutex);
+ if (input_device_enabled(ts->input_dev)) {
+ error = imagis_start(ts);
+ if (error)
+ return error;
+ }
- return retval;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(imagis_pm_ops, imagis_suspend, imagis_resume);
diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
index 85f697de2b7e..43d6c69e3088 100644
--- a/drivers/input/touchscreen/imx6ul_tsc.c
+++ b/drivers/input/touchscreen/imx6ul_tsc.c
@@ -551,13 +551,11 @@ static int imx6ul_tsc_suspend(struct device *dev)
struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
struct input_dev *input_dev = tsc->input;
- mutex_lock(&input_dev->mutex);
+ guard(mutex)(&input_dev->mutex);
if (input_device_enabled(input_dev))
imx6ul_tsc_stop(tsc);
- mutex_unlock(&input_dev->mutex);
-
return 0;
}
@@ -566,16 +564,17 @@ static int imx6ul_tsc_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
struct input_dev *input_dev = tsc->input;
- int retval = 0;
-
- mutex_lock(&input_dev->mutex);
+ int error;
- if (input_device_enabled(input_dev))
- retval = imx6ul_tsc_start(tsc);
+ guard(mutex)(&input_dev->mutex);
- mutex_unlock(&input_dev->mutex);
+ if (input_device_enabled(input_dev)) {
+ error = imx6ul_tsc_start(tsc);
+ if (error)
+ return error;
+ }
- return retval;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c
index a7604f2c4e3a..ac3836ff2a30 100644
--- a/drivers/input/touchscreen/inexio.c
+++ b/drivers/input/touchscreen/inexio.c
@@ -114,7 +114,7 @@ static int inexio_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- pinexio = kzalloc(sizeof(*pinexio), GFP_KERNEL);
+ pinexio = kzalloc_obj(*pinexio);
input_dev = input_allocate_device();
if (!pinexio || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c
index 94720c41c9be..243e6465d9bd 100644
--- a/drivers/input/touchscreen/ipaq-micro-ts.c
+++ b/drivers/input/touchscreen/ipaq-micro-ts.c
@@ -47,7 +47,7 @@ static void micro_ts_toggle_receive(struct touchscreen_data *ts, bool enable)
{
struct ipaq_micro *micro = ts->micro;
- spin_lock_irq(&micro->lock);
+ guard(spinlock_irq)(&micro->lock);
if (enable) {
micro->ts = micro_ts_receive;
@@ -56,8 +56,6 @@ static void micro_ts_toggle_receive(struct touchscreen_data *ts, bool enable)
micro->ts = NULL;
micro->ts_data = NULL;
}
-
- spin_unlock_irq(&ts->micro->lock);
}
static int micro_ts_open(struct input_dev *input)
@@ -133,13 +131,11 @@ static int micro_ts_resume(struct device *dev)
struct touchscreen_data *ts = dev_get_drvdata(dev);
struct input_dev *input = ts->input;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (input_device_enabled(input))
micro_ts_toggle_receive(ts, true);
- mutex_unlock(&input->mutex);
-
return 0;
}
diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c
index 4ebd7565ae6e..587665e4e6fd 100644
--- a/drivers/input/touchscreen/iqs5xx.c
+++ b/drivers/input/touchscreen/iqs5xx.c
@@ -17,6 +17,7 @@
#include <linux/err.h>
#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
+#include <linux/hex.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
@@ -72,8 +73,11 @@
#define IQS5XX_CSTM_LEN (IQS5XX_PMAP_END + 1 - IQS5XX_CSTM)
#define IQS5XX_PMAP_LEN (IQS5XX_PMAP_END + 1 - IQS5XX_CHKSM)
-#define IQS5XX_REC_HDR_LEN 4
-#define IQS5XX_REC_LEN_MAX 255
+/* Length of firmware header in hexadecimal characters */
+#define IQS5XX_REC_HDR_LEN_HEX (1 /* start */ + 2 /* size */ + \
+ 4 /* addr */ + 2 /* type */)
+#define IQS5XX_REC_HDR_SIZE 4 /* size + addr (2 bytes) + type, in bytes*/
+#define IQS5XX_REC_DATA_SIZE 255 /* maximum size of the data portion */
#define IQS5XX_REC_TYPE_DATA 0x00
#define IQS5XX_REC_TYPE_EOF 0x01
@@ -97,14 +101,6 @@ struct iqs5xx_dev_id_info {
u8 bl_status;
} __packed;
-struct iqs5xx_ihex_rec {
- char start;
- char len[2];
- char addr[4];
- char type[2];
- char data[2];
-} __packed;
-
struct iqs5xx_touch_data {
__be16 abs_x;
__be16 abs_y;
@@ -355,7 +351,7 @@ static int iqs5xx_bl_open(struct i2c_client *client)
}
static int iqs5xx_bl_write(struct i2c_client *client,
- u16 bl_addr, u8 *pmap_data, u16 pmap_len)
+ u16 bl_addr, const u8 *pmap_data, u16 pmap_len)
{
struct i2c_msg msg;
int ret, i;
@@ -394,7 +390,7 @@ msg_fail:
}
static int iqs5xx_bl_verify(struct i2c_client *client,
- u16 bl_addr, u8 *pmap_data, u16 pmap_len)
+ u16 bl_addr, const u8 *pmap_data, u16 pmap_len)
{
struct i2c_msg msg;
int ret, i;
@@ -445,27 +441,21 @@ static int iqs5xx_set_state(struct i2c_client *client, u8 state)
if (!iqs5xx->dev_id_info.bl_status)
return 0;
- mutex_lock(&iqs5xx->lock);
+ guard(mutex)(&iqs5xx->lock);
/*
* Addressing the device outside of a communication window prompts it
* to assert the RDY output, so disable the interrupt line to prevent
* the handler from servicing a false interrupt.
*/
- disable_irq(client->irq);
+ guard(disable_irq)(&client->irq);
error1 = iqs5xx_write_byte(client, IQS5XX_SYS_CTRL1, state);
error2 = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0);
usleep_range(50, 100);
- enable_irq(client->irq);
-
- mutex_unlock(&iqs5xx->lock);
- if (error1)
- return error1;
-
- return error2;
+ return error1 ?: error2;
}
static int iqs5xx_open(struct input_dev *input)
@@ -702,15 +692,13 @@ static irqreturn_t iqs5xx_irq(int irq, void *data)
static int iqs5xx_fw_file_parse(struct i2c_client *client,
const char *fw_file, u8 *pmap)
{
- const struct firmware *fw;
- struct iqs5xx_ihex_rec *rec;
size_t pos = 0;
int error, i;
u16 rec_num = 1;
u16 rec_addr;
u8 rec_len, rec_type, rec_chksm, chksm;
- u8 rec_hdr[IQS5XX_REC_HDR_LEN];
- u8 rec_data[IQS5XX_REC_LEN_MAX];
+ u8 rec_hdr[IQS5XX_REC_HDR_SIZE];
+ u8 rec_data[IQS5XX_REC_DATA_SIZE];
/*
* Firmware exported from the vendor's configuration tool deviates from
@@ -721,6 +709,7 @@ static int iqs5xx_fw_file_parse(struct i2c_client *client,
* Because the ihex2fw tool tolerates neither (1) nor (2), the slightly
* nonstandard ihex firmware is parsed directly by the driver.
*/
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, fw_file, &client->dev);
if (error) {
dev_err(&client->dev, "Failed to request firmware %s: %d\n",
@@ -729,53 +718,55 @@ static int iqs5xx_fw_file_parse(struct i2c_client *client,
}
do {
- if (pos + sizeof(*rec) > fw->size) {
+ if (pos + IQS5XX_REC_HDR_LEN_HEX > fw->size) {
dev_err(&client->dev, "Insufficient firmware size\n");
- error = -EINVAL;
- break;
+ return -EINVAL;
}
- rec = (struct iqs5xx_ihex_rec *)(fw->data + pos);
- pos += sizeof(*rec);
- if (rec->start != ':') {
+ if (fw->data[pos] != ':') {
dev_err(&client->dev, "Invalid start at record %u\n",
rec_num);
- error = -EINVAL;
- break;
+ return -EINVAL;
}
- error = hex2bin(rec_hdr, rec->len, sizeof(rec_hdr));
+ /* Convert all 3 fields (length, address, and type) in one go */
+ error = hex2bin(rec_hdr, &fw->data[pos + 1], sizeof(rec_hdr));
if (error) {
dev_err(&client->dev, "Invalid header at record %u\n",
rec_num);
- break;
+ return error;
}
+ pos += IQS5XX_REC_HDR_LEN_HEX;
rec_len = *rec_hdr;
rec_addr = get_unaligned_be16(rec_hdr + sizeof(rec_len));
rec_type = *(rec_hdr + sizeof(rec_len) + sizeof(rec_addr));
- if (pos + rec_len * 2 > fw->size) {
+ /*
+ * Check if we have enough data for the data portion of the
+ * record, as well as the checksum byte. Everything is doubled
+ * because data is in ASCII HEX and not binary format.
+ */
+ if (pos + (rec_len + sizeof(rec_chksm)) * 2 > fw->size) {
dev_err(&client->dev, "Insufficient firmware size\n");
- error = -EINVAL;
- break;
+ return -EINVAL;
}
- pos += (rec_len * 2);
- error = hex2bin(rec_data, rec->data, rec_len);
+ error = hex2bin(rec_data, &fw->data[pos], rec_len);
if (error) {
dev_err(&client->dev, "Invalid data at record %u\n",
rec_num);
- break;
+ return error;
}
+ pos += rec_len * 2;
- error = hex2bin(&rec_chksm,
- rec->data + rec_len * 2, sizeof(rec_chksm));
+ error = hex2bin(&rec_chksm, &fw->data[pos], sizeof(rec_chksm));
if (error) {
dev_err(&client->dev, "Invalid checksum at record %u\n",
rec_num);
- break;
+ return error;
}
+ pos += 2;
chksm = 0;
for (i = 0; i < sizeof(rec_hdr); i++)
@@ -799,23 +790,22 @@ static int iqs5xx_fw_file_parse(struct i2c_client *client,
dev_err(&client->dev,
"Invalid address at record %u\n",
rec_num);
- error = -EINVAL;
- } else {
- memcpy(pmap + rec_addr - IQS5XX_CHKSM,
- rec_data, rec_len);
+ return -EINVAL;
}
+
+ memcpy(pmap + rec_addr - IQS5XX_CHKSM,
+ rec_data, rec_len);
break;
+
case IQS5XX_REC_TYPE_EOF:
break;
+
default:
dev_err(&client->dev, "Invalid type at record %u\n",
rec_num);
- error = -EINVAL;
+ return -EINVAL;
}
- if (error)
- break;
-
rec_num++;
while (pos < fw->size) {
if (*(fw->data + pos) == ':')
@@ -824,33 +814,13 @@ static int iqs5xx_fw_file_parse(struct i2c_client *client,
}
} while (rec_type != IQS5XX_REC_TYPE_EOF);
- release_firmware(fw);
-
- return error;
+ return 0;
}
-static int iqs5xx_fw_file_write(struct i2c_client *client, const char *fw_file)
+static int iqs5xx_update_firmware(struct iqs5xx_private *iqs5xx, const u8 *pmap)
{
- struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
- int error, error_init = 0;
- u8 *pmap;
-
- pmap = kzalloc(IQS5XX_PMAP_LEN, GFP_KERNEL);
- if (!pmap)
- return -ENOMEM;
-
- error = iqs5xx_fw_file_parse(client, fw_file, pmap);
- if (error)
- goto err_kfree;
-
- mutex_lock(&iqs5xx->lock);
-
- /*
- * Disable the interrupt line in case the first attempt(s) to enter the
- * bootloader don't happen quickly enough, in which case the device may
- * assert the RDY output until the next attempt.
- */
- disable_irq(client->irq);
+ struct i2c_client *client = iqs5xx->client;
+ int error;
iqs5xx->dev_id_info.bl_status = 0;
@@ -858,22 +828,50 @@ static int iqs5xx_fw_file_write(struct i2c_client *client, const char *fw_file)
if (error) {
error = iqs5xx_bl_open(client);
if (error)
- goto err_reset;
+ return error;
}
error = iqs5xx_bl_write(client, IQS5XX_CHKSM, pmap, IQS5XX_PMAP_LEN);
if (error)
- goto err_reset;
+ return error;
error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_CRC, 0);
if (error)
- goto err_reset;
+ return error;
error = iqs5xx_bl_verify(client, IQS5XX_CSTM,
pmap + IQS5XX_CHKSM_LEN + IQS5XX_APP_LEN,
IQS5XX_CSTM_LEN);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static int iqs5xx_fw_file_write(struct i2c_client *client, const char *fw_file)
+{
+ struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
+ int error, error_init = 0;
+
+ u8 *pmap __free(kfree) = kzalloc(IQS5XX_PMAP_LEN, GFP_KERNEL);
+ if (!pmap)
+ return -ENOMEM;
+
+ error = iqs5xx_fw_file_parse(client, fw_file, pmap);
+ if (error)
+ return error;
+
+ guard(mutex)(&iqs5xx->lock);
+
+ /*
+ * Disable the interrupt line in case the first attempt(s) to enter the
+ * bootloader don't happen quickly enough, in which case the device may
+ * assert the RDY output until the next attempt.
+ */
+ guard(disable_irq)(&client->irq);
+
+ error = iqs5xx_update_firmware(iqs5xx, pmap);
-err_reset:
iqs5xx_reset(client);
usleep_range(15000, 15100);
@@ -881,14 +879,7 @@ err_reset:
if (!iqs5xx->dev_id_info.bl_status)
error_init = error_init ? : -EINVAL;
- enable_irq(client->irq);
-
- mutex_unlock(&iqs5xx->lock);
-
-err_kfree:
- kfree(pmap);
-
- return error ? : error_init;
+ return error ?: error_init;
}
static ssize_t fw_file_store(struct device *dev,
@@ -984,38 +975,30 @@ static int iqs5xx_suspend(struct device *dev)
{
struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev);
struct input_dev *input = iqs5xx->input;
- int error = 0;
if (!input || device_may_wakeup(dev))
- return error;
-
- mutex_lock(&input->mutex);
+ return 0;
+ guard(mutex)(&input->mutex);
if (input_device_enabled(input))
- error = iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND);
-
- mutex_unlock(&input->mutex);
+ return iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND);
- return error;
+ return 0;
}
static int iqs5xx_resume(struct device *dev)
{
struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev);
struct input_dev *input = iqs5xx->input;
- int error = 0;
if (!input || device_may_wakeup(dev))
- return error;
-
- mutex_lock(&input->mutex);
+ return 0;
+ guard(mutex)(&input->mutex);
if (input_device_enabled(input))
- error = iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME);
-
- mutex_unlock(&input->mutex);
+ return iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME);
- return error;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(iqs5xx_pm, iqs5xx_suspend, iqs5xx_resume);
diff --git a/drivers/input/touchscreen/iqs7211.c b/drivers/input/touchscreen/iqs7211.c
index c5d447ee6f53..26e0b501c5fc 100644
--- a/drivers/input/touchscreen/iqs7211.c
+++ b/drivers/input/touchscreen/iqs7211.c
@@ -2060,19 +2060,16 @@ static int iqs7211_parse_reg_grp(struct iqs7211_private *iqs7211,
for (i = 0; i < dev_desc->num_kp_events; i++) {
const char *event_name = dev_desc->kp_events[i].name;
- struct fwnode_handle *event_node;
if (dev_desc->kp_events[i].reg_grp != reg_grp)
continue;
reg_field.mask |= dev_desc->kp_events[i].enable;
- if (event_name)
- event_node = fwnode_get_named_child_node(reg_grp_node,
- event_name);
- else
- event_node = fwnode_handle_get(reg_grp_node);
-
+ struct fwnode_handle *event_node __free(fwnode_handle) =
+ event_name ? fwnode_get_named_child_node(reg_grp_node,
+ event_name) :
+ fwnode_handle_get(reg_grp_node);
if (!event_node)
continue;
@@ -2080,7 +2077,6 @@ static int iqs7211_parse_reg_grp(struct iqs7211_private *iqs7211,
dev_desc->kp_events[i].reg_grp,
dev_desc->kp_events[i].reg_key,
&iqs7211->kp_code[i]);
- fwnode_handle_put(event_node);
if (error)
return error;
@@ -2496,19 +2492,15 @@ static int iqs7211_probe(struct i2c_client *client)
for (reg_grp = 0; reg_grp < IQS7211_NUM_REG_GRPS; reg_grp++) {
const char *reg_grp_name = iqs7211_reg_grp_names[reg_grp];
- struct fwnode_handle *reg_grp_node;
-
- if (reg_grp_name)
- reg_grp_node = device_get_named_child_node(&client->dev,
- reg_grp_name);
- else
- reg_grp_node = fwnode_handle_get(dev_fwnode(&client->dev));
+ struct fwnode_handle *reg_grp_node __free(fwnode_handle) =
+ reg_grp_name ? device_get_named_child_node(&client->dev,
+ reg_grp_name) :
+ fwnode_handle_get(dev_fwnode(&client->dev));
if (!reg_grp_node)
continue;
error = iqs7211_parse_reg_grp(iqs7211, reg_grp_node, reg_grp);
- fwnode_handle_put(reg_grp_node);
if (error)
return error;
}
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c
index 9bad8b93c039..5de752a06b26 100644
--- a/drivers/input/touchscreen/lpc32xx_ts.c
+++ b/drivers/input/touchscreen/lpc32xx_ts.c
@@ -279,7 +279,7 @@ static int lpc32xx_ts_suspend(struct device *dev)
* avoid calling the TSC stop and start functions as the TSC
* isn't yet clocked.
*/
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (input_device_enabled(input)) {
if (device_may_wakeup(dev))
@@ -288,8 +288,6 @@ static int lpc32xx_ts_suspend(struct device *dev)
lpc32xx_stop_tsc(tsc);
}
- mutex_unlock(&input->mutex);
-
return 0;
}
@@ -298,7 +296,7 @@ static int lpc32xx_ts_resume(struct device *dev)
struct lpc32xx_tsc *tsc = dev_get_drvdata(dev);
struct input_dev *input = tsc->dev;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (input_device_enabled(input)) {
if (device_may_wakeup(dev))
@@ -307,8 +305,6 @@ static int lpc32xx_ts_resume(struct device *dev)
lpc32xx_setup_tsc(tsc);
}
- mutex_unlock(&input->mutex);
-
return 0;
}
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index 47b8da00027f..4b7e70a4c6d5 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -168,7 +168,7 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
struct input_dev *idev;
int ret = -ENOMEM;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
idev = input_allocate_device();
if (!priv || !idev)
goto err_free_mem;
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c
index 869884219908..10fccf4e5bb1 100644
--- a/drivers/input/touchscreen/melfas_mip4.c
+++ b/drivers/input/touchscreen/melfas_mip4.c
@@ -881,8 +881,6 @@ static int mip4_bl_program_page(struct mip4_ts *ts, int offset,
const u8 *data, int length, u16 buf_addr)
{
u8 cmd[6];
- u8 *data_buf;
- u16 buf_offset;
int ret;
int error;
@@ -895,7 +893,8 @@ static int mip4_bl_program_page(struct mip4_ts *ts, int offset,
return -EINVAL;
}
- data_buf = kmalloc(2 + MIP4_BL_PACKET_SIZE, GFP_KERNEL);
+ u8 *data_buf __free(kfree) = kmalloc(2 + MIP4_BL_PACKET_SIZE,
+ GFP_KERNEL);
if (!data_buf)
return -ENOMEM;
@@ -908,7 +907,7 @@ static int mip4_bl_program_page(struct mip4_ts *ts, int offset,
error = ret < 0 ? ret : -EIO;
dev_err(&ts->client->dev,
"Failed to send write page address: %d\n", error);
- goto out;
+ return error;
}
/* Size */
@@ -920,11 +919,11 @@ static int mip4_bl_program_page(struct mip4_ts *ts, int offset,
error = ret < 0 ? ret : -EIO;
dev_err(&ts->client->dev,
"Failed to send write page size: %d\n", error);
- goto out;
+ return error;
}
/* Data */
- for (buf_offset = 0;
+ for (int buf_offset = 0;
buf_offset < length;
buf_offset += MIP4_BL_PACKET_SIZE) {
dev_dbg(&ts->client->dev,
@@ -939,7 +938,7 @@ static int mip4_bl_program_page(struct mip4_ts *ts, int offset,
dev_err(&ts->client->dev,
"Failed to read chunk at %#04x (size %d): %d\n",
buf_offset, MIP4_BL_PACKET_SIZE, error);
- goto out;
+ return error;
}
}
@@ -952,35 +951,21 @@ static int mip4_bl_program_page(struct mip4_ts *ts, int offset,
error = ret < 0 ? ret : -EIO;
dev_err(&ts->client->dev,
"Failed to send 'write' command: %d\n", error);
- goto out;
+ return error;
}
/* Status */
error = mip4_bl_read_status(ts);
+ if (error)
+ return error;
-out:
- kfree(data_buf);
- return error ? error : 0;
+ return 0;
}
static int mip4_bl_verify_page(struct mip4_ts *ts, int offset,
const u8 *data, int length, int buf_addr)
{
u8 cmd[8];
- u8 *read_buf;
- int buf_offset;
- struct i2c_msg msg[] = {
- {
- .addr = ts->client->addr,
- .flags = 0,
- .buf = cmd,
- .len = 2,
- }, {
- .addr = ts->client->addr,
- .flags = I2C_M_RD,
- .len = MIP4_BL_PACKET_SIZE,
- },
- };
int ret;
int error;
@@ -1029,11 +1014,25 @@ static int mip4_bl_verify_page(struct mip4_ts *ts, int offset,
return error;
/* Read */
- msg[1].buf = read_buf = kmalloc(MIP4_BL_PACKET_SIZE, GFP_KERNEL);
+ u8 *read_buf __free(kfree) = kmalloc(MIP4_BL_PACKET_SIZE, GFP_KERNEL);
if (!read_buf)
return -ENOMEM;
- for (buf_offset = 0;
+ struct i2c_msg msg[] = {
+ {
+ .addr = ts->client->addr,
+ .flags = 0,
+ .buf = cmd,
+ .len = 2,
+ }, {
+ .addr = ts->client->addr,
+ .flags = I2C_M_RD,
+ .buf = read_buf,
+ .len = MIP4_BL_PACKET_SIZE,
+ },
+ };
+
+ for (int buf_offset = 0;
buf_offset < length;
buf_offset += MIP4_BL_PACKET_SIZE) {
dev_dbg(&ts->client->dev,
@@ -1046,7 +1045,7 @@ static int mip4_bl_verify_page(struct mip4_ts *ts, int offset,
dev_err(&ts->client->dev,
"Failed to read chunk at %#04x (size %d): %d\n",
buf_offset, MIP4_BL_PACKET_SIZE, error);
- break;
+ return error;
}
if (memcmp(&data[buf_offset], read_buf, MIP4_BL_PACKET_SIZE)) {
@@ -1064,13 +1063,11 @@ static int mip4_bl_verify_page(struct mip4_ts *ts, int offset,
DUMP_PREFIX_OFFSET, 16, 1,
read_buf, MIP4_BL_PAGE_SIZE, false);
#endif
- error = -EINVAL;
- break;
+ return -EINVAL;
}
}
- kfree(read_buf);
- return error ? error : 0;
+ return 0;
}
/*
@@ -1290,9 +1287,9 @@ static ssize_t mip4_sysfs_fw_update(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct mip4_ts *ts = i2c_get_clientdata(client);
- const struct firmware *fw;
int error;
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, ts->fw_name, dev);
if (error) {
dev_err(&ts->client->dev,
@@ -1306,14 +1303,9 @@ static ssize_t mip4_sysfs_fw_update(struct device *dev,
* userspace opening and closing the device and also suspend/resume
* transitions.
*/
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
error = mip4_execute_fw_update(ts, fw);
-
- mutex_unlock(&ts->input->mutex);
-
- release_firmware(fw);
-
if (error) {
dev_err(&ts->client->dev,
"Firmware update failed: %d\n", error);
@@ -1331,18 +1323,13 @@ static ssize_t mip4_sysfs_read_fw_version(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct mip4_ts *ts = i2c_get_clientdata(client);
- size_t count;
/* Take lock to prevent racing with firmware update */
- mutex_lock(&ts->input->mutex);
-
- count = sysfs_emit(buf, "%04X %04X %04X %04X\n",
- ts->fw_version.boot, ts->fw_version.core,
- ts->fw_version.app, ts->fw_version.param);
+ guard(mutex)(&ts->input->mutex);
- mutex_unlock(&ts->input->mutex);
-
- return count;
+ return sysfs_emit(buf, "%04X %04X %04X %04X\n",
+ ts->fw_version.boot, ts->fw_version.core,
+ ts->fw_version.app, ts->fw_version.param);
}
static DEVICE_ATTR(fw_version, S_IRUGO, mip4_sysfs_read_fw_version, NULL);
@@ -1353,21 +1340,16 @@ static ssize_t mip4_sysfs_read_hw_version(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct mip4_ts *ts = i2c_get_clientdata(client);
- size_t count;
/* Take lock to prevent racing with firmware update */
- mutex_lock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
/*
* product_name shows the name or version of the hardware
* paired with current firmware in the chip.
*/
- count = sysfs_emit(buf, "%.*s\n",
- (int)sizeof(ts->product_name), ts->product_name);
-
- mutex_unlock(&ts->input->mutex);
-
- return count;
+ return sysfs_emit(buf, "%.*s\n",
+ (int)sizeof(ts->product_name), ts->product_name);
}
static DEVICE_ATTR(hw_version, S_IRUGO, mip4_sysfs_read_hw_version, NULL);
@@ -1378,15 +1360,10 @@ static ssize_t mip4_sysfs_read_product_id(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct mip4_ts *ts = i2c_get_clientdata(client);
- size_t count;
-
- mutex_lock(&ts->input->mutex);
- count = sysfs_emit(buf, "%04X\n", ts->product_id);
+ guard(mutex)(&ts->input->mutex);
- mutex_unlock(&ts->input->mutex);
-
- return count;
+ return sysfs_emit(buf, "%04X\n", ts->product_id);
}
static DEVICE_ATTR(product_id, S_IRUGO, mip4_sysfs_read_product_id, NULL);
@@ -1397,16 +1374,10 @@ static ssize_t mip4_sysfs_read_ic_name(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct mip4_ts *ts = i2c_get_clientdata(client);
- size_t count;
-
- mutex_lock(&ts->input->mutex);
-
- count = sysfs_emit(buf, "%.*s\n",
- (int)sizeof(ts->ic_name), ts->ic_name);
- mutex_unlock(&ts->input->mutex);
+ guard(mutex)(&ts->input->mutex);
- return count;
+ return sysfs_emit(buf, "%.*s\n", (int)sizeof(ts->ic_name), ts->ic_name);
}
static DEVICE_ATTR(ic_name, S_IRUGO, mip4_sysfs_read_ic_name, NULL);
@@ -1520,15 +1491,13 @@ static int mip4_suspend(struct device *dev)
struct mip4_ts *ts = i2c_get_clientdata(client);
struct input_dev *input = ts->input;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (device_may_wakeup(dev))
ts->wake_irq_enabled = enable_irq_wake(client->irq) == 0;
else if (input_device_enabled(input))
mip4_disable(ts);
- mutex_unlock(&input->mutex);
-
return 0;
}
@@ -1538,15 +1507,13 @@ static int mip4_resume(struct device *dev)
struct mip4_ts *ts = i2c_get_clientdata(client);
struct input_dev *input = ts->input;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (ts->wake_irq_enabled)
disable_irq_wake(client->irq);
else if (input_device_enabled(input))
mip4_enable(ts);
- mutex_unlock(&input->mutex);
-
return 0;
}
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 7511a134e302..993d945dcd23 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -122,7 +122,7 @@ static int migor_ts_probe(struct i2c_client *client)
struct input_dev *input;
int error;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kzalloc_obj(*priv);
input = input_allocate_device();
if (!priv || !input) {
dev_err(&client->dev, "failed to allocate memory\n");
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
deleted file mode 100644
index 753d9cc1de1f..000000000000
--- a/drivers/input/touchscreen/mk712.c
+++ /dev/null
@@ -1,215 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * ICS MK712 touchscreen controller driver
- *
- * Copyright (c) 1999-2002 Transmeta Corporation
- * Copyright (c) 2005 Rick Koch <n1gp@hotmail.com>
- * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
- */
-
-
-/*
- * This driver supports the ICS MicroClock MK712 TouchScreen controller,
- * found in Gateway AOL Connected Touchpad computers.
- *
- * Documentation for ICS MK712 can be found at:
- * https://www.idt.com/general-parts/mk712-touch-screen-controller
- */
-
-/*
- * 1999-12-18: original version, Daniel Quinlan
- * 1999-12-19: added anti-jitter code, report pen-up events, fixed mk712_poll
- * to use queue_empty, Nathan Laredo
- * 1999-12-20: improved random point rejection, Nathan Laredo
- * 2000-01-05: checked in new anti-jitter code, changed mouse protocol, fixed
- * queue code, added module options, other fixes, Daniel Quinlan
- * 2002-03-15: Clean up for kernel merge <alan@redhat.com>
- * Fixed multi open race, fixed memory checks, fixed resource
- * allocation, fixed close/powerdown bug, switched to new init
- * 2005-01-18: Ported to 2.6 from 2.4.28, Rick Koch
- * 2005-02-05: Rewritten for the input layer, Vojtech Pavlik
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <asm/io.h>
-
-MODULE_AUTHOR("Daniel Quinlan <quinlan@pathname.com>, Vojtech Pavlik <vojtech@suse.cz>");
-MODULE_DESCRIPTION("ICS MicroClock MK712 TouchScreen driver");
-MODULE_LICENSE("GPL");
-
-static unsigned int mk712_io = 0x260; /* Also 0x200, 0x208, 0x300 */
-module_param_hw_named(io, mk712_io, uint, ioport, 0);
-MODULE_PARM_DESC(io, "I/O base address of MK712 touchscreen controller");
-
-static unsigned int mk712_irq = 10; /* Also 12, 14, 15 */
-module_param_hw_named(irq, mk712_irq, uint, irq, 0);
-MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller");
-
-/* eight 8-bit registers */
-#define MK712_STATUS 0
-#define MK712_X 2
-#define MK712_Y 4
-#define MK712_CONTROL 6
-#define MK712_RATE 7
-
-/* status */
-#define MK712_STATUS_TOUCH 0x10
-#define MK712_CONVERSION_COMPLETE 0x80
-
-/* control */
-#define MK712_ENABLE_INT 0x01
-#define MK712_INT_ON_CONVERSION_COMPLETE 0x02
-#define MK712_INT_ON_CHANGE_IN_TOUCH_STATUS 0x04
-#define MK712_ENABLE_PERIODIC_CONVERSIONS 0x10
-#define MK712_READ_ONE_POINT 0x20
-#define MK712_POWERUP 0x40
-
-static struct input_dev *mk712_dev;
-static DEFINE_SPINLOCK(mk712_lock);
-
-static irqreturn_t mk712_interrupt(int irq, void *dev_id)
-{
- unsigned char status;
- static int debounce = 1;
- static unsigned short last_x;
- static unsigned short last_y;
-
- spin_lock(&mk712_lock);
-
- status = inb(mk712_io + MK712_STATUS);
-
- if (~status & MK712_CONVERSION_COMPLETE) {
- debounce = 1;
- goto end;
- }
-
- if (~status & MK712_STATUS_TOUCH) {
- debounce = 1;
- input_report_key(mk712_dev, BTN_TOUCH, 0);
- goto end;
- }
-
- if (debounce) {
- debounce = 0;
- goto end;
- }
-
- input_report_key(mk712_dev, BTN_TOUCH, 1);
- input_report_abs(mk712_dev, ABS_X, last_x);
- input_report_abs(mk712_dev, ABS_Y, last_y);
-
- end:
- last_x = inw(mk712_io + MK712_X) & 0x0fff;
- last_y = inw(mk712_io + MK712_Y) & 0x0fff;
- input_sync(mk712_dev);
- spin_unlock(&mk712_lock);
- return IRQ_HANDLED;
-}
-
-static int mk712_open(struct input_dev *dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mk712_lock, flags);
-
- outb(0, mk712_io + MK712_CONTROL); /* Reset */
-
- outb(MK712_ENABLE_INT | MK712_INT_ON_CONVERSION_COMPLETE |
- MK712_INT_ON_CHANGE_IN_TOUCH_STATUS |
- MK712_ENABLE_PERIODIC_CONVERSIONS |
- MK712_POWERUP, mk712_io + MK712_CONTROL);
-
- outb(10, mk712_io + MK712_RATE); /* 187 points per second */
-
- spin_unlock_irqrestore(&mk712_lock, flags);
-
- return 0;
-}
-
-static void mk712_close(struct input_dev *dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&mk712_lock, flags);
-
- outb(0, mk712_io + MK712_CONTROL);
-
- spin_unlock_irqrestore(&mk712_lock, flags);
-}
-
-static int __init mk712_init(void)
-{
- int err;
-
- if (!request_region(mk712_io, 8, "mk712")) {
- printk(KERN_WARNING "mk712: unable to get IO region\n");
- return -ENODEV;
- }
-
- outb(0, mk712_io + MK712_CONTROL);
-
- if ((inw(mk712_io + MK712_X) & 0xf000) || /* Sanity check */
- (inw(mk712_io + MK712_Y) & 0xf000) ||
- (inw(mk712_io + MK712_STATUS) & 0xf333)) {
- printk(KERN_WARNING "mk712: device not present\n");
- err = -ENODEV;
- goto fail1;
- }
-
- mk712_dev = input_allocate_device();
- if (!mk712_dev) {
- printk(KERN_ERR "mk712: not enough memory\n");
- err = -ENOMEM;
- goto fail1;
- }
-
- mk712_dev->name = "ICS MicroClock MK712 TouchScreen";
- mk712_dev->phys = "isa0260/input0";
- mk712_dev->id.bustype = BUS_ISA;
- mk712_dev->id.vendor = 0x0005;
- mk712_dev->id.product = 0x0001;
- mk712_dev->id.version = 0x0100;
-
- mk712_dev->open = mk712_open;
- mk712_dev->close = mk712_close;
-
- mk712_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- mk712_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
- input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
-
- if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) {
- printk(KERN_WARNING "mk712: unable to get IRQ\n");
- err = -EBUSY;
- goto fail1;
- }
-
- err = input_register_device(mk712_dev);
- if (err)
- goto fail2;
-
- return 0;
-
- fail2: free_irq(mk712_irq, mk712_dev);
- fail1: input_free_device(mk712_dev);
- release_region(mk712_io, 8);
- return err;
-}
-
-static void __exit mk712_exit(void)
-{
- input_unregister_device(mk712_dev);
- free_irq(mk712_irq, mk712_dev);
- release_region(mk712_io, 8);
-}
-
-module_init(mk712_init);
-module_exit(mk712_exit);
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 9f947044c4d9..af462086a65c 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -216,20 +216,12 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
{
struct mms114_data *data = dev_id;
struct i2c_client *client = data->client;
- struct input_dev *input_dev = data->input_dev;
struct mms114_touch touch[MMS114_MAX_TOUCH];
int packet_size;
int touch_size;
int index;
int error;
- mutex_lock(&input_dev->mutex);
- if (!input_device_enabled(input_dev)) {
- mutex_unlock(&input_dev->mutex);
- goto out;
- }
- mutex_unlock(&input_dev->mutex);
-
packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
if (packet_size <= 0)
goto out;
@@ -646,10 +638,10 @@ static int mms114_suspend(struct device *dev)
input_mt_report_pointer_emulation(input_dev, true);
input_sync(input_dev);
- mutex_lock(&input_dev->mutex);
+ guard(mutex)(&input_dev->mutex);
+
if (input_device_enabled(input_dev))
mms114_stop(data);
- mutex_unlock(&input_dev->mutex);
return 0;
}
@@ -661,15 +653,13 @@ static int mms114_resume(struct device *dev)
struct input_dev *input_dev = data->input_dev;
int error;
- mutex_lock(&input_dev->mutex);
+ guard(mutex)(&input_dev->mutex);
+
if (input_device_enabled(input_dev)) {
error = mms114_start(data);
- if (error < 0) {
- mutex_unlock(&input_dev->mutex);
+ if (error)
return error;
- }
}
- mutex_unlock(&input_dev->mutex);
return 0;
}
diff --git a/drivers/input/touchscreen/msg2638.c b/drivers/input/touchscreen/msg2638.c
index a38af3fee34a..240d2eebf1c9 100644
--- a/drivers/input/touchscreen/msg2638.c
+++ b/drivers/input/touchscreen/msg2638.c
@@ -446,13 +446,11 @@ static int msg2638_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client);
- mutex_lock(&msg2638->input_dev->mutex);
+ guard(mutex)(&msg2638->input_dev->mutex);
if (input_device_enabled(msg2638->input_dev))
msg2638_stop(msg2638);
- mutex_unlock(&msg2638->input_dev->mutex);
-
return 0;
}
@@ -460,16 +458,17 @@ static int msg2638_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client);
- int ret = 0;
-
- mutex_lock(&msg2638->input_dev->mutex);
+ int error;
- if (input_device_enabled(msg2638->input_dev))
- ret = msg2638_start(msg2638);
+ guard(mutex)(&msg2638->input_dev->mutex);
- mutex_unlock(&msg2638->input_dev->mutex);
+ if (input_device_enabled(msg2638->input_dev)) {
+ error = msg2638_start(msg2638);
+ if (error)
+ return error;
+ }
- return ret;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(msg2638_pm_ops, msg2638_suspend, msg2638_resume);
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index 0427ae08c39d..cc2d206d2f3d 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -128,7 +128,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- mtouch = kzalloc(sizeof(*mtouch), GFP_KERNEL);
+ mtouch = kzalloc_obj(*mtouch);
input_dev = input_allocate_device();
if (!mtouch || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/mxs-lradc-ts.c b/drivers/input/touchscreen/mxs-lradc-ts.c
index 9e36fee38d61..137ab3b60f2d 100644
--- a/drivers/input/touchscreen/mxs-lradc-ts.c
+++ b/drivers/input/touchscreen/mxs-lradc-ts.c
@@ -500,15 +500,14 @@ static irqreturn_t mxs_lradc_ts_handle_irq(int irq, void *data)
LRADC_CTRL1_TOUCH_DETECT_IRQ |
LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2);
- unsigned long flags;
if (!(reg & mxs_lradc_irq_mask(lradc)))
return IRQ_NONE;
if (reg & ts_irq_mask) {
- spin_lock_irqsave(&ts->lock, flags);
- mxs_lradc_handle_touch(ts);
- spin_unlock_irqrestore(&ts->lock, flags);
+ scoped_guard(spinlock_irqsave, &ts->lock) {
+ mxs_lradc_handle_touch(ts);
+ }
/* Make sure we don't clear the next conversion's interrupt. */
clr_irq &= ~(LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL1) |
LRADC_CTRL1_LRADC_IRQ(TOUCHSCREEN_VCHANNEL2));
diff --git a/drivers/input/touchscreen/novatek-nvt-ts.c b/drivers/input/touchscreen/novatek-nvt-ts.c
index 3e6e2ee0ba8f..708bfb933ddd 100644
--- a/drivers/input/touchscreen/novatek-nvt-ts.c
+++ b/drivers/input/touchscreen/novatek-nvt-ts.c
@@ -170,10 +170,10 @@ static int nvt_ts_suspend(struct device *dev)
{
struct nvt_ts_data *data = i2c_get_clientdata(to_i2c_client(dev));
- mutex_lock(&data->input->mutex);
+ guard(mutex)(&data->input->mutex);
+
if (input_device_enabled(data->input))
nvt_ts_stop(data->input);
- mutex_unlock(&data->input->mutex);
return 0;
}
@@ -182,10 +182,10 @@ static int nvt_ts_resume(struct device *dev)
{
struct nvt_ts_data *data = i2c_get_clientdata(to_i2c_client(dev));
- mutex_lock(&data->input->mutex);
+ guard(mutex)(&data->input->mutex);
+
if (input_device_enabled(data->input))
nvt_ts_start(data->input);
- mutex_unlock(&data->input->mutex);
return 0;
}
diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c
index 083206a3457b..7b89eb74b9de 100644
--- a/drivers/input/touchscreen/pcap_ts.c
+++ b/drivers/input/touchscreen/pcap_ts.c
@@ -138,7 +138,7 @@ static int pcap_ts_probe(struct platform_device *pdev)
struct pcap_ts *pcap_ts;
int err = -ENOMEM;
- pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL);
+ pcap_ts = kzalloc_obj(*pcap_ts);
if (!pcap_ts)
return err;
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index e027c71cffd9..4b57b6664e37 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -199,7 +199,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
int max_x, max_y;
int err;
- pm = kzalloc(sizeof(*pm), GFP_KERNEL);
+ pm = kzalloc_obj(*pm);
input_dev = input_allocate_device();
if (!pm || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c
index dad5786e82a4..c6b3615c8775 100644
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -410,26 +410,25 @@ static int pixcir_i2c_ts_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
struct input_dev *input = ts->input;
- int ret = 0;
+ int error;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (device_may_wakeup(&client->dev)) {
if (!input_device_enabled(input)) {
- ret = pixcir_start(ts);
- if (ret) {
+ error = pixcir_start(ts);
+ if (error) {
dev_err(dev, "Failed to start\n");
- goto unlock;
+ return error;
}
}
} else if (input_device_enabled(input)) {
- ret = pixcir_stop(ts);
+ error = pixcir_stop(ts);
+ if (error)
+ return error;
}
-unlock:
- mutex_unlock(&input->mutex);
-
- return ret;
+ return 0;
}
static int pixcir_i2c_ts_resume(struct device *dev)
@@ -437,26 +436,25 @@ static int pixcir_i2c_ts_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client);
struct input_dev *input = ts->input;
- int ret = 0;
+ int error;
- mutex_lock(&input->mutex);
+ guard(mutex)(&input->mutex);
if (device_may_wakeup(&client->dev)) {
if (!input_device_enabled(input)) {
- ret = pixcir_stop(ts);
- if (ret) {
+ error = pixcir_stop(ts);
+ if (error) {
dev_err(dev, "Failed to stop\n");
- goto unlock;
+ return error;
}
}
} else if (input_device_enabled(input)) {
- ret = pixcir_start(ts);
+ error = pixcir_start(ts);
+ if (error)
+ return error;
}
-unlock:
- mutex_unlock(&input->mutex);
-
- return ret;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index f975b53e8825..f2d33ad86fd2 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -169,10 +169,9 @@ static int raydium_i2c_send(struct i2c_client *client,
{
int tries = 0;
int error;
- u8 *tx_buf;
u8 reg_addr = addr & 0xff;
- tx_buf = kmalloc(len + 1, GFP_KERNEL);
+ u8 *tx_buf __free(kfree) = kmalloc(len + 1, GFP_KERNEL);
if (!tx_buf)
return -ENOMEM;
@@ -210,14 +209,12 @@ static int raydium_i2c_send(struct i2c_client *client,
error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer));
if (likely(!error))
- goto out;
+ return 0;
msleep(RM_RETRY_DELAY_MS);
} while (++tries < RM_MAX_RETRIES);
dev_err(&client->dev, "%s failed: %d\n", __func__, error);
-out:
- kfree(tx_buf);
return error;
}
@@ -815,21 +812,21 @@ static int raydium_i2c_do_update_firmware(struct raydium_data *ts,
static int raydium_i2c_fw_update(struct raydium_data *ts)
{
struct i2c_client *client = ts->client;
- const struct firmware *fw = NULL;
- char *fw_file;
int error;
- fw_file = kasprintf(GFP_KERNEL, "raydium_%#04x.fw",
- le32_to_cpu(ts->info.hw_ver));
+ const char *fw_file __free(kfree) =
+ kasprintf(GFP_KERNEL, "raydium_%#04x.fw",
+ le32_to_cpu(ts->info.hw_ver));
if (!fw_file)
return -ENOMEM;
dev_dbg(&client->dev, "firmware name: %s\n", fw_file);
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, fw_file, &client->dev);
if (error) {
dev_err(&client->dev, "Unable to open firmware %s\n", fw_file);
- goto out_free_fw_file;
+ return error;
}
disable_irq(client->irq);
@@ -856,11 +853,6 @@ out_enable_irq:
enable_irq(client->irq);
msleep(100);
- release_firmware(fw);
-
-out_free_fw_file:
- kfree(fw_file);
-
return error;
}
@@ -965,15 +957,12 @@ static ssize_t raydium_i2c_update_fw_store(struct device *dev,
struct raydium_data *ts = i2c_get_clientdata(client);
int error;
- error = mutex_lock_interruptible(&ts->sysfs_mutex);
- if (error)
- return error;
-
- error = raydium_i2c_fw_update(ts);
-
- mutex_unlock(&ts->sysfs_mutex);
+ scoped_guard(mutex_intr, &ts->sysfs_mutex) {
+ error = raydium_i2c_fw_update(ts);
+ return error ?: count;
+ }
- return error ?: count;
+ return -EINTR;
}
static ssize_t raydium_i2c_calibrate_store(struct device *dev,
@@ -985,17 +974,20 @@ static ssize_t raydium_i2c_calibrate_store(struct device *dev,
static const u8 cal_cmd[] = { 0x00, 0x01, 0x9E };
int error;
- error = mutex_lock_interruptible(&ts->sysfs_mutex);
- if (error)
- return error;
+ scoped_guard(mutex_intr, &ts->sysfs_mutex) {
+ error = raydium_i2c_write_object(client,
+ cal_cmd, sizeof(cal_cmd),
+ RAYDIUM_WAIT_READY);
+ if (error) {
+ dev_err(&client->dev,
+ "calibrate command failed: %d\n", error);
+ return error;
+ }
- error = raydium_i2c_write_object(client, cal_cmd, sizeof(cal_cmd),
- RAYDIUM_WAIT_READY);
- if (error)
- dev_err(&client->dev, "calibrate command failed: %d\n", error);
+ return count;
+ }
- mutex_unlock(&ts->sysfs_mutex);
- return error ?: count;
+ return -EINTR;
}
static DEVICE_ATTR(fw_version, S_IRUGO, raydium_i2c_fw_ver_show, NULL);
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index 9b3901eec0a5..9b266927b7fe 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -15,6 +15,7 @@
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
+#include <linux/input/touch-overlay.h>
#include <linux/input/touchscreen.h>
#include <linux/interrupt.h>
#include <linux/module.h>
@@ -22,11 +23,14 @@
#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/types.h>
-#include <linux/input/touch-overlay.h>
+#include <asm/byteorder.h>
#define ST1232_TS_NAME "st1232-ts"
#define ST1633_TS_NAME "st1633-ts"
+#define REG_FIRMWARE_VERSION 0x00
+#define REG_FIRMWARE_REVISION_3 0x0C
+
#define REG_STATUS 0x01 /* Device Status | Error Code */
#define STATUS_NORMAL 0x00
@@ -61,8 +65,38 @@ struct st1232_ts_data {
struct list_head touch_overlay_list;
int read_buf_len;
u8 *read_buf;
+ u8 fw_version;
+ u32 fw_revision;
};
+static ssize_t fw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct st1232_ts_data *st1232_ts = i2c_get_clientdata(client);
+
+ return sysfs_emit(buf, "%u\n", st1232_ts->fw_version);
+}
+
+static ssize_t fw_revision_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct st1232_ts_data *st1232_ts = i2c_get_clientdata(client);
+
+ return sysfs_emit(buf, "%08x\n", st1232_ts->fw_revision);
+}
+
+static DEVICE_ATTR_RO(fw_version);
+static DEVICE_ATTR_RO(fw_revision);
+
+static struct attribute *st1232_attrs[] = {
+ &dev_attr_fw_version.attr,
+ &dev_attr_fw_revision.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(st1232);
+
static int st1232_ts_read_data(struct st1232_ts_data *ts, u8 reg,
unsigned int n)
{
@@ -110,6 +144,26 @@ static int st1232_ts_wait_ready(struct st1232_ts_data *ts)
return -ENXIO;
}
+static int st1232_ts_read_fw_version(struct st1232_ts_data *ts,
+ u8 *fw_version, u32 *fw_revision)
+{
+ int error;
+
+ /* select firmware version register */
+ error = st1232_ts_read_data(ts, REG_FIRMWARE_VERSION, 1);
+ if (error)
+ return error;
+ *fw_version = ts->read_buf[0];
+
+ /* select firmware revision register */
+ error = st1232_ts_read_data(ts, REG_FIRMWARE_REVISION_3, 4);
+ if (error)
+ return error;
+ *fw_revision = le32_to_cpup((__le32 *)ts->read_buf);
+
+ return 0;
+}
+
static int st1232_ts_read_resolution(struct st1232_ts_data *ts, u16 *max_x,
u16 *max_y)
{
@@ -299,6 +353,16 @@ static int st1232_ts_probe(struct i2c_client *client)
if (error)
return error;
+ /* Read firmware version from the chip */
+ error = st1232_ts_read_fw_version(ts, &ts->fw_version, &ts->fw_revision);
+ if (error) {
+ dev_err(&client->dev,
+ "Failed to read firmware version: %d\n", error);
+ return error;
+ }
+ dev_dbg(&client->dev, "Detected firmware version %u, rev %08x\n",
+ ts->fw_version, ts->fw_revision);
+
if (ts->chip_info->have_z)
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0,
ts->chip_info->max_area, 0, 0);
@@ -408,6 +472,7 @@ static struct i2c_driver st1232_ts_driver = {
.driver = {
.name = ST1232_TS_NAME,
.of_match_table = st1232_ts_dt_ids,
+ .dev_groups = st1232_groups,
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.pm = pm_sleep_ptr(&st1232_ts_pm_ops),
},
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 4b166b0a9a5a..8af87d0b6eb6 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -302,7 +302,7 @@ static irqreturn_t stmfts_irq_handler(int irq, void *dev)
struct stmfts_data *sdata = dev;
int err;
- mutex_lock(&sdata->mutex);
+ guard(mutex)(&sdata->mutex);
err = stmfts_read_events(sdata);
if (unlikely(err))
@@ -311,7 +311,6 @@ static irqreturn_t stmfts_irq_handler(int irq, void *dev)
else
stmfts_parse_events(sdata);
- mutex_unlock(&sdata->mutex);
return IRQ_HANDLED;
}
@@ -347,17 +346,17 @@ static int stmfts_input_open(struct input_dev *dev)
return err;
}
- mutex_lock(&sdata->mutex);
- sdata->running = true;
+ scoped_guard(mutex, &sdata->mutex) {
+ sdata->running = true;
- if (sdata->hover_enabled) {
- err = i2c_smbus_write_byte(sdata->client,
- STMFTS_SS_HOVER_SENSE_ON);
- if (err)
- dev_warn(&sdata->client->dev,
- "failed to enable hover\n");
+ if (sdata->hover_enabled) {
+ err = i2c_smbus_write_byte(sdata->client,
+ STMFTS_SS_HOVER_SENSE_ON);
+ if (err)
+ dev_warn(&sdata->client->dev,
+ "failed to enable hover\n");
+ }
}
- mutex_unlock(&sdata->mutex);
if (sdata->use_key) {
err = i2c_smbus_write_byte(sdata->client,
@@ -381,18 +380,17 @@ static void stmfts_input_close(struct input_dev *dev)
dev_warn(&sdata->client->dev,
"failed to disable touchscreen: %d\n", err);
- mutex_lock(&sdata->mutex);
+ scoped_guard(mutex, &sdata->mutex) {
+ sdata->running = false;
- sdata->running = false;
-
- if (sdata->hover_enabled) {
- err = i2c_smbus_write_byte(sdata->client,
- STMFTS_SS_HOVER_SENSE_OFF);
- if (err)
- dev_warn(&sdata->client->dev,
- "failed to disable hover: %d\n", err);
+ if (sdata->hover_enabled) {
+ err = i2c_smbus_write_byte(sdata->client,
+ STMFTS_SS_HOVER_SENSE_OFF);
+ if (err)
+ dev_warn(&sdata->client->dev,
+ "failed to disable hover: %d\n", err);
+ }
}
- mutex_unlock(&sdata->mutex);
if (sdata->use_key) {
err = i2c_smbus_write_byte(sdata->client,
@@ -474,26 +472,27 @@ static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
unsigned long value;
- int err = 0;
+ bool hover;
+ int err;
if (kstrtoul(buf, 0, &value))
return -EINVAL;
- mutex_lock(&sdata->mutex);
+ hover = !!value;
- if (value && sdata->hover_enabled)
- goto out;
+ guard(mutex)(&sdata->mutex);
- if (sdata->running)
- err = i2c_smbus_write_byte(sdata->client,
+ if (hover != sdata->hover_enabled) {
+ if (sdata->running) {
+ err = i2c_smbus_write_byte(sdata->client,
value ? STMFTS_SS_HOVER_SENSE_ON :
STMFTS_SS_HOVER_SENSE_OFF);
+ if (err)
+ return err;
+ }
- if (!err)
- sdata->hover_enabled = !!value;
-
-out:
- mutex_unlock(&sdata->mutex);
+ sdata->hover_enabled = hover;
+ }
return len;
}
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 7b3b10cbfcfc..fe63d53d56db 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -538,15 +538,15 @@ static void sur40_process_video(struct sur40_state *sur40)
return;
/* get a new buffer from the list */
- spin_lock(&sur40->qlock);
- if (list_empty(&sur40->buf_list)) {
- dev_dbg(sur40->dev, "buffer queue empty\n");
- spin_unlock(&sur40->qlock);
- return;
+ scoped_guard(spinlock, &sur40->qlock) {
+ if (list_empty(&sur40->buf_list)) {
+ dev_dbg(sur40->dev, "buffer queue empty\n");
+ return;
+ }
+ new_buf = list_first_entry(&sur40->buf_list,
+ struct sur40_buffer, list);
+ list_del(&new_buf->list);
}
- new_buf = list_entry(sur40->buf_list.next, struct sur40_buffer, list);
- list_del(&new_buf->list);
- spin_unlock(&sur40->qlock);
dev_dbg(sur40->dev, "buffer acquired\n");
@@ -672,7 +672,7 @@ static int sur40_probe(struct usb_interface *interface,
return -ENODEV;
/* Allocate memory for our device state and initialize it. */
- sur40 = kzalloc(sizeof(*sur40), GFP_KERNEL);
+ sur40 = kzalloc_obj(*sur40);
if (!sur40)
return -ENOMEM;
@@ -888,9 +888,8 @@ static void sur40_buffer_queue(struct vb2_buffer *vb)
struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
struct sur40_buffer *buf = (struct sur40_buffer *)vb;
- spin_lock(&sur40->qlock);
+ guard(spinlock)(&sur40->qlock);
list_add_tail(&buf->list, &sur40->buf_list);
- spin_unlock(&sur40->qlock);
}
static void return_all_buffers(struct sur40_state *sur40,
@@ -898,12 +897,12 @@ static void return_all_buffers(struct sur40_state *sur40,
{
struct sur40_buffer *buf, *node;
- spin_lock(&sur40->qlock);
+ guard(spinlock)(&sur40->qlock);
+
list_for_each_entry_safe(buf, node, &sur40->buf_list, list) {
vb2_buffer_done(&buf->vb.vb2_buf, state);
list_del(&buf->list);
}
- spin_unlock(&sur40->qlock);
}
/*
diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c
index 5fa47a1a6fdc..0d92aaeea3e0 100644
--- a/drivers/input/touchscreen/sx8654.c
+++ b/drivers/input/touchscreen/sx8654.c
@@ -117,12 +117,11 @@ static inline void sx865x_penrelease(struct sx8654 *ts)
static void sx865x_penrelease_timer_handler(struct timer_list *t)
{
struct sx8654 *ts = timer_container_of(ts, t, timer);
- unsigned long flags;
- spin_lock_irqsave(&ts->lock, flags);
- sx865x_penrelease(ts);
- spin_unlock_irqrestore(&ts->lock, flags);
dev_dbg(&ts->client->dev, "penrelease by timer\n");
+
+ guard(spinlock_irqsave)(&ts->lock);
+ sx865x_penrelease(ts);
}
static irqreturn_t sx8650_irq(int irq, void *handle)
@@ -130,7 +129,6 @@ static irqreturn_t sx8650_irq(int irq, void *handle)
struct sx8654 *ts = handle;
struct device *dev = &ts->client->dev;
int len, i;
- unsigned long flags;
u8 stat;
u16 x, y;
u16 ch;
@@ -153,7 +151,7 @@ static irqreturn_t sx8650_irq(int irq, void *handle)
return IRQ_HANDLED;
}
- spin_lock_irqsave(&ts->lock, flags);
+ guard(spinlock_irqsave)(&ts->lock);
x = 0;
y = 0;
@@ -184,7 +182,6 @@ static irqreturn_t sx8650_irq(int irq, void *handle)
dev_dbg(dev, "point(%4d,%4d)\n", x, y);
mod_timer(&ts->timer, jiffies + SX8650_PENIRQ_TIMEOUT);
- spin_unlock_irqrestore(&ts->lock, flags);
return IRQ_HANDLED;
}
@@ -394,9 +391,13 @@ static int sx8654_probe(struct i2c_client *client)
return error;
}
+ /*
+ * Start with the interrupt disabled, it will be enabled in
+ * sx8654_open().
+ */
error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, sx8654->data->irqh,
- IRQF_ONESHOT,
+ IRQF_ONESHOT | IRQF_NO_AUTOEN,
client->name, sx8654);
if (error) {
dev_err(&client->dev,
@@ -405,9 +406,6 @@ static int sx8654_probe(struct i2c_client *client)
return error;
}
- /* Disable the IRQ, we'll enable it in sx8654_open() */
- disable_irq(client->irq);
-
error = input_register_device(sx8654->input);
if (error)
return error;
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
index 0534b2ba650b..623546e80668 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
@@ -422,7 +422,7 @@ static int titsc_probe(struct platform_device *pdev)
int err;
/* Allocate memory for device */
- ts_dev = kzalloc(sizeof(*ts_dev), GFP_KERNEL);
+ ts_dev = kzalloc_obj(*ts_dev);
input_dev = input_allocate_device();
if (!ts_dev || !input_dev) {
dev_err(&pdev->dev, "failed to allocate memory.\n");
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c
index 53c39ed849f7..6d4a1acf57c9 100644
--- a/drivers/input/touchscreen/touchit213.c
+++ b/drivers/input/touchscreen/touchit213.c
@@ -139,7 +139,7 @@ static int touchit213_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- touchit213 = kzalloc(sizeof(*touchit213), GFP_KERNEL);
+ touchit213 = kzalloc_obj(*touchit213);
input_dev = input_allocate_device();
if (!touchit213 || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
index 9be7c6bf5e7f..d7fdf201e4d1 100644
--- a/drivers/input/touchscreen/touchright.c
+++ b/drivers/input/touchscreen/touchright.c
@@ -102,7 +102,7 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- tr = kzalloc(sizeof(*tr), GFP_KERNEL);
+ tr = kzalloc_obj(*tr);
input_dev = input_allocate_device();
if (!tr || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
index 4b92e8711e1d..099fd88e65d8 100644
--- a/drivers/input/touchscreen/touchwin.c
+++ b/drivers/input/touchscreen/touchwin.c
@@ -109,7 +109,7 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int err;
- tw = kzalloc(sizeof(*tw), GFP_KERNEL);
+ tw = kzalloc_obj(*tw);
input_dev = input_allocate_device();
if (!tw || !input_dev) {
err = -ENOMEM;
diff --git a/drivers/input/touchscreen/tsc2007_core.c b/drivers/input/touchscreen/tsc2007_core.c
index 948935de894b..524f14eb3da2 100644
--- a/drivers/input/touchscreen/tsc2007_core.c
+++ b/drivers/input/touchscreen/tsc2007_core.c
@@ -122,9 +122,10 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
/* pen is down, continue with the measurement */
- mutex_lock(&ts->mlock);
- tsc2007_read_values(ts, &tc);
- mutex_unlock(&ts->mlock);
+ /* Serialize access between the ISR and IIO reads. */
+ scoped_guard(mutex, &ts->mlock) {
+ tsc2007_read_values(ts, &tc);
+ }
rt = tsc2007_calculate_resistance(ts, &tc);
diff --git a/drivers/input/touchscreen/tsc2007_iio.c b/drivers/input/touchscreen/tsc2007_iio.c
index 752eb7fe5da3..e9e495ec0b6c 100644
--- a/drivers/input/touchscreen/tsc2007_iio.c
+++ b/drivers/input/touchscreen/tsc2007_iio.c
@@ -41,7 +41,6 @@ static int tsc2007_read_raw(struct iio_dev *indio_dev,
struct tsc2007_iio *iio = iio_priv(indio_dev);
struct tsc2007 *tsc = iio->ts;
int adc_chan = chan->channel;
- int ret = 0;
if (adc_chan >= ARRAY_SIZE(tsc2007_iio_channel))
return -EINVAL;
@@ -49,7 +48,7 @@ static int tsc2007_read_raw(struct iio_dev *indio_dev,
if (mask != IIO_CHAN_INFO_RAW)
return -EINVAL;
- mutex_lock(&tsc->mlock);
+ guard(mutex)(&tsc->mlock);
switch (chan->channel) {
case 0:
@@ -92,11 +91,7 @@ static int tsc2007_read_raw(struct iio_dev *indio_dev,
/* Prepare for next touch reading - power down ADC, enable PENIRQ */
tsc2007_xfer(tsc, PWRDOWN);
- mutex_unlock(&tsc->mlock);
-
- ret = IIO_VAL_INT;
-
- return ret;
+ return IIO_VAL_INT;
}
static const struct iio_info tsc2007_iio_info = {
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c
index c5dabebaf96d..2a28a309eab5 100644
--- a/drivers/input/touchscreen/tsc40.c
+++ b/drivers/input/touchscreen/tsc40.c
@@ -83,7 +83,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv)
struct input_dev *input_dev;
int error;
- ptsc = kzalloc(sizeof(*ptsc), GFP_KERNEL);
+ ptsc = kzalloc_obj(*ptsc);
input_dev = input_allocate_device();
if (!ptsc || !input_dev) {
error = -ENOMEM;
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 7567efabe014..daa28135f887 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -378,7 +378,7 @@ static int mtouch_alloc(struct usbtouch_usb *usbtouch)
{
struct mtouch_priv *priv;
- priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kmalloc_obj(*priv);
if (!priv)
return -ENOMEM;
@@ -938,7 +938,7 @@ static int nexio_alloc(struct usbtouch_usb *usbtouch)
struct nexio_priv *priv;
int ret = -ENOMEM;
- priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+ priv = kmalloc_obj(*priv);
if (!priv)
goto out_buf;
@@ -969,24 +969,21 @@ static int nexio_init(struct usbtouch_usb *usbtouch)
{
struct usb_device *dev = interface_to_usbdev(usbtouch->interface);
struct usb_host_interface *interface = usbtouch->interface->cur_altsetting;
+ struct usb_endpoint_descriptor *ep_in, *ep_out;
struct nexio_priv *priv = usbtouch->priv;
- int ret = -ENOMEM;
int actual_len, i;
char *firmware_ver = NULL, *device_name = NULL;
- int input_ep = 0, output_ep = 0;
+ int input_ep, output_ep;
+ int ret;
/* find first input and output endpoint */
- for (i = 0; i < interface->desc.bNumEndpoints; i++) {
- if (!input_ep &&
- usb_endpoint_dir_in(&interface->endpoint[i].desc))
- input_ep = interface->endpoint[i].desc.bEndpointAddress;
- if (!output_ep &&
- usb_endpoint_dir_out(&interface->endpoint[i].desc))
- output_ep = interface->endpoint[i].desc.bEndpointAddress;
- }
- if (!input_ep || !output_ep)
+ ret = usb_find_common_endpoints(interface, &ep_in, &ep_out, NULL, NULL);
+ if (ret)
return -ENXIO;
+ input_ep = usb_endpoint_num(ep_in);
+ output_ep = usb_endpoint_num(ep_out);
+
u8 *buf __free(kfree) = kmalloc(NEXIO_BUFSIZE, GFP_NOIO);
if (!buf)
return -ENOMEM;
@@ -1427,18 +1424,6 @@ static void usbtouch_free_buffers(struct usb_device *udev,
kfree(usbtouch->buffer);
}
-static struct usb_endpoint_descriptor *
-usbtouch_get_input_endpoint(struct usb_host_interface *interface)
-{
- int i;
-
- for (i = 0; i < interface->desc.bNumEndpoints; i++)
- if (usb_endpoint_dir_in(&interface->endpoint[i].desc))
- return &interface->endpoint[i].desc;
-
- return NULL;
-}
-
static int usbtouch_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -1447,18 +1432,22 @@ static int usbtouch_probe(struct usb_interface *intf,
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = interface_to_usbdev(intf);
const struct usbtouch_device_info *type;
- int err = -ENOMEM;
+ int err;
/* some devices are ignored */
type = (const struct usbtouch_device_info *)id->driver_info;
if (!type)
return -ENODEV;
- endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting);
- if (!endpoint)
- return -ENXIO;
+ err = usb_find_int_in_endpoint(intf->cur_altsetting, &endpoint);
+ if (err) {
+ err = usb_find_bulk_in_endpoint(intf->cur_altsetting, &endpoint);
+ if (err)
+ return -ENXIO;
+ }
- usbtouch = kzalloc(sizeof(*usbtouch), GFP_KERNEL);
+ err = -ENOMEM;
+ usbtouch = kzalloc_obj(*usbtouch);
input_dev = input_allocate_device();
if (!usbtouch || !input_dev)
goto out_free;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index ed2ca8a689d5..45930d731873 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -596,7 +596,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
char basename[64] = "Wacom Serial";
int err, err_pen, err_touch;
- w8001 = kzalloc(sizeof(*w8001), GFP_KERNEL);
+ w8001 = kzalloc_obj(*w8001);
input_dev_pen = input_allocate_device();
input_dev_touch = input_allocate_device();
if (!w8001 || !input_dev_pen || !input_dev_touch) {
diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c
index 1e2a6bbb88cb..bdaabb14dc8c 100644
--- a/drivers/input/touchscreen/wdt87xx_i2c.c
+++ b/drivers/input/touchscreen/wdt87xx_i2c.c
@@ -813,56 +813,46 @@ static int wdt87xx_load_chunk(struct i2c_client *client,
return 0;
}
-static int wdt87xx_do_update_firmware(struct i2c_client *client,
+static int wdt87xx_do_update_firmware(struct wdt87xx_data *wdt,
const struct firmware *fw,
unsigned int chunk_id)
{
- struct wdt87xx_data *wdt = i2c_get_clientdata(client);
+ struct i2c_client *client = wdt->client;
int error;
- error = wdt87xx_validate_firmware(wdt, fw);
- if (error)
- return error;
-
- error = mutex_lock_interruptible(&wdt->fw_mutex);
- if (error)
- return error;
-
- disable_irq(client->irq);
-
error = wdt87xx_load_chunk(client, fw, chunk_id);
if (error) {
dev_err(&client->dev,
"firmware load failed (type: %d): %d\n",
chunk_id, error);
- goto out;
+ return error;
}
error = wdt87xx_sw_reset(client);
if (error) {
dev_err(&client->dev, "soft reset failed: %d\n", error);
- goto out;
+ return error;
}
/* Refresh the parameters */
error = wdt87xx_get_sysparam(client, &wdt->param);
- if (error)
+ if (error) {
dev_err(&client->dev,
"failed to refresh system parameters: %d\n", error);
-out:
- enable_irq(client->irq);
- mutex_unlock(&wdt->fw_mutex);
+ return error;
+ }
- return error ? error : 0;
+ return 0;
}
static int wdt87xx_update_firmware(struct device *dev,
const char *fw_name, unsigned int chunk_id)
{
struct i2c_client *client = to_i2c_client(dev);
- const struct firmware *fw;
+ struct wdt87xx_data *wdt = i2c_get_clientdata(client);
int error;
+ const struct firmware *fw __free(firmware) = NULL;
error = request_firmware(&fw, fw_name, dev);
if (error) {
dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
@@ -870,11 +860,19 @@ static int wdt87xx_update_firmware(struct device *dev,
return error;
}
- error = wdt87xx_do_update_firmware(client, fw, chunk_id);
+ error = wdt87xx_validate_firmware(wdt, fw);
+ if (error)
+ return error;
+
+ scoped_cond_guard(mutex_intr, return -EINTR, &wdt->fw_mutex) {
+ guard(disable_irq)(&client->irq);
- release_firmware(fw);
+ error = wdt87xx_do_update_firmware(wdt, fw, chunk_id);
+ if (error)
+ return error;
+ }
- return error ? error : 0;
+ return 0;
}
static ssize_t config_csum_show(struct device *dev,
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 96354c44af87..c51822563f3f 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -126,7 +126,7 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
int timeout = 0;
/* get codec */
- mutex_lock(&wm->codec_mutex);
+ guard(mutex)(&wm->codec_mutex);
/* When the touchscreen is not in use, we may have to power up
* the AUX ADC before we can use sample the AUX inputs->
@@ -160,7 +160,6 @@ int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
wm->codec->dig_enable(wm, false);
}
- mutex_unlock(&wm->codec_mutex);
return (rc == RC_VALID ? auxval & 0xfff : -EBUSY);
}
EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
@@ -176,18 +175,11 @@ EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio)
{
u16 status;
- enum wm97xx_gpio_status ret;
- mutex_lock(&wm->codec_mutex);
- status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
-
- if (status & gpio)
- ret = WM97XX_GPIO_HIGH;
- else
- ret = WM97XX_GPIO_LOW;
+ guard(mutex)(&wm->codec_mutex);
- mutex_unlock(&wm->codec_mutex);
- return ret;
+ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
+ return (status & gpio) ? WM97XX_GPIO_HIGH : WM97XX_GPIO_LOW;
}
EXPORT_SYMBOL_GPL(wm97xx_get_gpio);
@@ -205,7 +197,8 @@ void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
{
u16 reg;
- mutex_lock(&wm->codec_mutex);
+ guard(mutex)(&wm->codec_mutex);
+
reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
if (status == WM97XX_GPIO_HIGH)
@@ -217,7 +210,6 @@ void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
else
wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
- mutex_unlock(&wm->codec_mutex);
}
EXPORT_SYMBOL_GPL(wm97xx_set_gpio);
@@ -231,7 +223,8 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir,
{
u16 reg;
- mutex_lock(&wm->codec_mutex);
+ guard(mutex)(&wm->codec_mutex);
+
reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
if (pol == WM97XX_GPIO_POL_HIGH)
@@ -264,7 +257,6 @@ void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir,
reg &= ~gpio;
wm97xx_reg_write(wm, AC97_GPIO_CFG, reg);
- mutex_unlock(&wm->codec_mutex);
}
EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
@@ -303,7 +295,9 @@ static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id)
wm->pen_is_down = 0;
} else {
u16 status, pol;
- mutex_lock(&wm->codec_mutex);
+
+ guard(mutex)(&wm->codec_mutex);
+
status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
@@ -323,7 +317,6 @@ static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id)
else
wm97xx_reg_write(wm, AC97_GPIO_STATUS, status &
~WM97XX_GPIO_13);
- mutex_unlock(&wm->codec_mutex);
}
/* If the system is not using continuous mode or it provides a
@@ -382,7 +375,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
struct wm97xx_data data;
int rc;
- mutex_lock(&wm->codec_mutex);
+ guard(mutex)(&wm->codec_mutex);
if (wm->mach_ops && wm->mach_ops->acc_enabled)
rc = wm->mach_ops->acc_pen_down(wm);
@@ -422,8 +415,7 @@ static int wm97xx_read_samples(struct wm97xx *wm)
abs_y[0] > (data.y & 0xfff) ||
abs_y[1] < (data.y & 0xfff)) {
dev_dbg(wm->dev, "Measurement out of range, dropping it\n");
- rc = RC_AGAIN;
- goto out;
+ return RC_AGAIN;
}
input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
@@ -439,8 +431,6 @@ static int wm97xx_read_samples(struct wm97xx *wm)
wm->ts_reader_interval = wm->ts_reader_min_interval;
}
-out:
- mutex_unlock(&wm->codec_mutex);
return rc;
}
@@ -773,7 +763,8 @@ static int wm97xx_suspend(struct device *dev)
else
suspend_mode = 0;
- mutex_lock(&wm->input_dev->mutex);
+ guard(mutex)(&wm->input_dev->mutex);
+
if (input_device_enabled(wm->input_dev))
cancel_delayed_work_sync(&wm->ts_reader);
@@ -791,7 +782,6 @@ static int wm97xx_suspend(struct device *dev)
reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000;
wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
}
- mutex_unlock(&wm->input_dev->mutex);
return 0;
}
@@ -800,7 +790,8 @@ static int wm97xx_resume(struct device *dev)
{
struct wm97xx *wm = dev_get_drvdata(dev);
- mutex_lock(&wm->input_dev->mutex);
+ guard(mutex)(&wm->input_dev->mutex);
+
/* restore digitiser and gpios */
if (wm->id == WM9713_ID2) {
wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
@@ -827,7 +818,6 @@ static int wm97xx_resume(struct device *dev)
queue_delayed_work(wm->ts_workq, &wm->ts_reader,
wm->ts_reader_interval);
}
- mutex_unlock(&wm->input_dev->mutex);
return 0;
}
@@ -840,13 +830,12 @@ static DEFINE_SIMPLE_DEV_PM_OPS(wm97xx_pm_ops, wm97xx_suspend, wm97xx_resume);
int wm97xx_register_mach_ops(struct wm97xx *wm,
struct wm97xx_mach_ops *mach_ops)
{
- mutex_lock(&wm->codec_mutex);
- if (wm->mach_ops) {
- mutex_unlock(&wm->codec_mutex);
+ guard(mutex)(&wm->codec_mutex);
+
+ if (wm->mach_ops)
return -EINVAL;
- }
+
wm->mach_ops = mach_ops;
- mutex_unlock(&wm->codec_mutex);
return 0;
}
@@ -854,9 +843,9 @@ EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops);
void wm97xx_unregister_mach_ops(struct wm97xx *wm)
{
- mutex_lock(&wm->codec_mutex);
+ guard(mutex)(&wm->codec_mutex);
+
wm->mach_ops = NULL;
- mutex_unlock(&wm->codec_mutex);
}
EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
diff --git a/drivers/input/touchscreen/zinitix.c b/drivers/input/touchscreen/zinitix.c
index 716d6fa60f86..0c36765bd79f 100644
--- a/drivers/input/touchscreen/zinitix.c
+++ b/drivers/input/touchscreen/zinitix.c
@@ -703,13 +703,11 @@ static int zinitix_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct bt541_ts_data *bt541 = i2c_get_clientdata(client);
- mutex_lock(&bt541->input_dev->mutex);
+ guard(mutex)(&bt541->input_dev->mutex);
if (input_device_enabled(bt541->input_dev))
zinitix_stop(bt541);
- mutex_unlock(&bt541->input_dev->mutex);
-
return 0;
}
@@ -717,16 +715,17 @@ static int zinitix_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct bt541_ts_data *bt541 = i2c_get_clientdata(client);
- int ret = 0;
-
- mutex_lock(&bt541->input_dev->mutex);
+ int error;
- if (input_device_enabled(bt541->input_dev))
- ret = zinitix_start(bt541);
+ guard(mutex)(&bt541->input_dev->mutex);
- mutex_unlock(&bt541->input_dev->mutex);
+ if (input_device_enabled(bt541->input_dev)) {
+ error = zinitix_start(bt541);
+ if (error)
+ return error;
+ }
- return ret;
+ return 0;
}
static DEFINE_SIMPLE_DEV_PM_OPS(zinitix_pm_ops, zinitix_suspend, zinitix_resume);