linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities
@ 2024-09-05  4:17 Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 01/24] Input: serio - define serio_pause_rx guard to pause and resume serio ports Dmitry Torokhov
                   ` (23 more replies)
  0 siblings, 24 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Hi,

This series converts drivers found in drivers/input/serio as well as a
few of input drivers using serio to use new __free() and guard() cleanup
facilities that simplify the code and ensure that all resources are
released appropriately.

First patch introduces serio_pause_rx guard that pauses delivery of
interrupts/data for a given serio port by calling serio_pause_rx()
helper and automatically resumes it by calling serio_resume_rx() when
needed.

The following 8 patches make use if this new guard.

The rest of the patches switch serio drivers to use guard(mutex),
guard(spinlock*) and other cleanup functions to simplify the code.

Thanks!

Dmitry Torokhov (24):
  Input: serio - define serio_pause_rx guard to pause and resume serio ports
  Input: libps2 - use guard notation when temporarily pausing serio ports
  Input: alps - use guard notation when pausing serio port
  Input: byd - use guard notation when pausing serio port
  Input: synaptics - use guard notation when pausing serio port
  Input: atkbd - use guard notation when pausing serio port
  Input: sunkbd - use guard notation when pausing serio port
  Input: synaptics-rmi4 - use guard notation when pausing serio port in F03
  Input: elo - use guard notation when pausing serio port
  Input: gscps2 - use guard notation when acquiring spinlock
  Input: hyperv-keyboard - use guard notation when acquiring spinlock
  Input: i8042 - tease apart interrupt handler
  Input: i8042 - use guard notation when acquiring spinlock
  Input: ps2-gpio - use guard notation when acquiring mutex
  Input: ps2mult - use guard notation when acquiring spinlock
  Input: q40kbd - use guard notation when acquiring spinlock
  Input: sa1111ps2 - use guard notation when acquiring spinlock
  Input: serport - use guard notation when acquiring spinlock
  Input: serio - use guard notation when acquiring mutexes and spinlocks
  Input: serio_raw - use guard notation for locks and other resources
  Input: serio-raw - fix potential serio port name truncation
  Input: sun4i-ps2 - use guard notation when acquiring spinlock
  Input: userio - switch to using cleanup functions
  Input: xilinx_ps2 - use guard notation when acquiring spinlock

 drivers/input/keyboard/atkbd.c        |   8 +-
 drivers/input/keyboard/sunkbd.c       |   5 +-
 drivers/input/mouse/alps.c            |   4 +-
 drivers/input/mouse/byd.c             |   5 +-
 drivers/input/mouse/synaptics.c       |   6 +-
 drivers/input/rmi4/rmi_f03.c          |   4 +-
 drivers/input/serio/gscps2.c          | 114 +++++----
 drivers/input/serio/hyperv-keyboard.c |  38 ++-
 drivers/input/serio/i8042.c           | 327 +++++++++++++-------------
 drivers/input/serio/libps2.c          |  28 ++-
 drivers/input/serio/ps2-gpio.c        |   4 +-
 drivers/input/serio/ps2mult.c         |  25 +-
 drivers/input/serio/q40kbd.c          |  10 +-
 drivers/input/serio/sa1111ps2.c       |   8 +-
 drivers/input/serio/serio.c           | 164 +++++--------
 drivers/input/serio/serio_raw.c       | 125 ++++------
 drivers/input/serio/serport.c         |  27 +--
 drivers/input/serio/sun4i-ps2.c       |   8 +-
 drivers/input/serio/userio.c          | 141 ++++++-----
 drivers/input/serio/xilinx_ps2.c      |  15 +-
 drivers/input/touchscreen/elo.c       |   8 +-
 include/linux/serio.h                 |   3 +
 22 files changed, 487 insertions(+), 590 deletions(-)

-- 
Dmitry


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 01/24] Input: serio - define serio_pause_rx guard to pause and resume serio ports
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 02/24] Input: libps2 - use guard notation when temporarily pausing " Dmitry Torokhov
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

serio_pause_rx() and serio_continue_rx() are usually used together to
temporarily stop receiving interrupts/data for a given serio port.
Define "serio_pause_rx" guard for this so that the port is always
resumed once critical section is over.

Example:

	scoped_guard(serio_pause_rx, elo->serio) {
		elo->expected_packet = toupper(packet[0]);
		init_completion(&elo->cmd_done);
	}

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 include/linux/serio.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/serio.h b/include/linux/serio.h
index 1911827bbe0d..f4ca0aa37553 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -6,6 +6,7 @@
 #define _SERIO_H
 
 
+#include <linux/cleanup.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
@@ -161,4 +162,6 @@ static inline void serio_continue_rx(struct serio *serio)
 	spin_unlock_irq(&serio->lock);
 }
 
+DEFINE_GUARD(serio_pause_rx, struct serio *, serio_pause_rx(_T), serio_continue_rx(_T))
+
 #endif
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 02/24] Input: libps2 - use guard notation when temporarily pausing serio ports
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 01/24] Input: serio - define serio_pause_rx guard to pause and resume serio ports Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 03/24] Input: alps - use guard notation when pausing serio port Dmitry Torokhov
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/libps2.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 6d78a1fe00c1..c22ea532276e 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -108,13 +108,11 @@ int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
 {
 	int retval;
 
-	serio_pause_rx(ps2dev->serio);
+	guard(serio_pause_rx)(ps2dev->serio);
 
 	retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
 	dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);
 
-	serio_continue_rx(ps2dev->serio);
-
 	return retval;
 }
 EXPORT_SYMBOL(ps2_sendbyte);
@@ -162,10 +160,10 @@ void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
 
 	ps2_begin_command(ps2dev);
 
-	serio_pause_rx(ps2dev->serio);
-	ps2dev->flags = PS2_FLAG_CMD;
-	ps2dev->cmdcnt = maxbytes;
-	serio_continue_rx(ps2dev->serio);
+	scoped_guard(serio_pause_rx, ps2dev->serio) {
+		ps2dev->flags = PS2_FLAG_CMD;
+		ps2dev->cmdcnt = maxbytes;
+	}
 
 	wait_event_timeout(ps2dev->wait,
 			   !(ps2dev->flags & PS2_FLAG_CMD),
@@ -224,9 +222,9 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev,
 		 * use alternative probe to detect it.
 		 */
 		if (ps2dev->cmdbuf[1] == 0xaa) {
-			serio_pause_rx(ps2dev->serio);
-			ps2dev->flags = 0;
-			serio_continue_rx(ps2dev->serio);
+			scoped_guard(serio_pause_rx, ps2dev->serio)
+				ps2dev->flags = 0;
+
 			timeout = 0;
 		}
 
@@ -235,9 +233,9 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev,
 		 * won't be 2nd byte of ID response.
 		 */
 		if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
-			serio_pause_rx(ps2dev->serio);
-			ps2dev->flags = ps2dev->cmdcnt = 0;
-			serio_continue_rx(ps2dev->serio);
+			scoped_guard(serio_pause_rx, ps2dev->serio)
+				ps2dev->flags = ps2dev->cmdcnt = 0;
+
 			timeout = 0;
 		}
 		break;
@@ -283,6 +281,10 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
 
 	memcpy(send_param, param, send);
 
+	/*
+	 * Not using guard notation because we need to break critical
+	 * section below while waiting for the response.
+	 */
 	serio_pause_rx(ps2dev->serio);
 
 	ps2dev->cmdcnt = receive;
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 03/24] Input: alps - use guard notation when pausing serio port
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 01/24] Input: serio - define serio_pause_rx guard to pause and resume serio ports Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 02/24] Input: libps2 - use guard notation when temporarily pausing " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05 15:46   ` Pali Rohár
  2024-09-05  4:17 ` [PATCH 04/24] Input: byd " Dmitry Torokhov
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/mouse/alps.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4e37fc3f1a9e..0728b5c08f02 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -1585,7 +1585,7 @@ static void alps_flush_packet(struct timer_list *t)
 	struct alps_data *priv = from_timer(priv, t, timer);
 	struct psmouse *psmouse = priv->psmouse;
 
-	serio_pause_rx(psmouse->ps2dev.serio);
+	guard(serio_pause_rx)(psmouse->ps2dev.serio);
 
 	if (psmouse->pktcnt == psmouse->pktsize) {
 
@@ -1605,8 +1605,6 @@ static void alps_flush_packet(struct timer_list *t)
 		}
 		psmouse->pktcnt = 0;
 	}
-
-	serio_continue_rx(psmouse->ps2dev.serio);
 }
 
 static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 04/24] Input: byd - use guard notation when pausing serio port
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (2 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 03/24] Input: alps - use guard notation when pausing serio port Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 05/24] Input: synaptics " Dmitry Torokhov
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/mouse/byd.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c
index 221a553f45cd..654b38d249f3 100644
--- a/drivers/input/mouse/byd.c
+++ b/drivers/input/mouse/byd.c
@@ -254,13 +254,12 @@ static void byd_clear_touch(struct timer_list *t)
 	struct byd_data *priv = from_timer(priv, t, timer);
 	struct psmouse *psmouse = priv->psmouse;
 
-	serio_pause_rx(psmouse->ps2dev.serio);
+	guard(serio_pause_rx)(psmouse->ps2dev.serio);
+
 	priv->touch = false;
 
 	byd_report_input(psmouse);
 
-	serio_continue_rx(psmouse->ps2dev.serio);
-
 	/*
 	 * Move cursor back to center of pad when we lose touch - this
 	 * specifically improves user experience when moving cursor with one
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 05/24] Input: synaptics - use guard notation when pausing serio port
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (3 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 04/24] Input: byd " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 06/24] Input: atkbd " Dmitry Torokhov
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/mouse/synaptics.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 380aa1614442..2735f86c23cc 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -650,9 +650,8 @@ static int synaptics_pt_start(struct serio *serio)
 	struct psmouse *parent = psmouse_from_serio(serio->parent);
 	struct synaptics_data *priv = parent->private;
 
-	serio_pause_rx(parent->ps2dev.serio);
+	guard(serio_pause_rx)(parent->ps2dev.serio);
 	priv->pt_port = serio;
-	serio_continue_rx(parent->ps2dev.serio);
 
 	return 0;
 }
@@ -662,9 +661,8 @@ static void synaptics_pt_stop(struct serio *serio)
 	struct psmouse *parent = psmouse_from_serio(serio->parent);
 	struct synaptics_data *priv = parent->private;
 
-	serio_pause_rx(parent->ps2dev.serio);
+	guard(serio_pause_rx)(parent->ps2dev.serio);
 	priv->pt_port = NULL;
-	serio_continue_rx(parent->ps2dev.serio);
 }
 
 static int synaptics_is_pt_packet(u8 *buf)
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 06/24] Input: atkbd - use guard notation when pausing serio port
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (4 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 05/24] Input: synaptics " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 07/24] Input: sunkbd " Dmitry Torokhov
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/atkbd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 5855d4fc6e6a..ec94fcfa4cde 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -713,9 +713,9 @@ static int atkbd_event(struct input_dev *dev,
 
 static inline void atkbd_enable(struct atkbd *atkbd)
 {
-	serio_pause_rx(atkbd->ps2dev.serio);
+	guard(serio_pause_rx)(atkbd->ps2dev.serio);
+
 	atkbd->enabled = true;
-	serio_continue_rx(atkbd->ps2dev.serio);
 }
 
 /*
@@ -725,9 +725,9 @@ static inline void atkbd_enable(struct atkbd *atkbd)
 
 static inline void atkbd_disable(struct atkbd *atkbd)
 {
-	serio_pause_rx(atkbd->ps2dev.serio);
+	guard(serio_pause_rx)(atkbd->ps2dev.serio);
+
 	atkbd->enabled = false;
-	serio_continue_rx(atkbd->ps2dev.serio);
 }
 
 static int atkbd_activate(struct atkbd *atkbd)
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 07/24] Input: sunkbd - use guard notation when pausing serio port
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (5 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 06/24] Input: atkbd " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 08/24] Input: synaptics-rmi4 - use guard notation when pausing serio port in F03 Dmitry Torokhov
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/sunkbd.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 72fb46029710..3299e1919b37 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -241,9 +241,8 @@ static void sunkbd_reinit(struct work_struct *work)
 
 static void sunkbd_enable(struct sunkbd *sunkbd, bool enable)
 {
-	serio_pause_rx(sunkbd->serio);
-	sunkbd->enabled = enable;
-	serio_continue_rx(sunkbd->serio);
+	scoped_guard(serio_pause_rx, sunkbd->serio)
+		sunkbd->enabled = enable;
 
 	if (!enable) {
 		wake_up_interruptible(&sunkbd->wait);
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 08/24] Input: synaptics-rmi4 - use guard notation when pausing serio port in F03
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (6 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 07/24] Input: sunkbd " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 09/24] Input: elo - use guard notation when pausing serio port Dmitry Torokhov
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/rmi4/rmi_f03.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c
index 1e11ea30d7bd..e1157ff0f00a 100644
--- a/drivers/input/rmi4/rmi_f03.c
+++ b/drivers/input/rmi4/rmi_f03.c
@@ -61,14 +61,14 @@ void rmi_f03_commit_buttons(struct rmi_function *fn)
 	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
 	struct serio *serio = f03->serio;
 
-	serio_pause_rx(serio);
+	guard(serio_pause_rx)(serio);
+
 	if (serio->drv) {
 		serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
 				      SERIO_OOB_DATA);
 		serio->drv->interrupt(serio, f03->overwrite_buttons,
 				      SERIO_OOB_DATA);
 	}
-	serio_continue_rx(serio);
 }
 
 static int rmi_f03_pt_write(struct serio *id, unsigned char val)
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 09/24] Input: elo - use guard notation when pausing serio port
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (7 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 08/24] Input: synaptics-rmi4 - use guard notation when pausing serio port in F03 Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 10/24] Input: gscps2 - use guard notation when acquiring spinlock Dmitry Torokhov
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that serio ports are resumed in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/elo.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index eb883db55420..ad209e6e82a6 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -225,10 +225,10 @@ static int elo_command_10(struct elo *elo, unsigned char *packet)
 
 	mutex_lock(&elo->cmd_mutex);
 
-	serio_pause_rx(elo->serio);
-	elo->expected_packet = toupper(packet[0]);
-	init_completion(&elo->cmd_done);
-	serio_continue_rx(elo->serio);
+	scoped_guard(serio_pause_rx, elo->serio) {
+		elo->expected_packet = toupper(packet[0]);
+		init_completion(&elo->cmd_done);
+	}
 
 	if (serio_write(elo->serio, ELO10_LEAD_BYTE))
 		goto out;
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 10/24] Input: gscps2 - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (8 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 09/24] Input: elo - use guard notation when pausing serio port Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 11/24] Input: hyperv-keyboard " Dmitry Torokhov
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/gscps2.c | 114 +++++++++++++++++++----------------
 1 file changed, 62 insertions(+), 52 deletions(-)

diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index d94c01eb3fc9..cf0603d1a113 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -145,7 +145,6 @@ static void gscps2_flush(struct gscps2port *ps2port)
 
 static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
 {
-	unsigned long flags;
 	char __iomem *addr = ps2port->addr;
 
 	if (!wait_TBE(addr)) {
@@ -156,9 +155,8 @@ static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
 	while (gscps2_readb_status(addr) & GSC_STAT_RBNE)
 		/* wait */;
 
-	spin_lock_irqsave(&ps2port->lock, flags);
-	writeb(data, addr+GSC_XMTDATA);
-	spin_unlock_irqrestore(&ps2port->lock, flags);
+	scoped_guard(spinlock_irqsave, &ps2port->lock)
+		writeb(data, addr+GSC_XMTDATA);
 
 	/* this is ugly, but due to timing of the port it seems to be necessary. */
 	mdelay(6);
@@ -177,19 +175,19 @@ static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
 
 static void gscps2_enable(struct gscps2port *ps2port, int enable)
 {
-	unsigned long flags;
 	u8 data;
 
 	/* now enable/disable the port */
-	spin_lock_irqsave(&ps2port->lock, flags);
-	gscps2_flush(ps2port);
-	data = gscps2_readb_control(ps2port->addr);
-	if (enable)
-		data |= GSC_CTRL_ENBL;
-	else
-		data &= ~GSC_CTRL_ENBL;
-	gscps2_writeb_control(data, ps2port->addr);
-	spin_unlock_irqrestore(&ps2port->lock, flags);
+	scoped_guard(spinlock_irqsave, &ps2port->lock) {
+		gscps2_flush(ps2port);
+		data = gscps2_readb_control(ps2port->addr);
+		if (enable)
+			data |= GSC_CTRL_ENBL;
+		else
+			data &= ~GSC_CTRL_ENBL;
+		gscps2_writeb_control(data, ps2port->addr);
+	}
+
 	wait_TBE(ps2port->addr);
 	gscps2_flush(ps2port);
 }
@@ -203,15 +201,56 @@ static void gscps2_reset(struct gscps2port *ps2port)
 	unsigned long flags;
 
 	/* reset the interface */
-	spin_lock_irqsave(&ps2port->lock, flags);
+	guard(spinlock_irqsave)(&ps2port->lock);
 	gscps2_flush(ps2port);
 	writeb(0xff, ps2port->addr + GSC_RESET);
 	gscps2_flush(ps2port);
-	spin_unlock_irqrestore(&ps2port->lock, flags);
 }
 
 static LIST_HEAD(ps2port_list);
 
+static void gscps2_read_data(struct gscps2port *ps2port)
+{
+	u8 status;
+
+	do {
+		status = gscps2_readb_status(ps2port->addr);
+		if (!(status & GSC_STAT_RBNE))
+			break;
+
+		ps2port->buffer[ps2port->append].ste = status;
+		ps2port->buffer[ps2port->append].data =
+				gscps2_readb_input(ps2port->addr);
+	} while (true);
+}
+
+static bool gscps2_report_data(struct gscps2port *ps2port)
+{
+	unsigned int rxflags;
+	u8 data, status;
+
+	while (ps2port->act != ps2port->append) {
+		/*
+		 * Did new data arrived while we read existing data ?
+		 * If yes, exit now and let the new irq handler start
+		 * over again.
+		 */
+		if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
+			return true;
+
+		status = ps2port->buffer[ps2port->act].str;
+		data   = ps2port->buffer[ps2port->act].data;
+
+		ps2port->act = (ps2port->act + 1) & BUFFER_SIZE;
+		rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
+			  ((status & GSC_STAT_PERR) ? SERIO_PARITY  : 0 );
+
+		serio_interrupt(ps2port->port, data, rxflags);
+	}
+
+	return false;
+}
+
 /**
  * gscps2_interrupt() - Interruption service routine
  *
@@ -229,47 +268,18 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev)
 	struct gscps2port *ps2port;
 
 	list_for_each_entry(ps2port, &ps2port_list, node) {
+		guard(spinlock_irqsave)(&ps2port->lock);
 
-	  unsigned long flags;
-	  spin_lock_irqsave(&ps2port->lock, flags);
-
-	  while ( (ps2port->buffer[ps2port->append].str =
-		   gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
-		ps2port->buffer[ps2port->append].data =
-				gscps2_readb_input(ps2port->addr);
-		ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
-	  }
-
-	  spin_unlock_irqrestore(&ps2port->lock, flags);
-
+		gscps2_read_data(ps2port);
 	} /* list_for_each_entry */
 
 	/* all data was read from the ports - now report the data to upper layer */
-
 	list_for_each_entry(ps2port, &ps2port_list, node) {
-
-	  while (ps2port->act != ps2port->append) {
-
-	    unsigned int rxflags;
-	    u8 data, status;
-
-	    /* Did new data arrived while we read existing data ?
-	       If yes, exit now and let the new irq handler start over again */
-	    if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
-		return IRQ_HANDLED;
-
-	    status = ps2port->buffer[ps2port->act].str;
-	    data   = ps2port->buffer[ps2port->act].data;
-
-	    ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
-	    rxflags =	((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
-			((status & GSC_STAT_PERR) ? SERIO_PARITY  : 0 );
-
-	    serio_interrupt(ps2port->port, data, rxflags);
-
-	  } /* while() */
-
-	} /* list_for_each_entry */
+		if (gscps2_report_data(ps2port)) {
+			/* More data ready - break early to restart interrupt */
+			break;
+		}
+	}
 
 	return IRQ_HANDLED;
 }
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 11/24] Input: hyperv-keyboard - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (9 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 10/24] Input: gscps2 - use guard notation when acquiring spinlock Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 12/24] Input: i8042 - tease apart interrupt handler Dmitry Torokhov
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/hyperv-keyboard.c | 38 +++++++++++++--------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c
index 31d9dacd2fd1..0ee7505427ac 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -102,7 +102,6 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
 {
 	struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
 	struct synth_kbd_keystroke *ks_msg;
-	unsigned long flags;
 	u32 msg_type = __le32_to_cpu(msg->header.type);
 	u32 info;
 	u16 scan_code;
@@ -147,21 +146,22 @@ static void hv_kbd_on_receive(struct hv_device *hv_dev,
 		/*
 		 * Inject the information through the serio interrupt.
 		 */
-		spin_lock_irqsave(&kbd_dev->lock, flags);
-		if (kbd_dev->started) {
-			if (info & IS_E0)
-				serio_interrupt(kbd_dev->hv_serio,
-						XTKBD_EMUL0, 0);
-			if (info & IS_E1)
-				serio_interrupt(kbd_dev->hv_serio,
-						XTKBD_EMUL1, 0);
-			scan_code = __le16_to_cpu(ks_msg->make_code);
-			if (info & IS_BREAK)
-				scan_code |= XTKBD_RELEASE;
+		scoped_guard(spinlock_irqsave, &kbd_dev->lock) {
+			if (kbd_dev->started) {
+				if (info & IS_E0)
+					serio_interrupt(kbd_dev->hv_serio,
+							XTKBD_EMUL0, 0);
+				if (info & IS_E1)
+					serio_interrupt(kbd_dev->hv_serio,
+							XTKBD_EMUL1, 0);
+				scan_code = __le16_to_cpu(ks_msg->make_code);
+				if (info & IS_BREAK)
+					scan_code |= XTKBD_RELEASE;
 
-			serio_interrupt(kbd_dev->hv_serio, scan_code, 0);
+				serio_interrupt(kbd_dev->hv_serio,
+						scan_code, 0);
+			}
 		}
-		spin_unlock_irqrestore(&kbd_dev->lock, flags);
 
 		/*
 		 * Only trigger a wakeup on key down, otherwise
@@ -292,11 +292,10 @@ static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev)
 static int hv_kbd_start(struct serio *serio)
 {
 	struct hv_kbd_dev *kbd_dev = serio->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&kbd_dev->lock, flags);
+	guard(spinlock_irqsave)(&kbd_dev->lock);
+
 	kbd_dev->started = true;
-	spin_unlock_irqrestore(&kbd_dev->lock, flags);
 
 	return 0;
 }
@@ -304,11 +303,10 @@ static int hv_kbd_start(struct serio *serio)
 static void hv_kbd_stop(struct serio *serio)
 {
 	struct hv_kbd_dev *kbd_dev = serio->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&kbd_dev->lock, flags);
+	guard(spinlock_irqsave)(&kbd_dev->lock);
+
 	kbd_dev->started = false;
-	spin_unlock_irqrestore(&kbd_dev->lock, flags);
 }
 
 static int hv_kbd_probe(struct hv_device *hv_dev,
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 12/24] Input: i8042 - tease apart interrupt handler
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (10 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 11/24] Input: hyperv-keyboard " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 13/24] Input: i8042 - use guard notation when acquiring spinlock Dmitry Torokhov
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

In preparation to using guard notation when acquiring mutexes and
spinlocks factor out handling of active multiplexing mode from
i8042_interrupt().

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/i8042.c | 139 +++++++++++++++++++++---------------
 1 file changed, 83 insertions(+), 56 deletions(-)

diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 8ec4872b4471..674cd155ec8f 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -178,7 +178,7 @@ static unsigned char i8042_suppress_kbd_ack;
 static struct platform_device *i8042_platform_device;
 static struct notifier_block i8042_kbd_bind_notifier_block;
 
-static irqreturn_t i8042_interrupt(int irq, void *dev_id);
+static bool i8042_handle_data(int irq);
 static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
 				     struct serio *serio);
 
@@ -434,7 +434,7 @@ static void i8042_port_close(struct serio *serio)
 	 * See if there is any data appeared while we were messing with
 	 * port state.
 	 */
-	i8042_interrupt(0, NULL);
+	i8042_handle_data(0);
 }
 
 /*
@@ -518,12 +518,68 @@ static bool i8042_filter(unsigned char data, unsigned char str,
 }
 
 /*
- * i8042_interrupt() is the most important function in this driver -
- * it handles the interrupts from the i8042, and sends incoming bytes
- * to the upper layers.
+ * i8042_handle_mux() handles case when data is coming from one of
+ * the multiplexed ports. It would be simple if not for quirks with
+ * handling errors:
+ *
+ * When MUXERR condition is signalled the data register can only contain
+ * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
+ * it is not always the case. Some KBCs also report 0xfc when there is
+ * nothing connected to the port while others sometimes get confused which
+ * port the data came from and signal error leaving the data intact. They
+ * _do not_ revert to legacy mode (actually I've never seen KBC reverting
+ * to legacy mode yet, when we see one we'll add proper handling).
+ * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the
+ * rest assume that the data came from the same serio last byte
+ * was transmitted (if transmission happened not too long ago).
  */
+static int i8042_handle_mux(u8 str, u8 *data, unsigned int *dfl)
+{
+	static unsigned long last_transmit;
+	static unsigned long last_port;
+	unsigned int mux_port;
+
+	mux_port = (str >> 6) & 3;
+	*dfl = 0;
+
+	if (str & I8042_STR_MUXERR) {
+		dbg("MUX error, status is %02x, data is %02x\n",
+		    str, *data);
+
+		switch (*data) {
+		default:
+			if (time_before(jiffies, last_transmit + HZ/10)) {
+				mux_port = last_port;
+				break;
+			}
+			fallthrough;	/* report timeout */
+		case 0xfc:
+		case 0xfd:
+		case 0xfe:
+			*dfl = SERIO_TIMEOUT;
+			*data = 0xfe;
+			break;
+		case 0xff:
+			*dfl = SERIO_PARITY;
+			*data = 0xfe;
+			break;
+		}
+	}
 
-static irqreturn_t i8042_interrupt(int irq, void *dev_id)
+	last_port = mux_port;
+	last_transmit = jiffies;
+
+	return I8042_MUX_PORT_NO + mux_port;
+}
+
+/*
+ * i8042_handle_data() is the most important function in this driver -
+ * it reads the data from the i8042, determines its destination serio
+ * port, and sends received byte to the upper layers.
+ *
+ * Returns true if there was data waiting, false otherwise.
+ */
+static bool i8042_handle_data(int irq)
 {
 	struct i8042_port *port;
 	struct serio *serio;
@@ -532,63 +588,24 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
 	unsigned int dfl;
 	unsigned int port_no;
 	bool filtered;
-	int ret = 1;
 
 	spin_lock_irqsave(&i8042_lock, flags);
 
 	str = i8042_read_status();
 	if (unlikely(~str & I8042_STR_OBF)) {
 		spin_unlock_irqrestore(&i8042_lock, flags);
-		if (irq)
-			dbg("Interrupt %d, without any data\n", irq);
-		ret = 0;
-		goto out;
+		return false;
 	}
 
 	data = i8042_read_data();
 
 	if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
-		static unsigned long last_transmit;
-		static unsigned char last_str;
-
-		dfl = 0;
-		if (str & I8042_STR_MUXERR) {
-			dbg("MUX error, status is %02x, data is %02x\n",
-			    str, data);
-/*
- * When MUXERR condition is signalled the data register can only contain
- * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
- * it is not always the case. Some KBCs also report 0xfc when there is
- * nothing connected to the port while others sometimes get confused which
- * port the data came from and signal error leaving the data intact. They
- * _do not_ revert to legacy mode (actually I've never seen KBC reverting
- * to legacy mode yet, when we see one we'll add proper handling).
- * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the
- * rest assume that the data came from the same serio last byte
- * was transmitted (if transmission happened not too long ago).
- */
-
-			switch (data) {
-				default:
-					if (time_before(jiffies, last_transmit + HZ/10)) {
-						str = last_str;
-						break;
-					}
-					fallthrough;	/* report timeout */
-				case 0xfc:
-				case 0xfd:
-				case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break;
-				case 0xff: dfl = SERIO_PARITY;  data = 0xfe; break;
-			}
-		}
-
-		port_no = I8042_MUX_PORT_NO + ((str >> 6) & 3);
-		last_str = str;
-		last_transmit = jiffies;
+		port_no = i8042_handle_mux(str, &data, &dfl);
 	} else {
 
-		dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
-		      ((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0);
+		dfl = (str & I8042_STR_PARITY) ? SERIO_PARITY : 0;
+		if ((str & I8042_STR_TIMEOUT) && !i8042_notimeout)
+			dfl |= SERIO_TIMEOUT;
 
 		port_no = (str & I8042_STR_AUXDATA) ?
 				I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
@@ -609,8 +626,17 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
 	if (likely(serio && !filtered))
 		serio_interrupt(serio, data, dfl);
 
- out:
-	return IRQ_RETVAL(ret);
+	return true;
+}
+
+static irqreturn_t i8042_interrupt(int irq, void *dev_id)
+{
+	if (unlikely(!i8042_handle_data(irq))) {
+		dbg("Interrupt %d, without any data\n", irq);
+		return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
 }
 
 /*
@@ -1216,13 +1242,14 @@ static int i8042_controller_resume(bool s2r_wants_reset)
 	if (i8042_mux_present) {
 		if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports())
 			pr_warn("failed to resume active multiplexor, mouse won't work\n");
-	} else if (i8042_ports[I8042_AUX_PORT_NO].serio)
+	} else if (i8042_ports[I8042_AUX_PORT_NO].serio) {
 		i8042_enable_aux_port();
+	}
 
 	if (i8042_ports[I8042_KBD_PORT_NO].serio)
 		i8042_enable_kbd_port();
 
-	i8042_interrupt(0, NULL);
+	i8042_handle_data(0);
 
 	return 0;
 }
@@ -1253,7 +1280,7 @@ static int i8042_pm_suspend(struct device *dev)
 static int i8042_pm_resume_noirq(struct device *dev)
 {
 	if (i8042_forcenorestore || !pm_resume_via_firmware())
-		i8042_interrupt(0, NULL);
+		i8042_handle_data(0);
 
 	return 0;
 }
@@ -1290,7 +1317,7 @@ static int i8042_pm_resume(struct device *dev)
 
 static int i8042_pm_thaw(struct device *dev)
 {
-	i8042_interrupt(0, NULL);
+	i8042_handle_data(0);
 
 	return 0;
 }
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 13/24] Input: i8042 - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (11 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 12/24] Input: i8042 - tease apart interrupt handler Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 14/24] Input: ps2-gpio - use guard notation when acquiring mutex Dmitry Torokhov
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/i8042.c | 204 +++++++++++++++---------------------
 1 file changed, 82 insertions(+), 122 deletions(-)

diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 674cd155ec8f..86916fe3925f 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -197,42 +197,26 @@ EXPORT_SYMBOL(i8042_unlock_chip);
 int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
 					struct serio *serio))
 {
-	unsigned long flags;
-	int ret = 0;
+	guard(spinlock_irqsave)(&i8042_lock);
 
-	spin_lock_irqsave(&i8042_lock, flags);
-
-	if (i8042_platform_filter) {
-		ret = -EBUSY;
-		goto out;
-	}
+	if (i8042_platform_filter)
+		return -EBUSY;
 
 	i8042_platform_filter = filter;
-
-out:
-	spin_unlock_irqrestore(&i8042_lock, flags);
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(i8042_install_filter);
 
 int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
 				       struct serio *port))
 {
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&i8042_lock, flags);
+	guard(spinlock_irqsave)(&i8042_lock);
 
-	if (i8042_platform_filter != filter) {
-		ret = -EINVAL;
-		goto out;
-	}
+	if (i8042_platform_filter != filter)
+		return -EINVAL;
 
 	i8042_platform_filter = NULL;
-
-out:
-	spin_unlock_irqrestore(&i8042_lock, flags);
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL(i8042_remove_filter);
 
@@ -271,28 +255,22 @@ static int i8042_wait_write(void)
 
 static int i8042_flush(void)
 {
-	unsigned long flags;
 	unsigned char data, str;
 	int count = 0;
-	int retval = 0;
 
-	spin_lock_irqsave(&i8042_lock, flags);
+	guard(spinlock_irqsave)(&i8042_lock);
 
 	while ((str = i8042_read_status()) & I8042_STR_OBF) {
-		if (count++ < I8042_BUFFER_SIZE) {
-			udelay(50);
-			data = i8042_read_data();
-			dbg("%02x <- i8042 (flush, %s)\n",
-			    data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
-		} else {
-			retval = -EIO;
-			break;
-		}
-	}
+		if (count++ >= I8042_BUFFER_SIZE)
+			return -EIO;
 
-	spin_unlock_irqrestore(&i8042_lock, flags);
+		udelay(50);
+		data = i8042_read_data();
+		dbg("%02x <- i8042 (flush, %s)\n",
+		    data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
+	}
 
-	return retval;
+	return 0;
 }
 
 /*
@@ -349,17 +327,12 @@ static int __i8042_command(unsigned char *param, int command)
 
 int i8042_command(unsigned char *param, int command)
 {
-	unsigned long flags;
-	int retval;
-
 	if (!i8042_present)
 		return -1;
 
-	spin_lock_irqsave(&i8042_lock, flags);
-	retval = __i8042_command(param, command);
-	spin_unlock_irqrestore(&i8042_lock, flags);
+	guard(spinlock_irqsave)(&i8042_lock);
 
-	return retval;
+	return __i8042_command(param, command);
 }
 EXPORT_SYMBOL(i8042_command);
 
@@ -369,19 +342,18 @@ EXPORT_SYMBOL(i8042_command);
 
 static int i8042_kbd_write(struct serio *port, unsigned char c)
 {
-	unsigned long flags;
-	int retval = 0;
+	int error;
 
-	spin_lock_irqsave(&i8042_lock, flags);
+	guard(spinlock_irqsave)(&i8042_lock);
 
-	if (!(retval = i8042_wait_write())) {
-		dbg("%02x -> i8042 (kbd-data)\n", c);
-		i8042_write_data(c);
-	}
+	error = i8042_wait_write();
+	if (error)
+		return error;
 
-	spin_unlock_irqrestore(&i8042_lock, flags);
+	dbg("%02x -> i8042 (kbd-data)\n", c);
+	i8042_write_data(c);
 
-	return retval;
+	return 0;
 }
 
 /*
@@ -460,9 +432,8 @@ static int i8042_start(struct serio *serio)
 		device_set_wakeup_enable(&serio->dev, true);
 	}
 
-	spin_lock_irq(&i8042_lock);
+	guard(spinlock_irq)(&i8042_lock);
 	port->exists = true;
-	spin_unlock_irq(&i8042_lock);
 
 	return 0;
 }
@@ -476,10 +447,10 @@ static void i8042_stop(struct serio *serio)
 {
 	struct i8042_port *port = serio->port_data;
 
-	spin_lock_irq(&i8042_lock);
-	port->exists = false;
-	port->serio = NULL;
-	spin_unlock_irq(&i8042_lock);
+	scoped_guard(spinlock_irq, &i8042_lock) {
+		port->exists = false;
+		port->serio = NULL;
+	}
 
 	/*
 	 * We need to make sure that interrupt handler finishes using
@@ -583,45 +554,41 @@ static bool i8042_handle_data(int irq)
 {
 	struct i8042_port *port;
 	struct serio *serio;
-	unsigned long flags;
 	unsigned char str, data;
 	unsigned int dfl;
 	unsigned int port_no;
 	bool filtered;
 
-	spin_lock_irqsave(&i8042_lock, flags);
-
-	str = i8042_read_status();
-	if (unlikely(~str & I8042_STR_OBF)) {
-		spin_unlock_irqrestore(&i8042_lock, flags);
-		return false;
-	}
-
-	data = i8042_read_data();
+	scoped_guard(spinlock_irqsave, &i8042_lock) {
+		str = i8042_read_status();
+		if (unlikely(~str & I8042_STR_OBF))
+			return false;
 
-	if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
-		port_no = i8042_handle_mux(str, &data, &dfl);
-	} else {
+		data = i8042_read_data();
 
-		dfl = (str & I8042_STR_PARITY) ? SERIO_PARITY : 0;
-		if ((str & I8042_STR_TIMEOUT) && !i8042_notimeout)
-			dfl |= SERIO_TIMEOUT;
+		if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
+			port_no = i8042_handle_mux(str, &data, &dfl);
+		} else {
 
-		port_no = (str & I8042_STR_AUXDATA) ?
-				I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
-	}
+			dfl = (str & I8042_STR_PARITY) ? SERIO_PARITY : 0;
+			if ((str & I8042_STR_TIMEOUT) && !i8042_notimeout)
+				dfl |= SERIO_TIMEOUT;
 
-	port = &i8042_ports[port_no];
-	serio = port->exists ? port->serio : NULL;
+			port_no = (str & I8042_STR_AUXDATA) ?
+					I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
+		}
 
-	filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n",
-		   port_no, irq,
-		   dfl & SERIO_PARITY ? ", bad parity" : "",
-		   dfl & SERIO_TIMEOUT ? ", timeout" : "");
+		port = &i8042_ports[port_no];
+		serio = port->exists ? port->serio : NULL;
 
-	filtered = i8042_filter(data, str, serio);
+		filter_dbg(port->driver_bound,
+			   data, "<- i8042 (interrupt, %d, %d%s%s)\n",
+			   port_no, irq,
+			   dfl & SERIO_PARITY ? ", bad parity" : "",
+			   dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
-	spin_unlock_irqrestore(&i8042_lock, flags);
+		filtered = i8042_filter(data, str, serio);
+	}
 
 	if (likely(serio && !filtered))
 		serio_interrupt(serio, data, dfl);
@@ -779,24 +746,22 @@ static bool i8042_irq_being_tested;
 
 static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id)
 {
-	unsigned long flags;
 	unsigned char str, data;
-	int ret = 0;
 
-	spin_lock_irqsave(&i8042_lock, flags);
+	guard(spinlock_irqsave)(&i8042_lock);
+
 	str = i8042_read_status();
-	if (str & I8042_STR_OBF) {
-		data = i8042_read_data();
-		dbg("%02x <- i8042 (aux_test_irq, %s)\n",
-		    data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
-		if (i8042_irq_being_tested &&
-		    data == 0xa5 && (str & I8042_STR_AUXDATA))
-			complete(&i8042_aux_irq_delivered);
-		ret = 1;
-	}
-	spin_unlock_irqrestore(&i8042_lock, flags);
+	if (!(str & I8042_STR_OBF))
+		return IRQ_NONE;
+
+	data = i8042_read_data();
+	dbg("%02x <- i8042 (aux_test_irq, %s)\n",
+	    data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
+
+	if (i8042_irq_being_tested && data == 0xa5 && (str & I8042_STR_AUXDATA))
+		complete(&i8042_aux_irq_delivered);
 
-	return IRQ_RETVAL(ret);
+	return IRQ_HANDLED;
 }
 
 /*
@@ -837,7 +802,6 @@ static int i8042_check_aux(void)
 	int retval = -1;
 	bool irq_registered = false;
 	bool aux_loop_broken = false;
-	unsigned long flags;
 	unsigned char param;
 
 /*
@@ -921,18 +885,15 @@ static int i8042_check_aux(void)
 	if (i8042_enable_aux_port())
 		goto out;
 
-	spin_lock_irqsave(&i8042_lock, flags);
-
-	init_completion(&i8042_aux_irq_delivered);
-	i8042_irq_being_tested = true;
-
-	param = 0xa5;
-	retval = __i8042_command(&param, I8042_CMD_AUX_LOOP & 0xf0ff);
-
-	spin_unlock_irqrestore(&i8042_lock, flags);
+	scoped_guard(spinlock_irqsave, &i8042_lock) {
+		init_completion(&i8042_aux_irq_delivered);
+		i8042_irq_being_tested = true;
 
-	if (retval)
-		goto out;
+		param = 0xa5;
+		retval = __i8042_command(&param, I8042_CMD_AUX_LOOP & 0xf0ff);
+		if (retval)
+			goto out;
+	}
 
 	if (wait_for_completion_timeout(&i8042_aux_irq_delivered,
 					msecs_to_jiffies(250)) == 0) {
@@ -1020,7 +981,6 @@ static int i8042_controller_selftest(void)
 
 static int i8042_controller_init(void)
 {
-	unsigned long flags;
 	int n = 0;
 	unsigned char ctr[2];
 
@@ -1057,14 +1017,14 @@ static int i8042_controller_init(void)
  * Handle keylock.
  */
 
-	spin_lock_irqsave(&i8042_lock, flags);
-	if (~i8042_read_status() & I8042_STR_KEYLOCK) {
-		if (i8042_unlock)
-			i8042_ctr |= I8042_CTR_IGNKEYLOCK;
-		else
-			pr_warn("Warning: Keylock active\n");
+	scoped_guard(spinlock_irqsave, &i8042_lock) {
+		if (~i8042_read_status() & I8042_STR_KEYLOCK) {
+			if (i8042_unlock)
+				i8042_ctr |= I8042_CTR_IGNKEYLOCK;
+			else
+				pr_warn("Warning: Keylock active\n");
+		}
 	}
-	spin_unlock_irqrestore(&i8042_lock, flags);
 
 /*
  * If the chip is configured into nontranslated mode by the BIOS, don't
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 14/24] Input: ps2-gpio - use guard notation when acquiring mutex
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (12 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 13/24] Input: i8042 - use guard notation when acquiring spinlock Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 15/24] Input: ps2mult - use guard notation when acquiring spinlock Dmitry Torokhov
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that mutexes are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/ps2-gpio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c
index 0c8b390b8b4f..c9c382989e55 100644
--- a/drivers/input/serio/ps2-gpio.c
+++ b/drivers/input/serio/ps2-gpio.c
@@ -133,12 +133,12 @@ static int ps2_gpio_write(struct serio *serio, unsigned char val)
 	int ret = 0;
 
 	if (in_task()) {
-		mutex_lock(&drvdata->tx.mutex);
+		guard(mutex)(&drvdata->tx.mutex);
+
 		__ps2_gpio_write(serio, val);
 		if (!wait_for_completion_timeout(&drvdata->tx.complete,
 						 msecs_to_jiffies(10000)))
 			ret = SERIO_TIMEOUT;
-		mutex_unlock(&drvdata->tx.mutex);
 	} else {
 		__ps2_gpio_write(serio, val);
 	}
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 15/24] Input: ps2mult - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (13 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 14/24] Input: ps2-gpio - use guard notation when acquiring mutex Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 16/24] Input: q40kbd " Dmitry Torokhov
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/ps2mult.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c
index 937ecdea491d..b96cee52fc52 100644
--- a/drivers/input/serio/ps2mult.c
+++ b/drivers/input/serio/ps2mult.c
@@ -76,9 +76,8 @@ static int ps2mult_serio_write(struct serio *serio, unsigned char data)
 	struct ps2mult *psm = serio_get_drvdata(mx_port);
 	struct ps2mult_port *port = serio->port_data;
 	bool need_escape;
-	unsigned long flags;
 
-	spin_lock_irqsave(&psm->lock, flags);
+	guard(spinlock_irqsave)(&psm->lock);
 
 	if (psm->out_port != port)
 		ps2mult_select_port(psm, port);
@@ -93,8 +92,6 @@ static int ps2mult_serio_write(struct serio *serio, unsigned char data)
 
 	serio_write(mx_port, data);
 
-	spin_unlock_irqrestore(&psm->lock, flags);
-
 	return 0;
 }
 
@@ -102,11 +99,10 @@ static int ps2mult_serio_start(struct serio *serio)
 {
 	struct ps2mult *psm = serio_get_drvdata(serio->parent);
 	struct ps2mult_port *port = serio->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&psm->lock, flags);
+	guard(spinlock_irqsave)(&psm->lock);
+
 	port->registered = true;
-	spin_unlock_irqrestore(&psm->lock, flags);
 
 	return 0;
 }
@@ -115,11 +111,10 @@ static void ps2mult_serio_stop(struct serio *serio)
 {
 	struct ps2mult *psm = serio_get_drvdata(serio->parent);
 	struct ps2mult_port *port = serio->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&psm->lock, flags);
+	guard(spinlock_irqsave)(&psm->lock);
+
 	port->registered = false;
-	spin_unlock_irqrestore(&psm->lock, flags);
 }
 
 static int ps2mult_create_port(struct ps2mult *psm, int i)
@@ -148,16 +143,12 @@ static int ps2mult_create_port(struct ps2mult *psm, int i)
 
 static void ps2mult_reset(struct ps2mult *psm)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&psm->lock, flags);
+	guard(spinlock_irqsave)(&psm->lock);
 
 	serio_write(psm->mx_serio, PS2MULT_SESSION_END);
 	serio_write(psm->mx_serio, PS2MULT_SESSION_START);
 
 	ps2mult_select_port(psm, &psm->ports[PS2MULT_KBD_PORT]);
-
-	spin_unlock_irqrestore(&psm->lock, flags);
 }
 
 static int ps2mult_connect(struct serio *serio, struct serio_driver *drv)
@@ -234,11 +225,10 @@ static irqreturn_t ps2mult_interrupt(struct serio *serio,
 {
 	struct ps2mult *psm = serio_get_drvdata(serio);
 	struct ps2mult_port *in_port;
-	unsigned long flags;
 
 	dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, dfl);
 
-	spin_lock_irqsave(&psm->lock, flags);
+	guard(spinlock_irqsave)(&psm->lock);
 
 	if (psm->escape) {
 		psm->escape = false;
@@ -285,7 +275,6 @@ static irqreturn_t ps2mult_interrupt(struct serio *serio,
 	}
 
  out:
-	spin_unlock_irqrestore(&psm->lock, flags);
 	return IRQ_HANDLED;
 }
 
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 16/24] Input: q40kbd - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (14 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 15/24] Input: ps2mult - use guard notation when acquiring spinlock Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 17/24] Input: sa1111ps2 " Dmitry Torokhov
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/q40kbd.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index cd4d5be946a3..cdd5c4ef9b36 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -39,17 +39,14 @@ struct q40kbd {
 static irqreturn_t q40kbd_interrupt(int irq, void *dev_id)
 {
 	struct q40kbd *q40kbd = dev_id;
-	unsigned long flags;
 
-	spin_lock_irqsave(&q40kbd->lock, flags);
+	guard(spinlock_irqsave)(&q40kbd->lock);
 
 	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
 		serio_interrupt(q40kbd->port, master_inb(KEYCODE_REG), 0);
 
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
 
-	spin_unlock_irqrestore(&q40kbd->lock, flags);
-
 	return IRQ_HANDLED;
 }
 
@@ -60,14 +57,11 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id)
 static void q40kbd_flush(struct q40kbd *q40kbd)
 {
 	int maxread = 100;
-	unsigned long flags;
 
-	spin_lock_irqsave(&q40kbd->lock, flags);
+	guard(spinlock_irqsave)(&q40kbd->lock);
 
 	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
 		master_inb(KEYCODE_REG);
-
-	spin_unlock_irqrestore(&q40kbd->lock, flags);
 }
 
 static void q40kbd_stop(void)
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 17/24] Input: sa1111ps2 - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (15 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 16/24] Input: q40kbd " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 18/24] Input: serport " Dmitry Torokhov
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/sa1111ps2.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 1311caf7dba4..375c6f5f905c 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -92,7 +92,8 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
 	struct ps2if *ps2if = dev_id;
 	unsigned int status;
 
-	spin_lock(&ps2if->lock);
+	guard(spinlock)(&ps2if->lock);
+
 	status = readl_relaxed(ps2if->base + PS2STAT);
 	if (ps2if->head == ps2if->tail) {
 		disable_irq_nosync(irq);
@@ -101,7 +102,6 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
 		writel_relaxed(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA);
 		ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
 	}
-	spin_unlock(&ps2if->lock);
 
 	return IRQ_HANDLED;
 }
@@ -113,10 +113,9 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
 static int ps2_write(struct serio *io, unsigned char val)
 {
 	struct ps2if *ps2if = io->port_data;
-	unsigned long flags;
 	unsigned int head;
 
-	spin_lock_irqsave(&ps2if->lock, flags);
+	guard(spinlock_irqsave)(&ps2if->lock);
 
 	/*
 	 * If the TX register is empty, we can go straight out.
@@ -133,7 +132,6 @@ static int ps2_write(struct serio *io, unsigned char val)
 		}
 	}
 
-	spin_unlock_irqrestore(&ps2if->lock, flags);
 	return 0;
 }
 
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 18/24] Input: serport - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (16 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 17/24] Input: sa1111ps2 " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 19/24] Input: serio - use guard notation when acquiring mutexes and spinlocks Dmitry Torokhov
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/serport.c | 27 ++++++++-------------------
 1 file changed, 8 insertions(+), 19 deletions(-)

diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 5a2b5404ffc2..74ac88796187 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -50,11 +50,9 @@ static int serport_serio_write(struct serio *serio, unsigned char data)
 static int serport_serio_open(struct serio *serio)
 {
 	struct serport *serport = serio->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serport->lock, flags);
+	guard(spinlock_irqsave)(&serport->lock);
 	set_bit(SERPORT_ACTIVE, &serport->flags);
-	spin_unlock_irqrestore(&serport->lock, flags);
 
 	return 0;
 }
@@ -63,11 +61,9 @@ static int serport_serio_open(struct serio *serio)
 static void serport_serio_close(struct serio *serio)
 {
 	struct serport *serport = serio->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serport->lock, flags);
+	guard(spinlock_irqsave)(&serport->lock);
 	clear_bit(SERPORT_ACTIVE, &serport->flags);
-	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
@@ -118,14 +114,13 @@ static void serport_ldisc_receive(struct tty_struct *tty, const u8 *cp,
 				  const u8 *fp, size_t count)
 {
 	struct serport *serport = tty->disc_data;
-	unsigned long flags;
 	unsigned int ch_flags = 0;
 	int i;
 
-	spin_lock_irqsave(&serport->lock, flags);
+	guard(spinlock_irqsave)(&serport->lock);
 
 	if (!test_bit(SERPORT_ACTIVE, &serport->flags))
-		goto out;
+		return;
 
 	for (i = 0; i < count; i++) {
 		if (fp) {
@@ -146,9 +141,6 @@ static void serport_ldisc_receive(struct tty_struct *tty, const u8 *cp,
 
 		serio_interrupt(serport->serio, cp[i], ch_flags);
 	}
-
-out:
-	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
@@ -246,11 +238,9 @@ static int serport_ldisc_compat_ioctl(struct tty_struct *tty,
 static void serport_ldisc_hangup(struct tty_struct *tty)
 {
 	struct serport *serport = tty->disc_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serport->lock, flags);
-	set_bit(SERPORT_DEAD, &serport->flags);
-	spin_unlock_irqrestore(&serport->lock, flags);
+	scoped_guard(spinlock_irqsave, &serport->lock)
+		set_bit(SERPORT_DEAD, &serport->flags);
 
 	wake_up_interruptible(&serport->wait);
 }
@@ -258,12 +248,11 @@ static void serport_ldisc_hangup(struct tty_struct *tty)
 static void serport_ldisc_write_wakeup(struct tty_struct * tty)
 {
 	struct serport *serport = tty->disc_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serport->lock, flags);
+	guard(spinlock_irqsave)(&serport->lock);
+
 	if (test_bit(SERPORT_ACTIVE, &serport->flags))
 		serio_drv_write_wakeup(serport->serio);
-	spin_unlock_irqrestore(&serport->lock, flags);
 }
 
 /*
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 19/24] Input: serio - use guard notation when acquiring mutexes and spinlocks
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (17 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 18/24] Input: serport " Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources Dmitry Torokhov
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/serio.c | 164 ++++++++++++++----------------------
 1 file changed, 65 insertions(+), 99 deletions(-)

diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 29a2b13a8cf5..aa386eb37a16 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -37,33 +37,27 @@ static void serio_reconnect_subtree(struct serio *serio);
 
 static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
 {
-	int retval;
-
-	mutex_lock(&serio->drv_mutex);
-	retval = drv->connect(serio, drv);
-	mutex_unlock(&serio->drv_mutex);
+	guard(mutex)(&serio->drv_mutex);
 
-	return retval;
+	return drv->connect(serio, drv);
 }
 
 static int serio_reconnect_driver(struct serio *serio)
 {
-	int retval = -1;
+	guard(mutex)(&serio->drv_mutex);
 
-	mutex_lock(&serio->drv_mutex);
 	if (serio->drv && serio->drv->reconnect)
-		retval = serio->drv->reconnect(serio);
-	mutex_unlock(&serio->drv_mutex);
+		return serio->drv->reconnect(serio);
 
-	return retval;
+	return -1;
 }
 
 static void serio_disconnect_driver(struct serio *serio)
 {
-	mutex_lock(&serio->drv_mutex);
+	guard(mutex)(&serio->drv_mutex);
+
 	if (serio->drv)
 		serio->drv->disconnect(serio);
-	mutex_unlock(&serio->drv_mutex);
 }
 
 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
@@ -145,9 +139,8 @@ static LIST_HEAD(serio_event_list);
 static struct serio_event *serio_get_event(void)
 {
 	struct serio_event *event = NULL;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serio_event_lock, flags);
+	guard(spinlock_irqsave)(&serio_event_lock);
 
 	if (!list_empty(&serio_event_list)) {
 		event = list_first_entry(&serio_event_list,
@@ -155,7 +148,6 @@ static struct serio_event *serio_get_event(void)
 		list_del_init(&event->node);
 	}
 
-	spin_unlock_irqrestore(&serio_event_lock, flags);
 	return event;
 }
 
@@ -169,9 +161,8 @@ static void serio_remove_duplicate_events(void *object,
 					  enum serio_event_type type)
 {
 	struct serio_event *e, *next;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serio_event_lock, flags);
+	guard(spinlock_irqsave)(&serio_event_lock);
 
 	list_for_each_entry_safe(e, next, &serio_event_list, node) {
 		if (object == e->object) {
@@ -187,15 +178,13 @@ static void serio_remove_duplicate_events(void *object,
 			serio_free_event(e);
 		}
 	}
-
-	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
 static void serio_handle_event(struct work_struct *work)
 {
 	struct serio_event *event;
 
-	mutex_lock(&serio_mutex);
+	guard(mutex)(&serio_mutex);
 
 	while ((event = serio_get_event())) {
 
@@ -222,8 +211,6 @@ static void serio_handle_event(struct work_struct *work)
 		serio_remove_duplicate_events(event->object, event->type);
 		serio_free_event(event);
 	}
-
-	mutex_unlock(&serio_mutex);
 }
 
 static DECLARE_WORK(serio_event_work, serio_handle_event);
@@ -231,11 +218,9 @@ static DECLARE_WORK(serio_event_work, serio_handle_event);
 static int serio_queue_event(void *object, struct module *owner,
 			     enum serio_event_type event_type)
 {
-	unsigned long flags;
 	struct serio_event *event;
-	int retval = 0;
 
-	spin_lock_irqsave(&serio_event_lock, flags);
+	guard(spinlock_irqsave)(&serio_event_lock);
 
 	/*
 	 * Scan event list for the other events for the same serio port,
@@ -247,7 +232,7 @@ static int serio_queue_event(void *object, struct module *owner,
 	list_for_each_entry_reverse(event, &serio_event_list, node) {
 		if (event->object == object) {
 			if (event->type == event_type)
-				goto out;
+				return 0;
 			break;
 		}
 	}
@@ -255,16 +240,14 @@ static int serio_queue_event(void *object, struct module *owner,
 	event = kmalloc(sizeof(*event), GFP_ATOMIC);
 	if (!event) {
 		pr_err("Not enough memory to queue event %d\n", event_type);
-		retval = -ENOMEM;
-		goto out;
+		return -ENOMEM;
 	}
 
 	if (!try_module_get(owner)) {
 		pr_warn("Can't get module reference, dropping event %d\n",
 			event_type);
 		kfree(event);
-		retval = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
 	event->type = event_type;
@@ -274,9 +257,7 @@ static int serio_queue_event(void *object, struct module *owner,
 	list_add_tail(&event->node, &serio_event_list);
 	queue_work(system_long_wq, &serio_event_work);
 
-out:
-	spin_unlock_irqrestore(&serio_event_lock, flags);
-	return retval;
+	return 0;
 }
 
 /*
@@ -286,9 +267,8 @@ static int serio_queue_event(void *object, struct module *owner,
 static void serio_remove_pending_events(void *object)
 {
 	struct serio_event *event, *next;
-	unsigned long flags;
 
-	spin_lock_irqsave(&serio_event_lock, flags);
+	guard(spinlock_irqsave)(&serio_event_lock);
 
 	list_for_each_entry_safe(event, next, &serio_event_list, node) {
 		if (event->object == object) {
@@ -296,8 +276,6 @@ static void serio_remove_pending_events(void *object)
 			serio_free_event(event);
 		}
 	}
-
-	spin_unlock_irqrestore(&serio_event_lock, flags);
 }
 
 /*
@@ -309,23 +287,19 @@ static void serio_remove_pending_events(void *object)
 static struct serio *serio_get_pending_child(struct serio *parent)
 {
 	struct serio_event *event;
-	struct serio *serio, *child = NULL;
-	unsigned long flags;
+	struct serio *serio;
 
-	spin_lock_irqsave(&serio_event_lock, flags);
+	guard(spinlock_irqsave)(&serio_event_lock);
 
 	list_for_each_entry(event, &serio_event_list, node) {
 		if (event->type == SERIO_REGISTER_PORT) {
 			serio = event->object;
-			if (serio->parent == parent) {
-				child = serio;
-				break;
-			}
+			if (serio->parent == parent)
+				return serio;
 		}
 	}
 
-	spin_unlock_irqrestore(&serio_event_lock, flags);
-	return child;
+	return NULL;
 }
 
 /*
@@ -376,29 +350,26 @@ static ssize_t drvctl_store(struct device *dev, struct device_attribute *attr, c
 	struct device_driver *drv;
 	int error;
 
-	error = mutex_lock_interruptible(&serio_mutex);
-	if (error)
-		return error;
-
-	if (!strncmp(buf, "none", count)) {
-		serio_disconnect_port(serio);
-	} else if (!strncmp(buf, "reconnect", count)) {
-		serio_reconnect_subtree(serio);
-	} else if (!strncmp(buf, "rescan", count)) {
-		serio_disconnect_port(serio);
-		serio_find_driver(serio);
-		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
-	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
-		serio_disconnect_port(serio);
-		error = serio_bind_driver(serio, to_serio_driver(drv));
-		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
-	} else {
-		error = -EINVAL;
+	scoped_cond_guard(mutex_intr, return -EINTR, &serio_mutex) {
+		if (!strncmp(buf, "none", count)) {
+			serio_disconnect_port(serio);
+		} else if (!strncmp(buf, "reconnect", count)) {
+			serio_reconnect_subtree(serio);
+		} else if (!strncmp(buf, "rescan", count)) {
+			serio_disconnect_port(serio);
+			serio_find_driver(serio);
+			serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
+		} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
+			serio_disconnect_port(serio);
+			error = serio_bind_driver(serio, to_serio_driver(drv));
+			serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
+			return error;
+		} else {
+			return -EINVAL;
+		}
 	}
 
-	mutex_unlock(&serio_mutex);
-
-	return error ? error : count;
+	return count;
 }
 
 static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf)
@@ -520,9 +491,9 @@ static void serio_add_port(struct serio *serio)
 	int error;
 
 	if (parent) {
-		serio_pause_rx(parent);
+		guard(serio_pause_rx)(parent);
+
 		list_add_tail(&serio->child_node, &parent->children);
-		serio_continue_rx(parent);
 	}
 
 	list_add_tail(&serio->node, &serio_list);
@@ -554,9 +525,9 @@ static void serio_destroy_port(struct serio *serio)
 		serio->stop(serio);
 
 	if (serio->parent) {
-		serio_pause_rx(serio->parent);
+		guard(serio_pause_rx)(serio->parent);
+
 		list_del_init(&serio->child_node);
-		serio_continue_rx(serio->parent);
 		serio->parent = NULL;
 	}
 
@@ -697,10 +668,10 @@ EXPORT_SYMBOL(__serio_register_port);
  */
 void serio_unregister_port(struct serio *serio)
 {
-	mutex_lock(&serio_mutex);
+	guard(mutex)(&serio_mutex);
+
 	serio_disconnect_port(serio);
 	serio_destroy_port(serio);
-	mutex_unlock(&serio_mutex);
 }
 EXPORT_SYMBOL(serio_unregister_port);
 
@@ -711,12 +682,12 @@ void serio_unregister_child_port(struct serio *serio)
 {
 	struct serio *s, *next;
 
-	mutex_lock(&serio_mutex);
+	guard(mutex)(&serio_mutex);
+
 	list_for_each_entry_safe(s, next, &serio->children, child_node) {
 		serio_disconnect_port(s);
 		serio_destroy_port(s);
 	}
-	mutex_unlock(&serio_mutex);
 }
 EXPORT_SYMBOL(serio_unregister_child_port);
 
@@ -780,10 +751,10 @@ static void serio_driver_remove(struct device *dev)
 
 static void serio_cleanup(struct serio *serio)
 {
-	mutex_lock(&serio->drv_mutex);
+	guard(mutex)(&serio->drv_mutex);
+
 	if (serio->drv && serio->drv->cleanup)
 		serio->drv->cleanup(serio);
-	mutex_unlock(&serio->drv_mutex);
 }
 
 static void serio_shutdown(struct device *dev)
@@ -822,7 +793,7 @@ void serio_unregister_driver(struct serio_driver *drv)
 {
 	struct serio *serio;
 
-	mutex_lock(&serio_mutex);
+	guard(mutex)(&serio_mutex);
 
 	drv->manual_bind = true;	/* so serio_find_driver ignores it */
 
@@ -837,15 +808,14 @@ void serio_unregister_driver(struct serio_driver *drv)
 	}
 
 	driver_unregister(&drv->driver);
-	mutex_unlock(&serio_mutex);
 }
 EXPORT_SYMBOL(serio_unregister_driver);
 
 static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
 {
-	serio_pause_rx(serio);
+	guard(serio_pause_rx)(serio);
+
 	serio->drv = drv;
-	serio_continue_rx(serio);
 }
 
 static int serio_bus_match(struct device *dev, struct device_driver *drv)
@@ -906,14 +876,14 @@ static int serio_resume(struct device *dev)
 	struct serio *serio = to_serio_port(dev);
 	int error = -ENOENT;
 
-	mutex_lock(&serio->drv_mutex);
-	if (serio->drv && serio->drv->fast_reconnect) {
-		error = serio->drv->fast_reconnect(serio);
-		if (error && error != -ENOENT)
-			dev_warn(dev, "fast reconnect failed with error %d\n",
-				 error);
+	scoped_guard(mutex, &serio->drv_mutex) {
+		if (serio->drv && serio->drv->fast_reconnect) {
+			error = serio->drv->fast_reconnect(serio);
+			if (error && error != -ENOENT)
+				dev_warn(dev, "fast reconnect failed with error %d\n",
+					 error);
+		}
 	}
-	mutex_unlock(&serio->drv_mutex);
 
 	if (error) {
 		/*
@@ -960,21 +930,17 @@ EXPORT_SYMBOL(serio_close);
 irqreturn_t serio_interrupt(struct serio *serio,
 		unsigned char data, unsigned int dfl)
 {
-	unsigned long flags;
-	irqreturn_t ret = IRQ_NONE;
+	guard(spinlock_irqsave)(&serio->lock);
 
-	spin_lock_irqsave(&serio->lock, flags);
+	if (likely(serio->drv))
+		return serio->drv->interrupt(serio, data, dfl);
 
-        if (likely(serio->drv)) {
-                ret = serio->drv->interrupt(serio, data, dfl);
-	} else if (!dfl && device_is_registered(&serio->dev)) {
+	if (!dfl && device_is_registered(&serio->dev)) {
 		serio_rescan(serio);
-		ret = IRQ_HANDLED;
+		return IRQ_HANDLED;
 	}
 
-	spin_unlock_irqrestore(&serio->lock, flags);
-
-	return ret;
+	return IRQ_NONE;
 }
 EXPORT_SYMBOL(serio_interrupt);
 
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (18 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 19/24] Input: serio - use guard notation when acquiring mutexes and spinlocks Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-10-21 20:41   ` Kees Bakker
  2024-09-05  4:17 ` [PATCH 21/24] Input: serio-raw - fix potential serio port name truncation Dmitry Torokhov
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Use guard notation when acquiring mutexes and spinlocks, and when
pausing and resuming serio port. Such guard notation makes the code
more compact and error handling more robust by ensuring that locks
are released in all code paths when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/serio_raw.c | 121 +++++++++++++-------------------
 1 file changed, 49 insertions(+), 72 deletions(-)

diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 0186d1b38f49..aef8301313b2 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -75,41 +75,31 @@ static int serio_raw_open(struct inode *inode, struct file *file)
 {
 	struct serio_raw *serio_raw;
 	struct serio_raw_client *client;
-	int retval;
 
-	retval = mutex_lock_interruptible(&serio_raw_mutex);
-	if (retval)
-		return retval;
+	scoped_guard(mutex_intr, &serio_raw_mutex) {
+		serio_raw = serio_raw_locate(iminor(inode));
+		if (!serio_raw)
+			return -ENODEV;
 
-	serio_raw = serio_raw_locate(iminor(inode));
-	if (!serio_raw) {
-		retval = -ENODEV;
-		goto out;
-	}
+		if (serio_raw->dead)
+			return -ENODEV;
 
-	if (serio_raw->dead) {
-		retval = -ENODEV;
-		goto out;
-	}
+		client = kzalloc(sizeof(*client), GFP_KERNEL);
+		if (!client)
+			return -ENOMEM;
 
-	client = kzalloc(sizeof(*client), GFP_KERNEL);
-	if (!client) {
-		retval = -ENOMEM;
-		goto out;
-	}
+		client->serio_raw = serio_raw;
+		file->private_data = client;
 
-	client->serio_raw = serio_raw;
-	file->private_data = client;
+		kref_get(&serio_raw->kref);
 
-	kref_get(&serio_raw->kref);
+		scoped_guard(serio_pause_rx, serio_raw->serio)
+			list_add_tail(&client->node, &serio_raw->client_list);
 
-	serio_pause_rx(serio_raw->serio);
-	list_add_tail(&client->node, &serio_raw->client_list);
-	serio_continue_rx(serio_raw->serio);
+		return 0;
+	}
 
-out:
-	mutex_unlock(&serio_raw_mutex);
-	return retval;
+	return -EINTR;
 }
 
 static void serio_raw_free(struct kref *kref)
@@ -126,9 +116,8 @@ static int serio_raw_release(struct inode *inode, struct file *file)
 	struct serio_raw_client *client = file->private_data;
 	struct serio_raw *serio_raw = client->serio_raw;
 
-	serio_pause_rx(serio_raw->serio);
-	list_del(&client->node);
-	serio_continue_rx(serio_raw->serio);
+	scoped_guard(serio_pause_rx, serio_raw->serio)
+		list_del(&client->node);
 
 	kfree(client);
 
@@ -139,19 +128,15 @@ static int serio_raw_release(struct inode *inode, struct file *file)
 
 static bool serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
 {
-	bool empty;
+	guard(serio_pause_rx)(serio_raw->serio);
 
-	serio_pause_rx(serio_raw->serio);
-
-	empty = serio_raw->head == serio_raw->tail;
-	if (!empty) {
-		*c = serio_raw->queue[serio_raw->tail];
-		serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
-	}
+	if (serio_raw->head == serio_raw->tail)
+		return false; /* queue is empty */
 
-	serio_continue_rx(serio_raw->serio);
+	*c = serio_raw->queue[serio_raw->tail];
+	serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
 
-	return !empty;
+	return true;
 }
 
 static ssize_t serio_raw_read(struct file *file, char __user *buffer,
@@ -200,40 +185,32 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
 {
 	struct serio_raw_client *client = file->private_data;
 	struct serio_raw *serio_raw = client->serio_raw;
-	int retval = 0;
+	int written;
 	unsigned char c;
 
-	retval = mutex_lock_interruptible(&serio_raw_mutex);
-	if (retval)
-		return retval;
+	scoped_guard(mutex_intr, &serio_raw_mutex) {
+		if (serio_raw->dead)
+			return -ENODEV;
 
-	if (serio_raw->dead) {
-		retval = -ENODEV;
-		goto out;
-	}
+		if (count > 32)
+			count = 32;
 
-	if (count > 32)
-		count = 32;
+		while (count--) {
+			if (get_user(c, buffer++))
+				return -EFAULT;
 
-	while (count--) {
-		if (get_user(c, buffer++)) {
-			retval = -EFAULT;
-			goto out;
-		}
+			if (serio_write(serio_raw->serio, c)) {
+				/* Either signal error or partial write */
+				return written ?: -EIO;
+			}
 
-		if (serio_write(serio_raw->serio, c)) {
-			/* Either signal error or partial write */
-			if (retval == 0)
-				retval = -EIO;
-			goto out;
+			written++;
 		}
 
-		retval++;
+		return written;
 	}
 
-out:
-	mutex_unlock(&serio_raw_mutex);
-	return retval;
+	return -EINTR;
 }
 
 static __poll_t serio_raw_poll(struct file *file, poll_table *wait)
@@ -379,10 +356,10 @@ static void serio_raw_hangup(struct serio_raw *serio_raw)
 {
 	struct serio_raw_client *client;
 
-	serio_pause_rx(serio_raw->serio);
-	list_for_each_entry(client, &serio_raw->client_list, node)
-		kill_fasync(&client->fasync, SIGIO, POLL_HUP);
-	serio_continue_rx(serio_raw->serio);
+	scoped_guard(serio_pause_rx, serio_raw->serio) {
+		list_for_each_entry(client, &serio_raw->client_list, node)
+			kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+	}
 
 	wake_up_interruptible(&serio_raw->wait);
 }
@@ -394,10 +371,10 @@ static void serio_raw_disconnect(struct serio *serio)
 
 	misc_deregister(&serio_raw->dev);
 
-	mutex_lock(&serio_raw_mutex);
-	serio_raw->dead = true;
-	list_del_init(&serio_raw->node);
-	mutex_unlock(&serio_raw_mutex);
+	scoped_guard(mutex, &serio_raw_mutex) {
+		serio_raw->dead = true;
+		list_del_init(&serio_raw->node);
+	}
 
 	serio_raw_hangup(serio_raw);
 
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 21/24] Input: serio-raw - fix potential serio port name truncation
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (19 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 22/24] Input: sun4i-ps2 - use guard notation when acquiring spinlock Dmitry Torokhov
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

When compiling with W=1 the following warnings are triggered:

drivers/input/serio/serio_raw.c: In function ‘serio_raw_connect’:
drivers/input/serio/serio_raw.c:303:28: error: ‘%ld’ directive output may be truncated writing between 1 and 11 bytes into a region of size 7 [-Werror=format-truncation=]
  303 |                  "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));

atomic_inc_return() returns an int, so there is no reason to cast it
to long and print as such. Fix the issue by removing the cast,
printing it as unsigned decimal, and expanding the name from 16 to 20
bytes to accommodate the largest possible port number.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/serio_raw.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index aef8301313b2..e058fef07f57 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -29,7 +29,7 @@ struct serio_raw {
 	unsigned char queue[SERIO_RAW_QUEUE_LEN];
 	unsigned int tail, head;
 
-	char name[16];
+	char name[20];
 	struct kref kref;
 	struct serio *serio;
 	struct miscdevice dev;
@@ -277,7 +277,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
 	}
 
 	snprintf(serio_raw->name, sizeof(serio_raw->name),
-		 "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
+		 "serio_raw%u", atomic_inc_return(&serio_raw_no));
 	kref_init(&serio_raw->kref);
 	INIT_LIST_HEAD(&serio_raw->client_list);
 	init_waitqueue_head(&serio_raw->wait);
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 22/24] Input: sun4i-ps2 - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (20 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 21/24] Input: serio-raw - fix potential serio port name truncation Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 23/24] Input: userio - switch to using cleanup functions Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 24/24] Input: xilinx_ps2 - use guard notation when acquiring spinlock Dmitry Torokhov
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/sun4i-ps2.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c
index 95cd8aaee65d..267214ca9b51 100644
--- a/drivers/input/serio/sun4i-ps2.c
+++ b/drivers/input/serio/sun4i-ps2.c
@@ -101,7 +101,7 @@ static irqreturn_t sun4i_ps2_interrupt(int irq, void *dev_id)
 	unsigned int rxflags = 0;
 	u32 rval;
 
-	spin_lock(&drvdata->lock);
+	guard(spinlock)(&drvdata->lock);
 
 	/* Get the PS/2 interrupts and clear them */
 	intr_status  = readl(drvdata->reg_base + PS2_REG_LSTS);
@@ -134,8 +134,6 @@ static irqreturn_t sun4i_ps2_interrupt(int irq, void *dev_id)
 	writel(intr_status, drvdata->reg_base + PS2_REG_LSTS);
 	writel(fifo_status, drvdata->reg_base + PS2_REG_FSTS);
 
-	spin_unlock(&drvdata->lock);
-
 	return IRQ_HANDLED;
 }
 
@@ -146,7 +144,6 @@ static int sun4i_ps2_open(struct serio *serio)
 	u32 clk_scdf;
 	u32 clk_pcdf;
 	u32 rval;
-	unsigned long flags;
 
 	/* Set line control and enable interrupt */
 	rval = PS2_LCTL_STOPERREN | PS2_LCTL_ACKERREN
@@ -171,9 +168,8 @@ static int sun4i_ps2_open(struct serio *serio)
 	rval = PS2_GCTL_RESET | PS2_GCTL_INTEN | PS2_GCTL_MASTER
 		| PS2_GCTL_BUSEN;
 
-	spin_lock_irqsave(&drvdata->lock, flags);
+	guard(spinlock_irqsave)(&drvdata->lock);
 	writel(rval, drvdata->reg_base + PS2_REG_GCTL);
-	spin_unlock_irqrestore(&drvdata->lock, flags);
 
 	return 0;
 }
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 23/24] Input: userio - switch to using cleanup functions
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (21 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 22/24] Input: sun4i-ps2 - use guard notation when acquiring spinlock Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  2024-09-05  4:17 ` [PATCH 24/24] Input: xilinx_ps2 - use guard notation when acquiring spinlock Dmitry Torokhov
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Use __free() and guard() primitives to simplify the code and error
handling.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/userio.c | 141 +++++++++++++++++------------------
 1 file changed, 70 insertions(+), 71 deletions(-)

