diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2026-04-19 18:28:57 -0700 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2026-04-19 18:28:57 -0700 |
| commit | f4b369c6fe0ceaba2da2daff8c9eb415f85926dd (patch) | |
| tree | 30465d0a429b2c224685b5d8e804bf053c4d129a /drivers/input | |
| parent | ff14dafde15c11403fac61367a34fea08926e9ee (diff) | |
| parent | 2ca45e57ea027fffe3350ae5e21ad9cecb0dce74 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 7.1 merge window.
Diffstat (limited to 'drivers/input')
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(µ->lock); + guard(spinlock_irq)(µ->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); |
