From 6c7cc1a29d1e679be4a98b01141f1ba491e5775e Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Thu, 30 May 2024 13:51:32 -0700 Subject: [PATCH 01/71] Input: wacom_w8001 - simplify device name generation Replace pairs of strscpy/strlcat calls with snprintf. Signed-off-by: Jason Gerecke Link: https://lore.kernel.org/r/CANRwn3SuTjdCCK4YH1ObvsC_gZuythAQ7kSHJP-CiAFw9h5Qcw@mail.gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index 928c5ee3ac36..c61908518afe 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -595,7 +595,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) struct w8001 *w8001; struct input_dev *input_dev_pen; struct input_dev *input_dev_touch; - char basename[64]; + char basename[64] = "Wacom Serial"; int err, err_pen, err_touch; w8001 = kzalloc(sizeof(struct w8001), GFP_KERNEL); @@ -625,8 +625,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) /* For backwards-compatibility we compose the basename based on * capabilities and then just append the tool type */ - strscpy(basename, "Wacom Serial", sizeof(basename)); - err_pen = w8001_setup_pen(w8001, basename, sizeof(basename)); err_touch = w8001_setup_touch(w8001, basename, sizeof(basename)); if (err_pen && err_touch) { @@ -635,8 +633,8 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) } if (!err_pen) { - strscpy(w8001->pen_name, basename, sizeof(w8001->pen_name)); - strlcat(w8001->pen_name, " Pen", sizeof(w8001->pen_name)); + snprintf(w8001->pen_name, sizeof(w8001->pen_name), + "%s Pen", basename); input_dev_pen->name = w8001->pen_name; w8001_set_devdata(input_dev_pen, w8001, serio); @@ -651,9 +649,8 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) } if (!err_touch) { - strscpy(w8001->touch_name, basename, sizeof(w8001->touch_name)); - strlcat(w8001->touch_name, " Finger", - sizeof(w8001->touch_name)); + snprintf(w8001->pen_name, sizeof(w8001->pen_name), + "%s Finger", basename); input_dev_touch->name = w8001->touch_name; w8001_set_devdata(input_dev_touch, w8001, serio); From bb8706a41946d161222cdddd6b3de3025877c204 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sun, 2 Jun 2024 21:29:43 -0700 Subject: [PATCH 02/71] Input: keyboard - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB7237277464F23CA168BFB3B18BF52@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 2 +- drivers/input/keyboard/lkkbd.c | 2 +- drivers/input/keyboard/locomokbd.c | 2 +- drivers/input/keyboard/maple_keyb.c | 2 +- drivers/input/keyboard/newtonkbd.c | 2 +- drivers/input/keyboard/stowaway.c | 2 +- drivers/input/keyboard/sunkbd.c | 2 +- drivers/input/keyboard/xtkbd.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 7f67f9f2946b..f4f2078cf501 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -1279,7 +1279,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *dev; int err = -ENOMEM; - atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL); + atkbd = kzalloc(sizeof(*atkbd), GFP_KERNEL); dev = input_allocate_device(); if (!atkbd || !dev) goto fail1; diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 047b654b3752..c035216dd27c 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(struct lkkbd), GFP_KERNEL); + lk = kzalloc(sizeof(*lk), GFP_KERNEL); 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 f866c03b9d0e..4b0f8323c492 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c @@ -227,7 +227,7 @@ static int locomokbd_probe(struct locomo_dev *dev) struct input_dev *input_dev; int i, err; - locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL); + locomokbd = kzalloc(sizeof(*locomokbd), GFP_KERNEL); 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 d08b565be24c..91a1d2958109 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -154,7 +154,7 @@ static int probe_maple_kbd(struct device *dev) mdev = to_maple_dev(dev); mdrv = to_maple_driver(dev->driver); - kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); + kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); if (!kbd) { error = -ENOMEM; goto fail; diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index df00a119aa9a..71e0a3f830dd 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(struct nkbd), GFP_KERNEL); + nkbd = kzalloc(sizeof(*nkbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!nkbd || !input_dev) goto fail1; diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index 56e784936059..7ef0b3f4f549 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(struct skbd), GFP_KERNEL); + skbd = kzalloc(sizeof(*skbd), GFP_KERNEL); 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 b123a208ef36..72fb46029710 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -263,7 +263,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL); + sunkbd = kzalloc(sizeof(*sunkbd), GFP_KERNEL); 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 c9d7c2481726..befa713268ae 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(struct xtkbd), GFP_KERNEL); + xtkbd = kmalloc(sizeof(*xtkbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!xtkbd || !input_dev) goto fail1; From a0bd7adadb50471331f0ca28caf068f7fab37b64 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sun, 2 Jun 2024 21:26:14 -0700 Subject: [PATCH 03/71] Input: misc - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB7237884EB989EFF55D1BEF8B8BFE2@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/88pm80x_onkey.c | 2 +- drivers/input/misc/cma3000_d0x.c | 2 +- drivers/input/misc/ims-pcu.c | 4 ++-- drivers/input/misc/max8997_haptic.c | 2 +- drivers/input/misc/pcap_keys.c | 2 +- drivers/input/misc/powermate.c | 2 +- drivers/input/misc/uinput.c | 2 +- drivers/input/misc/yealink.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/input/misc/88pm80x_onkey.c b/drivers/input/misc/88pm80x_onkey.c index 4b0685f96113..6477a41c4bac 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(struct pm80x_onkey_info), GFP_KERNEL); + info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index 1772846708d2..0c68e924a1cc 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c @@ -292,7 +292,7 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, goto err_out; } - data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); input_dev = input_allocate_device(); if (!data || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 80d16c92a08b..408a586f8c36 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -287,7 +287,7 @@ static int ims_pcu_setup_gamepad(struct ims_pcu *pcu) struct input_dev *input; int error; - gamepad = kzalloc(sizeof(struct ims_pcu_gamepad), GFP_KERNEL); + gamepad = kzalloc(sizeof(*gamepad), GFP_KERNEL); input = input_allocate_device(); if (!gamepad || !input) { dev_err(pcu->dev, @@ -1993,7 +1993,7 @@ static int ims_pcu_probe(struct usb_interface *intf, struct ims_pcu *pcu; int error; - pcu = kzalloc(sizeof(struct ims_pcu), GFP_KERNEL); + pcu = kzalloc(sizeof(*pcu), GFP_KERNEL); if (!pcu) return -ENOMEM; diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index 8861a67be575..11cac4b7dddc 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c @@ -249,7 +249,7 @@ static int max8997_haptic_probe(struct platform_device *pdev) return -EINVAL; } - chip = kzalloc(sizeof(struct max8997_haptic), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); input_dev = input_allocate_device(); if (!chip || !input_dev) { dev_err(&pdev->dev, "unable to allocate memory\n"); diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index 8a7e9ada5952..f8954a2cab24 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(struct pcap_keys), GFP_KERNEL); + pcap_keys = kmalloc(sizeof(*pcap_keys), GFP_KERNEL); if (!pcap_keys) return err; diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index db2ba89adaef..4b039abffc4b 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c @@ -320,7 +320,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(struct powermate_device), GFP_KERNEL); + pm = kzalloc(sizeof(*pm), GFP_KERNEL); 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 d98212d55108..d23f3225b00f 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -379,7 +379,7 @@ static int uinput_open(struct inode *inode, struct file *file) { struct uinput_device *newdev; - newdev = kzalloc(sizeof(struct uinput_device), GFP_KERNEL); + newdev = kzalloc(sizeof(*newdev), GFP_KERNEL); if (!newdev) return -ENOMEM; diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 69420781db30..c3221b960a75 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -868,7 +868,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(struct yealink_dev), GFP_KERNEL); + yld = kzalloc(sizeof(*yld), GFP_KERNEL); if (!yld) return -ENOMEM; From dc2f1423f056f26144f60b089430e193a4dfc672 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sun, 2 Jun 2024 21:30:36 -0700 Subject: [PATCH 04/71] Input: mouse - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB7237FB736DBF67A58798FDF38BFE2@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 2 +- drivers/input/mouse/appletouch.c | 2 +- drivers/input/mouse/bcm5974.c | 2 +- drivers/input/mouse/cypress_ps2.c | 2 +- drivers/input/mouse/focaltech.c | 3 +-- drivers/input/mouse/hgpk.c | 2 +- drivers/input/mouse/lifebook.c | 2 +- drivers/input/mouse/maplemouse.c | 2 +- drivers/input/mouse/psmouse-base.c | 2 +- drivers/input/mouse/sentelic.c | 2 +- drivers/input/mouse/sermouse.c | 2 +- drivers/input/mouse/synaptics.c | 4 ++-- drivers/input/mouse/synaptics_i2c.c | 2 +- drivers/input/mouse/vsxxxaa.c | 2 +- 14 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index e2c11d9f3868..d5ef5a112d6f 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -3201,7 +3201,7 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) */ psmouse_reset(psmouse); - priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 627048bc6a12..e669f86f1882 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -855,7 +855,7 @@ static int atp_probe(struct usb_interface *iface, } /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(struct atp), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); input_dev = input_allocate_device(); if (!dev || !input_dev) { dev_err(&iface->dev, "Out of memory\n"); diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index ca150618d32f..10a03a566905 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -904,7 +904,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(struct bcm5974), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); input_dev = input_allocate_device(); if (!dev || !input_dev) { dev_err(&iface->dev, "out of memory\n"); diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index d272f1ec27ba..c693130bef41 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -659,7 +659,7 @@ int cypress_init(struct psmouse *psmouse) { struct cytp_data *cytp; - cytp = kzalloc(sizeof(struct cytp_data), GFP_KERNEL); + cytp = kzalloc(sizeof(*cytp), GFP_KERNEL); if (!cytp) return -ENOMEM; diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index c74b99077d16..356b99d48544 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -408,8 +408,7 @@ int focaltech_init(struct psmouse *psmouse) struct focaltech_data *priv; int error; - psmouse->private = priv = kzalloc(sizeof(struct focaltech_data), - GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 3c8310da0b05..6125652e5ad8 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -981,7 +981,7 @@ int hgpk_init(struct psmouse *psmouse) struct hgpk_data *priv; int err; - priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { err = -ENOMEM; goto alloc_fail; diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index bd9955730176..7147dacc404f 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(struct lifebook_data), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); dev2 = input_allocate_device(); if (!priv || !dev2) goto err_out; diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index 2de64d6a04d1..baef4be14b54 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(struct dc_mouse), GFP_KERNEL); + mse = kzalloc(sizeof(*mse), GFP_KERNEL); if (!mse) { error = -ENOMEM; goto fail; diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index a0aac76b1e41..a2c9f7144864 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1591,7 +1591,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_deactivate(parent); } - psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL); + psmouse = kzalloc(sizeof(*psmouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!psmouse || !input_dev) goto err_free; diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 2716d2ba386a..44b136fc29aa 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(struct fsp_data), GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 993f90333380..218c8432a13b 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(struct sermouse), GFP_KERNEL); + sermouse = kzalloc(sizeof(*sermouse), GFP_KERNEL); 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 7a303a9d6bf7..38191c3b31bf 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -708,7 +708,7 @@ static void synaptics_pt_create(struct psmouse *psmouse) { struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) { psmouse_err(psmouse, "not enough memory for pass-through port\n"); @@ -1563,7 +1563,7 @@ static int synaptics_init_ps2(struct psmouse *psmouse, synaptics_apply_quirks(psmouse, info); - psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index 56e9ba396858..a0d707e47d93 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -508,7 +508,7 @@ static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *clien { struct synaptics_i2c *touch; - touch = kzalloc(sizeof(struct synaptics_i2c), GFP_KERNEL); + touch = kzalloc(sizeof(*touch), GFP_KERNEL); if (!touch) return NULL; diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 8af8e4a15f95..707cd28f4ba6 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(struct vsxxxaa), GFP_KERNEL); + mouse = kzalloc(sizeof(*mouse), GFP_KERNEL); input_dev = input_allocate_device(); if (!mouse || !input_dev) goto fail1; From 2960d4c8e77aba365df80b69e72f88b29011b111 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sun, 2 Jun 2024 21:30:48 -0700 Subject: [PATCH 05/71] Input: tablet - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB7237B05083487507CFAF96B08BFE2@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/acecad.c | 2 +- drivers/input/tablet/aiptek.c | 2 +- drivers/input/tablet/hanwang.c | 2 +- drivers/input/tablet/kbtab.c | 2 +- drivers/input/tablet/wacom_serial4.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index b20e5a1afbcc..0ac16f32b31f 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(struct usb_acecad), GFP_KERNEL); + acecad = kzalloc(sizeof(*acecad), GFP_KERNEL); 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 baabc51547b8..2d176fbab251 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1673,7 +1673,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ speeds[0] = programmableDelay; - aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); + aiptek = kzalloc(sizeof(*aiptek), GFP_KERNEL); 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 9bc631518b92..42c1e5eaddd5 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(struct hanwang), GFP_KERNEL); + hanwang = kzalloc(sizeof(*hanwang), GFP_KERNEL); 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 aa577898e952..38d36d25f6f4 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(struct kbtab), GFP_KERNEL); + kbtab = kzalloc(sizeof(*kbtab), GFP_KERNEL); input_dev = input_allocate_device(); if (!kbtab || !input_dev) goto fail1; diff --git a/drivers/input/tablet/wacom_serial4.c b/drivers/input/tablet/wacom_serial4.c index 1cedb45ba497..cf7cea77dabc 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(struct wacom), GFP_KERNEL); + wacom = kzalloc(sizeof(*wacom), GFP_KERNEL); input_dev = input_allocate_device(); if (!wacom || !input_dev) goto free_device; From 7ba38c2a9e1a8d11d5286ef8e14f86247d5443ff Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Thu, 6 Jun 2024 13:41:01 -0700 Subject: [PATCH 06/71] Input: wacom_w8001 - correct device name generation Fixes: 6c7cc1a29d1e ("Input: wacom_w8001 - simplify device name generation") Signed-off-by: Jason Gerecke Link: https://lore.kernel.org/r/20240605164656.61623-1-jason.gerecke@wacom.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index c61908518afe..4ddb6b3baba5 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -649,7 +649,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) } if (!err_touch) { - snprintf(w8001->pen_name, sizeof(w8001->pen_name), + snprintf(w8001->touch_name, sizeof(w8001->touch_name), "%s Finger", basename); input_dev_touch->name = w8001->touch_name; From c76494768761aef7630e7e0db820ba7b375964da Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 30 May 2024 11:07:19 -0700 Subject: [PATCH 07/71] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ Drivers often need to first disable an interrupt, carry out some action, and then reenable the interrupt. Introduce support for the "guard" notation for this so that the following is possible: ... scoped_cond_guard(mutex_intr, return -EINTR, &data->sysfs_mutex) { guard(disable_irq)(&client->irq); error = elan_acquire_baseline(data); if (error) return error; } ... Reviewed-by: Thomas Gleixner Link: https://lore.kernel.org/r/ZljAV6HjkPSEhWSw@google.com Signed-off-by: Dmitry Torokhov --- include/linux/interrupt.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 5c9bdd3ffccc..3a36e64119c8 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -235,6 +236,9 @@ extern void enable_percpu_irq(unsigned int irq, unsigned int type); extern bool irq_percpu_is_enabled(unsigned int irq); extern void irq_wake_thread(unsigned int irq, void *dev_id); +DEFINE_LOCK_GUARD_1(disable_irq, int, + disable_irq(*_T->lock), enable_irq(*_T->lock)) + extern void disable_nmi_nosync(unsigned int irq); extern void disable_percpu_nmi(unsigned int irq); extern void enable_nmi(unsigned int irq); From 06b449d7f7c361dc15ea040966a46ed2c6508f3b Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Fri, 7 Jun 2024 19:04:23 +0200 Subject: [PATCH 08/71] Input: serio - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB7237D3D898CCC9C50C18DE078BFB2@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/altera_ps2.c | 2 +- drivers/input/serio/ambakmi.c | 4 ++-- drivers/input/serio/apbps2.c | 2 +- drivers/input/serio/arc_ps2.c | 2 +- drivers/input/serio/ct82c710.c | 2 +- drivers/input/serio/gscps2.c | 4 ++-- drivers/input/serio/hyperv-keyboard.c | 4 ++-- drivers/input/serio/i8042.c | 4 ++-- drivers/input/serio/maceps2.c | 2 +- drivers/input/serio/olpc_apsp.c | 4 ++-- drivers/input/serio/parkbd.c | 2 +- drivers/input/serio/pcips2.c | 4 ++-- drivers/input/serio/ps2-gpio.c | 4 ++-- drivers/input/serio/ps2mult.c | 2 +- drivers/input/serio/q40kbd.c | 4 ++-- drivers/input/serio/rpckbd.c | 2 +- drivers/input/serio/sa1111ps2.c | 4 ++-- drivers/input/serio/serio.c | 2 +- drivers/input/serio/serio_raw.c | 4 ++-- drivers/input/serio/serport.c | 4 ++-- drivers/input/serio/sun4i-ps2.c | 4 ++-- drivers/input/serio/userio.c | 4 ++-- drivers/input/serio/xilinx_ps2.c | 4 ++-- 23 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index c5b634940cfc..611eb9fe2d04 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(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 8fbfa448be4a..29c421a8e627 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(struct amba_kmi_port), GFP_KERNEL); - io = kzalloc(sizeof(struct serio), GFP_KERNEL); + kmi = kzalloc(sizeof(*kmi), GFP_KERNEL); + io = kzalloc(sizeof(*io), GFP_KERNEL); if (!kmi || !io) { ret = -ENOMEM; goto out; diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c index dbbb10251520..4015e75fcb90 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(struct serio), GFP_KERNEL); + priv->io = kzalloc(sizeof(*priv->io), GFP_KERNEL); if (!priv->io) return -ENOMEM; diff --git a/drivers/input/serio/arc_ps2.c b/drivers/input/serio/arc_ps2.c index 9d8726830140..a9180a005872 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(struct serio), GFP_KERNEL); + io = kzalloc(sizeof(*io), GFP_KERNEL); if (!io) return -ENOMEM; diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index d5c9bb3d0103..6834440b37f6 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -158,7 +158,7 @@ static int __init ct82c710_detect(void) static int ct82c710_probe(struct platform_device *dev) { - ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL); + ct82c710_port = kzalloc(sizeof(*ct82c710_port), GFP_KERNEL); if (!ct82c710_port) return -ENOMEM; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 633c7de49d67..d94c01eb3fc9 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -338,8 +338,8 @@ static int __init gscps2_probe(struct parisc_device *dev) if (dev->id.sversion == 0x96) hpa += GSC_DINO_OFFSET; - ps2port = kzalloc(sizeof(struct gscps2port), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + ps2port = kzalloc(sizeof(*ps2port), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!ps2port || !serio) { ret = -ENOMEM; goto fail_nomem; diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index 31def6ce5157..31d9dacd2fd1 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -318,8 +318,8 @@ static int hv_kbd_probe(struct hv_device *hv_dev, struct serio *hv_serio; int error; - kbd_dev = kzalloc(sizeof(struct hv_kbd_dev), GFP_KERNEL); - hv_serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + kbd_dev = kzalloc(sizeof(*kbd_dev), GFP_KERNEL); + hv_serio = kzalloc(sizeof(*hv_serio), GFP_KERNEL); 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 9fbb8d31575a..e0fb1db653b7 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1329,7 +1329,7 @@ static int i8042_create_kbd_port(void) struct serio *serio; struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) return -ENOMEM; @@ -1359,7 +1359,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(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c index 5ccfb82759b3..42ac1eb94866 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(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); 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 240a714f7081..0ad95e880cc2 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(struct serio), GFP_KERNEL); + kb_serio = kzalloc(sizeof(*kb_serio), GFP_KERNEL); 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(struct serio), GFP_KERNEL); + pad_serio = kzalloc(sizeof(*pad_serio), GFP_KERNEL); if (!pad_serio) { error = -ENOMEM; goto err_pad; diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index 0d54895428f5..328932297aad 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(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); 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 05878750f2c2..6b9abb2e18c9 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(struct pcips2_data), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!ps2if || !serio) { ret = -ENOMEM; goto release; diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c index c3ff60859a03..0c8b390b8b4f 100644 --- a/drivers/input/serio/ps2-gpio.c +++ b/drivers/input/serio/ps2-gpio.c @@ -404,8 +404,8 @@ static int ps2_gpio_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int error; - drvdata = devm_kzalloc(dev, sizeof(struct ps2_gpio_data), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!drvdata || !serio) { error = -ENOMEM; goto err_free_serio; diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c index 902e81826fbf..937ecdea491d 100644 --- a/drivers/input/serio/ps2mult.c +++ b/drivers/input/serio/ps2mult.c @@ -127,7 +127,7 @@ static int ps2mult_create_port(struct ps2mult *psm, int i) struct serio *mx_serio = psm->mx_serio; struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 3f81f8749cd5..cd4d5be946a3 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -108,8 +108,8 @@ static int q40kbd_probe(struct platform_device *pdev) struct serio *port; int error; - q40kbd = kzalloc(sizeof(struct q40kbd), GFP_KERNEL); - port = kzalloc(sizeof(struct serio), GFP_KERNEL); + q40kbd = kzalloc(sizeof(*q40kbd), GFP_KERNEL); + port = kzalloc(sizeof(*port), GFP_KERNEL); if (!q40kbd || !port) { error = -ENOMEM; goto err_free_mem; diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 9bbfefd092c0..e236bb7e1014 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -108,7 +108,7 @@ static int rpckbd_probe(struct platform_device *dev) if (tx_irq < 0) return tx_irq; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL); if (!serio || !rpckbd) { kfree(rpckbd); diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 2724c3aa512c..1311caf7dba4 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -256,8 +256,8 @@ static int ps2_probe(struct sa1111_dev *dev) struct serio *serio; int ret; - ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!ps2if || !serio) { ret = -ENOMEM; goto free; diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index a8838b522627..04967494eeb6 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -258,7 +258,7 @@ static int serio_queue_event(void *object, struct module *owner, } } - event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); + event = kmalloc(sizeof(*event), GFP_ATOMIC); if (!event) { pr_err("Not enough memory to queue event %d\n", event_type); retval = -ENOMEM; diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 1e4770094415..0186d1b38f49 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -92,7 +92,7 @@ static int serio_raw_open(struct inode *inode, struct file *file) goto out; } - client = kzalloc(sizeof(struct serio_raw_client), GFP_KERNEL); + client = kzalloc(sizeof(*client), GFP_KERNEL); if (!client) { retval = -ENOMEM; goto out; @@ -293,7 +293,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) struct serio_raw *serio_raw; int err; - serio_raw = kzalloc(sizeof(struct serio_raw), GFP_KERNEL); + serio_raw = kzalloc(sizeof(*serio_raw), GFP_KERNEL); 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 1db3f30011c4..5a2b5404ffc2 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -82,7 +82,7 @@ static int serport_ldisc_open(struct tty_struct *tty) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - serport = kzalloc(sizeof(struct serport), GFP_KERNEL); + serport = kzalloc(sizeof(*serport), GFP_KERNEL); if (!serport) return -ENOMEM; @@ -167,7 +167,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(struct serio), GFP_KERNEL); + serport->serio = serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c index aec66d9f5176..95cd8aaee65d 100644 --- a/drivers/input/serio/sun4i-ps2.c +++ b/drivers/input/serio/sun4i-ps2.c @@ -213,8 +213,8 @@ static int sun4i_ps2_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int error; - drvdata = kzalloc(sizeof(struct sun4i_ps2data), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!drvdata || !serio) { error = -ENOMEM; goto err_free_mem; diff --git a/drivers/input/serio/userio.c b/drivers/input/serio/userio.c index 9ab5c45c3a9f..a88e2eee55c3 100644 --- a/drivers/input/serio/userio.c +++ b/drivers/input/serio/userio.c @@ -77,7 +77,7 @@ static int userio_char_open(struct inode *inode, struct file *file) { struct userio_device *userio; - userio = kzalloc(sizeof(struct userio_device), GFP_KERNEL); + userio = kzalloc(sizeof(*userio), GFP_KERNEL); if (!userio) return -ENOMEM; @@ -85,7 +85,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(struct serio), GFP_KERNEL); + userio->serio = kzalloc(sizeof(*userio->serio), GFP_KERNEL); if (!userio->serio) { kfree(userio); return -ENOMEM; diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index bb758346a33d..1543267d02ac 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -252,8 +252,8 @@ static int xps2_of_probe(struct platform_device *ofdev) return -ENODEV; } - drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL); - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); + serio = kzalloc(sizeof(*serio), GFP_KERNEL); if (!drvdata || !serio) { error = -ENOMEM; goto failed1; From 5bbcece640ef7570ca090a5b35af035fe4ecc7b1 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Fri, 7 Jun 2024 19:17:55 +0200 Subject: [PATCH 09/71] Input: gameport - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/PAXPR02MB72483F512F863C74A4AECA2B8BFB2@PAXPR02MB7248.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/emu10k1-gp.c | 2 +- drivers/input/gameport/fm801-gp.c | 2 +- drivers/input/gameport/gameport.c | 2 +- drivers/input/gameport/ns558.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 76ce41e58df0..4f4583048f24 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(struct emu), GFP_KERNEL); + emu = kzalloc(sizeof(*emu), GFP_KERNEL); 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 e785d36b1926..7ae5009385cc 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(struct fm801_gp), GFP_KERNEL); + gp = kzalloc(sizeof(*gp), GFP_KERNEL); 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 cfcc81c47b50..ad39ac6fa96d 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -372,7 +372,7 @@ static int gameport_queue_event(void *object, struct module *owner, } } - event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); + event = kmalloc(sizeof(*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 91a8cd346e9b..880e714b49bc 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(struct ns558), GFP_KERNEL); + ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL); 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(struct ns558), GFP_KERNEL); + ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL); port = gameport_allocate_port(); if (!ns558 || !port) { printk(KERN_ERR "ns558: Memory allocation failed\n"); From 6560cfcfb46511d47893d6e3994ce1d3c58ddf7f Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 19 Jan 2024 00:19:08 -0800 Subject: [PATCH 10/71] Input: adc-joystick - handle inverted axes When one or more axes are inverted, (where min > max), normalize the data so that min < max and invert the values reported to the input stack. This ensures we can continue defining the device correctly in the device tree while not breaking downstream assumptions that min is always less than max. Signed-off-by: Chris Morgan Acked-by: Artur Rojek Link: https://lore.kernel.org/r/20240115192752.266367-1-macroalpha82@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/adc-joystick.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c index c0deff5d4282..916e78e4dc9f 100644 --- a/drivers/input/joystick/adc-joystick.c +++ b/drivers/input/joystick/adc-joystick.c @@ -18,6 +18,7 @@ struct adc_joystick_axis { s32 range[2]; s32 fuzz; s32 flat; + bool inverted; }; struct adc_joystick { @@ -29,6 +30,15 @@ struct adc_joystick { bool polled; }; +static int adc_joystick_invert(struct input_dev *dev, + unsigned int axis, int val) +{ + int min = input_abs_get_min(dev, axis); + int max = input_abs_get_max(dev, axis); + + return (max + min) - val; +} + static void adc_joystick_poll(struct input_dev *input) { struct adc_joystick *joy = input_get_drvdata(input); @@ -38,6 +48,8 @@ static void adc_joystick_poll(struct input_dev *input) ret = iio_read_channel_raw(&joy->chans[i], &val); if (ret < 0) return; + if (joy->axes[i].inverted) + val = adc_joystick_invert(input, i, val); input_report_abs(input, joy->axes[i].code, val); } input_sync(input); @@ -86,6 +98,8 @@ static int adc_joystick_handle(const void *data, void *private) val = sign_extend32(val, msb); else val &= GENMASK(msb, 0); + if (joy->axes[i].inverted) + val = adc_joystick_invert(joy->input, i, val); input_report_abs(joy->input, joy->axes[i].code, val); } @@ -168,6 +182,12 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) goto err_fwnode_put; } + if (axes[i].range[0] > axes[i].range[1]) { + dev_dbg(dev, "abs-axis %d inverted\n", i); + axes[i].inverted = true; + swap(axes[i].range[0], axes[i].range[1]); + } + fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz); fwnode_property_read_u32(child, "abs-flat", &axes[i].flat); From f4c7fa7c058b9893b7a949cdb2f2aa504903f497 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 12 Dec 2023 21:33:58 -0800 Subject: [PATCH 11/71] Input: cap11xx - stop using chip ID when configuring it struct cap11xx_hw_model is supposed to describe the chip capabilities, however later code changes introduced checks against chip ID. Introduce new capabilities in cap11xx_hw_model and use them when applying chip configuration, and remove the enum for chip ID. While at it, rename no_gain to has_gain to match the rest of the new capabilities. Reviewed-by: Jiri Valek - 2N Link: https://lore.kernel.org/r/ZXlCRsnOu_L8xeTC@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/cap11xx.c | 125 +++++++++++++++++-------------- 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 52fba9ee7c1d..b21ef9d6ff9d 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -86,7 +86,6 @@ struct cap11xx_priv { struct device *dev; struct input_dev *idev; const struct cap11xx_hw_model *model; - u8 id; struct cap11xx_led *leds; int num_leds; @@ -104,27 +103,10 @@ struct cap11xx_hw_model { u8 product_id; unsigned int num_channels; unsigned int num_leds; - bool no_gain; -}; - -enum { - CAP1106, - CAP1126, - CAP1188, - CAP1203, - CAP1206, - CAP1293, - CAP1298 -}; - -static const struct cap11xx_hw_model cap11xx_devices[] = { - [CAP1106] = { .product_id = 0x55, .num_channels = 6, .num_leds = 0, .no_gain = false }, - [CAP1126] = { .product_id = 0x53, .num_channels = 6, .num_leds = 2, .no_gain = false }, - [CAP1188] = { .product_id = 0x50, .num_channels = 8, .num_leds = 8, .no_gain = false }, - [CAP1203] = { .product_id = 0x6d, .num_channels = 3, .num_leds = 0, .no_gain = true }, - [CAP1206] = { .product_id = 0x67, .num_channels = 6, .num_leds = 0, .no_gain = true }, - [CAP1293] = { .product_id = 0x6f, .num_channels = 3, .num_leds = 0, .no_gain = false }, - [CAP1298] = { .product_id = 0x71, .num_channels = 8, .num_leds = 0, .no_gain = false }, + bool has_gain; + bool has_irq_config; + bool has_sensitivity_control; + bool has_signal_guard; }; static const struct reg_default cap11xx_reg_defaults[] = { @@ -224,7 +206,7 @@ static int cap11xx_init_keys(struct cap11xx_priv *priv) } if (!of_property_read_u32(node, "microchip,sensor-gain", &u32_val)) { - if (priv->model->no_gain) { + if (!priv->model->has_gain) { dev_warn(dev, "This model doesn't support 'sensor-gain'\n"); } else if (is_power_of_2(u32_val) && u32_val <= 8) { @@ -243,9 +225,7 @@ static int cap11xx_init_keys(struct cap11xx_priv *priv) } if (of_property_read_bool(node, "microchip,irq-active-high")) { - if (priv->id == CAP1106 || - priv->id == CAP1126 || - priv->id == CAP1188) { + if (priv->model->has_irq_config) { error = regmap_update_bits(priv->regmap, CAP11XX_REG_CONFIG2, CAP11XX_REG_CONFIG2_ALT_POL, @@ -296,7 +276,7 @@ static int cap11xx_init_keys(struct cap11xx_priv *priv) if (!of_property_read_u32_array(node, "microchip,calib-sensitivity", priv->calib_sensitivities, priv->model->num_channels)) { - if (priv->id == CAP1293 || priv->id == CAP1298) { + if (priv->model->has_sensitivity_control) { for (i = 0; i < priv->model->num_channels; i++) { if (!is_power_of_2(priv->calib_sensitivities[i]) || priv->calib_sensitivities[i] > 4) { @@ -311,7 +291,7 @@ static int cap11xx_init_keys(struct cap11xx_priv *priv) if (error) return error; - if (priv->id == CAP1298) { + if (priv->model->num_channels > 4) { error = cap11xx_write_calib_sens_config_2(priv); if (error) return error; @@ -333,7 +313,7 @@ static int cap11xx_init_keys(struct cap11xx_priv *priv) } if (priv->signal_guard_inputs_mask) { - if (priv->id == CAP1293 || priv->id == CAP1298) { + if (priv->model->has_signal_guard) { error = regmap_write(priv->regmap, CAP11XX_REG_SIGNAL_GUARD_ENABLE, priv->signal_guard_inputs_mask); @@ -508,20 +488,16 @@ static int cap11xx_init_leds(struct device *dev, static int cap11xx_i2c_probe(struct i2c_client *i2c_client) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c_client); + const struct i2c_device_id *id; + const struct cap11xx_hw_model *cap; struct device *dev = &i2c_client->dev; struct cap11xx_priv *priv; - const struct cap11xx_hw_model *cap; int i, error; unsigned int val, rev; - if (id->driver_data >= ARRAY_SIZE(cap11xx_devices)) { - dev_err(dev, "Invalid device ID %lu\n", id->driver_data); - return -EINVAL; - } - - cap = &cap11xx_devices[id->driver_data]; - if (!cap || !cap->num_channels) { + id = i2c_client_get_device_id(i2c_client); + cap = i2c_get_match_data(i2c_client); + if (!id || !cap || !cap->num_channels) { dev_err(dev, "Invalid device configuration\n"); return -EINVAL; } @@ -566,7 +542,6 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client) id->name, rev); priv->model = cap; - priv->id = id->driver_data; dev_info(dev, "CAP11XX device detected, model %s, revision 0x%02x\n", id->name, rev); @@ -627,27 +602,67 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client) return 0; } +static const struct cap11xx_hw_model cap1106_model = { + .product_id = 0x55, .num_channels = 6, .num_leds = 0, + .has_gain = true, + .has_irq_config = true, +}; + +static const struct cap11xx_hw_model cap1126_model = { + .product_id = 0x53, .num_channels = 6, .num_leds = 2, + .has_gain = true, + .has_irq_config = true, +}; + +static const struct cap11xx_hw_model cap1188_model = { + .product_id = 0x50, .num_channels = 8, .num_leds = 8, + .has_gain = true, + .has_irq_config = true, +}; + +static const struct cap11xx_hw_model cap1203_model = { + .product_id = 0x6d, .num_channels = 3, .num_leds = 0, +}; + +static const struct cap11xx_hw_model cap1206_model = { + .product_id = 0x67, .num_channels = 6, .num_leds = 0, +}; + +static const struct cap11xx_hw_model cap1293_model = { + .product_id = 0x6f, .num_channels = 3, .num_leds = 0, + .has_gain = true, + .has_sensitivity_control = true, + .has_signal_guard = true, +}; + +static const struct cap11xx_hw_model cap1298_model = { + .product_id = 0x71, .num_channels = 8, .num_leds = 0, + .has_gain = true, + .has_sensitivity_control = true, + .has_signal_guard = true, +}; + static const struct of_device_id cap11xx_dt_ids[] = { - { .compatible = "microchip,cap1106", }, - { .compatible = "microchip,cap1126", }, - { .compatible = "microchip,cap1188", }, - { .compatible = "microchip,cap1203", }, - { .compatible = "microchip,cap1206", }, - { .compatible = "microchip,cap1293", }, - { .compatible = "microchip,cap1298", }, - {} + { .compatible = "microchip,cap1106", .data = &cap1106_model }, + { .compatible = "microchip,cap1126", .data = &cap1126_model }, + { .compatible = "microchip,cap1188", .data = &cap1188_model }, + { .compatible = "microchip,cap1203", .data = &cap1203_model }, + { .compatible = "microchip,cap1206", .data = &cap1206_model }, + { .compatible = "microchip,cap1293", .data = &cap1293_model }, + { .compatible = "microchip,cap1298", .data = &cap1298_model }, + { } }; MODULE_DEVICE_TABLE(of, cap11xx_dt_ids); static const struct i2c_device_id cap11xx_i2c_ids[] = { - { "cap1106", CAP1106 }, - { "cap1126", CAP1126 }, - { "cap1188", CAP1188 }, - { "cap1203", CAP1203 }, - { "cap1206", CAP1206 }, - { "cap1293", CAP1293 }, - { "cap1298", CAP1298 }, - {} + { "cap1106", (kernel_ulong_t)&cap1106_model }, + { "cap1126", (kernel_ulong_t)&cap1126_model }, + { "cap1188", (kernel_ulong_t)&cap1188_model }, + { "cap1203", (kernel_ulong_t)&cap1203_model }, + { "cap1206", (kernel_ulong_t)&cap1206_model }, + { "cap1293", (kernel_ulong_t)&cap1293_model }, + { "cap1298", (kernel_ulong_t)&cap1298_model }, + { } }; MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids); From f81d03d43965261056d963572d0335645008a8e8 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sat, 8 Jun 2024 16:34:49 +0200 Subject: [PATCH 12/71] Input: touchscreen - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). The refactoring is mostly trivial except for "usbtouchscreen.c" file. Here, in the "mtouch_alloc" and "nexio_alloc" functions, it is necessary to use a variable with a predefined type instead of the "usbtouch->priv" variable (void * type). This way, the "sizeof" operator can now know the correct size. Moreover, we need to set the "usbtouch->priv" pointer after the memory allocation since now the "kmalloc" return value is not assigned directly. This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB723708364CC0DF2EAAFEE5968BC42@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/da9052_tsi.c | 2 +- drivers/input/touchscreen/dynapro.c | 2 +- drivers/input/touchscreen/egalax_ts_serial.c | 2 +- drivers/input/touchscreen/elo.c | 2 +- drivers/input/touchscreen/fujitsu_ts.c | 2 +- drivers/input/touchscreen/gunze.c | 2 +- drivers/input/touchscreen/hampshire.c | 2 +- drivers/input/touchscreen/inexio.c | 2 +- drivers/input/touchscreen/mtouch.c | 2 +- drivers/input/touchscreen/penmount.c | 2 +- drivers/input/touchscreen/sur40.c | 2 +- drivers/input/touchscreen/touchit213.c | 2 +- drivers/input/touchscreen/touchright.c | 2 +- drivers/input/touchscreen/touchwin.c | 2 +- drivers/input/touchscreen/tsc40.c | 2 +- drivers/input/touchscreen/usbtouchscreen.c | 15 ++++++++------- drivers/input/touchscreen/wacom_w8001.c | 2 +- 17 files changed, 24 insertions(+), 23 deletions(-) diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c index d71690ce6463..52e0e834e76f 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(struct da9052_tsi), GFP_KERNEL); + tsi = kzalloc(sizeof(*tsi), GFP_KERNEL); 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 dc07fca7c5ed..fe626a226b85 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(struct dynapro), GFP_KERNEL); + pdynapro = kzalloc(sizeof(*pdynapro), GFP_KERNEL); input_dev = input_allocate_device(); if (!pdynapro || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/egalax_ts_serial.c b/drivers/input/touchscreen/egalax_ts_serial.c index 375922d3a6d1..07a4aa1c19bb 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(struct egalax), GFP_KERNEL); + egalax = kzalloc(sizeof(*egalax), GFP_KERNEL); input_dev = input_allocate_device(); if (!egalax || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 96173232e53f..eb883db55420 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -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(struct elo), GFP_KERNEL); + elo = kzalloc(sizeof(*elo), GFP_KERNEL); input_dev = input_allocate_device(); if (!elo || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c index 3b0b8fccc3f0..1a3e14ea2e08 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(struct fujitsu), GFP_KERNEL); + fujitsu = kzalloc(sizeof(*fujitsu), GFP_KERNEL); input_dev = input_allocate_device(); if (!fujitsu || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 5a5f9da73fa1..dbf92fb02f80 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(struct gunze), GFP_KERNEL); + gunze = kzalloc(sizeof(*gunze), GFP_KERNEL); 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 5c4d877564ee..dc0a2482ddd6 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(struct hampshire), GFP_KERNEL); + phampshire = kzalloc(sizeof(*phampshire), GFP_KERNEL); input_dev = input_allocate_device(); if (!phampshire || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c index 1d7e4c3966ce..82f7ac62a4f2 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(struct inexio), GFP_KERNEL); + pinexio = kzalloc(sizeof(*pinexio), GFP_KERNEL); input_dev = input_allocate_device(); if (!pinexio || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 28e449eea318..eefae96a2d40 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(struct mtouch), GFP_KERNEL); + mtouch = kzalloc(sizeof(*mtouch), GFP_KERNEL); input_dev = input_allocate_device(); if (!mtouch || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 12abb3b36128..95adede26703 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(struct pm), GFP_KERNEL); + pm = kzalloc(sizeof(*pm), GFP_KERNEL); input_dev = input_allocate_device(); if (!pm || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index 5f2cf8881e72..8365a2ac6fce 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c @@ -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(struct sur40_state), GFP_KERNEL); + sur40 = kzalloc(sizeof(*sur40), GFP_KERNEL); if (!sur40) return -ENOMEM; diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c index fb49687da405..c2718350815c 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(struct touchit213), GFP_KERNEL); + touchit213 = kzalloc(sizeof(*touchit213), GFP_KERNEL); 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 3cd58a13e44f..30ba97bd00a1 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(struct tr), GFP_KERNEL); + tr = kzalloc(sizeof(*tr), GFP_KERNEL); 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 bde3c6ee3c60..fbd72789ea80 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(struct tw), GFP_KERNEL); + tw = kzalloc(sizeof(*tw), GFP_KERNEL); input_dev = input_allocate_device(); if (!tw || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c index 139577021413..9f485cf57a72 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(struct tsc_ser), GFP_KERNEL); + ptsc = kzalloc(sizeof(*ptsc), GFP_KERNEL); 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 60354ebc7242..dd6b12c6dc58 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -505,12 +505,14 @@ static int mtouch_get_fw_revision(struct usbtouch_usb *usbtouch) static int mtouch_alloc(struct usbtouch_usb *usbtouch) { + struct mtouch_priv *priv; int ret; - usbtouch->priv = kmalloc(sizeof(struct mtouch_priv), GFP_KERNEL); - if (!usbtouch->priv) + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; + usbtouch->priv = priv; ret = sysfs_create_group(&usbtouch->interface->dev.kobj, &mtouch_attr_group); if (ret) { @@ -924,12 +926,11 @@ static int nexio_alloc(struct usbtouch_usb *usbtouch) struct nexio_priv *priv; int ret = -ENOMEM; - usbtouch->priv = kmalloc(sizeof(struct nexio_priv), GFP_KERNEL); - if (!usbtouch->priv) + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) goto out_buf; - priv = usbtouch->priv; - + usbtouch->priv = priv; priv->ack_buf = kmemdup(nexio_ack_pkt, sizeof(nexio_ack_pkt), GFP_KERNEL); if (!priv->ack_buf) @@ -1661,7 +1662,7 @@ static int usbtouch_probe(struct usb_interface *intf, if (!endpoint) return -ENXIO; - usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); + usbtouch = kzalloc(sizeof(*usbtouch), GFP_KERNEL); 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 4ddb6b3baba5..c8abb9557ee8 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -598,7 +598,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(struct w8001), GFP_KERNEL); + w8001 = kzalloc(sizeof(*w8001), GFP_KERNEL); input_dev_pen = input_allocate_device(); input_dev_touch = input_allocate_device(); if (!w8001 || !input_dev_pen || !input_dev_touch) { From 4654c4cc7950440571d142e56db60106d84429d8 Mon Sep 17 00:00:00 2001 From: Erick Archer Date: Sat, 8 Jun 2024 17:13:57 +0200 Subject: [PATCH 13/71] Input: joystick - use sizeof(*pointer) instead of sizeof(type) It is preferred to use sizeof(*pointer) instead of sizeof(type) due to the type of the variable can change and one needs not change the former (unlike the latter). At the same time refactor the code to not use assignment in "if" conditions. This patch has no effect on runtime behavior. Signed-off-by: Erick Archer Link: https://lore.kernel.org/r/AS8PR02MB7237FEA55FAC8A9453F2DA6F8BC42@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/a3d.c | 2 +- drivers/input/joystick/adi.c | 2 +- drivers/input/joystick/analog.c | 3 ++- drivers/input/joystick/as5011.c | 2 +- drivers/input/joystick/cobra.c | 2 +- drivers/input/joystick/db9.c | 2 +- drivers/input/joystick/gamecon.c | 2 +- drivers/input/joystick/gf2k.c | 2 +- drivers/input/joystick/grip.c | 3 ++- drivers/input/joystick/grip_mp.c | 3 ++- drivers/input/joystick/guillemot.c | 2 +- drivers/input/joystick/interact.c | 2 +- drivers/input/joystick/magellan.c | 2 +- drivers/input/joystick/maplecontrol.c | 2 +- drivers/input/joystick/n64joy.c | 2 +- drivers/input/joystick/sidewinder.c | 2 +- drivers/input/joystick/spaceball.c | 2 +- drivers/input/joystick/spaceorb.c | 2 +- drivers/input/joystick/stinger.c | 2 +- drivers/input/joystick/tmdc.c | 3 ++- drivers/input/joystick/turbografx.c | 2 +- drivers/input/joystick/twidjoy.c | 2 +- drivers/input/joystick/warrior.c | 2 +- drivers/input/joystick/xpad.c | 4 ++-- drivers/input/joystick/zhenhua.c | 2 +- 25 files changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index fd1827baf27c..15182f16ed19 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(struct a3d), GFP_KERNEL); + a3d = kzalloc(sizeof(*a3d), GFP_KERNEL); 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 f1a720be458b..963250de24b7 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(struct adi_port), GFP_KERNEL); + port = kzalloc(sizeof(*port), GFP_KERNEL); if (!port) return -ENOMEM; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 0c9e172a9818..c709b58d770a 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -582,7 +582,8 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv int i; int err; - if (!(port = kzalloc(sizeof(struct analog_port), GFP_KERNEL))) + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) return -ENOMEM; err = analog_init_port(gameport, drv, port); diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c index 407062bcc84b..49a0dfbbeb49 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(struct as5011_device), GFP_KERNEL); + as5011 = kmalloc(sizeof(*as5011), GFP_KERNEL); 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 7ff78c9388bd..5a0ea3ad5efa 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(struct cobra), GFP_KERNEL); + cobra = kzalloc(sizeof(*cobra), GFP_KERNEL); if (!cobra) return -ENOMEM; diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index 4fba28b1a1e7..682a29c27832 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -587,7 +587,7 @@ static void db9_attach(struct parport *pp) return; } - db9 = kzalloc(sizeof(struct db9), GFP_KERNEL); + db9 = kzalloc(sizeof(*db9), GFP_KERNEL); if (!db9) goto err_unreg_pardev; diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 41d5dac05448..c38de3094553 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -950,7 +950,7 @@ static void gc_attach(struct parport *pp) return; } - gc = kzalloc(sizeof(struct gc), GFP_KERNEL); + gc = kzalloc(sizeof(*gc), GFP_KERNEL); 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 abefbd1484df..e7ff7bdb1a3a 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -222,7 +222,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) unsigned char data[GF2K_LENGTH]; int i, err; - gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL); + gf2k = kzalloc(sizeof(*gf2k), GFP_KERNEL); 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 0e86b269a90e..f339ce2b7a33 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -284,7 +284,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) int i, j, t; int err; - if (!(grip = kzalloc(sizeof(struct grip), GFP_KERNEL))) + grip = kzalloc(sizeof(*grip), GFP_KERNEL); + if (!grip) return -ENOMEM; grip->gameport = gameport; diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 056a89ac2bdf..5eadb5a3ca37 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -632,7 +632,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) struct grip_mp *grip; int err; - if (!(grip = kzalloc(sizeof(struct grip_mp), GFP_KERNEL))) + grip = kzalloc(sizeof(*grip), GFP_KERNEL); + if (!grip) return -ENOMEM; grip->gameport = gameport; diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 205eb6f8b84d..1c5a76f72239 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(struct guillemot), GFP_KERNEL); + guillemot = kzalloc(sizeof(*guillemot), GFP_KERNEL); input_dev = input_allocate_device(); if (!guillemot || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index 03a9f0829f7e..262f022e5695 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(struct interact), GFP_KERNEL); + interact = kzalloc(sizeof(*interact), GFP_KERNEL); input_dev = input_allocate_device(); if (!interact || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 017ef8c6170b..2eaa25c9c68c 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(struct magellan), GFP_KERNEL); + magellan = kzalloc(sizeof(*magellan), GFP_KERNEL); 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 3833ac47b2b8..8b54f9b18e7c 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(struct dc_pad), GFP_KERNEL); + pad = kzalloc(sizeof(*pad), GFP_KERNEL); idev = input_allocate_device(); if (!pad || !idev) { error = -ENOMEM; diff --git a/drivers/input/joystick/n64joy.c b/drivers/input/joystick/n64joy.c index 9dbca366613e..b0986d2195d6 100644 --- a/drivers/input/joystick/n64joy.c +++ b/drivers/input/joystick/n64joy.c @@ -246,7 +246,7 @@ static int __init n64joy_probe(struct platform_device *pdev) int err = 0; u32 i, j, found = 0; - priv = kzalloc(sizeof(struct n64joy_priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; mutex_init(&priv->n64joy_mutex); diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 7282301c3ae7..f6e92db4d789 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -577,7 +577,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) comment[0] = 0; - sw = kzalloc(sizeof(struct sw), GFP_KERNEL); + sw = kzalloc(sizeof(*sw), GFP_KERNEL); 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 fa8ec533cd69..49101f1c858b 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(struct spaceball), GFP_KERNEL); + spaceball = kmalloc(sizeof(*spaceball), GFP_KERNEL); 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 dbbc69f17c89..7250d74d62a1 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(struct spaceorb), GFP_KERNEL); + spaceorb = kzalloc(sizeof(*spaceorb), GFP_KERNEL); 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 530de468cb61..1b24ea21aa30 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(struct stinger), GFP_KERNEL); + stinger = kmalloc(sizeof(*stinger), GFP_KERNEL); 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 93562ecc0ca1..514b1026e379 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -348,7 +348,8 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) int i; int err; - if (!(tmdc = kzalloc(sizeof(struct tmdc), GFP_KERNEL))) + tmdc = kzalloc(sizeof(*tmdc), GFP_KERNEL); + if (!tmdc) return -ENOMEM; tmdc->gameport = gameport; diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index dfb9c684651f..eb8455c34e67 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -172,7 +172,7 @@ static void tgfx_attach(struct parport *pp) return; } - tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL); + tgfx = kzalloc(sizeof(*tgfx), GFP_KERNEL); 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 9b6792ac27f1..ab99d76e5d8d 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(struct twidjoy), GFP_KERNEL); + twidjoy = kzalloc(sizeof(*twidjoy), GFP_KERNEL); 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 f66bddf145c2..ebeab441e9ec 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(struct warrior), GFP_KERNEL); + warrior = kzalloc(sizeof(*warrior), GFP_KERNEL); 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 70f0654c58b6..40a4ddee0b14 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -1686,7 +1686,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(struct xpad_led), GFP_KERNEL); + xpad->led = led = kzalloc(sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; @@ -2022,7 +2022,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id break; } - xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); + xpad = kzalloc(sizeof(*xpad), GFP_KERNEL); if (!xpad) return -ENOMEM; diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c index 3f2460e2b095..cc0e2a77ac5e 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(struct zhenhua), GFP_KERNEL); + zhenhua = kzalloc(sizeof(*zhenhua), GFP_KERNEL); input_dev = input_allocate_device(); if (!zhenhua || !input_dev) goto fail1; From e17fb91cd4cde13001dc75ad99a378ab28dd44df Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 9 Jun 2024 13:03:30 -0700 Subject: [PATCH 14/71] Input: add missing MODULE_DESCRIPTION() macros On x86, make allmodconfig && make W=1 C=1 reports: WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/touchscreen/cyttsp_i2c_common.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/misc/soc_button_array.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/matrix-keymap.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/vivaldi-fmap.o WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/tests/input_test.o Add the missing invocation of the MODULE_DESCRIPTION() macro to all files which have a MODULE_LICENSE(). This includes drivers/input/misc/sgi_btns.c which, although it did not produce a warning with the x86 allmodconfig configuration, may cause this warning with other configurations when either CONFIG_SGI_IP22 or CONFIG_SGI_IP32 is enabled. Signed-off-by: Jeff Johnson Link: https://lore.kernel.org/r/20240609-md-drivers-input-v1-1-a2f394e0f9d8@quicinc.com Signed-off-by: Dmitry Torokhov --- drivers/input/matrix-keymap.c | 1 + drivers/input/misc/sgi_btns.c | 1 + drivers/input/misc/soc_button_array.c | 1 + drivers/input/tests/input_test.c | 1 + drivers/input/touchscreen/cyttsp_i2c_common.c | 1 + drivers/input/vivaldi-fmap.c | 1 + 6 files changed, 6 insertions(+) diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 4fa53423f56c..5d93043bad8e 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c @@ -199,4 +199,5 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, } EXPORT_SYMBOL(matrix_keypad_build_keymap); +MODULE_DESCRIPTION("Helpers for matrix keyboard bindings"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index 0657d785b3cc..39c2882b8e1a 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c @@ -128,4 +128,5 @@ static struct platform_driver sgi_buttons_driver = { }; module_platform_driver(sgi_buttons_driver); +MODULE_DESCRIPTION("SGI Indy/O2 volume button interface driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index f6d060377d18..5c5d407fe965 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -620,4 +620,5 @@ static struct platform_driver soc_button_driver = { }; module_platform_driver(soc_button_driver); +MODULE_DESCRIPTION("Windows-compatible SoC Button Array driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c index 2fa5b725ae0a..e11cf4bbead9 100644 --- a/drivers/input/tests/input_test.c +++ b/drivers/input/tests/input_test.c @@ -179,4 +179,5 @@ static struct kunit_suite input_test_suite = { kunit_test_suite(input_test_suite); MODULE_AUTHOR("Javier Martinez Canillas "); +MODULE_DESCRIPTION("KUnit test for the input core"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c index 1f0b6d6f48e2..7e752fb9fad7 100644 --- a/drivers/input/touchscreen/cyttsp_i2c_common.c +++ b/drivers/input/touchscreen/cyttsp_i2c_common.c @@ -81,5 +81,6 @@ int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data); +MODULE_DESCRIPTION("Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Cypress"); diff --git a/drivers/input/vivaldi-fmap.c b/drivers/input/vivaldi-fmap.c index 0d29ec014e2f..978949eba9eb 100644 --- a/drivers/input/vivaldi-fmap.c +++ b/drivers/input/vivaldi-fmap.c @@ -36,4 +36,5 @@ ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data, } EXPORT_SYMBOL_GPL(vivaldi_function_row_physmap_show); +MODULE_DESCRIPTION("Helpers for ChromeOS Vivaldi keyboard function row mapping"); MODULE_LICENSE("GPL"); From 6f7e4f81f738ac765318c54097a6235203073049 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 10 Jun 2024 09:42:57 -0700 Subject: [PATCH 15/71] Input: adxl34x - use device core to create driver-specific device attributes Instead of creating driver-specific device attributes with sysfs_create_group() have device core do this by setting up dev_groups pointer in the driver structure. Reviewed-by: Nuno Sa Acked-by: Michael Hennerich Link: https://lore.kernel.org/r/20240610164301.1048482-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/adxl34x-i2c.c | 1 + drivers/input/misc/adxl34x-spi.c | 1 + drivers/input/misc/adxl34x.c | 15 +++++++-------- drivers/input/misc/adxl34x.h | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index d4014e367c77..7531c7b2d657 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c @@ -132,6 +132,7 @@ MODULE_DEVICE_TABLE(of, adxl34x_of_id); static struct i2c_driver adxl34x_driver = { .driver = { .name = "adxl34x", + .dev_groups = adxl34x_groups, .pm = pm_sleep_ptr(&adxl34x_pm), .of_match_table = adxl34x_of_id, }, diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index f1094a8ccdd5..2befcc4df0be 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c @@ -97,6 +97,7 @@ static void adxl34x_spi_remove(struct spi_device *spi) static struct spi_driver adxl34x_driver = { .driver = { .name = "adxl34x", + .dev_groups = adxl34x_groups, .pm = pm_sleep_ptr(&adxl34x_pm), }, .probe = adxl34x_spi_probe, diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index a3f45e0ee0c7..fbe5a56c19d1 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -664,6 +664,12 @@ static const struct attribute_group adxl34x_attr_group = { .attrs = adxl34x_attributes, }; +const struct attribute_group *adxl34x_groups[] = { + &adxl34x_attr_group, + NULL +}; +EXPORT_SYMBOL_GPL(adxl34x_groups); + static int adxl34x_input_open(struct input_dev *input) { struct adxl34x *ac = input_get_drvdata(input); @@ -823,13 +829,9 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, goto err_free_mem; } - err = sysfs_create_group(&dev->kobj, &adxl34x_attr_group); - if (err) - goto err_free_irq; - err = input_register_device(input_dev); if (err) - goto err_remove_attr; + goto err_free_irq; AC_WRITE(ac, OFSX, pdata->x_axis_offset); ac->hwcal.x = pdata->x_axis_offset; @@ -889,8 +891,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, return ac; - err_remove_attr: - sysfs_remove_group(&dev->kobj, &adxl34x_attr_group); err_free_irq: free_irq(ac->irq, ac); err_free_mem: @@ -903,7 +903,6 @@ EXPORT_SYMBOL_GPL(adxl34x_probe); void adxl34x_remove(struct adxl34x *ac) { - sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group); free_irq(ac->irq, ac); input_unregister_device(ac->input); dev_dbg(ac->dev, "unregistered accelerometer\n"); diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h index f9272a2e7a96..67e0ddc5c3eb 100644 --- a/drivers/input/misc/adxl34x.h +++ b/drivers/input/misc/adxl34x.h @@ -26,5 +26,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, void adxl34x_remove(struct adxl34x *ac); extern const struct dev_pm_ops adxl34x_pm; +extern const struct attribute_group *adxl34x_groups[]; #endif From 8f275fc73dd6ff78c6041aa4c138410bf2c95ce6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 10 Jun 2024 09:42:58 -0700 Subject: [PATCH 16/71] Input: adxl34x - use input_set_capability() Switch to using input_set_capability() instead of using __set_bit() to make clear what exactly kinds of events (EV_KEY, EV_REL) are being declared. Also drop redundant calls setting EV_ABS and ABS_X|Y|Z bits as that is taken care by input_set_abs_params(). Link: https://lore.kernel.org/r/20240610164301.1048482-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/adxl34x.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index fbe5a56c19d1..830acf29c32b 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -769,18 +769,12 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, input_set_drvdata(input_dev, ac); - __set_bit(ac->pdata.ev_type, input_dev->evbit); - if (ac->pdata.ev_type == EV_REL) { - __set_bit(REL_X, input_dev->relbit); - __set_bit(REL_Y, input_dev->relbit); - __set_bit(REL_Z, input_dev->relbit); + input_set_capability(input_dev, EV_REL, REL_X); + input_set_capability(input_dev, EV_REL, REL_Y); + input_set_capability(input_dev, EV_REL, REL_Z); } else { /* EV_ABS */ - __set_bit(ABS_X, input_dev->absbit); - __set_bit(ABS_Y, input_dev->absbit); - __set_bit(ABS_Z, input_dev->absbit); - if (pdata->data_range & FULL_RES) range = ADXL_FULLRES_MAX_VAL; /* Signed 13-bit */ else @@ -791,18 +785,18 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, input_set_abs_params(input_dev, ABS_Z, -range, range, 3, 3); } - __set_bit(EV_KEY, input_dev->evbit); - __set_bit(pdata->ev_code_tap[ADXL_X_AXIS], input_dev->keybit); - __set_bit(pdata->ev_code_tap[ADXL_Y_AXIS], input_dev->keybit); - __set_bit(pdata->ev_code_tap[ADXL_Z_AXIS], input_dev->keybit); + input_set_capability(input_dev, EV_KEY, pdata->ev_code_tap[ADXL_X_AXIS]); + input_set_capability(input_dev, EV_KEY, pdata->ev_code_tap[ADXL_Y_AXIS]); + input_set_capability(input_dev, EV_KEY, pdata->ev_code_tap[ADXL_Z_AXIS]); if (pdata->ev_code_ff) { ac->int_mask = FREE_FALL; - __set_bit(pdata->ev_code_ff, input_dev->keybit); + input_set_capability(input_dev, EV_KEY, pdata->ev_code_ff); } if (pdata->ev_code_act_inactivity) - __set_bit(pdata->ev_code_act_inactivity, input_dev->keybit); + input_set_capability(input_dev, EV_KEY, + pdata->ev_code_act_inactivity); ac->int_mask |= ACTIVITY | INACTIVITY; @@ -874,13 +868,13 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D) for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++) - __set_bit(pdata->ev_codes_orient_3d[i], - input_dev->keybit); + input_set_capability(input_dev, EV_KEY, + pdata->ev_codes_orient_3d[i]); if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D) for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++) - __set_bit(pdata->ev_codes_orient_2d[i], - input_dev->keybit); + input_set_capability(input_dev, EV_KEY, + pdata->ev_codes_orient_2d[i]); } else { ac->pdata.orientation_enable = 0; } From 985addc13304639876c2ddbcc1c149007c5d67ff Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 10 Jun 2024 09:42:59 -0700 Subject: [PATCH 17/71] Input: adxl34x - switch to using managed resources Switch the driver to use managed resources to simplify error handling. Link: https://lore.kernel.org/r/20240610164301.1048482-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/adxl34x-i2c.c | 8 ----- drivers/input/misc/adxl34x-spi.c | 8 ----- drivers/input/misc/adxl34x.c | 53 ++++++++++---------------------- drivers/input/misc/adxl34x.h | 1 - 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c index 7531c7b2d657..c05d898898e8 100644 --- a/drivers/input/misc/adxl34x-i2c.c +++ b/drivers/input/misc/adxl34x-i2c.c @@ -98,13 +98,6 @@ static int adxl34x_i2c_probe(struct i2c_client *client) return 0; } -static void adxl34x_i2c_remove(struct i2c_client *client) -{ - struct adxl34x *ac = i2c_get_clientdata(client); - - adxl34x_remove(ac); -} - static const struct i2c_device_id adxl34x_id[] = { { "adxl34x" }, { } @@ -137,7 +130,6 @@ static struct i2c_driver adxl34x_driver = { .of_match_table = adxl34x_of_id, }, .probe = adxl34x_i2c_probe, - .remove = adxl34x_i2c_remove, .id_table = adxl34x_id, }; diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c index 2befcc4df0be..fd716d861832 100644 --- a/drivers/input/misc/adxl34x-spi.c +++ b/drivers/input/misc/adxl34x-spi.c @@ -87,13 +87,6 @@ static int adxl34x_spi_probe(struct spi_device *spi) return 0; } -static void adxl34x_spi_remove(struct spi_device *spi) -{ - struct adxl34x *ac = spi_get_drvdata(spi); - - adxl34x_remove(ac); -} - static struct spi_driver adxl34x_driver = { .driver = { .name = "adxl34x", @@ -101,7 +94,6 @@ static struct spi_driver adxl34x_driver = { .pm = pm_sleep_ptr(&adxl34x_pm), }, .probe = adxl34x_spi_probe, - .remove = adxl34x_spi_remove, }; module_spi_driver(adxl34x_driver); diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index 830acf29c32b..c6c34005f5d2 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -707,21 +707,21 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, struct adxl34x *ac; struct input_dev *input_dev; const struct adxl34x_platform_data *pdata; - int err, range, i; + int error, range, i; int revid; if (!irq) { dev_err(dev, "no IRQ?\n"); - err = -ENODEV; - goto err_out; + return ERR_PTR(-ENODEV); } - ac = kzalloc(sizeof(*ac), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!ac || !input_dev) { - err = -ENOMEM; - goto err_free_mem; - } + ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL); + if (!ac) + return ERR_PTR(-ENOMEM); + + input_dev = devm_input_allocate_device(dev); + if (!input_dev) + return ERR_PTR(-ENOMEM); ac->fifo_delay = fifo_delay_default; @@ -754,14 +754,12 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, break; default: dev_err(dev, "Failed to probe %s\n", input_dev->name); - err = -ENODEV; - goto err_free_mem; + return ERR_PTR(-ENODEV); } snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(dev)); input_dev->phys = ac->phys; - input_dev->dev.parent = dev; input_dev->id.product = ac->model; input_dev->id.bustype = bops->bustype; input_dev->open = adxl34x_input_open; @@ -816,16 +814,16 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, AC_WRITE(ac, POWER_CTL, 0); - err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, - IRQF_ONESHOT, dev_name(dev), ac); - if (err) { + error = devm_request_threaded_irq(dev, ac->irq, NULL, adxl34x_irq, + IRQF_ONESHOT, dev_name(dev), ac); + if (error) { dev_err(dev, "irq %d busy?\n", ac->irq); - goto err_free_mem; + return ERR_PTR(error); } - err = input_register_device(input_dev); - if (err) - goto err_free_irq; + error = input_register_device(input_dev); + if (error) + return ERR_PTR(error); AC_WRITE(ac, OFSX, pdata->x_axis_offset); ac->hwcal.x = pdata->x_axis_offset; @@ -884,26 +882,9 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq, ac->pdata.power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK); return ac; - - err_free_irq: - free_irq(ac->irq, ac); - err_free_mem: - input_free_device(input_dev); - kfree(ac); - err_out: - return ERR_PTR(err); } EXPORT_SYMBOL_GPL(adxl34x_probe); -void adxl34x_remove(struct adxl34x *ac) -{ - free_irq(ac->irq, ac); - input_unregister_device(ac->input); - dev_dbg(ac->dev, "unregistered accelerometer\n"); - kfree(ac); -} -EXPORT_SYMBOL_GPL(adxl34x_remove); - EXPORT_GPL_SIMPLE_DEV_PM_OPS(adxl34x_pm, adxl34x_suspend, adxl34x_resume); MODULE_AUTHOR("Michael Hennerich "); diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h index 67e0ddc5c3eb..718e90c2046d 100644 --- a/drivers/input/misc/adxl34x.h +++ b/drivers/input/misc/adxl34x.h @@ -23,7 +23,6 @@ struct adxl34x_bus_ops { struct adxl34x *adxl34x_probe(struct device *dev, int irq, bool fifo_delay_default, const struct adxl34x_bus_ops *bops); -void adxl34x_remove(struct adxl34x *ac); extern const struct dev_pm_ops adxl34x_pm; extern const struct attribute_group *adxl34x_groups[]; From 9b9247397e2e20016031e59f76dae563b79b6ee2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 10 Jun 2024 09:43:00 -0700 Subject: [PATCH 18/71] Input: adxl34x - switch to using "guard" notation Switch to using guard(mutex)() notation to acquire and automatically release mutexes. Reviewed-by: Nuno Sa Link: https://lore.kernel.org/r/20240610164301.1048482-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/adxl34x.c | 61 ++++++++++++------------------------ 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c index c6c34005f5d2..7cafbf8d5f1a 100644 --- a/drivers/input/misc/adxl34x.c +++ b/drivers/input/misc/adxl34x.c @@ -241,7 +241,8 @@ static void adxl34x_get_triple(struct adxl34x *ac, struct axis_triple *axis) ac->bops->read_block(ac->dev, DATAX0, DATAZ1 - DATAX0 + 1, buf); - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); + ac->saved.x = (s16) le16_to_cpu(buf[0]); axis->x = ac->saved.x; @@ -250,7 +251,6 @@ static void adxl34x_get_triple(struct adxl34x *ac, struct axis_triple *axis) ac->saved.z = (s16) le16_to_cpu(buf[2]); axis->z = ac->saved.z; - mutex_unlock(&ac->mutex); } static void adxl34x_service_ev_fifo(struct adxl34x *ac) @@ -416,15 +416,13 @@ static int adxl34x_suspend(struct device *dev) { struct adxl34x *ac = dev_get_drvdata(dev); - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); if (!ac->suspended && !ac->disabled && ac->opened) __adxl34x_disable(ac); ac->suspended = true; - mutex_unlock(&ac->mutex); - return 0; } @@ -432,15 +430,13 @@ static int adxl34x_resume(struct device *dev) { struct adxl34x *ac = dev_get_drvdata(dev); - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); if (ac->suspended && !ac->disabled && ac->opened) __adxl34x_enable(ac); ac->suspended = false; - mutex_unlock(&ac->mutex); - return 0; } @@ -464,7 +460,7 @@ static ssize_t adxl34x_disable_store(struct device *dev, if (error) return error; - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); if (!ac->suspended && ac->opened) { if (val) { @@ -478,8 +474,6 @@ static ssize_t adxl34x_disable_store(struct device *dev, ac->disabled = !!val; - mutex_unlock(&ac->mutex); - return count; } @@ -489,16 +483,13 @@ static ssize_t adxl34x_calibrate_show(struct device *dev, struct device_attribute *attr, char *buf) { struct adxl34x *ac = dev_get_drvdata(dev); - ssize_t count; - mutex_lock(&ac->mutex); - count = sprintf(buf, "%d,%d,%d\n", - ac->hwcal.x * 4 + ac->swcal.x, - ac->hwcal.y * 4 + ac->swcal.y, - ac->hwcal.z * 4 + ac->swcal.z); - mutex_unlock(&ac->mutex); + guard(mutex)(&ac->mutex); - return count; + return sprintf(buf, "%d,%d,%d\n", + ac->hwcal.x * 4 + ac->swcal.x, + ac->hwcal.y * 4 + ac->swcal.y, + ac->hwcal.z * 4 + ac->swcal.z); } static ssize_t adxl34x_calibrate_store(struct device *dev, @@ -512,7 +503,8 @@ static ssize_t adxl34x_calibrate_store(struct device *dev, * We use HW calibration and handle the remaining bits in SW. (4mg/LSB) */ - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); + ac->hwcal.x -= (ac->saved.x / 4); ac->swcal.x = ac->saved.x % 4; @@ -525,7 +517,6 @@ static ssize_t adxl34x_calibrate_store(struct device *dev, AC_WRITE(ac, OFSX, (s8) ac->hwcal.x); AC_WRITE(ac, OFSY, (s8) ac->hwcal.y); AC_WRITE(ac, OFSZ, (s8) ac->hwcal.z); - mutex_unlock(&ac->mutex); return count; } @@ -553,15 +544,13 @@ static ssize_t adxl34x_rate_store(struct device *dev, if (error) return error; - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); ac->pdata.data_rate = RATE(val); AC_WRITE(ac, BW_RATE, ac->pdata.data_rate | (ac->pdata.low_power_mode ? LOW_POWER : 0)); - mutex_unlock(&ac->mutex); - return count; } @@ -588,7 +577,7 @@ static ssize_t adxl34x_autosleep_store(struct device *dev, if (error) return error; - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); if (val) ac->pdata.power_mode |= (PCTL_AUTO_SLEEP | PCTL_LINK); @@ -598,8 +587,6 @@ static ssize_t adxl34x_autosleep_store(struct device *dev, if (!ac->disabled && !ac->suspended && ac->opened) AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); - mutex_unlock(&ac->mutex); - return count; } @@ -610,14 +597,11 @@ static ssize_t adxl34x_position_show(struct device *dev, struct device_attribute *attr, char *buf) { struct adxl34x *ac = dev_get_drvdata(dev); - ssize_t count; - mutex_lock(&ac->mutex); - count = sprintf(buf, "(%d, %d, %d)\n", - ac->saved.x, ac->saved.y, ac->saved.z); - mutex_unlock(&ac->mutex); + guard(mutex)(&ac->mutex); - return count; + return sprintf(buf, "(%d, %d, %d)\n", + ac->saved.x, ac->saved.y, ac->saved.z); } static DEVICE_ATTR(position, S_IRUGO, adxl34x_position_show, NULL); @@ -638,9 +622,8 @@ static ssize_t adxl34x_write_store(struct device *dev, if (error) return error; - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); AC_WRITE(ac, val >> 8, val & 0xFF); - mutex_unlock(&ac->mutex); return count; } @@ -674,15 +657,13 @@ static int adxl34x_input_open(struct input_dev *input) { struct adxl34x *ac = input_get_drvdata(input); - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); if (!ac->suspended && !ac->disabled) __adxl34x_enable(ac); ac->opened = true; - mutex_unlock(&ac->mutex); - return 0; } @@ -690,14 +671,12 @@ static void adxl34x_input_close(struct input_dev *input) { struct adxl34x *ac = input_get_drvdata(input); - mutex_lock(&ac->mutex); + guard(mutex)(&ac->mutex); if (!ac->suspended && !ac->disabled) __adxl34x_disable(ac); ac->opened = false; - - mutex_unlock(&ac->mutex); } struct adxl34x *adxl34x_probe(struct device *dev, int irq, From e8135f9dc774f956bca44a13cf056403140e2337 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Wed, 19 Jun 2024 23:13:21 +0200 Subject: [PATCH 19/71] Input: ims-pcu - annotate struct ims_pcu_flash_fmt with __counted_by Use the __counted_by compiler attribute for the data[] flexible array member to improve the results of array bound sanitizers. Signed-off-by: Javier Carrasco Reviewed-by: Kees Cook Reviewed-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20240619-ims-pcu-counted_by-v1-1-3ee0ead2e57d@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ims-pcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 408a586f8c36..91f8ad826238 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -761,7 +761,7 @@ static int ims_pcu_switch_to_bootloader(struct ims_pcu *pcu) struct ims_pcu_flash_fmt { __le32 addr; u8 len; - u8 data[]; + u8 data[] __counted_by(len); }; static unsigned int ims_pcu_count_fw_records(const struct firmware *fw) From daa268ae2866ae5c80a0650c04a4989fb069b5d9 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Wed, 19 Jun 2024 23:13:22 +0200 Subject: [PATCH 20/71] Input: ims-pcu - drop repeated "input" in error message This case of the common error message upon failure of input_allocate_device() repeats the word "input". Drop one "input" from the error message. Signed-off-by: Javier Carrasco Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/20240619-ims-pcu-counted_by-v1-2-3ee0ead2e57d@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ims-pcu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 91f8ad826238..a8c474de01ad 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -207,8 +207,7 @@ static int ims_pcu_setup_buttons(struct ims_pcu *pcu, input = input_allocate_device(); if (!input) { - dev_err(pcu->dev, - "Not enough memory for input input device\n"); + dev_err(pcu->dev, "Not enough memory for input device\n"); return -ENOMEM; } From 204d18a7a0c67352857dee1bbac517ed63f01d8e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 21:18:10 -0700 Subject: [PATCH 21/71] Input: ims-pcu - use driver core to instantiate device attributes Instead of manually creating driver-specific device attributes set struct usb_driver->dev_groups pointer to have the driver core do it. Link: https://lore.kernel.org/r/20240610041813.722445-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ims-pcu.c | 53 +++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index a8c474de01ad..6f0e4f6567b0 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -1465,9 +1465,27 @@ static struct attribute *ims_pcu_ofn_attrs[] = { NULL }; +static umode_t ims_pcu_ofn_is_attr_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct usb_interface *intf = to_usb_interface(dev); + struct ims_pcu *pcu = usb_get_intfdata(intf); + umode_t mode = attr->mode; + + /* + * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor. + */ + if (pcu->bootloader_mode || pcu->device_id == IMS_PCU_PCU_B_DEVICE_ID) + mode = 0; + + return mode; +} + static const struct attribute_group ims_pcu_ofn_attr_group = { - .name = "ofn", - .attrs = ims_pcu_ofn_attrs, + .name = "ofn", + .is_visible = ims_pcu_ofn_is_attr_visible, + .attrs = ims_pcu_ofn_attrs, }; static void ims_pcu_irq(struct urb *urb) @@ -1889,16 +1907,6 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu) /* Device appears to be operable, complete initialization */ pcu->device_no = atomic_inc_return(&device_no); - /* - * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor - */ - if (pcu->device_id != IMS_PCU_PCU_B_DEVICE_ID) { - error = sysfs_create_group(&pcu->dev->kobj, - &ims_pcu_ofn_attr_group); - if (error) - return error; - } - error = ims_pcu_setup_backlight(pcu); if (error) return error; @@ -1935,10 +1943,6 @@ static void ims_pcu_destroy_application_mode(struct ims_pcu *pcu) ims_pcu_destroy_gamepad(pcu); ims_pcu_destroy_buttons(pcu); ims_pcu_destroy_backlight(pcu); - - if (pcu->device_id != IMS_PCU_PCU_B_DEVICE_ID) - sysfs_remove_group(&pcu->dev->kobj, - &ims_pcu_ofn_attr_group); } } @@ -2030,20 +2034,14 @@ static int ims_pcu_probe(struct usb_interface *intf, if (error) goto err_stop_io; - error = sysfs_create_group(&intf->dev.kobj, &ims_pcu_attr_group); - if (error) - goto err_stop_io; - error = pcu->bootloader_mode ? ims_pcu_init_bootloader_mode(pcu) : ims_pcu_init_application_mode(pcu); if (error) - goto err_remove_sysfs; + goto err_stop_io; return 0; -err_remove_sysfs: - sysfs_remove_group(&intf->dev.kobj, &ims_pcu_attr_group); err_stop_io: ims_pcu_stop_io(pcu); err_free_buffers: @@ -2069,8 +2067,6 @@ static void ims_pcu_disconnect(struct usb_interface *intf) if (alt->desc.bInterfaceClass != USB_CLASS_COMM) return; - sysfs_remove_group(&intf->dev.kobj, &ims_pcu_attr_group); - ims_pcu_stop_io(pcu); if (pcu->bootloader_mode) @@ -2129,9 +2125,16 @@ static const struct usb_device_id ims_pcu_id_table[] = { { } }; +static const struct attribute_group *ims_pcu_sysfs_groups[] = { + &ims_pcu_attr_group, + &ims_pcu_ofn_attr_group, + NULL +}; + static struct usb_driver ims_pcu_driver = { .name = "ims_pcu", .id_table = ims_pcu_id_table, + .dev_groups = ims_pcu_sysfs_groups, .probe = ims_pcu_probe, .disconnect = ims_pcu_disconnect, #ifdef CONFIG_PM From 703f12672e1f7ca9d13bbfa56ecdd741b1e2c9d1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 21:18:11 -0700 Subject: [PATCH 22/71] Input: ims-pcu - switch to using cleanup functions Start using __free() and guard() primitives to simplify the code and error handling. Link: https://lore.kernel.org/r/20240610041813.722445-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ims-pcu.c | 137 ++++++++++++++++------------------- 1 file changed, 63 insertions(+), 74 deletions(-) diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 6f0e4f6567b0..c086dadb45e3 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -927,9 +927,8 @@ static void ims_pcu_process_async_firmware(const struct firmware *fw, goto out; } - mutex_lock(&pcu->cmd_mutex); - ims_pcu_handle_firmware_update(pcu, fw); - mutex_unlock(&pcu->cmd_mutex); + scoped_guard(mutex, &pcu->cmd_mutex) + ims_pcu_handle_firmware_update(pcu, fw); release_firmware(fw); @@ -953,7 +952,7 @@ static int ims_pcu_backlight_set_brightness(struct led_classdev *cdev, __le16 br_val = cpu_to_le16(value); int error; - mutex_lock(&pcu->cmd_mutex); + guard(mutex)(&pcu->cmd_mutex); error = ims_pcu_execute_command(pcu, SET_BRIGHTNESS, &br_val, sizeof(br_val)); @@ -962,8 +961,6 @@ static int ims_pcu_backlight_set_brightness(struct led_classdev *cdev, "Failed to set desired brightness %u, error: %d\n", value, error); - mutex_unlock(&pcu->cmd_mutex); - return error; } @@ -977,7 +974,7 @@ ims_pcu_backlight_get_brightness(struct led_classdev *cdev) int brightness; int error; - mutex_lock(&pcu->cmd_mutex); + guard(mutex)(&pcu->cmd_mutex); error = ims_pcu_execute_query(pcu, GET_BRIGHTNESS); if (error) { @@ -991,8 +988,6 @@ ims_pcu_backlight_get_brightness(struct led_classdev *cdev) get_unaligned_le16(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET]); } - mutex_unlock(&pcu->cmd_mutex); - return brightness; } @@ -1072,24 +1067,23 @@ static ssize_t ims_pcu_attribute_store(struct device *dev, if (data_len > attr->field_length) return -EINVAL; - error = mutex_lock_interruptible(&pcu->cmd_mutex); - if (error) - return error; + scoped_cond_guard(mutex, return -EINTR, &pcu->cmd_mutex) { + memset(field, 0, attr->field_length); + memcpy(field, buf, data_len); - memset(field, 0, attr->field_length); - memcpy(field, buf, data_len); + error = ims_pcu_set_info(pcu); - error = ims_pcu_set_info(pcu); + /* + * Even if update failed, let's fetch the info again as we just + * clobbered one of the fields. + */ + ims_pcu_get_info(pcu); - /* - * Even if update failed, let's fetch the info again as we just - * clobbered one of the fields. - */ - ims_pcu_get_info(pcu); + if (error) + return error; + } - mutex_unlock(&pcu->cmd_mutex); - - return error < 0 ? error : count; + return count; } #define IMS_PCU_ATTR(_field, _mode) \ @@ -1152,7 +1146,6 @@ static ssize_t ims_pcu_update_firmware_store(struct device *dev, { struct usb_interface *intf = to_usb_interface(dev); struct ims_pcu *pcu = usb_get_intfdata(intf); - const struct firmware *fw = NULL; int value; int error; @@ -1163,35 +1156,33 @@ static ssize_t ims_pcu_update_firmware_store(struct device *dev, if (value != 1) return -EINVAL; - error = mutex_lock_interruptible(&pcu->cmd_mutex); - if (error) - return error; - + const struct firmware *fw __free(firmware) = NULL; error = request_ihex_firmware(&fw, IMS_PCU_FIRMWARE_NAME, pcu->dev); if (error) { dev_err(pcu->dev, "Failed to request firmware %s, error: %d\n", IMS_PCU_FIRMWARE_NAME, error); - goto out; + return error; } - /* - * If we are already in bootloader mode we can proceed with - * flashing the firmware. - * - * If we are in application mode, then we need to switch into - * bootloader mode, which will cause the device to disconnect - * and reconnect as different device. - */ - if (pcu->bootloader_mode) - error = ims_pcu_handle_firmware_update(pcu, fw); - else - error = ims_pcu_switch_to_bootloader(pcu); + scoped_cond_guard(mutex_intr, return -EINTR, &pcu->cmd_mutex) { + /* + * If we are already in bootloader mode we can proceed with + * flashing the firmware. + * + * If we are in application mode, then we need to switch into + * bootloader mode, which will cause the device to disconnect + * and reconnect as different device. + */ + if (pcu->bootloader_mode) + error = ims_pcu_handle_firmware_update(pcu, fw); + else + error = ims_pcu_switch_to_bootloader(pcu); - release_firmware(fw); + if (error) + return error; + } -out: - mutex_unlock(&pcu->cmd_mutex); - return error ?: count; + return count; } static DEVICE_ATTR(update_firmware, S_IWUSR, @@ -1301,12 +1292,11 @@ static ssize_t ims_pcu_ofn_reg_data_show(struct device *dev, int error; u8 data; - mutex_lock(&pcu->cmd_mutex); - error = ims_pcu_read_ofn_config(pcu, pcu->ofn_reg_addr, &data); - mutex_unlock(&pcu->cmd_mutex); - - if (error) - return error; + scoped_guard(mutex, &pcu->cmd_mutex) { + error = ims_pcu_read_ofn_config(pcu, pcu->ofn_reg_addr, &data); + if (error) + return error; + } return sysfs_emit(buf, "%x\n", data); } @@ -1324,11 +1314,13 @@ static ssize_t ims_pcu_ofn_reg_data_store(struct device *dev, if (error) return error; - mutex_lock(&pcu->cmd_mutex); - error = ims_pcu_write_ofn_config(pcu, pcu->ofn_reg_addr, value); - mutex_unlock(&pcu->cmd_mutex); + guard(mutex)(&pcu->cmd_mutex); - return error ?: count; + error = ims_pcu_write_ofn_config(pcu, pcu->ofn_reg_addr, value); + if (error) + return error; + + return count; } static DEVICE_ATTR(reg_data, S_IRUGO | S_IWUSR, @@ -1340,13 +1332,10 @@ static ssize_t ims_pcu_ofn_reg_addr_show(struct device *dev, { struct usb_interface *intf = to_usb_interface(dev); struct ims_pcu *pcu = usb_get_intfdata(intf); - int error; - mutex_lock(&pcu->cmd_mutex); - error = sysfs_emit(buf, "%x\n", pcu->ofn_reg_addr); - mutex_unlock(&pcu->cmd_mutex); + guard(mutex)(&pcu->cmd_mutex); - return error; + return sysfs_emit(buf, "%x\n", pcu->ofn_reg_addr); } static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev, @@ -1362,9 +1351,9 @@ static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev, if (error) return error; - mutex_lock(&pcu->cmd_mutex); + guard(mutex)(&pcu->cmd_mutex); + pcu->ofn_reg_addr = value; - mutex_unlock(&pcu->cmd_mutex); return count; } @@ -1389,12 +1378,11 @@ static ssize_t ims_pcu_ofn_bit_show(struct device *dev, int error; u8 data; - mutex_lock(&pcu->cmd_mutex); - error = ims_pcu_read_ofn_config(pcu, attr->addr, &data); - mutex_unlock(&pcu->cmd_mutex); - - if (error) - return error; + scoped_guard(mutex, &pcu->cmd_mutex) { + error = ims_pcu_read_ofn_config(pcu, attr->addr, &data); + if (error) + return error; + } return sysfs_emit(buf, "%d\n", !!(data & (1 << attr->nr))); } @@ -1418,21 +1406,22 @@ static ssize_t ims_pcu_ofn_bit_store(struct device *dev, if (value > 1) return -EINVAL; - mutex_lock(&pcu->cmd_mutex); + scoped_guard(mutex, &pcu->cmd_mutex) { + error = ims_pcu_read_ofn_config(pcu, attr->addr, &data); + if (error) + return error; - error = ims_pcu_read_ofn_config(pcu, attr->addr, &data); - if (!error) { if (value) data |= 1U << attr->nr; else data &= ~(1U << attr->nr); error = ims_pcu_write_ofn_config(pcu, attr->addr, data); + if (error) + return error; } - mutex_unlock(&pcu->cmd_mutex); - - return error ?: count; + return count; } #define IMS_PCU_OFN_BIT_ATTR(_field, _addr, _nr) \ From 50717edb6dd74dbc0726fb2ba8723ba2a22a2011 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 20 Jun 2024 17:38:55 -0700 Subject: [PATCH 23/71] Input: adc-joystick - move axes data into the main structure There is no need to allocate axes information separately from the main joystick structure so let's fold the allocation and also drop members (such as range, flat and fuzz) that are only used during initialization of the device. Acked-by: Artur Rojek Link: https://lore.kernel.org/r/ZmkrgTlxNwm_oHxv@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/adc-joystick.c | 114 ++++++++++++++------------ 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c index 916e78e4dc9f..5f46a7104b52 100644 --- a/drivers/input/joystick/adc-joystick.c +++ b/drivers/input/joystick/adc-joystick.c @@ -15,19 +15,15 @@ struct adc_joystick_axis { u32 code; - s32 range[2]; - s32 fuzz; - s32 flat; bool inverted; }; struct adc_joystick { struct input_dev *input; struct iio_cb_buffer *buffer; - struct adc_joystick_axis *axes; struct iio_channel *chans; - int num_chans; - bool polled; + unsigned int num_chans; + struct adc_joystick_axis axes[] __counted_by(num_chans); }; static int adc_joystick_invert(struct input_dev *dev, @@ -135,9 +131,11 @@ static void adc_joystick_cleanup(void *data) static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) { - struct adc_joystick_axis *axes; + struct adc_joystick_axis *axes = joy->axes; struct fwnode_handle *child; - int num_axes, error, i; + s32 range[2], fuzz, flat; + unsigned int num_axes; + int error, i; num_axes = device_get_child_node_count(dev); if (!num_axes) { @@ -151,10 +149,6 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) return -EINVAL; } - axes = devm_kmalloc_array(dev, num_axes, sizeof(*axes), GFP_KERNEL); - if (!axes) - return -ENOMEM; - device_for_each_child_node(dev, child) { error = fwnode_property_read_u32(child, "reg", &i); if (error) { @@ -176,29 +170,25 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) } error = fwnode_property_read_u32_array(child, "abs-range", - axes[i].range, 2); + range, 2); if (error) { dev_err(dev, "abs-range invalid or missing\n"); goto err_fwnode_put; } - if (axes[i].range[0] > axes[i].range[1]) { + if (range[0] > range[1]) { dev_dbg(dev, "abs-axis %d inverted\n", i); axes[i].inverted = true; - swap(axes[i].range[0], axes[i].range[1]); + swap(range[0], range[1]); } - fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz); - fwnode_property_read_u32(child, "abs-flat", &axes[i].flat); + fwnode_property_read_u32(child, "abs-fuzz", &fuzz); + fwnode_property_read_u32(child, "abs-flat", &flat); input_set_abs_params(joy->input, axes[i].code, - axes[i].range[0], axes[i].range[1], - axes[i].fuzz, axes[i].flat); - input_set_capability(joy->input, EV_ABS, axes[i].code); + range[0], range[1], fuzz, flat); } - joy->axes = axes; - return 0; err_fwnode_put: @@ -206,23 +196,50 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) return error; } + +static int adc_joystick_count_channels(struct device *dev, + const struct iio_channel *chans, + bool polled, + unsigned int *num_chans) +{ + int bits; + int i; + + /* + * Count how many channels we got. NULL terminated. + * Do not check the storage size if using polling. + */ + for (i = 0; chans[i].indio_dev; i++) { + if (polled) + continue; + bits = chans[i].channel->scan_type.storagebits; + if (!bits || bits > 16) { + dev_err(dev, "Unsupported channel storage size\n"); + return -EINVAL; + } + if (bits != chans[0].channel->scan_type.storagebits) { + dev_err(dev, "Channels must have equal storage size\n"); + return -EINVAL; + } + } + + *num_chans = i; + return 0; +} + static int adc_joystick_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct iio_channel *chans; struct adc_joystick *joy; struct input_dev *input; + unsigned int poll_interval = 0; + unsigned int num_chans; int error; - int bits; - int i; - unsigned int poll_interval; - joy = devm_kzalloc(dev, sizeof(*joy), GFP_KERNEL); - if (!joy) - return -ENOMEM; - - joy->chans = devm_iio_channel_get_all(dev); - if (IS_ERR(joy->chans)) { - error = PTR_ERR(joy->chans); + chans = devm_iio_channel_get_all(dev); + error = PTR_ERR_OR_ZERO(chans); + if (error) { if (error != -EPROBE_DEFER) dev_err(dev, "Unable to get IIO channels"); return error; @@ -236,28 +253,19 @@ static int adc_joystick_probe(struct platform_device *pdev) } else if (poll_interval == 0) { dev_err(dev, "Unable to get poll-interval\n"); return -EINVAL; - } else { - joy->polled = true; } - /* - * Count how many channels we got. NULL terminated. - * Do not check the storage size if using polling. - */ - for (i = 0; joy->chans[i].indio_dev; i++) { - if (joy->polled) - continue; - bits = joy->chans[i].channel->scan_type.storagebits; - if (!bits || bits > 16) { - dev_err(dev, "Unsupported channel storage size\n"); - return -EINVAL; - } - if (bits != joy->chans[0].channel->scan_type.storagebits) { - dev_err(dev, "Channels must have equal storage size\n"); - return -EINVAL; - } - } - joy->num_chans = i; + error = adc_joystick_count_channels(dev, chans, poll_interval != 0, + &num_chans); + if (error) + return error; + + joy = devm_kzalloc(dev, struct_size(joy, axes, num_chans), GFP_KERNEL); + if (!joy) + return -ENOMEM; + + joy->chans = chans; + joy->num_chans = num_chans; input = devm_input_allocate_device(dev); if (!input) { @@ -273,7 +281,7 @@ static int adc_joystick_probe(struct platform_device *pdev) if (error) return error; - if (joy->polled) { + if (poll_interval != 0) { input_setup_polling(input, adc_joystick_poll); input_set_poll_interval(input, poll_interval); } else { From e7202f646717e0be355f1acc5ed57370bc1e201c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 21 Jun 2024 13:34:44 -0700 Subject: [PATCH 24/71] dt-bindings: ads7846: Add hsync-gpios The TI ADS7846 emits a horizontal sync signal that is usually connected to a GPIO for polling. Add a binding for this. Signed-off-by: Linus Walleij Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240430-gpio-leds-miscarm-v1-2-9c94d7711f6c@linaro.org Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/input/touchscreen/ads7846.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/ads7846.txt b/Documentation/devicetree/bindings/input/touchscreen/ads7846.txt index 81f6bda97d3c..399c87782935 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/ads7846.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/ads7846.txt @@ -57,6 +57,7 @@ Optional properties: pendown-gpio (u32). pendown-gpio GPIO handle describing the pin the !PENIRQ line is connected to. + ti,hsync-gpios GPIO line to poll for hsync wakeup-source use any event on touchscreen as wakeup event. (Legacy property support: "linux,wakeup") touchscreen-size-x General touchscreen binding, see [1]. From 8685f22b5bfdab0b335232eb70a0af3388d35299 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 21 Jun 2024 13:35:52 -0700 Subject: [PATCH 25/71] Input: ads7846 - handle HSYNC GPIO Add handling of HSYNC signal emitted by the TI ADS7846 if it is hooked up to a GPIO. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20240430-gpio-leds-miscarm-v1-3-9c94d7711f6c@linaro.org [dtor: dropped Spitz changes, kept platform data wait_for_sync option] Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 35 ++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index d2bbb436a77d..6e11cb877ae1 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -138,6 +138,7 @@ struct ads7846 { void *filter_data; int (*get_pendown_state)(void); struct gpio_desc *gpio_pendown; + struct gpio_desc *gpio_hsync; void (*wait_for_sync)(void); }; @@ -634,10 +635,6 @@ ATTRIBUTE_GROUPS(ads784x); /*--------------------------------------------------------------------------*/ -static void null_wait_for_sync(void) -{ -} - static int ads7846_debounce_filter(void *ads, int data_idx, int *val) { struct ads7846 *ts = ads; @@ -790,6 +787,28 @@ static int ads7846_filter(struct ads7846 *ts) return 0; } +static void ads7846_wait_for_hsync(struct ads7846 *ts) +{ + if (ts->wait_for_sync) { + ts->wait_for_sync(); + return; + } + + if (!ts->gpio_hsync) + return; + + /* + * Wait for HSYNC to assert the line should be flagged + * as active low so here we are waiting for it to assert + */ + while (!gpiod_get_value(ts->gpio_hsync)) + cpu_relax(); + + /* Then we wait for it do de-assert */ + while (gpiod_get_value(ts->gpio_hsync)) + cpu_relax(); +} + static void ads7846_read_state(struct ads7846 *ts) { struct ads7846_packet *packet = ts->packet; @@ -800,7 +819,7 @@ static void ads7846_read_state(struct ads7846 *ts) packet->last_cmd_idx = 0; while (true) { - ts->wait_for_sync(); + ads7846_wait_for_hsync(ts); m = &ts->msg[msg_idx]; error = spi_sync(ts->spi, m); @@ -1258,7 +1277,11 @@ static int ads7846_probe(struct spi_device *spi) ts->penirq_recheck_delay_usecs = pdata->penirq_recheck_delay_usecs; - ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; + ts->wait_for_sync = pdata->wait_for_sync; + + ts->gpio_hsync = devm_gpiod_get_optional(dev, "ti,hsync", GPIOD_IN); + if (IS_ERR(ts->gpio_hsync)) + return PTR_ERR(ts->gpio_hsync); snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); From dfb60401314413a71e731984906c5688369e0496 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Sat, 22 Jun 2024 00:40:20 +0200 Subject: [PATCH 26/71] dt-bindings: touchscreen: convert elan,ektf2127 to json-schema Convert EKTF2127 infrared touchscreen controller binding to DT schema and add ektf2232 compatible. Signed-off-by: Andreas Kemnade Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240621224022.1620897-2-andreas@kemnade.info Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/ektf2127.txt | 25 -------- .../input/touchscreen/elan,ektf2127.yaml | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+), 25 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt create mode 100644 Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml diff --git a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt b/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt deleted file mode 100644 index c9f2c9f578e3..000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/ektf2127.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Elan eKTF2127 I2C touchscreen controller - -Required properties: - - compatible : "elan,ektf2127" or "elan,ektf2132" - - reg : I2C slave address of the chip (0x40) - - interrupts : interrupt specification for the ektf2127 interrupt - - power-gpios : GPIO specification for the pin connected to the - ektf2127's wake input. This needs to be driven high - to take ektf2127 out of its low power state - -For additional optional properties see: touchscreen.txt - -Example: - -i2c@00000000 { - ektf2127: touchscreen@15 { - compatible = "elan,ektf2127"; - reg = <0x15>; - interrupt-parent = <&pio>; - interrupts = <6 11 IRQ_TYPE_EDGE_FALLING> - power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; - touchscreen-inverted-x; - touchscreen-swapped-x-y; - }; -}; diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml new file mode 100644 index 000000000000..5c4c29da0b11 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/elan,ektf2127.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Elan eKTF2127 I2C touchscreen controller + +maintainers: + - Siebren Vroegindeweij + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: + enum: + - elan,ektf2127 + - elan,ektf2132 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + power-gpios: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - power-gpios + +unevaluatedProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@15 { + compatible = "elan,ektf2127"; + reg = <0x15>; + interrupt-parent = <&pio>; + interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>; + power-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; + touchscreen-inverted-x; + touchscreen-swapped-x-y; + }; + }; +... From a65506057abf228ef566df4db61b3898c17d3cf5 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Sat, 22 Jun 2024 00:40:21 +0200 Subject: [PATCH 27/71] dt-bindings: touchscreen: elan,ektf2127: Add EKTF2232 Add a compatible for the EKTF2232, which is similar to other chips in this document. Signed-off-by: Andreas Kemnade Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240621224022.1620897-3-andreas@kemnade.info Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/touchscreen/elan,ektf2127.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml index 5c4c29da0b11..ff0ec3fd24c5 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/elan,ektf2127.yaml @@ -17,6 +17,7 @@ properties: enum: - elan,ektf2127 - elan,ektf2132 + - elan,ektf2232 reg: maxItems: 1 From f7b41baa102c5d0e22c80e685ac6af83f02bce78 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Sat, 22 Jun 2024 00:40:22 +0200 Subject: [PATCH 28/71] Input: ektf2127 - add ektf2232 support The chip is similar, but has status bits at different positions, so use the correct bits. Signed-off-by: Andreas Kemnade Link: https://lore.kernel.org/r/20240621224022.1620897-4-andreas@kemnade.info Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ektf2127.c | 36 +++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/ektf2127.c b/drivers/input/touchscreen/ektf2127.c index ab8159e1c99d..46a0611fac82 100644 --- a/drivers/input/touchscreen/ektf2127.c +++ b/drivers/input/touchscreen/ektf2127.c @@ -13,6 +13,7 @@ * Hans de Goede */ +#include #include #include #include @@ -46,6 +47,11 @@ struct ektf2127_ts { struct input_dev *input; struct gpio_desc *power_gpios; struct touchscreen_properties prop; + int status_shift; +}; + +struct ektf2127_i2c_chip_data { + int status_shift; }; static void ektf2127_parse_coordinates(const u8 *buf, unsigned int touch_count, @@ -112,8 +118,8 @@ static void ektf2127_report2_contact(struct ektf2127_ts *ts, int slot, static void ektf2127_report2_event(struct ektf2127_ts *ts, const u8 *buf) { - ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & 2)); - ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & 4)); + ektf2127_report2_contact(ts, 0, &buf[1], !!(buf[7] & BIT(ts->status_shift))); + ektf2127_report2_contact(ts, 1, &buf[4], !!(buf[7] & BIT(ts->status_shift + 1))); input_mt_sync_frame(ts->input); input_sync(ts->input); @@ -247,6 +253,7 @@ static int ektf2127_query_dimension(struct i2c_client *client, bool width) static int ektf2127_probe(struct i2c_client *client) { struct device *dev = &client->dev; + const struct ektf2127_i2c_chip_data *chip_data; struct ektf2127_ts *ts; struct input_dev *input; u8 buf[4]; @@ -303,6 +310,13 @@ static int ektf2127_probe(struct i2c_client *client) return error; ts->input = input; + + chip_data = i2c_get_match_data(client); + if (!chip_data) + return dev_err_probe(&client->dev, -EINVAL, "missing chip data\n"); + + ts->status_shift = chip_data->status_shift; + input_set_drvdata(input, ts); error = devm_request_threaded_irq(dev, client->irq, @@ -325,18 +339,28 @@ static int ektf2127_probe(struct i2c_client *client) return 0; } +static const struct ektf2127_i2c_chip_data ektf2127_data = { + .status_shift = 1, +}; + +static const struct ektf2127_i2c_chip_data ektf2232_data = { + .status_shift = 0, +}; + #ifdef CONFIG_OF static const struct of_device_id ektf2127_of_match[] = { - { .compatible = "elan,ektf2127" }, - { .compatible = "elan,ektf2132" }, + { .compatible = "elan,ektf2127", .data = &ektf2127_data}, + { .compatible = "elan,ektf2132", .data = &ektf2127_data}, + { .compatible = "elan,ektf2232", .data = &ektf2232_data}, {} }; MODULE_DEVICE_TABLE(of, ektf2127_of_match); #endif static const struct i2c_device_id ektf2127_i2c_id[] = { - { "ektf2127" }, - { "ektf2132" }, + { .name = "ektf2127", .driver_data = (long)&ektf2127_data }, + { .name = "ektf2132", .driver_data = (long)&ektf2127_data }, + { .name = "ektf2232", .driver_data = (long)&ektf2232_data }, {} }; MODULE_DEVICE_TABLE(i2c, ektf2127_i2c_id); From 2e23b7f3b7dbb5bffd570867eea164e88be47faf Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Wed, 1 May 2024 22:47:57 +0200 Subject: [PATCH 29/71] dt-bindings: input: touchscreen: edt-ft5x06: Add ft5426 Add compatible for ft5426. Searches for documentation reveal neither edt nor evervision as some related company, only FocalTech. Signed-off-by: Andreas Kemnade Acked-by: Krzysztof Kozlowski Reviewed-by: Oliver Graute Link: https://lore.kernel.org/r/20240501204758.758537-2-andreas@kemnade.info Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/touchscreen/edt-ft5x06.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml index 745e57c05176..379721027bf8 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml @@ -39,6 +39,7 @@ properties: - edt,edt-ft5406 - edt,edt-ft5506 - evervision,ev-ft5726 + - focaltech,ft5426 - focaltech,ft5452 - focaltech,ft6236 - focaltech,ft8719 From 0ca1323c6aba8fd9309ca33a4bf57c1c9fc06171 Mon Sep 17 00:00:00 2001 From: Andreas Kemnade Date: Wed, 1 May 2024 22:47:58 +0200 Subject: [PATCH 30/71] Input: edt-ft5x06 - add ft5426 As ft5426 seems to be compatible with this driver, add it. Debug output during identification: Model "generic ft5x06 (79)", Rev. " Signed-off-by: Andreas Kemnade Reviewed-by: Oliver Graute Link: https://lore.kernel.org/r/20240501204758.758537-3-andreas@kemnade.info Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/edt-ft5x06.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 06ec0f2e18ae..42f99e57fbb7 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -1496,6 +1496,7 @@ static const struct of_device_id edt_ft5x06_of_match[] = { { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data }, { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data }, { .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data }, + { .compatible = "focaltech,ft5426", .data = &edt_ft5506_data }, { .compatible = "focaltech,ft5452", .data = &edt_ft5452_data }, /* Note focaltech vendor prefix for compatibility with ft6236.c */ { .compatible = "focaltech,ft6236", .data = &edt_ft6236_data }, From 866a5c7e2781cf1b019072288f1f5c64186dcb63 Mon Sep 17 00:00:00 2001 From: Andrei Lalaev Date: Mon, 17 Jun 2024 20:30:18 +0200 Subject: [PATCH 31/71] Input: qt1050 - handle CHIP_ID reading error If the device is missing, we get the following error: qt1050 3-0041: ID -1340767592 not supported Let's handle this situation and print more informative error when reading of CHIP_ID fails: qt1050 3-0041: Failed to read chip ID: -6 Fixes: cbebf5addec1 ("Input: qt1050 - add Microchip AT42QT1050 support") Signed-off-by: Andrei Lalaev Reviewed-by: Marco Felsch Link: https://lore.kernel.org/r/20240617183018.916234-1-andrey.lalaev@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/qt1050.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c index b51dfcd76038..056e9bc26026 100644 --- a/drivers/input/keyboard/qt1050.c +++ b/drivers/input/keyboard/qt1050.c @@ -226,7 +226,12 @@ static bool qt1050_identify(struct qt1050_priv *ts) int err; /* Read Chip ID */ - regmap_read(ts->regmap, QT1050_CHIP_ID, &val); + err = regmap_read(ts->regmap, QT1050_CHIP_ID, &val); + if (err) { + dev_err(&ts->client->dev, "Failed to read chip ID: %d\n", err); + return false; + } + if (val != QT1050_CHIP_ID_VER) { dev_err(&ts->client->dev, "ID %d not supported\n", val); return false; From 68bf7a8cc5f3ec6630d6a8b2675288694b1a5f63 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 11 Jun 2024 22:31:42 -0700 Subject: [PATCH 32/71] Input: wacom_w8001 - use "guard" notation when acquiring mutex Switch the driver to use guard notation when acquiring mutex to have it released automatically. Link: https://lore.kernel.org/r/Zmkyvkr9AFyywy1V@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/wacom_w8001.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index c8abb9557ee8..ed2ca8a689d5 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -380,30 +380,28 @@ static int w8001_open(struct input_dev *dev) struct w8001 *w8001 = input_get_drvdata(dev); int err; - err = mutex_lock_interruptible(&w8001->mutex); - if (err) - return err; + scoped_guard(mutex_intr, &w8001->mutex) { + if (w8001->open_count == 0) { + err = w8001_command(w8001, W8001_CMD_START, false); + if (err) + return err; + } - if (w8001->open_count++ == 0) { - err = w8001_command(w8001, W8001_CMD_START, false); - if (err) - w8001->open_count--; + w8001->open_count++; + return 0; } - mutex_unlock(&w8001->mutex); - return err; + return -EINTR; } static void w8001_close(struct input_dev *dev) { struct w8001 *w8001 = input_get_drvdata(dev); - mutex_lock(&w8001->mutex); + guard(mutex)(&w8001->mutex); if (--w8001->open_count == 0) w8001_command(w8001, W8001_CMD_STOP, false); - - mutex_unlock(&w8001->mutex); } static int w8001_detect(struct w8001 *w8001) From 03db8425cc716b60b6254e1f4368f7b967b30149 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 11 Jun 2024 22:42:32 -0700 Subject: [PATCH 33/71] Input: goodix_berlin - use __free() cleanup in SPI transport Switch the driver to use __free(kfree) cleanup facility instead of freeing memory by hand. Link: https://lore.kernel.org/r/Zmk1SGwVt3rIbbMU@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix_berlin_spi.c | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/goodix_berlin_spi.c b/drivers/input/touchscreen/goodix_berlin_spi.c index 4cc557da048a..82774a412956 100644 --- a/drivers/input/touchscreen/goodix_berlin_spi.c +++ b/drivers/input/touchscreen/goodix_berlin_spi.c @@ -36,13 +36,14 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf, struct spi_transfer xfers; struct spi_message spi_msg; const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */ - u8 *buf; int error; if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH) return -EINVAL; - buf = kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size, GFP_KERNEL); + u8 *buf __free(kfree) = + kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size, + GFP_KERNEL); if (!buf) return -ENOMEM; @@ -62,12 +63,12 @@ static int goodix_berlin_spi_read(void *context, const void *reg_buf, spi_message_add_tail(&xfers, &spi_msg); error = spi_sync(spi, &spi_msg); - if (error < 0) + if (error < 0) { dev_err(&spi->dev, "spi transfer error, %d", error); - else - memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size); + return error; + } - kfree(buf); + memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size); return error; } @@ -79,10 +80,10 @@ static int goodix_berlin_spi_write(void *context, const void *data, struct spi_transfer xfers; struct spi_message spi_msg; const u32 *reg = data; /* reg is stored as native u32 at start of buffer */ - u8 *buf; int error; - buf = kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL); + u8 *buf __free(kfree) = + kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -100,11 +101,12 @@ static int goodix_berlin_spi_write(void *context, const void *data, spi_message_add_tail(&xfers, &spi_msg); error = spi_sync(spi, &spi_msg); - if (error < 0) + if (error < 0) { dev_err(&spi->dev, "spi transfer error, %d", error); + return error; + } - kfree(buf); - return error; + return 0; } static const struct regmap_config goodix_berlin_spi_regmap_conf = { From 4a56aea539c9c5e8bf6a6a8b72d2d82ca8d5a311 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 16:51:30 -0700 Subject: [PATCH 34/71] Input: rohm_bu21023 - factor out settings update code The code to toggle axis swapping and inversion is repetitive and can be factored out. Link: https://lore.kernel.org/r/20240609235134.614592-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/rohm_bu21023.c | 77 +++++++++--------------- 1 file changed, 29 insertions(+), 48 deletions(-) diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index 06fa3a19d266..c432ed682d31 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -727,6 +727,29 @@ static int rohm_ts_load_firmware(struct i2c_client *client, return error ? error : error2; } +static int rohm_ts_update_setting(struct rohm_ts_data *ts, + unsigned int setting_bit, bool on) +{ + int error; + + error = mutex_lock_interruptible(&ts->input->mutex); + if (error) + return error; + + if (on) + ts->setup2 |= setting_bit; + else + ts->setup2 &= ~setting_bit; + + if (ts->initialized) + error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2, + ts->setup2); + + mutex_unlock(&ts->input->mutex); + + return error; +} + static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -748,22 +771,8 @@ static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr, if (error) return error; - error = mutex_lock_interruptible(&ts->input->mutex); - if (error) - return error; - - if (val) - ts->setup2 |= SWAP_XY; - else - ts->setup2 &= ~SWAP_XY; - - if (ts->initialized) - error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2, - ts->setup2); - - mutex_unlock(&ts->input->mutex); - - return error ? error : count; + error = rohm_ts_update_setting(ts, SWAP_XY, val); + return error ?: count; } static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr, @@ -787,22 +796,8 @@ static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr, if (error) return error; - error = mutex_lock_interruptible(&ts->input->mutex); - if (error) - return error; - - if (val) - ts->setup2 |= INV_X; - else - ts->setup2 &= ~INV_X; - - if (ts->initialized) - error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2, - ts->setup2); - - mutex_unlock(&ts->input->mutex); - - return error ? error : count; + error = rohm_ts_update_setting(ts, INV_X, val); + return error ?: count; } static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr, @@ -826,22 +821,8 @@ static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr, if (error) return error; - error = mutex_lock_interruptible(&ts->input->mutex); - if (error) - return error; - - if (val) - ts->setup2 |= INV_Y; - else - ts->setup2 &= ~INV_Y; - - if (ts->initialized) - error = i2c_smbus_write_byte_data(client, COMMON_SETUP2, - ts->setup2); - - mutex_unlock(&ts->input->mutex); - - return error ? error : count; + error = rohm_ts_update_setting(ts, INV_Y, val); + return error ?: count; } static DEVICE_ATTR_RW(swap_xy); From bf5cba8cf5c5843c5e6f51f0db846181904ef6f8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 16:51:31 -0700 Subject: [PATCH 35/71] Input: rohm_bu21023 - switch to using sysfs_emit() sysfs_emit() is preferred over snprintf() for sysfs attribute handling. Link: https://lore.kernel.org/r/20240609235134.614592-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/rohm_bu21023.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index c432ed682d31..7be2549fde85 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -756,7 +756,7 @@ static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct rohm_ts_data *ts = i2c_get_clientdata(client); - return sprintf(buf, "%d\n", !!(ts->setup2 & SWAP_XY)); + return sysfs_emit(buf, "%d\n", !!(ts->setup2 & SWAP_XY)); } static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr, @@ -781,7 +781,7 @@ static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct rohm_ts_data *ts = i2c_get_clientdata(client); - return sprintf(buf, "%d\n", !!(ts->setup2 & INV_X)); + return sysfs_emit(buf, "%d\n", !!(ts->setup2 & INV_X)); } static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr, @@ -806,7 +806,7 @@ static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr, struct i2c_client *client = to_i2c_client(dev); struct rohm_ts_data *ts = i2c_get_clientdata(client); - return sprintf(buf, "%d\n", !!(ts->setup2 & INV_Y)); + return sysfs_emit(buf, "%d\n", !!(ts->setup2 & INV_Y)); } static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr, From f2845b4f1b2d459ca2ddbcaf165b1dab0b366ea6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 16:51:32 -0700 Subject: [PATCH 36/71] Input: rohm_bu21023 - switch to using cleanup functions Start using __free() and guard() primitives to simplify the code and error handling. Link: https://lore.kernel.org/r/20240609235134.614592-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/rohm_bu21023.c | 40 +++++++++++------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index 7be2549fde85..0e5cc9fbad17 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -643,12 +643,12 @@ static int rohm_ts_load_firmware(struct i2c_client *client, const char *firmware_name) { struct device *dev = &client->dev; - const struct firmware *fw; s32 status; unsigned int offset, len, xfer_len; unsigned int retry = 0; int error, error2; + const struct firmware *fw __free(firmware) = NULL; error = request_firmware(&fw, firmware_name, dev); if (error) { dev_err(dev, "unable to retrieve firmware %s: %d\n", @@ -722,8 +722,6 @@ static int rohm_ts_load_firmware(struct i2c_client *client, out: error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL); - release_firmware(fw); - return error ? error : error2; } @@ -732,22 +730,22 @@ static int rohm_ts_update_setting(struct rohm_ts_data *ts, { int error; - error = mutex_lock_interruptible(&ts->input->mutex); - if (error) - return error; + scoped_cond_guard(mutex_intr, return -EINTR, &ts->input->mutex) { + if (on) + ts->setup2 |= setting_bit; + else + ts->setup2 &= ~setting_bit; - if (on) - ts->setup2 |= setting_bit; - else - ts->setup2 &= ~setting_bit; + if (ts->initialized) { + error = i2c_smbus_write_byte_data(ts->client, + COMMON_SETUP2, + ts->setup2); + if (error) + return error; + } + } - if (ts->initialized) - error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2, - ts->setup2); - - mutex_unlock(&ts->input->mutex); - - return error; + return 0; } static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr, @@ -842,7 +840,7 @@ static int rohm_ts_device_init(struct i2c_client *client, u8 setup2) struct device *dev = &client->dev; int error; - disable_irq(client->irq); + guard(disable_irq)(&client->irq); /* * Wait 200usec for reset @@ -1017,10 +1015,10 @@ static int rohm_ts_device_init(struct i2c_client *client, u8 setup2) /* controller CPU power on */ error = i2c_smbus_write_byte_data(client, SYSTEM, ANALOG_POWER_ON | CPU_POWER_ON); + if (error) + return error; - enable_irq(client->irq); - - return error; + return 0; } static int rohm_ts_power_off(struct i2c_client *client) From 17f5eebf6780eee50f887542e1833fda95f53e4d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 16:47:53 -0700 Subject: [PATCH 37/71] Input: ili210x - use kvmalloc() to allocate buffer for firmware update Allocating a contiguous buffer of 64K may fail if memory is sufficiently fragmented, and may cause OOM kill of an unrelated process. However we do not need to have contiguous memory. We also do not need to zero out the buffer since it will be overwritten with firmware data. Switch to using kvmalloc() instead of kzalloc(). Link: https://lore.kernel.org/r/20240609234757.610273-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 31ffdc2a93f3..9e5b44cbe389 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -597,7 +597,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, * once, copy them all into this buffer at the right locations, and then * do all operations on this linear buffer. */ - fw_buf = kzalloc(SZ_64K, GFP_KERNEL); + fw_buf = kvmalloc(SZ_64K, GFP_KERNEL); if (!fw_buf) return -ENOMEM; @@ -627,7 +627,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, return 0; err_big: - kfree(fw_buf); + kvfree(fw_buf); return error; } @@ -870,7 +870,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, ili210x_hardware_reset(priv->reset_gpio); dev_dbg(dev, "Firmware update ended, error=%i\n", error); enable_irq(client->irq); - kfree(fwbuf); + kvfree(fwbuf); return error; } From ac7e0839daf19a125c4d8f26a102868770cfd48f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 16:47:54 -0700 Subject: [PATCH 38/71] Input: ili210x - switch to using cleanup functions in firmware code Start using __free() attributes to simplify the code and error handling. Link: https://lore.kernel.org/r/20240609234757.610273-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 153 ++++++++++++++-------------- 1 file changed, 78 insertions(+), 75 deletions(-) diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index 9e5b44cbe389..d0713a27ad6a 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -582,14 +582,12 @@ static ssize_t ili210x_calibrate(struct device *dev, } static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate); -static int ili251x_firmware_to_buffer(const struct firmware *fw, - u8 **buf, u16 *ac_end, u16 *df_end) +static const u8 *ili251x_firmware_to_buffer(const struct firmware *fw, + u16 *ac_end, u16 *df_end) { const struct ihex_binrec *rec; u32 fw_addr, fw_last_addr = 0; u16 fw_len; - u8 *fw_buf; - int error; /* * The firmware ihex blob can never be bigger than 64 kiB, so make this @@ -597,9 +595,9 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, * once, copy them all into this buffer at the right locations, and then * do all operations on this linear buffer. */ - fw_buf = kvmalloc(SZ_64K, GFP_KERNEL); + u8* fw_buf __free(kvfree) = kvmalloc(SZ_64K, GFP_KERNEL); if (!fw_buf) - return -ENOMEM; + return ERR_PTR(-ENOMEM); rec = (const struct ihex_binrec *)fw->data; while (rec) { @@ -607,10 +605,8 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, fw_len = be16_to_cpu(rec->len); /* The last 32 Byte firmware block can be 0xffe0 */ - if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32) { - error = -EFBIG; - goto err_big; - } + if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32) + return ERR_PTR(-EFBIG); /* Find the last address before DF start address, that is AC end */ if (fw_addr == 0xf000) @@ -623,12 +619,8 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw, /* DF end address is the last address in the firmware blob */ *df_end = fw_addr + fw_len; - *buf = fw_buf; - return 0; -err_big: - kvfree(fw_buf); - return error; + return_ptr(fw_buf); } /* Switch mode between Application and BootLoader */ @@ -691,7 +683,7 @@ static int ili251x_firmware_busy(struct i2c_client *client) return 0; } -static int ili251x_firmware_write_to_ic(struct device *dev, u8 *fwbuf, +static int ili251x_firmware_write_to_ic(struct device *dev, const u8 *fwbuf, u16 start, u16 end, u8 dataflash) { struct i2c_client *client = to_i2c_client(dev); @@ -776,6 +768,67 @@ static void ili210x_hardware_reset(struct gpio_desc *reset_gpio) msleep(300); } +static int ili210x_do_firmware_update(struct ili210x *priv, + const u8 *fwbuf, u16 ac_end, u16 df_end) +{ + struct i2c_client *client = priv->client; + struct device *dev = &client->dev; + int error; + int i; + + error = ili251x_firmware_reset(client); + if (error) + return error; + + /* This may not succeed on first try, so re-try a few times. */ + for (i = 0; i < 5; i++) { + error = ili251x_switch_ic_mode(client, REG_SET_MODE_BL); + if (!error) + break; + } + + if (error) + return error; + + dev_dbg(dev, "IC is now in BootLoader mode\n"); + + msleep(200); /* The bootloader seems to need some time too. */ + + error = ili251x_firmware_write_to_ic(dev, fwbuf, 0xf000, df_end, 1); + if (error) { + dev_err(dev, "DF firmware update failed, error=%d\n", error); + return error; + } + + dev_dbg(dev, "DataFlash firmware written\n"); + + error = ili251x_firmware_write_to_ic(dev, fwbuf, 0x2000, ac_end, 0); + if (error) { + dev_err(dev, "AC firmware update failed, error=%d\n", error); + return error; + } + + dev_dbg(dev, "Application firmware written\n"); + + /* This may not succeed on first try, so re-try a few times. */ + for (i = 0; i < 5; i++) { + error = ili251x_switch_ic_mode(client, REG_SET_MODE_AP); + if (!error) + break; + } + + if (error) + return error; + + dev_dbg(dev, "IC is now in Application mode\n"); + + error = ili251x_firmware_update_cached_state(dev); + if (error) + return error; + + return 0; +} + static ssize_t ili210x_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -783,12 +836,10 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, struct i2c_client *client = to_i2c_client(dev); struct ili210x *priv = i2c_get_clientdata(client); const char *fwname = ILI251X_FW_FILENAME; - const struct firmware *fw; u16 ac_end, df_end; - u8 *fwbuf; int error; - int i; + const struct firmware *fw __free(firmware) = NULL; error = request_ihex_firmware(&fw, fwname, dev); if (error) { dev_err(dev, "Failed to request firmware %s, error=%d\n", @@ -796,8 +847,9 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, return error; } - error = ili251x_firmware_to_buffer(fw, &fwbuf, &ac_end, &df_end); - release_firmware(fw); + const u8* fwbuf __free(kvfree) = + ili251x_firmware_to_buffer(fw, &ac_end, &df_end); + error = PTR_ERR_OR_ZERO(fwbuf); if (error) return error; @@ -814,64 +866,15 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, ili210x_hardware_reset(priv->reset_gpio); - error = ili251x_firmware_reset(client); - if (error) - goto exit; + error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); - /* This may not succeed on first try, so re-try a few times. */ - for (i = 0; i < 5; i++) { - error = ili251x_switch_ic_mode(client, REG_SET_MODE_BL); - if (!error) - break; - } - - if (error) - goto exit; - - dev_dbg(dev, "IC is now in BootLoader mode\n"); - - msleep(200); /* The bootloader seems to need some time too. */ - - error = ili251x_firmware_write_to_ic(dev, fwbuf, 0xf000, df_end, 1); - if (error) { - dev_err(dev, "DF firmware update failed, error=%d\n", error); - goto exit; - } - - dev_dbg(dev, "DataFlash firmware written\n"); - - error = ili251x_firmware_write_to_ic(dev, fwbuf, 0x2000, ac_end, 0); - if (error) { - dev_err(dev, "AC firmware update failed, error=%d\n", error); - goto exit; - } - - dev_dbg(dev, "Application firmware written\n"); - - /* This may not succeed on first try, so re-try a few times. */ - for (i = 0; i < 5; i++) { - error = ili251x_switch_ic_mode(client, REG_SET_MODE_AP); - if (!error) - break; - } - - if (error) - goto exit; - - dev_dbg(dev, "IC is now in Application mode\n"); - - error = ili251x_firmware_update_cached_state(dev); - if (error) - goto exit; - - error = count; - -exit: ili210x_hardware_reset(priv->reset_gpio); + dev_dbg(dev, "Firmware update ended, error=%i\n", error); + enable_irq(client->irq); - kvfree(fwbuf); - return error; + + return error ?: count; } static DEVICE_ATTR(firmware_update, 0200, NULL, ili210x_firmware_update_store); From 7c459517252ebbad515a0b6f972454962ca549e2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 9 Jun 2024 16:47:55 -0700 Subject: [PATCH 39/71] Input: ili210x - use guard notation when disabling and reenabling IRQ This makes the code more compact and error handling more robust. Link: https://lore.kernel.org/r/20240609234757.610273-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ili210x.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index d0713a27ad6a..b6d0c1463595 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -860,19 +860,17 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, * the touch controller to disable the IRQs during update, so we have * to do it this way here. */ - disable_irq(client->irq); + scoped_guard(disable_irq, &client->irq) { + dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname); - dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname); + ili210x_hardware_reset(priv->reset_gpio); - ili210x_hardware_reset(priv->reset_gpio); + error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); - error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); + ili210x_hardware_reset(priv->reset_gpio); - ili210x_hardware_reset(priv->reset_gpio); - - dev_dbg(dev, "Firmware update ended, error=%i\n", error); - - enable_irq(client->irq); + dev_dbg(dev, "Firmware update ended, error=%i\n", error); + } return error ?: count; } From 5f82c1e04721e7cd98e604eb4e58f0724d8e5a65 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Thu, 6 Jun 2024 23:02:48 -0700 Subject: [PATCH 40/71] Input: elan_i2c - do not leave interrupt disabled on suspend failure Make sure interrupts are not left disabled when we fail to suspend the touch controller. Fixes: 6696777c6506 ("Input: add driver for Elan I2C/SMbus touchpad") Link: https://lore.kernel.org/r/ZmKiiL-1wzKrhqBj@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elan_i2c_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index c2aec5c360b3..ce96513b34f6 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1356,6 +1356,8 @@ static int elan_suspend(struct device *dev) } err: + if (ret) + enable_irq(client->irq); mutex_unlock(&data->sysfs_mutex); return ret; } From c1a339001191e60f70c4da827569b3bb27500a9a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 28 Jun 2024 15:47:23 -0700 Subject: [PATCH 41/71] Input: cypress_ps2 - clean up setting reporting rate Casting an integer field containing desired rate to a pointer to bytes works on little endian architectures where the driver is used, but not a good practice. Use a temporary of proper type instead. Link: https://lore.kernel.org/r/20240628224728.2180126-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index c693130bef41..32b55b2b9b76 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -612,6 +612,7 @@ static psmouse_ret_t cypress_protocol_handler(struct psmouse *psmouse) static void cypress_set_rate(struct psmouse *psmouse, unsigned int rate) { struct cytp_data *cytp = psmouse->private; + u8 rate_param; if (rate >= 80) { psmouse->rate = 80; @@ -621,8 +622,8 @@ static void cypress_set_rate(struct psmouse *psmouse, unsigned int rate) cytp->mode &= ~CYTP_BIT_HIGH_RATE; } - ps2_command(&psmouse->ps2dev, (unsigned char *)&psmouse->rate, - PSMOUSE_CMD_SETRATE); + rate_param = (u8)rate; + ps2_command(&psmouse->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE); } static void cypress_disconnect(struct psmouse *psmouse) From e8688b93ce00230614406d189e8286315832469a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 28 Jun 2024 15:47:24 -0700 Subject: [PATCH 42/71] Input: cypress_ps2 - fix error handling when sending command fails Stop layering error handling in cypress_ps2_sendbyte() and simply pass on error code from ps2_sendbyte() and use it in the callers. This fixes mishandling of error condition in cypress_ps2_read_cmd_status() which expects errors to be negative. Reported-by: Igor Artemiev Link: https://lore.kernel.org/r/20240628224728.2180126-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 32 +++++++++++++++---------------- drivers/input/mouse/cypress_ps2.h | 6 ------ 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 32b55b2b9b76..fcc3921e49e0 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -38,15 +38,14 @@ static const unsigned char cytp_resolution[] = {0x00, 0x01, 0x02, 0x03}; static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value) { struct ps2dev *ps2dev = &psmouse->ps2dev; + int error; - if (ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT) < 0) { + error = ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT); + if (error) { psmouse_dbg(psmouse, - "sending command 0x%02x failed, resp 0x%02x\n", - value & 0xff, ps2dev->nak); - if (ps2dev->nak == CYTP_PS2_RETRY) - return CYTP_PS2_RETRY; - else - return CYTP_PS2_ERROR; + "sending command 0x%02x failed, resp 0x%02x, error %d\n", + value & 0xff, ps2dev->nak, error); + return error; } #ifdef CYTP_DEBUG_VERBOSE @@ -73,21 +72,20 @@ static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, * to make the device return to the ready state. */ rc = cypress_ps2_sendbyte(psmouse, cmd & 0xff); - if (rc == CYTP_PS2_RETRY) { + if (rc == -EAGAIN) { rc = cypress_ps2_sendbyte(psmouse, 0x00); - if (rc == CYTP_PS2_RETRY) + if (rc == -EAGAIN) rc = cypress_ps2_sendbyte(psmouse, 0x0a); } - if (rc == CYTP_PS2_ERROR) - continue; - rc = cypress_ps2_sendbyte(psmouse, data); - if (rc == CYTP_PS2_RETRY) + if (!rc) { rc = cypress_ps2_sendbyte(psmouse, data); - if (rc == CYTP_PS2_ERROR) - continue; - else - break; + if (rc == -EAGAIN) + rc = cypress_ps2_sendbyte(psmouse, data); + + if (!rc) + break; + } } while (--tries > 0); ps2_end_command(ps2dev); diff --git a/drivers/input/mouse/cypress_ps2.h b/drivers/input/mouse/cypress_ps2.h index bb4979d06bf9..47d538a49089 100644 --- a/drivers/input/mouse/cypress_ps2.h +++ b/drivers/input/mouse/cypress_ps2.h @@ -72,12 +72,6 @@ #define CYTP_DATA_TIMEOUT 30 #define CYTP_EXT_CMD 0xe8 -#define CYTP_PS2_RETRY 0xfe -#define CYTP_PS2_ERROR 0xfc - -#define CYTP_RESP_RETRY 0x01 -#define CYTP_RESP_ERROR 0xfe - #define CYTP_105001_WIDTH 97 /* Dell XPS 13 */ #define CYTP_105001_HIGH 59 From 8bccf667f62a2351fd0b2a2fe5ba90806702c048 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 28 Jun 2024 15:47:25 -0700 Subject: [PATCH 43/71] Input: cypress_ps2 - report timeouts when reading command status Report -ETIMEDOUT error code from cypress_ps2_read_cmd_status() when device does not send enough data within the allotted time in response to a command. Link: https://lore.kernel.org/r/20240628224728.2180126-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index fcc3921e49e0..8e17cd0bc437 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -115,9 +115,12 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, if (rc < 0) goto out; - wait_event_timeout(ps2dev->wait, - (psmouse->pktcnt >= pktsize), - msecs_to_jiffies(CYTP_CMD_TIMEOUT)); + if (!wait_event_timeout(ps2dev->wait, + psmouse->pktcnt >= pktsize, + msecs_to_jiffies(CYTP_CMD_TIMEOUT))) { + rc = -ETIMEDOUT; + goto out; + } memcpy(param, psmouse->packet, pktsize); From 93f25f92fc7dda195c3a7ec38d6bc67c1cbed2c6 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 28 Jun 2024 15:47:26 -0700 Subject: [PATCH 44/71] Input: cypress_ps2 - propagate errors from lower layers Do not override errors reported by lower layers with generic "-1", but propagate them to the callers. Change the checks for errors to be in the form of "if (error)" to maintain consistency. Link: https://lore.kernel.org/r/20240628224728.2180126-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 62 +++++++++++++++++-------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 8e17cd0bc437..87b87f14e749 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -97,10 +97,10 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, unsigned char cmd, unsigned char *param) { - int rc; struct ps2dev *ps2dev = &psmouse->ps2dev; enum psmouse_state old_state; int pktsize; + int rc; ps2_begin_command(ps2dev); @@ -112,7 +112,7 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, memset(param, 0, pktsize); rc = cypress_ps2_sendbyte(psmouse, 0xe9); - if (rc < 0) + if (rc) goto out; if (!wait_event_timeout(ps2dev->wait, @@ -322,15 +322,15 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse) static int cypress_query_hardware(struct psmouse *psmouse) { - int ret; + int error; - ret = cypress_read_fw_version(psmouse); - if (ret) - return ret; + error = cypress_read_fw_version(psmouse); + if (error) + return error; - ret = cypress_read_tp_metrics(psmouse); - if (ret) - return ret; + error = cypress_read_tp_metrics(psmouse); + if (error) + return error; return 0; } @@ -339,9 +339,12 @@ static int cypress_set_absolute_mode(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; unsigned char param[3]; + int error; - if (cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE, param) < 0) - return -1; + error = cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE, + param); + if (error) + return error; cytp->mode = (cytp->mode & ~CYTP_BIT_ABS_REL_MASK) | CYTP_BIT_ABS_PRESSURE; @@ -366,7 +369,7 @@ static void cypress_reset(struct psmouse *psmouse) static int cypress_set_input_params(struct input_dev *input, struct cytp_data *cytp) { - int ret; + int error; if (!cytp->tp_res_x || !cytp->tp_res_y) return -EINVAL; @@ -383,10 +386,10 @@ static int cypress_set_input_params(struct input_dev *input, input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cytp->tp_max_abs_y, 0, 0); input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0); - ret = input_mt_init_slots(input, CYTP_MAX_MT_SLOTS, - INPUT_MT_DROP_UNUSED|INPUT_MT_TRACK); - if (ret < 0) - return ret; + error = input_mt_init_slots(input, CYTP_MAX_MT_SLOTS, + INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); + if (error) + return error; __set_bit(INPUT_PROP_SEMI_MT, input->propbit); @@ -637,21 +640,22 @@ static void cypress_disconnect(struct psmouse *psmouse) static int cypress_reconnect(struct psmouse *psmouse) { int tries = CYTP_PS2_CMD_TRIES; - int rc; + int error; do { cypress_reset(psmouse); - rc = cypress_detect(psmouse, false); - } while (rc && (--tries > 0)); + error = cypress_detect(psmouse, false); + } while (error && (--tries > 0)); - if (rc) { + if (error) { psmouse_err(psmouse, "Reconnect: unable to detect trackpad.\n"); - return -1; + return error; } - if (cypress_set_absolute_mode(psmouse)) { + error = cypress_set_absolute_mode(psmouse); + if (error) { psmouse_err(psmouse, "Reconnect: Unable to initialize Cypress absolute mode.\n"); - return -1; + return error; } return 0; @@ -660,6 +664,7 @@ static int cypress_reconnect(struct psmouse *psmouse) int cypress_init(struct psmouse *psmouse) { struct cytp_data *cytp; + int error; cytp = kzalloc(sizeof(*cytp), GFP_KERNEL); if (!cytp) @@ -670,17 +675,20 @@ int cypress_init(struct psmouse *psmouse) cypress_reset(psmouse); - if (cypress_query_hardware(psmouse)) { + error = cypress_query_hardware(psmouse); + if (error) { psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); goto err_exit; } - if (cypress_set_absolute_mode(psmouse)) { + error = cypress_set_absolute_mode(psmouse); + if (error) { psmouse_err(psmouse, "init: Unable to initialize Cypress absolute mode.\n"); goto err_exit; } - if (cypress_set_input_params(psmouse->dev, cytp) < 0) { + error = cypress_set_input_params(psmouse->dev, cytp); + if (error) { psmouse_err(psmouse, "init: Unable to set input params.\n"); goto err_exit; } @@ -705,5 +713,5 @@ int cypress_init(struct psmouse *psmouse) psmouse->private = NULL; kfree(cytp); - return -1; + return error; } From 5e13bea78df88c7185ce2f06645a7e4d8a2ba042 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 28 Jun 2024 15:47:27 -0700 Subject: [PATCH 45/71] Input: cypress_ps2 - use u8 when dealing with byte data When dealing with byte data use u8 instead of unsigned char or int. Stop layering error handling in cypress_ps2_sendbyte() and simply pass on error code from ps2_sendbyte(). Additionally use u8 instead of unisgned char throughout the code. Link: https://lore.kernel.org/r/20240628224728.2180126-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 76 ++++++++++++++----------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 87b87f14e749..b3c34ebcc4ef 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -32,32 +32,30 @@ static void cypress_set_packet_size(struct psmouse *psmouse, unsigned int n) cytp->pkt_size = n; } -static const unsigned char cytp_rate[] = {10, 20, 40, 60, 100, 200}; -static const unsigned char cytp_resolution[] = {0x00, 0x01, 0x02, 0x03}; +static const u8 cytp_rate[] = {10, 20, 40, 60, 100, 200}; +static const u8 cytp_resolution[] = {0x00, 0x01, 0x02, 0x03}; -static int cypress_ps2_sendbyte(struct psmouse *psmouse, int value) +static int cypress_ps2_sendbyte(struct psmouse *psmouse, u8 cmd) { struct ps2dev *ps2dev = &psmouse->ps2dev; int error; - error = ps2_sendbyte(ps2dev, value & 0xff, CYTP_CMD_TIMEOUT); + error = ps2_sendbyte(ps2dev, cmd, CYTP_CMD_TIMEOUT); if (error) { psmouse_dbg(psmouse, "sending command 0x%02x failed, resp 0x%02x, error %d\n", - value & 0xff, ps2dev->nak, error); + cmd, ps2dev->nak, error); return error; } #ifdef CYTP_DEBUG_VERBOSE - psmouse_dbg(psmouse, "sending command 0x%02x succeeded, resp 0xfa\n", - value & 0xff); + psmouse_dbg(psmouse, "sending command 0x%02x succeeded\n", cmd); #endif return 0; } -static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, - unsigned char data) +static int cypress_ps2_ext_cmd(struct psmouse *psmouse, u8 prefix, u8 nibble) { struct ps2dev *ps2dev = &psmouse->ps2dev; int tries = CYTP_PS2_CMD_TRIES; @@ -71,7 +69,7 @@ static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, * If sending the command fails, send recovery command * to make the device return to the ready state. */ - rc = cypress_ps2_sendbyte(psmouse, cmd & 0xff); + rc = cypress_ps2_sendbyte(psmouse, prefix); if (rc == -EAGAIN) { rc = cypress_ps2_sendbyte(psmouse, 0x00); if (rc == -EAGAIN) @@ -79,9 +77,9 @@ static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, } if (!rc) { - rc = cypress_ps2_sendbyte(psmouse, data); + rc = cypress_ps2_sendbyte(psmouse, nibble); if (rc == -EAGAIN) - rc = cypress_ps2_sendbyte(psmouse, data); + rc = cypress_ps2_sendbyte(psmouse, nibble); if (!rc) break; @@ -94,8 +92,7 @@ static int cypress_ps2_ext_cmd(struct psmouse *psmouse, unsigned short cmd, } static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, - unsigned char cmd, - unsigned char *param) + u8 cmd, u8 *param) { struct ps2dev *ps2dev = &psmouse->ps2dev; enum psmouse_state old_state; @@ -111,7 +108,7 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, pktsize = (cmd == CYTP_CMD_READ_TP_METRICS) ? 8 : 3; memset(param, 0, pktsize); - rc = cypress_ps2_sendbyte(psmouse, 0xe9); + rc = cypress_ps2_sendbyte(psmouse, PSMOUSE_CMD_GETINFO & 0xff); if (rc) goto out; @@ -136,8 +133,7 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, return rc; } -static bool cypress_verify_cmd_state(struct psmouse *psmouse, - unsigned char cmd, unsigned char *param) +static bool cypress_verify_cmd_state(struct psmouse *psmouse, u8 cmd, u8* param) { bool rate_match = false; bool resolution_match = false; @@ -167,31 +163,24 @@ static bool cypress_verify_cmd_state(struct psmouse *psmouse, return false; } -static int cypress_send_ext_cmd(struct psmouse *psmouse, unsigned char cmd, - unsigned char *param) +static int cypress_send_ext_cmd(struct psmouse *psmouse, u8 cmd, u8 *param) { + u8 cmd_prefix = PSMOUSE_CMD_SETRES & 0xff; int tries = CYTP_PS2_CMD_TRIES; - int rc; + int error; psmouse_dbg(psmouse, "send extension cmd 0x%02x, [%d %d %d %d]\n", cmd, DECODE_CMD_AA(cmd), DECODE_CMD_BB(cmd), DECODE_CMD_CC(cmd), DECODE_CMD_DD(cmd)); do { - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_DD(cmd)); - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_CC(cmd)); - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_BB(cmd)); - cypress_ps2_ext_cmd(psmouse, - PSMOUSE_CMD_SETRES, DECODE_CMD_AA(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_DD(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_CC(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_BB(cmd)); + cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_AA(cmd)); - rc = cypress_ps2_read_cmd_status(psmouse, cmd, param); - if (rc) - continue; - - if (cypress_verify_cmd_state(psmouse, cmd, param)) + error = cypress_ps2_read_cmd_status(psmouse, cmd, param); + if (!error && cypress_verify_cmd_state(psmouse, cmd, param)) return 0; } while (--tries > 0); @@ -201,7 +190,7 @@ static int cypress_send_ext_cmd(struct psmouse *psmouse, unsigned char cmd, int cypress_detect(struct psmouse *psmouse, bool set_properties) { - unsigned char param[3]; + u8 param[3]; if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param)) return -ENODEV; @@ -221,7 +210,7 @@ int cypress_detect(struct psmouse *psmouse, bool set_properties) static int cypress_read_fw_version(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; - unsigned char param[3]; + u8 param[3]; if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param)) return -ENODEV; @@ -250,7 +239,7 @@ static int cypress_read_fw_version(struct psmouse *psmouse) static int cypress_read_tp_metrics(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; - unsigned char param[8]; + u8 param[8]; /* set default values for tp metrics. */ cytp->tp_width = CYTP_DEFAULT_WIDTH; @@ -338,7 +327,7 @@ static int cypress_query_hardware(struct psmouse *psmouse) static int cypress_set_absolute_mode(struct psmouse *psmouse) { struct cytp_data *cytp = psmouse->private; - unsigned char param[3]; + u8 param[3]; int error; error = cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE, @@ -418,9 +407,9 @@ static int cypress_set_input_params(struct input_dev *input, return 0; } -static int cypress_get_finger_count(unsigned char header_byte) +static int cypress_get_finger_count(u8 header_byte) { - unsigned char bits6_7; + u8 bits6_7; int finger_count; bits6_7 = header_byte >> 6; @@ -445,10 +434,11 @@ static int cypress_get_finger_count(unsigned char header_byte) static int cypress_parse_packet(struct psmouse *psmouse, - struct cytp_data *cytp, struct cytp_report_data *report_data) + struct cytp_data *cytp, + struct cytp_report_data *report_data) { - unsigned char *packet = psmouse->packet; - unsigned char header_byte = packet[0]; + u8 *packet = psmouse->packet; + u8 header_byte = packet[0]; memset(report_data, 0, sizeof(struct cytp_report_data)); @@ -563,7 +553,7 @@ static psmouse_ret_t cypress_validate_byte(struct psmouse *psmouse) { int contact_cnt; int index = psmouse->pktcnt - 1; - unsigned char *packet = psmouse->packet; + u8 *packet = psmouse->packet; struct cytp_data *cytp = psmouse->private; if (index < 0 || index > cytp->pkt_size) From 366d586684701ee23c1e891664422be64c981c1a Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Fri, 5 Jul 2024 19:38:50 +0200 Subject: [PATCH 46/71] Input: qt1050 - constify struct regmap_config `qt1050_regmap_config` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco Link: https://lore.kernel.org/r/20240705-input-const-regmap_config-v1-1-f712a4494883@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/qt1050.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/keyboard/qt1050.c b/drivers/input/keyboard/qt1050.c index 056e9bc26026..5a2592e6293d 100644 --- a/drivers/input/keyboard/qt1050.c +++ b/drivers/input/keyboard/qt1050.c @@ -208,7 +208,7 @@ static const struct regmap_access_table qt1050_writeable_table = { .n_yes_ranges = ARRAY_SIZE(qt1050_writeable_ranges), }; -static struct regmap_config qt1050_regmap_config = { +static const struct regmap_config qt1050_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = QT1050_RES_CAL, From f275b3ae3aeef8831290ecce4156a365fea13737 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Fri, 5 Jul 2024 19:38:51 +0200 Subject: [PATCH 47/71] Input: fsl-imx25-tcq - constify struct regmap_config `mx25_tcq_regconfig` is not modified and can be declared as const to move its data to a read-only section. Signed-off-by: Javier Carrasco Link: https://lore.kernel.org/r/20240705-input-const-regmap_config-v1-2-f712a4494883@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/fsl-imx25-tcq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/fsl-imx25-tcq.c b/drivers/input/touchscreen/fsl-imx25-tcq.c index 60a7246c5157..a32708652d10 100644 --- a/drivers/input/touchscreen/fsl-imx25-tcq.c +++ b/drivers/input/touchscreen/fsl-imx25-tcq.c @@ -38,7 +38,7 @@ struct mx25_tcq_priv { struct device *dev; }; -static struct regmap_config mx25_tcq_regconfig = { +static const struct regmap_config mx25_tcq_regconfig = { .fast_io = true, .max_register = 0x5c, .reg_bits = 32, From 3b42b9ade16bfb758dd581cdbf39e4f7d1233ac6 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Wed, 12 Jun 2024 10:07:11 -0500 Subject: [PATCH 48/71] dt-bindings: input: ti,nspire-keypad: convert to YAML format Convert TI-NSPIRE Keypad controller bindings to DT schema. Signed-off-by: Andrew Davis Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20240612150711.26706-1-afd@ti.com Signed-off-by: Dmitry Torokhov --- .../bindings/input/ti,nspire-keypad.txt | 60 --------------- .../bindings/input/ti,nspire-keypad.yaml | 74 +++++++++++++++++++ 2 files changed, 74 insertions(+), 60 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/ti,nspire-keypad.txt create mode 100644 Documentation/devicetree/bindings/input/ti,nspire-keypad.yaml diff --git a/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt b/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt deleted file mode 100644 index 513d94d6e899..000000000000 --- a/Documentation/devicetree/bindings/input/ti,nspire-keypad.txt +++ /dev/null @@ -1,60 +0,0 @@ -TI-NSPIRE Keypad - -Required properties: -- compatible: Compatible property value should be "ti,nspire-keypad". - -- reg: Physical base address of the peripheral and length of memory mapped - region. - -- interrupts: The interrupt number for the peripheral. - -- scan-interval: How often to scan in us. Based on a APB speed of 33MHz, the - maximum and minimum delay time is ~2000us and ~500us respectively - -- row-delay: How long to wait before scanning each row. - -- clocks: The clock this peripheral is attached to. - -- linux,keymap: The keymap to use - (see Documentation/devicetree/bindings/input/matrix-keymap.txt) - -Optional properties: -- active-low: Specify that the keypad is active low (i.e. logical low signifies - a key press). - -Example: - -input { - compatible = "ti,nspire-keypad"; - reg = <0x900E0000 0x1000>; - interrupts = <16>; - - scan-interval = <1000>; - row-delay = <200>; - - clocks = <&apb_pclk>; - - linux,keymap = < - 0x0000001c 0x0001001c 0x00040039 - 0x0005002c 0x00060015 0x0007000b - 0x0008000f 0x0100002d 0x01010011 - 0x0102002f 0x01030004 0x01040016 - 0x01050014 0x0106001f 0x01070002 - 0x010a006a 0x02000013 0x02010010 - 0x02020019 0x02030007 0x02040018 - 0x02050031 0x02060032 0x02070005 - 0x02080028 0x0209006c 0x03000026 - 0x03010025 0x03020024 0x0303000a - 0x03040017 0x03050023 0x03060022 - 0x03070008 0x03080035 0x03090069 - 0x04000021 0x04010012 0x04020020 - 0x0404002e 0x04050030 0x0406001e - 0x0407000d 0x04080037 0x04090067 - 0x05010038 0x0502000c 0x0503001b - 0x05040034 0x0505001a 0x05060006 - 0x05080027 0x0509000e 0x050a006f - 0x0600002b 0x0602004e 0x06030068 - 0x06040003 0x0605006d 0x06060009 - 0x06070001 0x0609000f 0x0708002a - 0x0709001d 0x070a0033 >; -}; diff --git a/Documentation/devicetree/bindings/input/ti,nspire-keypad.yaml b/Documentation/devicetree/bindings/input/ti,nspire-keypad.yaml new file mode 100644 index 000000000000..ed3cfff13add --- /dev/null +++ b/Documentation/devicetree/bindings/input/ti,nspire-keypad.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/ti,nspire-keypad.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI-NSPIRE Keypad + +maintainers: + - Andrew Davis + +allOf: + - $ref: input.yaml# + - $ref: matrix-keymap.yaml# + +properties: + compatible: + enum: + - ti,nspire-keypad + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + scan-interval: + $ref: /schemas/types.yaml#/definitions/uint32 + description: How often to scan in us. Based on a APB speed of 33MHz, the + maximum and minimum delay time is ~2000us and ~500us respectively + + row-delay: + $ref: /schemas/types.yaml#/definitions/uint32 + description: How long to wait between scanning each row in us. + + active-low: + description: Specify that the keypad is active low. + +required: + - compatible + - reg + - interrupts + - clocks + - scan-interval + - row-delay + - linux,keymap + +unevaluatedProperties: false + +examples: + - | + #include + keypad@900e0000 { + compatible = "ti,nspire-keypad"; + reg = <0x900e0000 0x1000>; + interrupts = <16>; + + clocks = <&apb_pclk>; + + scan-interval = <1000>; + row-delay = <200>; + + linux,keymap = < + MATRIX_KEY(0, 0, KEY_ENTER) + MATRIX_KEY(0, 1, KEY_ENTER) + MATRIX_KEY(0, 4, KEY_SPACE) + MATRIX_KEY(0, 5, KEY_Z) + MATRIX_KEY(0, 6, KEY_Y) + MATRIX_KEY(0, 7, KEY_0) + >; + }; From ff2f28c7714130db5ebb31e616c8b03bbdc500c8 Mon Sep 17 00:00:00 2001 From: Raymond Hackley Date: Thu, 13 Jun 2024 02:56:54 +0000 Subject: [PATCH 49/71] Input: imagis - clarify the usage of protocol_b protocol_b is a property, which tells Imagis panel to use a different format for coordinates. IST30XXC series is known for using protocol B, while the other series aren't. Note this could be confusing, unlike the model name implies. Adjust the usage of protocol_b to avoid confusion. Signed-off-by: Raymond Hackley Link: https://lore.kernel.org/r/20240613025631.5425-2-raymondhackley@protonmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/imagis.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/imagis.c b/drivers/input/touchscreen/imagis.c index 074dd6c342ec..886bcfc8497a 100644 --- a/drivers/input/touchscreen/imagis.c +++ b/drivers/input/touchscreen/imagis.c @@ -120,12 +120,12 @@ static irqreturn_t imagis_interrupt(int irq, void *dev_id) for (i = 0; i < finger_count; i++) { if (ts->tdata->protocol_b) - error = imagis_i2c_read_reg(ts, - ts->tdata->touch_coord_cmd, &finger_status); - else error = imagis_i2c_read_reg(ts, ts->tdata->touch_coord_cmd + (i * 4), &finger_status); + else + error = imagis_i2c_read_reg(ts, + ts->tdata->touch_coord_cmd, &finger_status); if (error) { dev_err(&ts->client->dev, "failed to read coordinates for finger %d: %d\n", @@ -394,6 +394,7 @@ static const struct imagis_properties imagis_3032c_data = { .whoami_cmd = IST3038C_REG_CHIPID, .whoami_val = IST3032C_WHOAMI, .touch_keys_supported = true, + .protocol_b = true, }; static const struct imagis_properties imagis_3038b_data = { @@ -401,7 +402,6 @@ static const struct imagis_properties imagis_3038b_data = { .touch_coord_cmd = IST3038B_REG_STATUS, .whoami_cmd = IST3038B_REG_CHIPID, .whoami_val = IST3038B_WHOAMI, - .protocol_b = true, }; static const struct imagis_properties imagis_3038c_data = { @@ -409,6 +409,7 @@ static const struct imagis_properties imagis_3038c_data = { .touch_coord_cmd = IST3038C_REG_TOUCH_COORD, .whoami_cmd = IST3038C_REG_CHIPID, .whoami_val = IST3038C_WHOAMI, + .protocol_b = true, }; #ifdef CONFIG_OF From 72d45b66587aefdb192ba4e8667ce4ce669cc9de Mon Sep 17 00:00:00 2001 From: Raymond Hackley Date: Thu, 13 Jun 2024 02:57:03 +0000 Subject: [PATCH 50/71] dt-bindings: input/touchscreen: imagis: Document ist3038 Imagis IST3038 is a variant of Imagis touchscreen IC. Document it in imagis,ist3038c bindings. Signed-off-by: Raymond Hackley Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240613025631.5425-3-raymondhackley@protonmail.com Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml b/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml index 77ba280b3bdc..e24cbd960993 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml @@ -16,6 +16,7 @@ properties: compatible: enum: - imagis,ist3032c + - imagis,ist3038 - imagis,ist3038b - imagis,ist3038c From 1e48ee99f603000688ea8d65ef7e58627bb4c8d1 Mon Sep 17 00:00:00 2001 From: Raymond Hackley Date: Thu, 13 Jun 2024 02:57:11 +0000 Subject: [PATCH 51/71] Input: imagis - add supports for Imagis IST3038 Imagis IST3038 is another variant of Imagis IST3038 IC, which has a different register interface from IST3038C (possibly firmware defined). Unlike IST3038C/IST3032C, IST3038 has different registers for commands, which means IST3038 doesn't use protocol B. Similar to IST3032C and maybe the other variants, IST3038 has touch keys support, which provides KEY_APPSELECT and KEY_BACK. Add support for IST3038 with touch keys. Signed-off-by: Raymond Hackley Link: https://lore.kernel.org/r/20240613025631.5425-4-raymondhackley@protonmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/imagis.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/imagis.c b/drivers/input/touchscreen/imagis.c index 886bcfc8497a..aeabf8d057de 100644 --- a/drivers/input/touchscreen/imagis.c +++ b/drivers/input/touchscreen/imagis.c @@ -12,9 +12,17 @@ #include #include -#define IST3032C_WHOAMI 0x32c +#define IST30XX_REG_STATUS 0x20 +#define IST30XX_REG_CHIPID (0x40000000 | IST3038C_DIRECT_ACCESS) + +#define IST30XX_WHOAMI 0x30003000 +#define IST30XXA_WHOAMI 0x300a300a +#define IST30XXB_WHOAMI 0x300b300b +#define IST3038_WHOAMI 0x30383038 + +#define IST3032C_WHOAMI 0x32c +#define IST3038C_WHOAMI 0x38c -#define IST3038B_REG_STATUS 0x20 #define IST3038B_REG_CHIPID 0x30 #define IST3038B_WHOAMI 0x30380b @@ -25,7 +33,6 @@ #define IST3038C_REG_TOUCH_STATUS (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS) #define IST3038C_REG_TOUCH_COORD (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x8) #define IST3038C_REG_INTR_MESSAGE (IST3038C_REG_HIB_BASE | IST3038C_HIB_ACCESS | 0x4) -#define IST3038C_WHOAMI 0x38c #define IST3038C_CHIP_ON_DELAY_MS 60 #define IST3038C_I2C_RETRY_COUNT 3 #define IST3038C_MAX_FINGER_NUM 10 @@ -397,9 +404,17 @@ static const struct imagis_properties imagis_3032c_data = { .protocol_b = true, }; +static const struct imagis_properties imagis_3038_data = { + .interrupt_msg_cmd = IST30XX_REG_STATUS, + .touch_coord_cmd = IST30XX_REG_STATUS, + .whoami_cmd = IST30XX_REG_CHIPID, + .whoami_val = IST3038_WHOAMI, + .touch_keys_supported = true, +}; + static const struct imagis_properties imagis_3038b_data = { - .interrupt_msg_cmd = IST3038B_REG_STATUS, - .touch_coord_cmd = IST3038B_REG_STATUS, + .interrupt_msg_cmd = IST30XX_REG_STATUS, + .touch_coord_cmd = IST30XX_REG_STATUS, .whoami_cmd = IST3038B_REG_CHIPID, .whoami_val = IST3038B_WHOAMI, }; @@ -415,6 +430,7 @@ static const struct imagis_properties imagis_3038c_data = { #ifdef CONFIG_OF static const struct of_device_id imagis_of_match[] = { { .compatible = "imagis,ist3032c", .data = &imagis_3032c_data }, + { .compatible = "imagis,ist3038", .data = &imagis_3038_data }, { .compatible = "imagis,ist3038b", .data = &imagis_3038b_data }, { .compatible = "imagis,ist3038c", .data = &imagis_3038c_data }, { }, From b3d65108ac8abd79e0367d77598d539b117044a3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:48 -0700 Subject: [PATCH 52/71] Input: evdev - remove ->event() method Input core favors ->events() (batch) method over ->event() method if the former is defined, so there is no point in defining evdev_event() as it is never called. Remove it. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 51e0c4954600..05abcd45b5d4 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -308,17 +308,6 @@ static void evdev_events(struct input_handle *handle, rcu_read_unlock(); } -/* - * Pass incoming event to all connected clients. - */ -static void evdev_event(struct input_handle *handle, - unsigned int type, unsigned int code, int value) -{ - struct input_value vals[] = { { type, code, value } }; - - evdev_events(handle, vals, 1); -} - static int evdev_fasync(int fd, struct file *file, int on) { struct evdev_client *client = file->private_data; @@ -1418,7 +1407,6 @@ static const struct input_device_id evdev_ids[] = { MODULE_DEVICE_TABLE(input, evdev_ids); static struct input_handler evdev_handler = { - .event = evdev_event, .events = evdev_events, .connect = evdev_connect, .disconnect = evdev_disconnect, From a184cf98b1d4397fe7eca881da596059fea36a18 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:49 -0700 Subject: [PATCH 53/71] Input: make sure input handlers define only one processing method Input core expects input handlers to be either filters, or regular handlers, but not both. Additionally, for regular handlers it does not make sense to define both single event method and batch method. Refuse registering handler if it defines more than one method. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/input/input.c b/drivers/input/input.c index fd4997ba263c..7e4f8824f4fd 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -2517,6 +2517,26 @@ void input_unregister_device(struct input_dev *dev) } EXPORT_SYMBOL(input_unregister_device); +static int input_handler_check_methods(const struct input_handler *handler) +{ + int count = 0; + + if (handler->filter) + count++; + if (handler->events) + count++; + if (handler->event) + count++; + + if (count > 1) { + pr_err("%s: only one event processing method can be defined (%s)\n", + __func__, handler->name); + return -EINVAL; + } + + return 0; +} + /** * input_register_handler - register a new input handler * @handler: handler to be registered @@ -2530,6 +2550,10 @@ int input_register_handler(struct input_handler *handler) struct input_dev *dev; int error; + error = input_handler_check_methods(handler); + if (error) + return error; + error = mutex_lock_interruptible(&input_mutex); if (error) return error; From 14498e993fb77adce75f0106162902b2f8b1d480 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:50 -0700 Subject: [PATCH 54/71] Input: make events() method return number of events processed In preparation to consolidating filtering and event processing in the input core change events() method to return number of events processed by it. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 6 ++++-- include/linux/input.h | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 05abcd45b5d4..a8ce3d140722 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -288,8 +288,8 @@ static void evdev_pass_values(struct evdev_client *client, /* * Pass incoming events to all connected clients. */ -static void evdev_events(struct input_handle *handle, - const struct input_value *vals, unsigned int count) +static unsigned int evdev_events(struct input_handle *handle, + struct input_value *vals, unsigned int count) { struct evdev *evdev = handle->private; struct evdev_client *client; @@ -306,6 +306,8 @@ static void evdev_events(struct input_handle *handle, evdev_pass_values(client, vals, count, ev_time); rcu_read_unlock(); + + return count; } static int evdev_fasync(int fd, struct file *file, int on) diff --git a/include/linux/input.h b/include/linux/input.h index c22ac465254b..89a0be6ee0e2 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -275,7 +275,8 @@ struct input_handle; * it may not sleep * @events: event sequence handler. This method is being called by * input core with interrupts disabled and dev->event_lock - * spinlock held and so it may not sleep + * spinlock held and so it may not sleep. The method must return + * number of events passed to it. * @filter: similar to @event; separates normal event handlers from * "filters". * @match: called after comparing device's id with handler's id_table @@ -312,8 +313,8 @@ struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); - void (*events)(struct input_handle *handle, - const struct input_value *vals, unsigned int count); + unsigned int (*events)(struct input_handle *handle, + struct input_value *vals, unsigned int count); bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*match)(struct input_handler *handler, struct input_dev *dev); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); From d469647bafd9353730e0f74ec5fbefcd431c576b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:51 -0700 Subject: [PATCH 55/71] Input: simplify event handling logic Streamline event handling code by providing batch implementations for filtering and event processing and using them in place of the main event handler, as needed, instead of having complex branching logic in the middle of the event processing code. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 109 ++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 41 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 7e4f8824f4fd..40a04154f99d 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -99,45 +99,13 @@ static void input_stop_autorepeat(struct input_dev *dev) del_timer(&dev->timer); } -/* - * Pass event first through all filters and then, if event has not been - * filtered out, through all open handles. This function is called with - * dev->event_lock held and interrupts disabled. - */ -static unsigned int input_to_handler(struct input_handle *handle, - struct input_value *vals, unsigned int count) -{ - struct input_handler *handler = handle->handler; - struct input_value *end = vals; - struct input_value *v; - - if (handler->filter) { - for (v = vals; v != vals + count; v++) { - if (handler->filter(handle, v->type, v->code, v->value)) - continue; - if (end != v) - *end = *v; - end++; - } - count = end - vals; - } - - if (!count) - return 0; - - if (handler->events) - handler->events(handle, vals, count); - else if (handler->event) - for (v = vals; v != vals + count; v++) - handler->event(handle, v->type, v->code, v->value); - - return count; -} - /* * Pass values first through all filters and then, if event has not been - * filtered out, through all open handles. This function is called with - * dev->event_lock held and interrupts disabled. + * filtered out, through all open handles. This order is achieved by placing + * filters at the head of the list of handles attached to the device, and + * placing regular handles at the tail of the list. + * + * This function is called with dev->event_lock held and interrupts disabled. */ static void input_pass_values(struct input_dev *dev, struct input_value *vals, unsigned int count) @@ -154,11 +122,12 @@ static void input_pass_values(struct input_dev *dev, handle = rcu_dereference(dev->grab); if (handle) { - count = input_to_handler(handle, vals, count); + count = handle->handler->events(handle, vals, count); } else { list_for_each_entry_rcu(handle, &dev->h_list, d_node) if (handle->open) { - count = input_to_handler(handle, vals, count); + count = handle->handler->events(handle, vals, + count); if (!count) break; } @@ -2537,6 +2506,57 @@ static int input_handler_check_methods(const struct input_handler *handler) return 0; } +/* + * An implementation of input_handler's events() method that simply + * invokes handler->event() method for each event one by one. + */ +static unsigned int input_handler_events_default(struct input_handle *handle, + struct input_value *vals, + unsigned int count) +{ + struct input_handler *handler = handle->handler; + struct input_value *v; + + for (v = vals; v != vals + count; v++) + handler->event(handle, v->type, v->code, v->value); + + return count; +} + +/* + * An implementation of input_handler's events() method that invokes + * handler->filter() method for each event one by one and removes events + * that were filtered out from the "vals" array. + */ +static unsigned int input_handler_events_filter(struct input_handle *handle, + struct input_value *vals, + unsigned int count) +{ + struct input_handler *handler = handle->handler; + struct input_value *end = vals; + struct input_value *v; + + for (v = vals; v != vals + count; v++) { + if (handler->filter(handle, v->type, v->code, v->value)) + continue; + if (end != v) + *end = *v; + end++; + } + + return end - vals; +} + +/* + * An implementation of input_handler's events() method that does nothing. + */ +static unsigned int input_handler_events_null(struct input_handle *handle, + struct input_value *vals, + unsigned int count) +{ + return count; +} + /** * input_register_handler - register a new input handler * @handler: handler to be registered @@ -2554,12 +2574,19 @@ int input_register_handler(struct input_handler *handler) if (error) return error; + INIT_LIST_HEAD(&handler->h_list); + + if (handler->filter) + handler->events = input_handler_events_filter; + else if (handler->event) + handler->events = input_handler_events_default; + else if (!handler->events) + handler->events = input_handler_events_null; + error = mutex_lock_interruptible(&input_mutex); if (error) return error; - INIT_LIST_HEAD(&handler->h_list); - list_add_tail(&handler->node, &input_handler_list); list_for_each_entry(dev, &input_dev_list, node) From 3544cf574a577d92111f0b29e6d649b7ea3210ed Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:52 -0700 Subject: [PATCH 56/71] Input: rearrange input_alloc_device() to prepare for preallocating of vals In preparation to have dev->vals memory pre-allocated rearrange code in input_alloc_device() so that it allows handling multiple points of failure. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-6-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 40a04154f99d..9981fdfaee9f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1982,21 +1982,28 @@ struct input_dev *input_allocate_device(void) struct input_dev *dev; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev) { - dev->dev.type = &input_dev_type; - dev->dev.class = &input_class; - device_initialize(&dev->dev); - mutex_init(&dev->mutex); - spin_lock_init(&dev->event_lock); - timer_setup(&dev->timer, NULL, 0); - INIT_LIST_HEAD(&dev->h_list); - INIT_LIST_HEAD(&dev->node); + if (!dev) + return NULL; - dev_set_name(&dev->dev, "input%lu", - (unsigned long)atomic_inc_return(&input_no)); + mutex_init(&dev->mutex); + spin_lock_init(&dev->event_lock); + timer_setup(&dev->timer, NULL, 0); + INIT_LIST_HEAD(&dev->h_list); + INIT_LIST_HEAD(&dev->node); - __module_get(THIS_MODULE); - } + dev->dev.type = &input_dev_type; + dev->dev.class = &input_class; + device_initialize(&dev->dev); + /* + * From this point on we can no longer simply "kfree(dev)", we need + * to use input_free_device() so that device core properly frees its + * resources associated with the input device. + */ + + dev_set_name(&dev->dev, "input%lu", + (unsigned long)atomic_inc_return(&input_no)); + + __module_get(THIS_MODULE); return dev; } From 0cd58773520584ccb4ce1eeebd8d43f1b27bb24a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:53 -0700 Subject: [PATCH 57/71] Input: preallocate memory to hold event values Preallocate memory for holding event values (input_dev->vals) so that there is no need to check if it was allocated or not in the event processing code. The amount of memory will be adjusted after input device has been fully set up upon registering device with the input core. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-7-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 61 +++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 9981fdfaee9f..4e12fa79883e 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -323,9 +323,6 @@ static void input_event_dispose(struct input_dev *dev, int disposition, if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event) dev->event(dev, type, code, value); - if (!dev->vals) - return; - if (disposition & INPUT_PASS_TO_HANDLERS) { struct input_value *v; @@ -1985,6 +1982,18 @@ struct input_dev *input_allocate_device(void) if (!dev) return NULL; + /* + * Start with space for SYN_REPORT + 7 EV_KEY/EV_MSC events + 2 spare, + * see input_estimate_events_per_packet(). We will tune the number + * when we register the device. + */ + dev->max_vals = 10; + dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); + if (!dev->vals) { + kfree(dev); + return NULL; + } + mutex_init(&dev->mutex); spin_lock_init(&dev->event_lock); timer_setup(&dev->timer, NULL, 0); @@ -2344,6 +2353,35 @@ bool input_device_enabled(struct input_dev *dev) } EXPORT_SYMBOL_GPL(input_device_enabled); +static int input_device_tune_vals(struct input_dev *dev) +{ + struct input_value *vals; + unsigned int packet_size; + unsigned int max_vals; + + packet_size = input_estimate_events_per_packet(dev); + if (dev->hint_events_per_packet < packet_size) + dev->hint_events_per_packet = packet_size; + + max_vals = dev->hint_events_per_packet + 2; + if (dev->max_vals >= max_vals) + return 0; + + vals = kcalloc(max_vals, sizeof(*vals), GFP_KERNEL); + if (!vals) + return -ENOMEM; + + spin_lock_irq(&dev->event_lock); + dev->max_vals = max_vals; + swap(dev->vals, vals); + spin_unlock_irq(&dev->event_lock); + + /* Because of swap() above, this frees the old vals memory */ + kfree(vals); + + return 0; +} + /** * input_register_device - register device with input core * @dev: device to be registered @@ -2371,7 +2409,6 @@ int input_register_device(struct input_dev *dev) { struct input_devres *devres = NULL; struct input_handler *handler; - unsigned int packet_size; const char *path; int error; @@ -2399,16 +2436,9 @@ int input_register_device(struct input_dev *dev) /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ input_cleanse_bitmasks(dev); - packet_size = input_estimate_events_per_packet(dev); - if (dev->hint_events_per_packet < packet_size) - dev->hint_events_per_packet = packet_size; - - dev->max_vals = dev->hint_events_per_packet + 2; - dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); - if (!dev->vals) { - error = -ENOMEM; + error = input_device_tune_vals(dev); + if (error) goto err_devres_free; - } /* * If delay and period are pre-set by the driver, then autorepeating @@ -2428,7 +2458,7 @@ int input_register_device(struct input_dev *dev) error = device_add(&dev->dev); if (error) - goto err_free_vals; + goto err_devres_free; path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); pr_info("%s as %s\n", @@ -2458,9 +2488,6 @@ int input_register_device(struct input_dev *dev) err_device_del: device_del(&dev->dev); -err_free_vals: - kfree(dev->vals); - dev->vals = NULL; err_devres_free: devres_free(devres); return error; From 735877fde06304ae9d90e17102dc2b139e8d802a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Jul 2024 14:37:54 -0700 Subject: [PATCH 58/71] Input: do not check number of events in input_pass_values() Now that the input_dev->vals array is always there we can be assured that input_pass_values() is always called with a non-0 number of events. Remove the check. Reviewed-by: Jeff LaBundy Reviewed-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20240703213756.3375978-8-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 4e12fa79883e..54c57b267b25 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -115,9 +115,6 @@ static void input_pass_values(struct input_dev *dev, lockdep_assert_held(&dev->event_lock); - if (!count) - return; - rcu_read_lock(); handle = rcu_dereference(dev->grab); From a742e61dbb7198b51af772c7b80ed81ed298a88f Mon Sep 17 00:00:00 2001 From: Felix Kaechele Date: Thu, 20 Jun 2024 10:50:02 -0400 Subject: [PATCH 59/71] dt-bindings: input: touchscreen: himax,hx83112b: add HX83100A Add a compatible string for the Himax HX83100A touch controller. The HX83100A presents touch events on the internal bus rather than offering a dedicated event register like the other chips in this family do. Signed-off-by: Felix Kaechele Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240620145019.156187-2-felix@kaechele.ca Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/touchscreen/himax,hx83112b.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml b/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml index f42b23d532eb..f5cfacb5e966 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml @@ -15,6 +15,7 @@ allOf: properties: compatible: enum: + - himax,hx83100a - himax,hx83112b reg: From 05eab5456b24230a30b65bcd6793937cb84d3de8 Mon Sep 17 00:00:00 2001 From: Felix Kaechele Date: Thu, 20 Jun 2024 10:50:03 -0400 Subject: [PATCH 60/71] Input: himax_hx83112b - use more descriptive register defines Himax uses an AHB-style bus to communicate with different parts of the display driver and touch controller system. Use more descriptive names for the register and address defines. The names were taken from a driver submission for the similar HX83102J chip. Signed-off-by: Felix Kaechele Link: https://lore.kernel.org/all/TY0PR06MB561105A3386E9D76F429110D9E0F2@TY0PR06MB5611.apcprd06.prod.outlook.com/ Link: https://lore.kernel.org/r/20240620145019.156187-3-felix@kaechele.ca Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/himax_hx83112b.c | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index bafabd06dabc..d6c4a68eac23 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -24,12 +24,14 @@ #define HIMAX_MAX_POINTS 10 -#define HIMAX_REG_CFG_SET_ADDR 0x00 -#define HIMAX_REG_CFG_INIT_READ 0x0c -#define HIMAX_REG_CFG_READ_VALUE 0x08 -#define HIMAX_REG_READ_EVENT 0x30 +#define HIMAX_AHB_ADDR_BYTE_0 0x00 +#define HIMAX_AHB_ADDR_RDATA_BYTE_0 0x08 +#define HIMAX_AHB_ADDR_ACCESS_DIRECTION 0x0c +#define HIMAX_AHB_ADDR_EVENT_STACK 0x30 -#define HIMAX_CFG_PRODUCT_ID 0x900000d0 +#define HIMAX_AHB_CMD_ACCESS_DIRECTION_READ 0x00 + +#define HIMAX_REG_ADDR_ICID 0x900000d0 #define HIMAX_INVALID_COORD 0xffff @@ -67,15 +69,16 @@ static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst) { int error; - error = regmap_write(ts->regmap, HIMAX_REG_CFG_SET_ADDR, address); + error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, address); if (error) return error; - error = regmap_write(ts->regmap, HIMAX_REG_CFG_INIT_READ, 0x0); + error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_ACCESS_DIRECTION, + HIMAX_AHB_CMD_ACCESS_DIRECTION_READ); if (error) return error; - error = regmap_read(ts->regmap, HIMAX_REG_CFG_READ_VALUE, dst); + error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0, dst); if (error) return error; @@ -101,7 +104,7 @@ static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id) { int error; - error = himax_read_config(ts, HIMAX_CFG_PRODUCT_ID, product_id); + error = himax_read_config(ts, HIMAX_REG_ADDR_ICID, product_id); if (error) return error; @@ -235,7 +238,7 @@ static int himax_handle_input(struct himax_ts_data *ts) int error; struct himax_event event; - error = regmap_raw_read(ts->regmap, HIMAX_REG_READ_EVENT, &event, + error = regmap_raw_read(ts->regmap, HIMAX_AHB_ADDR_EVENT_STACK, &event, sizeof(event)); if (error) { dev_err(&ts->client->dev, "Failed to read input event: %d\n", From 0944829d491e0f342924154d2e58c6b2e61e3595 Mon Sep 17 00:00:00 2001 From: Felix Kaechele Date: Thu, 20 Jun 2024 10:50:04 -0400 Subject: [PATCH 61/71] Input: himax_hx83112b - implement MCU register reading Implement reading from the MCU in a more universal fashion. This allows properly handling reads of more than 4 bytes using the AHB FIFO implemented in the chip. Signed-off-by: Felix Kaechele Link: https://lore.kernel.org/r/20240620145019.156187-4-felix@kaechele.ca Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/himax_hx83112b.c | 50 ++++++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index d6c4a68eac23..c9cc69bf242a 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -27,9 +27,13 @@ #define HIMAX_AHB_ADDR_BYTE_0 0x00 #define HIMAX_AHB_ADDR_RDATA_BYTE_0 0x08 #define HIMAX_AHB_ADDR_ACCESS_DIRECTION 0x0c +#define HIMAX_AHB_ADDR_INCR4 0x0d +#define HIMAX_AHB_ADDR_CONTI 0x13 #define HIMAX_AHB_ADDR_EVENT_STACK 0x30 #define HIMAX_AHB_CMD_ACCESS_DIRECTION_READ 0x00 +#define HIMAX_AHB_CMD_INCR4 0x10 +#define HIMAX_AHB_CMD_CONTI 0x31 #define HIMAX_REG_ADDR_ICID 0x900000d0 @@ -65,10 +69,34 @@ static const struct regmap_config himax_regmap_config = { .val_format_endian = REGMAP_ENDIAN_LITTLE, }; -static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst) +static int himax_bus_enable_burst(struct himax_ts_data *ts) { int error; + error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_CONTI, + HIMAX_AHB_CMD_CONTI); + if (error) + return error; + + error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_INCR4, + HIMAX_AHB_CMD_INCR4); + if (error) + return error; + + return 0; +} + +static int himax_bus_read(struct himax_ts_data *ts, u32 address, void *dst, + size_t length) +{ + int error; + + if (length > 4) { + error = himax_bus_enable_burst(ts); + if (error) + return error; + } + error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, address); if (error) return error; @@ -78,7 +106,23 @@ static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst) if (error) return error; - error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0, dst); + if (length > 4) + error = regmap_noinc_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0, + dst, length); + else + error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0, + dst); + if (error) + return error; + + return 0; +} + +static int himax_read_mcu(struct himax_ts_data *ts, u32 address, u32 *dst) +{ + int error; + + error = himax_bus_read(ts, address, dst, sizeof(dst)); if (error) return error; @@ -104,7 +148,7 @@ static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id) { int error; - error = himax_read_config(ts, HIMAX_REG_ADDR_ICID, product_id); + error = himax_read_mcu(ts, HIMAX_REG_ADDR_ICID, product_id); if (error) return error; From aa9007ed2d3880d41566625dd4df40886e4f45cb Mon Sep 17 00:00:00 2001 From: Felix Kaechele Date: Thu, 20 Jun 2024 10:50:05 -0400 Subject: [PATCH 62/71] Input: himax_hx83112b - add himax_chip struct for multi-chip support In preparation for HX83100A support allow defining separate functions for specific chip operations. Signed-off-by: Felix Kaechele Link: https://lore.kernel.org/r/20240620145019.156187-5-felix@kaechele.ca Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/himax_hx83112b.c | 51 +++++++++++++++------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index c9cc69bf242a..5092a357c332 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -20,8 +20,6 @@ #include #include -#define HIMAX_ID_83112B 0x83112b - #define HIMAX_MAX_POINTS 10 #define HIMAX_AHB_ADDR_BYTE_0 0x00 @@ -55,7 +53,16 @@ struct himax_event { static_assert(sizeof(struct himax_event) == 56); +struct himax_ts_data; +struct himax_chip { + u32 id; + int (*check_id)(struct himax_ts_data *ts); + int (*read_events)(struct himax_ts_data *ts, struct himax_event *event, + size_t length); +}; + struct himax_ts_data { + const struct himax_chip *chip; struct gpio_desc *gpiod_rst; struct input_dev *input_dev; struct i2c_client *client; @@ -167,15 +174,12 @@ static int himax_check_product_id(struct himax_ts_data *ts) dev_dbg(&ts->client->dev, "Product id: %x\n", product_id); - switch (product_id) { - case HIMAX_ID_83112B: + if (product_id == ts->chip->id) return 0; - default: - dev_err(&ts->client->dev, - "Unknown product id: %x\n", product_id); - return -EINVAL; - } + dev_err(&ts->client->dev, "Unknown product id: %x\n", + product_id); + return -EINVAL; } static int himax_input_register(struct himax_ts_data *ts) @@ -277,13 +281,19 @@ static bool himax_verify_checksum(struct himax_ts_data *ts, return true; } +static int himax_read_events(struct himax_ts_data *ts, + struct himax_event *event, size_t length) +{ + return regmap_raw_read(ts->regmap, HIMAX_AHB_ADDR_EVENT_STACK, event, + length); +} + static int himax_handle_input(struct himax_ts_data *ts) { int error; struct himax_event event; - error = regmap_raw_read(ts->regmap, HIMAX_AHB_ADDR_EVENT_STACK, &event, - sizeof(event)); + error = ts->chip->read_events(ts, &event, sizeof(event)); if (error) { dev_err(&ts->client->dev, "Failed to read input event: %d\n", error); @@ -329,6 +339,7 @@ static int himax_probe(struct i2c_client *client) i2c_set_clientdata(client, ts); ts->client = client; + ts->chip = i2c_get_match_data(client); ts->regmap = devm_regmap_init_i2c(client, &himax_regmap_config); error = PTR_ERR_OR_ZERO(ts->regmap); @@ -346,9 +357,11 @@ static int himax_probe(struct i2c_client *client) himax_reset(ts); - error = himax_check_product_id(ts); - if (error) - return error; + if (ts->chip->check_id) { + error = himax_check_product_id(ts); + if (error) + return error; + } error = himax_input_register(ts); if (error) @@ -381,15 +394,21 @@ static int himax_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume); +static const struct himax_chip hx83112b_chip = { + .id = 0x83112b, + .check_id = himax_check_product_id, + .read_events = himax_read_events, +}; + static const struct i2c_device_id himax_ts_id[] = { - { "hx83112b" }, + { "hx83112b", (kernel_ulong_t)&hx83112b_chip }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, himax_ts_id); #ifdef CONFIG_OF static const struct of_device_id himax_of_match[] = { - { .compatible = "himax,hx83112b" }, + { .compatible = "himax,hx83112b", .data = &hx83112b_chip }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, himax_of_match); From 5e91cef94426d71e3156864d52753ace4cee721a Mon Sep 17 00:00:00 2001 From: Felix Kaechele Date: Thu, 20 Jun 2024 10:50:06 -0400 Subject: [PATCH 63/71] Input: himax_hx83112b - add support for HX83100A The HX83100A is a bit of an outlier in the Himax HX831xxx series of touch controllers as it requires reading touch events through the AHB interface of the MCU rather than providing a dedicated FIFO address like the other chips do. This patch implements the specific read function and introduces the HX83100A chip with an appropriate i2c ID and DT compatible string. The HX83100A doesn't have a straightforward way to do chip identification, which is why it is not implemented in this patch. Tested on: Lenovo ThinkSmart View (CD-18781Y) / Innolux P080DDD-AB2 LCM Signed-off-by: Felix Kaechele Tested-by: Paul Gale Link: https://lore.kernel.org/r/20240620145019.156187-6-felix@kaechele.ca Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/himax_hx83112b.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/input/touchscreen/himax_hx83112b.c b/drivers/input/touchscreen/himax_hx83112b.c index 5092a357c332..9ed3bccde4ac 100644 --- a/drivers/input/touchscreen/himax_hx83112b.c +++ b/drivers/input/touchscreen/himax_hx83112b.c @@ -4,6 +4,9 @@ * * Copyright (C) 2022 Job Noorman * + * HX83100A support + * Copyright (C) 2024 Felix Kaechele + * * This code is based on "Himax Android Driver Sample Code for QCT platform": * * Copyright (C) 2017 Himax Corporation. @@ -35,6 +38,8 @@ #define HIMAX_REG_ADDR_ICID 0x900000d0 +#define HX83100A_REG_FW_EVENT_STACK 0x90060000 + #define HIMAX_INVALID_COORD 0xffff struct himax_event_point { @@ -288,6 +293,12 @@ static int himax_read_events(struct himax_ts_data *ts, length); } +static int hx83100a_read_events(struct himax_ts_data *ts, + struct himax_event *event, size_t length) +{ + return himax_bus_read(ts, HX83100A_REG_FW_EVENT_STACK, event, length); +}; + static int himax_handle_input(struct himax_ts_data *ts) { int error; @@ -394,6 +405,10 @@ static int himax_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume); +static const struct himax_chip hx83100a_chip = { + .read_events = hx83100a_read_events, +}; + static const struct himax_chip hx83112b_chip = { .id = 0x83112b, .check_id = himax_check_product_id, @@ -401,6 +416,7 @@ static const struct himax_chip hx83112b_chip = { }; static const struct i2c_device_id himax_ts_id[] = { + { "hx83100a", (kernel_ulong_t)&hx83100a_chip }, { "hx83112b", (kernel_ulong_t)&hx83112b_chip }, { /* sentinel */ } }; @@ -408,6 +424,7 @@ MODULE_DEVICE_TABLE(i2c, himax_ts_id); #ifdef CONFIG_OF static const struct of_device_id himax_of_match[] = { + { .compatible = "himax,hx83100a", .data = &hx83100a_chip }, { .compatible = "himax,hx83112b", .data = &hx83112b_chip }, { /* sentinel */ } }; From f48ecbd2ce1ca2b0c92843f67879b583b1f85cda Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 9 Jul 2024 17:04:35 -0700 Subject: [PATCH 64/71] Input: twl4030-pwrbutton - fix kernel-doc warning Do not use kernel-doc style for comment describing contents of the source file, as it trips the script: scripts/kernel-doc -none drivers/input/misc/twl4030-pwrbutton.c drivers/input/misc/twl4030-pwrbutton.c:2: info: Scanning doc for function twl4030 drivers/input/misc/twl4030-pwrbutton.c:33: warning: expecting prototype for twl4030(). Prototype was for PWR_PWRON_IRQ() instead 1 warnings Also remove file name from the same comment - it it not the best idea to have it as they tend to get stale when sources get moved or renamed. Reported-by: Mirsad Todorovac Tested-by: Mirsad Todorovac Link: https://lore.kernel.org/r/Zo3QE00GqCrA3M9b@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/twl4030-pwrbutton.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index e3ee0638ffba..f85cc289c053 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -1,5 +1,5 @@ -/** - * twl4030-pwrbutton.c - TWL4030 Power Button Input Driver +/* + * TWL4030 Power Button Input Driver * * Copyright (C) 2008-2009 Nokia Corporation * From 87d9d1e3eb5daa45764ea5a5f387ab8b337fcf88 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 10 Jul 2024 12:28:31 +0200 Subject: [PATCH 65/71] dt-bindings: input: touchscreen: exc3000: add EXC81W32 Add compatible for EXC81W32 touchscreen controllers. They use the same protocol and have the same resolution as EXC80H84. Signed-off-by: Philipp Zabel Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240710-input-exc3000-exc81w32-v3-1-4272183628b4@pengutronix.de Signed-off-by: Dmitry Torokhov --- .../bindings/input/touchscreen/eeti,exc3000.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml b/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml index 9dc25d30a0a8..1c7ae05a8c15 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml @@ -14,10 +14,14 @@ allOf: properties: compatible: - enum: - - eeti,exc3000 - - eeti,exc80h60 - - eeti,exc80h84 + oneOf: + - const: eeti,exc3000 + - const: eeti,exc80h60 + - const: eeti,exc80h84 + - items: + - enum: + - eeti,exc81w32 + - const: eeti,exc80h84 reg: const: 0x2a interrupts: From 8c98dddc233c233a35e56b49d5cd9e032d442300 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 10 Jul 2024 12:28:32 +0200 Subject: [PATCH 66/71] Input: exc3000 - add EXC81W32 support Add support for EXC81W32 controllers. Tested with firmware reported as type "PCAP81X32 Series", model "Orion_0183_1019", fw_version "8001280G". Signed-off-by: Philipp Zabel Link: https://lore.kernel.org/r/20240710-input-exc3000-exc81w32-v3-2-4272183628b4@pengutronix.de Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/exc3000.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/input/touchscreen/exc3000.c b/drivers/input/touchscreen/exc3000.c index a4030cc9ff60..2e77cfb63f32 100644 --- a/drivers/input/touchscreen/exc3000.c +++ b/drivers/input/touchscreen/exc3000.c @@ -53,6 +53,7 @@ enum eeti_dev_id { EETI_EXC3000, EETI_EXC80H60, EETI_EXC80H84, + EETI_EXC81W32, }; static struct eeti_dev_info exc3000_info[] = { @@ -68,6 +69,10 @@ static struct eeti_dev_info exc3000_info[] = { .name = "EETI EXC80H84 Touch Screen", .max_xy = SZ_16K - 1, }, + [EETI_EXC81W32] = { + .name = "EETI EXC81W32 Touch Screen", + .max_xy = SZ_16K - 1, + }, }; struct exc3000_data { @@ -441,6 +446,7 @@ static const struct i2c_device_id exc3000_id[] = { { "exc3000", EETI_EXC3000 }, { "exc80h60", EETI_EXC80H60 }, { "exc80h84", EETI_EXC80H84 }, + { "exc81w32", EETI_EXC81W32 }, { } }; MODULE_DEVICE_TABLE(i2c, exc3000_id); @@ -450,6 +456,7 @@ static const struct of_device_id exc3000_of_match[] = { { .compatible = "eeti,exc3000", .data = &exc3000_info[EETI_EXC3000] }, { .compatible = "eeti,exc80h60", .data = &exc3000_info[EETI_EXC80H60] }, { .compatible = "eeti,exc80h84", .data = &exc3000_info[EETI_EXC80H84] }, + { .compatible = "eeti,exc81w32", .data = &exc3000_info[EETI_EXC81W32] }, { } }; MODULE_DEVICE_TABLE(of, exc3000_of_match); From a122a6fd72d64de1e2f7521046823e25cb269f06 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 10 Jul 2024 21:49:12 -0700 Subject: [PATCH 67/71] Input: atmel_mxt_ts - use driver core to instantiate device attributes Instead of manually creating driver-specific device attributes, set struct driver->dev_groups pointer to have the driver core do it. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/Zo9kSFeGOZB9b3rq@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/atmel_mxt_ts.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 8a606bd441ae..cfc92157701f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3069,9 +3069,7 @@ static struct attribute *mxt_attrs[] = { NULL }; -static const struct attribute_group mxt_attr_group = { - .attrs = mxt_attrs, -}; +ATTRIBUTE_GROUPS(mxt); static void mxt_start(struct mxt_data *data) { @@ -3348,18 +3346,8 @@ static int mxt_probe(struct i2c_client *client) if (error) goto err_disable_regulators; - error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); - if (error) { - dev_err(&client->dev, "Failure %d creating sysfs group\n", - error); - goto err_free_object; - } - return 0; -err_free_object: - mxt_free_input_device(data); - mxt_free_object_table(data); err_disable_regulators: regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); @@ -3371,7 +3359,6 @@ static void mxt_remove(struct i2c_client *client) struct mxt_data *data = i2c_get_clientdata(client); disable_irq(data->irq); - sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); mxt_free_input_device(data); mxt_free_object_table(data); regulator_bulk_disable(ARRAY_SIZE(data->regulators), @@ -3455,6 +3442,7 @@ MODULE_DEVICE_TABLE(i2c, mxt_id); static struct i2c_driver mxt_driver = { .driver = { .name = "atmel_mxt_ts", + .dev_groups = mxt_groups, .of_match_table = mxt_of_match, .acpi_match_table = ACPI_PTR(mxt_acpi_id), .pm = pm_sleep_ptr(&mxt_pm_ops), From 2d7877d797aaa16b18ac156ed87fa0f23b9907c8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 10 Jul 2024 22:03:29 -0700 Subject: [PATCH 68/71] Input: omap-keypad - use driver core to instantiate device attributes Instead of manually creating driver-specific device attributes set struct driver->dev_groups pointer to have the driver core do it. This also fixes issue with the attribute not being deleted on driver unbind. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/Zo9nofWJ1xg9MgKs@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/omap-keypad.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 16f936db7305..57587541110b 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -171,6 +171,12 @@ static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, omap_kp_enable_show, omap_kp_enable_store); +static struct attribute *omap_kp_attrs[] = { + &dev_attr_enable.attr, + NULL +}; +ATTRIBUTE_GROUPS(omap_kp); + static int omap_kp_probe(struct platform_device *pdev) { struct omap_kp *omap_kp; @@ -214,10 +220,6 @@ static int omap_kp_probe(struct platform_device *pdev) kp_tasklet.data = (unsigned long) omap_kp; tasklet_enable(&kp_tasklet); - ret = device_create_file(&pdev->dev, &dev_attr_enable); - if (ret < 0) - goto err2; - /* setup input device */ input_dev->name = "omap-keypad"; input_dev->phys = "omap-keypad/input0"; @@ -235,12 +237,12 @@ static int omap_kp_probe(struct platform_device *pdev) pdata->rows, pdata->cols, omap_kp->keymap, input_dev); if (ret < 0) - goto err3; + goto err2; ret = input_register_device(omap_kp->input); if (ret < 0) { printk(KERN_ERR "Unable to register omap-keypad input device\n"); - goto err3; + goto err2; } if (pdata->dbounce) @@ -252,17 +254,15 @@ static int omap_kp_probe(struct platform_device *pdev) if (omap_kp->irq >= 0) { if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, "omap-keypad", omap_kp) < 0) - goto err4; + goto err3; } omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); return 0; -err4: +err3: input_unregister_device(omap_kp->input); input_dev = NULL; -err3: - device_remove_file(&pdev->dev, &dev_attr_enable); err2: kfree(omap_kp); input_free_device(input_dev); @@ -293,6 +293,7 @@ static struct platform_driver omap_kp_driver = { .remove_new = omap_kp_remove, .driver = { .name = "omap-keypad", + .dev_groups = omap_kp_groups, }, }; module_platform_driver(omap_kp_driver); From b20d6bf8014b2d6fcf65c150453d95a6276fd1fa Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 10 Jul 2024 16:59:36 -0700 Subject: [PATCH 69/71] Input: ati-remote2 - use driver core to instantiate device attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of manually creating driver-specific device attributes set struct usb_driver->dev_groups pointer to have the driver core do it. Reviewed-by: Ville Syrjälä Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/Zo8gaF_lKPAfcye1@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/ati_remote2.c | 50 +++++++++++--------------------- 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 946bf75aa106..795f69edb4b2 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -204,26 +204,7 @@ struct ati_remote2 { unsigned int mode_mask; }; -static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id); -static void ati_remote2_disconnect(struct usb_interface *interface); -static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message); -static int ati_remote2_resume(struct usb_interface *interface); -static int ati_remote2_reset_resume(struct usb_interface *interface); -static int ati_remote2_pre_reset(struct usb_interface *interface); -static int ati_remote2_post_reset(struct usb_interface *interface); - -static struct usb_driver ati_remote2_driver = { - .name = "ati_remote2", - .probe = ati_remote2_probe, - .disconnect = ati_remote2_disconnect, - .id_table = ati_remote2_id_table, - .suspend = ati_remote2_suspend, - .resume = ati_remote2_resume, - .reset_resume = ati_remote2_reset_resume, - .pre_reset = ati_remote2_pre_reset, - .post_reset = ati_remote2_post_reset, - .supports_autosuspend = 1, -}; +static struct usb_driver ati_remote2_driver; static int ati_remote2_submit_urbs(struct ati_remote2 *ar2) { @@ -791,10 +772,7 @@ static struct attribute *ati_remote2_attrs[] = { &dev_attr_mode_mask.attr, NULL, }; - -static struct attribute_group ati_remote2_attr_group = { - .attrs = ati_remote2_attrs, -}; +ATTRIBUTE_GROUPS(ati_remote2); static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) { @@ -861,13 +839,9 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name)); - r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); - if (r) - goto fail3; - r = ati_remote2_input_init(ar2); if (r) - goto fail4; + goto fail3; usb_set_intfdata(interface, ar2); @@ -875,8 +849,6 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d return 0; - fail4: - sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); fail3: ati_remote2_urb_cleanup(ar2); fail2: @@ -900,8 +872,6 @@ static void ati_remote2_disconnect(struct usb_interface *interface) input_unregister_device(ar2->idev); - sysfs_remove_group(&ar2->udev->dev.kobj, &ati_remote2_attr_group); - ati_remote2_urb_cleanup(ar2); usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); @@ -1032,4 +1002,18 @@ static int ati_remote2_post_reset(struct usb_interface *interface) return r; } +static struct usb_driver ati_remote2_driver = { + .name = "ati_remote2", + .probe = ati_remote2_probe, + .disconnect = ati_remote2_disconnect, + .dev_groups = ati_remote2_groups, + .id_table = ati_remote2_id_table, + .suspend = ati_remote2_suspend, + .resume = ati_remote2_resume, + .reset_resume = ati_remote2_reset_resume, + .pre_reset = ati_remote2_pre_reset, + .post_reset = ati_remote2_post_reset, + .supports_autosuspend = 1, +}; + module_usb_driver(ati_remote2_driver); From 295b89a631fe2935d268a95a9dea284992a7a27d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 10 Jul 2024 16:48:53 -0700 Subject: [PATCH 70/71] Input: yealink - use driver core to instantiate device attributes Instead of manually creating driver-specific device attributes set struct usb_driver->dev_groups pointer to have the driver core do it. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20240710234855.311366-1-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/yealink.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index c3221b960a75..435a46baad9d 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -771,7 +771,7 @@ static DEVICE_ATTR(show_icon , _M220, NULL , show_icon ); static DEVICE_ATTR(hide_icon , _M220, NULL , hide_icon ); static DEVICE_ATTR(ringtone , _M220, NULL , store_ringtone); -static struct attribute *yld_attributes[] = { +static struct attribute *yld_attrs[] = { &dev_attr_line1.attr, &dev_attr_line2.attr, &dev_attr_line3.attr, @@ -782,10 +782,7 @@ static struct attribute *yld_attributes[] = { &dev_attr_ringtone.attr, NULL }; - -static const struct attribute_group yld_attr_group = { - .attrs = yld_attributes -}; +ATTRIBUTE_GROUPS(yld); /******************************************************************************* * Linux interface and usb initialisation @@ -842,7 +839,6 @@ static void usb_disconnect(struct usb_interface *intf) down_write(&sysfs_rwsema); yld = usb_get_intfdata(intf); - sysfs_remove_group(&intf->dev.kobj, &yld_attr_group); usb_set_intfdata(intf, NULL); up_write(&sysfs_rwsema); @@ -975,8 +971,6 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) store_line3(&intf->dev, NULL, DRIVER_VERSION, sizeof(DRIVER_VERSION)); - /* Register sysfs hooks (don't care about failure) */ - ret = sysfs_create_group(&intf->dev.kobj, &yld_attr_group); return 0; } @@ -985,6 +979,7 @@ static struct usb_driver yealink_driver = { .probe = usb_probe, .disconnect = usb_disconnect, .id_table = usb_table, + .dev_groups = yld_groups, }; module_usb_driver(yealink_driver); From f3efefb6fdcce604413135bd8d4c5568e53a1f13 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 10 Jul 2024 16:48:54 -0700 Subject: [PATCH 71/71] Input: yealink - simplify locking in sysfs attribute handling The locking rules in the driver came from era when sysfs attributes could live past the point of time when device would be unbound from the driver, and so used module-global semaphore (potentially shared between multiple yealink devices). Thankfully these times are long gone and attributes will not be accessible once they are removed. Simplify the logic by moving to per-device mutex, stop checking if there is driver data instance attached to the interface, and use guard notation to acquire the mutex. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20240710234855.311366-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/yealink.c | 72 ++++++++++-------------------------- 1 file changed, 20 insertions(+), 52 deletions(-) diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 435a46baad9d..8866bf65d347 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -103,6 +103,8 @@ struct yealink_dev { u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */ int key_code; /* last reported key */ + struct mutex sysfs_mutex; + unsigned int shutdown:1; int stat_ix; @@ -548,8 +550,6 @@ static void input_close(struct input_dev *dev) * sysfs interface ******************************************************************************/ -static DECLARE_RWSEM(sysfs_rwsema); - /* Interface to the 7-segments translation table aka. char set. */ static ssize_t show_map(struct device *dev, struct device_attribute *attr, @@ -580,15 +580,10 @@ static ssize_t store_map(struct device *dev, struct device_attribute *attr, */ static ssize_t show_line(struct device *dev, char *buf, int a, int b) { - struct yealink_dev *yld; + struct yealink_dev *yld = dev_get_drvdata(dev); int i; - down_read(&sysfs_rwsema); - yld = dev_get_drvdata(dev); - if (yld == NULL) { - up_read(&sysfs_rwsema); - return -ENODEV; - } + guard(mutex)(&yld->sysfs_mutex); for (i = a; i < b; i++) *buf++ = lcdMap[i].type; @@ -598,7 +593,6 @@ static ssize_t show_line(struct device *dev, char *buf, int a, int b) *buf++ = '\n'; *buf = 0; - up_read(&sysfs_rwsema); return 3 + ((b - a) << 1); } @@ -630,22 +624,16 @@ static ssize_t show_line3(struct device *dev, struct device_attribute *attr, static ssize_t store_line(struct device *dev, const char *buf, size_t count, int el, size_t len) { - struct yealink_dev *yld; + struct yealink_dev *yld = dev_get_drvdata(dev); int i; - down_write(&sysfs_rwsema); - yld = dev_get_drvdata(dev); - if (yld == NULL) { - up_write(&sysfs_rwsema); - return -ENODEV; - } + guard(mutex)(&yld->sysfs_mutex); if (len > count) len = count; for (i = 0; i < len; i++) setChar(yld, el++, buf[i]); - up_write(&sysfs_rwsema); return count; } @@ -675,15 +663,10 @@ static ssize_t store_line3(struct device *dev, struct device_attribute *attr, static ssize_t get_icons(struct device *dev, struct device_attribute *attr, char *buf) { - struct yealink_dev *yld; + struct yealink_dev *yld = dev_get_drvdata(dev); int i, ret = 1; - down_read(&sysfs_rwsema); - yld = dev_get_drvdata(dev); - if (yld == NULL) { - up_read(&sysfs_rwsema); - return -ENODEV; - } + guard(mutex)(&yld->sysfs_mutex); for (i = 0; i < ARRAY_SIZE(lcdMap); i++) { if (lcdMap[i].type != '.') @@ -692,7 +675,7 @@ static ssize_t get_icons(struct device *dev, struct device_attribute *attr, yld->lcdMap[i] == ' ' ? " " : "on", lcdMap[i].u.p.name); } - up_read(&sysfs_rwsema); + return ret; } @@ -700,15 +683,10 @@ static ssize_t get_icons(struct device *dev, struct device_attribute *attr, static ssize_t set_icon(struct device *dev, const char *buf, size_t count, int chr) { - struct yealink_dev *yld; + struct yealink_dev *yld = dev_get_drvdata(dev); int i; - down_write(&sysfs_rwsema); - yld = dev_get_drvdata(dev); - if (yld == NULL) { - up_write(&sysfs_rwsema); - return -ENODEV; - } + guard(mutex)(&yld->sysfs_mutex); for (i = 0; i < ARRAY_SIZE(lcdMap); i++) { if (lcdMap[i].type != '.') @@ -719,7 +697,6 @@ static ssize_t set_icon(struct device *dev, const char *buf, size_t count, } } - up_write(&sysfs_rwsema); return count; } @@ -739,22 +716,16 @@ static ssize_t hide_icon(struct device *dev, struct device_attribute *attr, */ /* Stores raw ringtone data in the phone */ -static ssize_t store_ringtone(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_ringtone(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct yealink_dev *yld; + struct yealink_dev *yld = dev_get_drvdata(dev); - down_write(&sysfs_rwsema); - yld = dev_get_drvdata(dev); - if (yld == NULL) { - up_write(&sysfs_rwsema); - return -ENODEV; - } + guard(mutex)(&yld->sysfs_mutex); /* TODO locking with async usb control interface??? */ yealink_set_ringtone(yld, (char *)buf, count); - up_write(&sysfs_rwsema); + return count; } @@ -835,14 +806,10 @@ static int usb_cleanup(struct yealink_dev *yld, int err) static void usb_disconnect(struct usb_interface *intf) { - struct yealink_dev *yld; - - down_write(&sysfs_rwsema); - yld = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - up_write(&sysfs_rwsema); + struct yealink_dev *yld = usb_get_intfdata(intf); usb_cleanup(yld, 0); + usb_set_intfdata(intf, NULL); } static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -870,6 +837,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) yld->udev = udev; yld->intf = intf; + mutex_init(&yld->sysfs_mutex); yld->idev = input_dev = input_allocate_device(); if (!input_dev)