]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Input: cros_ec_keyb - factor out column processing
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 23 Feb 2026 21:31:12 +0000 (13:31 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 23 Feb 2026 21:47:52 +0000 (13:47 -0800)
Factor out column processing and eagerly skip processing columns that do
not have any changes in them.

Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260222003717.471977-7-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/keyboard/cros_ec_keyb.c

index d11c9d4940040c35d79236c50ce4d1b6c77fdc3a..177e5d4a3382cb54440a37a014f8533d24f34ca0 100644 (file)
@@ -254,6 +254,26 @@ static void cros_ec_keyb_process_key_fn_map(struct cros_ec_keyb *ckdev,
        input_report_key(idev, code, state);
 }
 
+static void cros_ec_keyb_process_col(struct cros_ec_keyb *ckdev, int col,
+                                    u8 col_state, u8 changed)
+{
+       for (int row = 0; row < ckdev->rows; row++) {
+               if (changed & BIT(row)) {
+                       u8 key_state = col_state & BIT(row);
+
+                       dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n",
+                               row, col, key_state);
+
+                       if (ckdev->has_fn_map)
+                               cros_ec_keyb_process_key_fn_map(ckdev, row, col,
+                                                               key_state);
+                       else
+                               cros_ec_keyb_process_key_plain(ckdev, row, col,
+                                                              key_state);
+               }
+       }
+}
+
 /*
  * Compares the new keyboard state to the old one and produces key
  * press/release events accordingly.  The keyboard state is one byte
@@ -261,10 +281,6 @@ static void cros_ec_keyb_process_key_fn_map(struct cros_ec_keyb *ckdev,
  */
 static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, u8 *kb_state, int len)
 {
-       int col, row;
-       int new_state;
-       int old_state;
-
        if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
                /*
                 * Simple-minded solution: ignore this state. The obvious
@@ -275,24 +291,15 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, u8 *kb_state, int l
                return;
        }
 
-       for (col = 0; col < ckdev->cols; col++) {
-               for (row = 0; row < ckdev->rows; row++) {
-                       new_state = kb_state[col] & BIT(row);
-                       old_state = ckdev->old_kb_state[col] & BIT(row);
-
-                       if (new_state == old_state)
-                               continue;
-
-                       dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n",
-                               row, col, new_state);
+       for (int col = 0; col < ckdev->cols; col++) {
+               u8 changed = kb_state[col] ^ ckdev->old_kb_state[col];
 
-                       if (ckdev->has_fn_map)
-                               cros_ec_keyb_process_key_fn_map(ckdev, row, col, new_state);
-                       else
-                               cros_ec_keyb_process_key_plain(ckdev, row, col, new_state);
-               }
-               ckdev->old_kb_state[col] = kb_state[col];
+               if (changed)
+                       cros_ec_keyb_process_col(ckdev, col, kb_state[col],
+                                                changed);
        }
+
+       memcpy(ckdev->old_kb_state, kb_state, sizeof(ckdev->old_kb_state));
        input_sync(ckdev->idev);
 }