diff --git a/drivers/input/serio/userio.c b/drivers/input/serio/userio.c
index a88e2eee55c3..66c9838a1fa7 100644
--- a/drivers/input/serio/userio.c
+++ b/drivers/input/serio/userio.c
@@ -55,18 +55,15 @@ struct userio_device {
 static int userio_device_write(struct serio *id, unsigned char val)
 {
 	struct userio_device *userio = id->port_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&userio->buf_lock, flags);
+	scoped_guard(spinlock_irqsave, &userio->buf_lock) {
+		userio->buf[userio->head] = val;
+		userio->head = (userio->head + 1) % USERIO_BUFSIZE;
 
-	userio->buf[userio->head] = val;
-	userio->head = (userio->head + 1) % USERIO_BUFSIZE;
-
-	if (userio->head == userio->tail)
-		dev_warn(userio_misc.this_device,
-			 "Buffer overflowed, userio client isn't keeping up");
-
-	spin_unlock_irqrestore(&userio->buf_lock, flags);
+		if (userio->head == userio->tail)
+			dev_warn(userio_misc.this_device,
+				 "Buffer overflowed, userio client isn't keeping up");
+	}
 
 	wake_up_interruptible(&userio->waitq);
 
@@ -75,9 +72,8 @@ static int userio_device_write(struct serio *id, unsigned char val)
 
 static int userio_char_open(struct inode *inode, struct file *file)
 {
-	struct userio_device *userio;
-
-	userio = kzalloc(sizeof(*userio), GFP_KERNEL);
+	struct userio_device *userio __free(kfree) =
+			kzalloc(sizeof(*userio), GFP_KERNEL);
 	if (!userio)
 		return -ENOMEM;
 
@@ -86,15 +82,13 @@ static int userio_char_open(struct inode *inode, struct file *file)
 	init_waitqueue_head(&userio->waitq);
 
 	userio->serio = kzalloc(sizeof(*userio->serio), GFP_KERNEL);
-	if (!userio->serio) {
-		kfree(userio);
+	if (!userio->serio)
 		return -ENOMEM;
-	}
 
 	userio->serio->write = userio_device_write;
-	userio->serio->port_data = userio;
+	userio->serio->port_data = userio;;
 
-	file->private_data = userio;
+	file->private_data = no_free_ptr(userio);
 
 	return 0;
 }
@@ -118,14 +112,32 @@ static int userio_char_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
+static size_t userio_fetch_data(struct userio_device *userio, u8 *buf,
+				size_t count, size_t *copylen)
+{
+	size_t available, len;
+
+	guard(spinlock_irqsave)(&userio->buf_lock);
+
+	available = CIRC_CNT_TO_END(userio->head, userio->tail,
+				    USERIO_BUFSIZE);
+	len = min(available, count);
+	if (len) {
+		memcpy(buf, &userio->buf[userio->tail], len);
+		userio->tail = (userio->tail + len) % USERIO_BUFSIZE;
+	}
+
+	*copylen = len;
+	return available;
+}
+
 static ssize_t userio_char_read(struct file *file, char __user *user_buffer,
 				size_t count, loff_t *ppos)
 {
 	struct userio_device *userio = file->private_data;
 	int error;
-	size_t nonwrap_len, copylen;
-	unsigned char buf[USERIO_BUFSIZE];
-	unsigned long flags;
+	size_t available, copylen;
+	u8 buf[USERIO_BUFSIZE];
 
 	/*
 	 * By the time we get here, the data that was waiting might have
@@ -135,21 +147,8 @@ static ssize_t userio_char_read(struct file *file, char __user *user_buffer,
 	 * of course).
 	 */
 	for (;;) {
-		spin_lock_irqsave(&userio->buf_lock, flags);
-
-		nonwrap_len = CIRC_CNT_TO_END(userio->head,
-					      userio->tail,
-					      USERIO_BUFSIZE);
-		copylen = min(nonwrap_len, count);
-		if (copylen) {
-			memcpy(buf, &userio->buf[userio->tail], copylen);
-			userio->tail = (userio->tail + copylen) %
-							USERIO_BUFSIZE;
-		}
-
-		spin_unlock_irqrestore(&userio->buf_lock, flags);
-
-		if (nonwrap_len)
+		available = userio_fetch_data(userio, buf, count, &copylen);
+		if (available)
 			break;
 
 		/* buffer was/is empty */
@@ -176,40 +175,21 @@ static ssize_t userio_char_read(struct file *file, char __user *user_buffer,
 	return copylen;
 }
 
-static ssize_t userio_char_write(struct file *file, const char __user *buffer,
-				 size_t count, loff_t *ppos)
+static int userio_execute_cmd(struct userio_device *userio,
+			      const struct userio_cmd *cmd)
 {
-	struct userio_device *userio = file->private_data;
-	struct userio_cmd cmd;
-	int error;
-
-	if (count != sizeof(cmd)) {
-		dev_warn(userio_misc.this_device, "Invalid payload size\n");
-		return -EINVAL;
-	}
-
-	if (copy_from_user(&cmd, buffer, sizeof(cmd)))
-		return -EFAULT;
-
-	error = mutex_lock_interruptible(&userio->mutex);
-	if (error)
-		return error;
-
-	switch (cmd.type) {
+	switch (cmd->type) {
 	case USERIO_CMD_REGISTER:
 		if (!userio->serio->id.type) {
 			dev_warn(userio_misc.this_device,
 				 "No port type given on /dev/userio\n");
-
-			error = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 
 		if (userio->running) {
 			dev_warn(userio_misc.this_device,
 				 "Begin command sent, but we're already running\n");
-			error = -EBUSY;
-			goto out;
+			return -EBUSY;
 		}
 
 		userio->running = true;
@@ -220,32 +200,51 @@ static ssize_t userio_char_write(struct file *file, const char __user *buffer,
 		if (userio->running) {
 			dev_warn(userio_misc.this_device,
 				 "Can't change port type on an already running userio instance\n");
-			error = -EBUSY;
-			goto out;
+			return -EBUSY;
 		}
 
-		userio->serio->id.type = cmd.data;
+		userio->serio->id.type = cmd->data;
 		break;
 
 	case USERIO_CMD_SEND_INTERRUPT:
 		if (!userio->running) {
 			dev_warn(userio_misc.this_device,
 				 "The device must be registered before sending interrupts\n");
-			error = -ENODEV;
-			goto out;
+			return -ENODEV;
 		}
 
-		serio_interrupt(userio->serio, cmd.data, 0);
+		serio_interrupt(userio->serio, cmd->data, 0);
 		break;
 
 	default:
-		error = -EOPNOTSUPP;
-		goto out;
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static ssize_t userio_char_write(struct file *file, const char __user *buffer,
+				 size_t count, loff_t *ppos)
+{
+	struct userio_device *userio = file->private_data;
+	struct userio_cmd cmd;
+	int error;
+
+	if (count != sizeof(cmd)) {
+		dev_warn(userio_misc.this_device, "Invalid payload size\n");
+		return -EINVAL;
+	}
+
+	if (copy_from_user(&cmd, buffer, sizeof(cmd)))
+		return -EFAULT;
+
+	scoped_cond_guard(mutex_intr, return -EINTR, &userio->mutex) {
+		error = userio_execute_cmd(userio, &cmd);
+		if (error)
+			return error;
 	}
 
-out:
-	mutex_unlock(&userio->mutex);
-	return error ?: count;
+	return count;
 }
 
 static __poll_t userio_char_poll(struct file *file, poll_table *wait)
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 24/24] Input: xilinx_ps2 - use guard notation when acquiring spinlock
  2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
                   ` (22 preceding siblings ...)
  2024-09-05  4:17 ` [PATCH 23/24] Input: userio - switch to using cleanup functions Dmitry Torokhov
@ 2024-09-05  4:17 ` Dmitry Torokhov
  23 siblings, 0 replies; 27+ messages in thread
From: Dmitry Torokhov @ 2024-09-05  4:17 UTC (permalink / raw)
  To: linux-input
  Cc: Pali Rohár, Helge Deller, K. Y. Srinivasan, Wei Liu,
	Dexuan Cui, Samuel Holland, Lyude Paul, Michal Simek,
	Hans de Goede, linux-kernel, linux-hyperv, linux-arm-kernel,
	linux-sunxi

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/xilinx_ps2.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c
index 1543267d02ac..0316760168e5 100644
--- a/drivers/input/serio/xilinx_ps2.c
+++ b/drivers/input/serio/xilinx_ps2.c
@@ -155,22 +155,17 @@ static irqreturn_t xps2_interrupt(int irq, void *dev_id)
 static int sxps2_write(struct serio *pserio, unsigned char c)
 {
 	struct xps2data *drvdata = pserio->port_data;
-	unsigned long flags;
 	u32 sr;
-	int status = -1;
 
-	spin_lock_irqsave(&drvdata->lock, flags);
+	guard(spinlock_irqsave)(&drvdata->lock);
 
 	/* If the PS/2 transmitter is empty send a byte of data */
 	sr = in_be32(drvdata->base_address + XPS2_STATUS_OFFSET);
-	if (!(sr & XPS2_STATUS_TX_FULL)) {
-		out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
-		status = 0;
-	}
+	if (sr & XPS2_STATUS_TX_FULL)
+		return -EAGAIN;
 
-	spin_unlock_irqrestore(&drvdata->lock, flags);
-
-	return status;
+	out_be32(drvdata->base_address + XPS2_TX_DATA_OFFSET, c);
+	return 0;
 }
 
 /**
-- 
2.46.0.469.g59c65b2a67-goog


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 03/24] Input: alps - use guard notation when pausing serio port
  2024-09-05  4:17 ` [PATCH 03/24] Input: alps - use guard notation when pausing serio port Dmitry Torokhov
@ 2024-09-05 15:46   ` Pali Rohár
  0 siblings, 0 replies; 27+ messages in thread
From: Pali Rohár @ 2024-09-05 15:46 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, linux-kernel

On Wednesday 04 September 2024 21:17:08 Dmitry Torokhov wrote:
> Using guard notation makes the code more compact and error handling
> more robust by ensuring that serio ports are resumed in all code paths
> when control leaves critical section.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Looks good for me.
Acked-by: Pali Rohár <pali@kernel.org>

> ---
>  drivers/input/mouse/alps.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
> index 4e37fc3f1a9e..0728b5c08f02 100644
> --- a/drivers/input/mouse/alps.c
> +++ b/drivers/input/mouse/alps.c
> @@ -1585,7 +1585,7 @@ static void alps_flush_packet(struct timer_list *t)
>  	struct alps_data *priv = from_timer(priv, t, timer);
>  	struct psmouse *psmouse = priv->psmouse;
>  
> -	serio_pause_rx(psmouse->ps2dev.serio);
> +	guard(serio_pause_rx)(psmouse->ps2dev.serio);
>  
>  	if (psmouse->pktcnt == psmouse->pktsize) {
>  
> @@ -1605,8 +1605,6 @@ static void alps_flush_packet(struct timer_list *t)
>  		}
>  		psmouse->pktcnt = 0;
>  	}
> -
> -	serio_continue_rx(psmouse->ps2dev.serio);
>  }
>  
>  static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
> -- 
> 2.46.0.469.g59c65b2a67-goog
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources
  2024-09-05  4:17 ` [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources Dmitry Torokhov
@ 2024-10-21 20:41   ` Kees Bakker
  0 siblings, 0 replies; 27+ messages in thread
From: Kees Bakker @ 2024-10-21 20:41 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input

Op 05-09-2024 om 06:17 schreef Dmitry Torokhov:
> Use guard notation when acquiring mutexes and spinlocks, and when
> pausing and resuming serio port. Such guard notation makes the code
> more compact and error handling more robust by ensuring that locks
> are released in all code paths when control leaves critical section.
>
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>   drivers/input/serio/serio_raw.c | 121 +++++++++++++-------------------
>   1 file changed, 49 insertions(+), 72 deletions(-)
>
> diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
> index 0186d1b38f49..aef8301313b2 100644
> [...]
>   static ssize_t serio_raw_read(struct file *file, char __user *buffer,
> @@ -200,40 +185,32 @@ static ssize_t serio_raw_write(struct file *file, const char __user *buffer,
>   {
>   	struct serio_raw_client *client = file->private_data;
>   	struct serio_raw *serio_raw = client->serio_raw;
> -	int retval = 0;
> +	int written;
Didn't you forget to initialize `written` to zero?
> [...]
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2024-10-21 20:41 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-05  4:17 [PATCH 00/24] Convert serio-related drivers to use new cleanup facilities Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 01/24] Input: serio - define serio_pause_rx guard to pause and resume serio ports Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 02/24] Input: libps2 - use guard notation when temporarily pausing " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 03/24] Input: alps - use guard notation when pausing serio port Dmitry Torokhov
2024-09-05 15:46   ` Pali Rohár
2024-09-05  4:17 ` [PATCH 04/24] Input: byd " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 05/24] Input: synaptics " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 06/24] Input: atkbd " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 07/24] Input: sunkbd " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 08/24] Input: synaptics-rmi4 - use guard notation when pausing serio port in F03 Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 09/24] Input: elo - use guard notation when pausing serio port Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 10/24] Input: gscps2 - use guard notation when acquiring spinlock Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 11/24] Input: hyperv-keyboard " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 12/24] Input: i8042 - tease apart interrupt handler Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 13/24] Input: i8042 - use guard notation when acquiring spinlock Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 14/24] Input: ps2-gpio - use guard notation when acquiring mutex Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 15/24] Input: ps2mult - use guard notation when acquiring spinlock Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 16/24] Input: q40kbd " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 17/24] Input: sa1111ps2 " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 18/24] Input: serport " Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 19/24] Input: serio - use guard notation when acquiring mutexes and spinlocks Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 20/24] Input: serio_raw - use guard notation for locks and other resources Dmitry Torokhov
2024-10-21 20:41   ` Kees Bakker
2024-09-05  4:17 ` [PATCH 21/24] Input: serio-raw - fix potential serio port name truncation Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 22/24] Input: sun4i-ps2 - use guard notation when acquiring spinlock Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 23/24] Input: userio - switch to using cleanup functions Dmitry Torokhov
2024-09-05  4:17 ` [PATCH 24/24] Input: xilinx_ps2 - use guard notation when acquiring spinlock Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).