Bladeren bron

Update v5.12 patches

Changes:
 - SAM:
   - Fix bug when disabling events.
   - Add support for forwarding events to user-space via debug device.

 - Work around bug preventing IRQ setup and subsequently SAM drivers from
   loading on the 13" AMD Surface Laptop 4.

 - Add quirk to prevent incorrect battery reporting via the Surface Go
   touchscreen.

Links:
 - SAM: https://github.com/linux-surface/surface-aggregator-module/commit/6b6edef7c794363f5a036784474fe46422d5da70
 - kernel: https://github.com/linux-surface/kernel/commit/41c3cb408425de97370d73097bcdee614384e4c0
Maximilian Luz 4 jaren geleden
bovenliggende
commit
2ed5d39129

+ 1 - 1
patches/5.12/0001-surface3-oemb.patch

@@ -1,4 +1,4 @@
-From e32193f759f5015304c1b166f57a08a0e2aebc9c Mon Sep 17 00:00:00 2001
+From 0b7d702ff3d3e80a5b4550e87f0dc4fdf921065f Mon Sep 17 00:00:00 2001
 From: Tsuchiya Yuto <kitakar@gmail.com>
 Date: Sun, 18 Oct 2020 16:42:44 +0900
 Subject: [PATCH] (surface3-oemb) add DMI matches for Surface 3 with broken DMI

+ 26 - 26
patches/5.12/0002-mwifiex.patch

@@ -1,4 +1,4 @@
-From 0aef6b916936b29043d7b13664b73f1d8982159c Mon Sep 17 00:00:00 2001
+From 98ebfc6454882e275332c76d655f595d2d6806fd Mon Sep 17 00:00:00 2001
 From: Tsuchiya Yuto <kitakar@gmail.com>
 Date: Mon, 28 Sep 2020 17:46:49 +0900
 Subject: [PATCH] mwifiex: pcie: add DMI-based quirk impl for Surface devices
@@ -206,7 +206,7 @@ index 000000000000..5326ae7e5671
 -- 
 2.31.1
 
-From 00f9b02f1345a3149e9ac363f31751af8eb46ae6 Mon Sep 17 00:00:00 2001
+From 5cc746ee1210ad5363479196ae8fb4c7e303ea34 Mon Sep 17 00:00:00 2001
 From: Tsuchiya Yuto <kitakar@gmail.com>
 Date: Tue, 29 Sep 2020 17:25:22 +0900
 Subject: [PATCH] mwifiex: pcie: add reset_d3cold quirk for Surface gen4+
@@ -407,7 +407,7 @@ index 5326ae7e5671..8b9dcb5070d8 100644
 -- 
 2.31.1
 
-From 281569bd050a8ca25436c6ca709b197d4bb49843 Mon Sep 17 00:00:00 2001
+From 0b5b8849304e9b3866f5f18ec4bb420dc876001c Mon Sep 17 00:00:00 2001
 From: Tsuchiya Yuto <kitakar@gmail.com>
 Date: Tue, 29 Sep 2020 17:32:22 +0900
 Subject: [PATCH] mwifiex: pcie: add reset_wsid quirk for Surface 3
@@ -586,7 +586,7 @@ index 8b9dcb5070d8..3ef7440418e3 100644
 -- 
 2.31.1
 
-From be3356648a559869236bd6c9bf1212d8e78db9d3 Mon Sep 17 00:00:00 2001
+From 57f08db99446c4838288bd5d4ca21ab4ee44dd19 Mon Sep 17 00:00:00 2001
 From: Tsuchiya Yuto <kitakar@gmail.com>
 Date: Wed, 30 Sep 2020 18:08:24 +0900
 Subject: [PATCH] mwifiex: pcie: (OEMB) add quirk for Surface 3 with broken DMI
@@ -648,7 +648,7 @@ index f0a6fa0a7ae5..34dcd84f02a6 100644
 -- 
 2.31.1
 
-From 2d5e92b5d97093c4f44eb2ac123cf141a890bb28 Mon Sep 17 00:00:00 2001
+From 4b9bbee449db156d0be90952cb63ff5bc87d9571 Mon Sep 17 00:00:00 2001
 From: Tsuchiya Yuto <kitakar@gmail.com>
 Date: Sun, 4 Oct 2020 00:11:49 +0900
 Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+
@@ -803,7 +803,7 @@ index 3ef7440418e3..a95ebac06e13 100644
 -- 
 2.31.1
 
-From 9b0b59c12ab94db6703a74119b36a8feb64d4217 Mon Sep 17 00:00:00 2001
+From b9d0f717c806b9352950ce64dbe29a8054b561c2 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 3 Nov 2020 13:28:04 +0100
 Subject: [PATCH] mwifiex: Add quirk resetting the PCI bridge on MS Surface
@@ -970,7 +970,7 @@ index a95ebac06e13..4ec2ae72f632 100644
 -- 
 2.31.1
 
-From 7565dad537b399a2572aa395f7b6175d3aa73d0f Mon Sep 17 00:00:00 2001
+From 68011fe772d7e1fd4ee45cf1dbd585571989ae4e Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Thu, 25 Mar 2021 11:33:02 +0100
 Subject: [PATCH] Bluetooth: btusb: Lower passive lescan interval on Marvell
@@ -1048,7 +1048,7 @@ index 4a901508e48e..e69ebe224566 100644
 -- 
 2.31.1
 
-From ccf9b0283ecb585491d210112fca7118e8389271 Mon Sep 17 00:00:00 2001
+From 75a76e714ed0a2c55d1b7dd883d4f977c2aea047 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Wed, 11 Nov 2020 12:31:26 +0100
 Subject: [PATCH] mwifiex: Small cleanup for handling virtual interface type
@@ -1149,7 +1149,7 @@ index a2ed268ce0da..789de1b0c5b1 100644
 -- 
 2.31.1
 
-From 25a98041e86b9992322b8a4811dd1601449ac7c7 Mon Sep 17 00:00:00 2001
+From ca337fdd043efa39580192c036e37956fcbadcf5 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 10 Nov 2020 12:49:56 +0100
 Subject: [PATCH] mwifiex: Use non-posted PCI register writes
@@ -1206,7 +1206,7 @@ index 8a99e243aff2..84b1d30e07e4 100644
 -- 
 2.31.1
 
-From c2384d6540fb2b2a0e077f256b41ca79cebfbac7 Mon Sep 17 00:00:00 2001
+From ba021eb98178c6579f0b9b42828c6f6d68e16af5 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Wed, 11 Nov 2020 12:44:39 +0100
 Subject: [PATCH] mwifiex: Use function to check whether interface type change
@@ -1439,7 +1439,7 @@ index 789de1b0c5b1..13698818e58a 100644
 -- 
 2.31.1
 
-From 93ae52288c36fe63952dd86cf51ba47d9dc06c03 Mon Sep 17 00:00:00 2001
+From 3787c5a02d28b6daefa8ee517d5f544fdf7fc56e Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Wed, 11 Nov 2020 13:33:04 +0100
 Subject: [PATCH] mwifiex: Run SET_BSS_MODE when changing from P2P to STATION
@@ -1507,7 +1507,7 @@ index 13698818e58a..f5b9f1d26114 100644
 -- 
 2.31.1
 
-From b9e5ad7cf003ff39a26d5dfe5418776a6a2188c3 Mon Sep 17 00:00:00 2001
+From 4abee5b35000507095db69c8b8e6212ffce70404 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Wed, 11 Nov 2020 14:42:54 +0100
 Subject: [PATCH] mwifiex: Use helper function for counting interface types
@@ -1683,7 +1683,7 @@ index f5b9f1d26114..44cff715bf29 100644
 -- 
 2.31.1
 
-From 26c1940301224a570733c8bbc1410b6f69482541 Mon Sep 17 00:00:00 2001
+From 42329bd1f3386c7518eb8aff85fc333df57f9751 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Fri, 26 Mar 2021 15:56:58 +0100
 Subject: [PATCH] mwifiex: Update virtual interface counters right after
@@ -1786,7 +1786,7 @@ index 44cff715bf29..e637129a411f 100644
 -- 
 2.31.1
 
-From ddae0a553a63830167d42b250033995c65ed1503 Mon Sep 17 00:00:00 2001
+From ee520b6a494804b43aff75673fd447dbc88c6221 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Wed, 11 Nov 2020 13:42:40 +0100
 Subject: [PATCH] mwifiex: Allow switching interface type from P2P_CLIENT to
@@ -1875,7 +1875,7 @@ index e637129a411f..395573db6405 100644
 -- 
 2.31.1
 
-From b112df31313ca22f9a941aca8782e98e69c6de21 Mon Sep 17 00:00:00 2001
+From 3d13d13fd53674b4f7066d7bc3517122473c6a9a Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Fri, 26 Mar 2021 15:31:08 +0100
 Subject: [PATCH] mwifiex: Handle interface type changes from AP to STATION
@@ -1902,7 +1902,7 @@ index 395573db6405..90a757aa0b25 100644
 -- 
 2.31.1
 
-From 58eb72275515f416b4499da7c5e693ad10be1913 Mon Sep 17 00:00:00 2001
+From 4c2aff52d7917a6e1143e259f889f2ee611d2305 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Fri, 26 Mar 2021 15:32:16 +0100
 Subject: [PATCH] mwifiex: Properly initialize private structure on interface
@@ -1957,7 +1957,7 @@ index 90a757aa0b25..0c01d8f9048e 100644
 -- 
 2.31.1
 
-From f8a4c649f696fc361022cde2bf20a2cefa6f4588 Mon Sep 17 00:00:00 2001
+From ede2847b36d421e780be5f3ed1751a67bc4f2197 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Sat, 27 Mar 2021 12:19:14 +0100
 Subject: [PATCH] mwifiex: Fix copy-paste mistake when creating virtual
@@ -1989,7 +1989,7 @@ index 0c01d8f9048e..8c472b2d982a 100644
 -- 
 2.31.1
 
-From 2d7663ab1ffdb66950aa9dab732dd00e655f8544 Mon Sep 17 00:00:00 2001
+From 133335d748375f7826a154e0f6eca36065289b64 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Sun, 28 Mar 2021 21:10:06 +0200
 Subject: [PATCH] mwifiex: Try waking the firmware until we get an interrupt
@@ -2078,7 +2078,7 @@ index 84b1d30e07e4..88d30ec6d57d 100644
 -- 
 2.31.1
 
-From a0069a2759d304f866462c26414ab0822e52436a Mon Sep 17 00:00:00 2001
+From 5474582b5e5f9a43629caa3fe0c9a235502a8335 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 13 Apr 2021 14:30:28 +0200
 Subject: [PATCH] mwifiex: Deactive host sleep using HSCFG after it was
@@ -2234,7 +2234,7 @@ index d3a968ef21ef..76db9a7b8199 100644
 -- 
 2.31.1
 
-From 6ffcb13111c25bd6551e2d1b85a279c123093d2c Mon Sep 17 00:00:00 2001
+From 4a162ffaeea061ec940104b40121fc6dc2d5d8df Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 13 Apr 2021 14:23:05 +0200
 Subject: [PATCH] mwifiex: Add quirk to disable deep sleep with certain
@@ -2337,7 +2337,7 @@ index 6b5d35d9e69f..8e49ebca1847 100644
 -- 
 2.31.1
 
-From a84e9db5063e20ed7378f1c5ad30b204ed929b3d Mon Sep 17 00:00:00 2001
+From 62e5303cd8c507b4b8e53ee84aa9ba9f80404e98 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Wed, 11 Nov 2020 15:17:07 +0100
 Subject: [PATCH] mwifiex: Don't log error on suspend if wake-on-wlan is
@@ -2369,7 +2369,7 @@ index 8c472b2d982a..153025d1b2fa 100644
 -- 
 2.31.1
 
-From 28e081c5ac395edfc8bc993a96925795c786bdbf Mon Sep 17 00:00:00 2001
+From fec159688c4c8d0c096a3b2deaa47a1d2d22b4fb Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Sun, 28 Mar 2021 21:42:54 +0200
 Subject: [PATCH] mwifiex: Log an error on command failure during key-material
@@ -2409,7 +2409,7 @@ index 153025d1b2fa..ef6ce3f63aec 100644
 -- 
 2.31.1
 
-From 9b5097c53271f00a4360e4648eabcec2cb3dee9d Mon Sep 17 00:00:00 2001
+From eea252f1a184557646a14d7fccd44827f47b4c0e Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 13 Apr 2021 12:44:03 +0200
 Subject: [PATCH] mwifiex: Fix an incorrect comment
@@ -2437,7 +2437,7 @@ index 6696bce56178..b0695432b26a 100644
 -- 
 2.31.1
 
-From 3947daf26cebed21fdd532677b3def6dd4d49385 Mon Sep 17 00:00:00 2001
+From 18a6c332038f9be7a6dbb0c19f6abd98affa1407 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 13 Apr 2021 12:45:59 +0200
 Subject: [PATCH] mwifiex: Send DELBA requests according to spec
@@ -2480,7 +2480,7 @@ index b0695432b26a..9ff2058bcd7e 100644
 -- 
 2.31.1
 
-From 5628ca91778c31ab1ff2a7be53f372082355e929 Mon Sep 17 00:00:00 2001
+From e6cb7bd319a6d34ab059be62c8ec280550f40215 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Tue, 13 Apr 2021 12:57:41 +0200
 Subject: [PATCH] mwifiex: Ignore BTCOEX events from the firmware
@@ -2518,7 +2518,7 @@ index 68c63268e2e6..933111a3511c 100644
 -- 
 2.31.1
 
-From 7da03fe0645b284f55dae8618184fcad34d2d180 Mon Sep 17 00:00:00 2001
+From b258bfaa0c4788b2d8221a8d9b808ab429c3325c Mon Sep 17 00:00:00 2001
 From: Brian Norris <briannorris@chromium.org>
 Date: Fri, 14 May 2021 19:42:27 -0700
 Subject: [PATCH] mwifiex: bring down link before deleting interface

+ 1 - 1
patches/5.12/0003-ath10k.patch

@@ -1,4 +1,4 @@
-From c88e9d8da7a3c9adbb3a9f01cfab90c00c70fdf6 Mon Sep 17 00:00:00 2001
+From d5c1e06cf9c5c98f534ddcc56aecb3ed95a154bb Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 27 Feb 2021 00:45:52 +0100
 Subject: [PATCH] ath10k: Add module parameters to override board files

+ 2 - 2
patches/5.12/0004-ipts.patch

@@ -1,4 +1,4 @@
-From 7736b0d22c072170eb82cf72cf51d244ec324324 Mon Sep 17 00:00:00 2001
+From 37d30bfc9cbb42c28a2e4a5ceb957789337967b3 Mon Sep 17 00:00:00 2001
 From: Dorian Stoll <dorian.stoll@tmsp.io>
 Date: Thu, 30 Jul 2020 13:21:53 +0200
 Subject: [PATCH] misc: mei: Add missing IPTS device IDs
@@ -36,7 +36,7 @@ index c3393b383e59..0098f98426c1 100644
 -- 
 2.31.1
 
-From 27f03a1bb1b2da7d19a997a57b28bd0d47811485 Mon Sep 17 00:00:00 2001
+From c18bb81733f1819ef21665f3929f642a9d1d4b34 Mon Sep 17 00:00:00 2001
 From: Dorian Stoll <dorian.stoll@tmsp.io>
 Date: Thu, 6 Aug 2020 11:20:41 +0200
 Subject: [PATCH] misc: Add support for Intel Precise Touch & Stylus

+ 2 - 2
patches/5.12/0005-surface-sam-over-hid.patch

@@ -1,4 +1,4 @@
-From aa1fa4f78bd8dafe45d140385b2ea50e8f1c56d3 Mon Sep 17 00:00:00 2001
+From 7ab2ec4dac982191ec138367e3aef13998155445 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 25 Jul 2020 17:19:53 +0200
 Subject: [PATCH] i2c: acpi: Implement RawBytes read access
@@ -110,7 +110,7 @@ index 8ceaa88dd78f..deceed0d76c6 100644
 -- 
 2.31.1
 
-From 85bc7f0b733802d4e7fda5997973b4f6f8ef9ed2 Mon Sep 17 00:00:00 2001
+From 43f8060274256ac0b05c42216961e77c3efd8b29 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sat, 13 Feb 2021 16:41:18 +0100
 Subject: [PATCH] platform/surface: Add driver for Surface Book 1 dGPU switch

+ 1983 - 150
patches/5.12/0006-surface-sam.patch

@@ -1,4 +1,4 @@
-From 5c461f9a02a6b246cd5d6f336e9857f68e3f33f5 Mon Sep 17 00:00:00 2001
+From dcb58a8f57f0fe583ec6547a8ec3d11a10283aa2 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 12 Feb 2021 12:54:34 +0100
 Subject: [PATCH] platform/surface: Set up Surface Aggregator device registry
@@ -396,7 +396,7 @@ index 000000000000..a051d941ad96
 -- 
 2.31.1
 
-From b16adfbcbbcfcb91a12bbef70e97d5fcb46fc738 Mon Sep 17 00:00:00 2001
+From bd9ec0b3ff53a71c2b1a2c724b753af409a5ec54 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 12 Feb 2021 12:54:35 +0100
 Subject: [PATCH] platform/surface: aggregator_registry: Add base device hub
@@ -725,7 +725,7 @@ index a051d941ad96..6c23d75a044c 100644
 -- 
 2.31.1
 
-From 7043f508f8f6436aa15bcd10b06162de51492b3c Mon Sep 17 00:00:00 2001
+From 2af15024e9648d0dc1ef1d7abd7ac9eb6659c6b2 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 12 Feb 2021 12:54:36 +0100
 Subject: [PATCH] platform/surface: aggregator_registry: Add battery subsystem
@@ -814,7 +814,7 @@ index 6c23d75a044c..cde279692842 100644
 -- 
 2.31.1
 
-From ec9ff6fd822f864d1e7a79d49f3fe04ae94541d7 Mon Sep 17 00:00:00 2001
+From 69b3eb33af3167156be96cdcd5c5c9c4952ae9aa Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 12 Feb 2021 12:54:37 +0100
 Subject: [PATCH] platform/surface: aggregator_registry: Add platform profile
@@ -916,7 +916,7 @@ index cde279692842..33904613dd4b 100644
 -- 
 2.31.1
 
-From 3a39df8ec143ff5544ca9782b0fbdcdabe102f14 Mon Sep 17 00:00:00 2001
+From 9bd7f46ec3d7999f4b1f9d4225bb58d4cc0d16c7 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 12 Feb 2021 12:54:38 +0100
 Subject: [PATCH] platform/surface: aggregator_registry: Add DTX device
@@ -960,7 +960,7 @@ index 33904613dd4b..dc044d06828b 100644
 -- 
 2.31.1
 
-From b9f0fb9a6e1ccafadcab8db17f47cf2710ec355e Mon Sep 17 00:00:00 2001
+From 229bf15da7ff9158a9655d3a87af1e1a10bcf222 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 12 Feb 2021 12:54:39 +0100
 Subject: [PATCH] platform/surface: aggregator_registry: Add HID subsystem
@@ -1056,7 +1056,7 @@ index dc044d06828b..caee90d135c5 100644
 -- 
 2.31.1
 
-From 0299787a20eaab2f25644780c5bdd5c6b5673a20 Mon Sep 17 00:00:00 2001
+From 07a77412635bee826d430cc6abb3aa568f62f98e Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Thu, 11 Feb 2021 21:17:03 +0100
 Subject: [PATCH] platform/surface: Add platform profile driver
@@ -1342,7 +1342,7 @@ index 000000000000..0081b01a5b0f
 -- 
 2.31.1
 
-From 5968fbbdf26439b3f999e793e94b2c08e53e24f7 Mon Sep 17 00:00:00 2001
+From 54aa4ce443abfea49d246dc67f0f7b5286657cef Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Thu, 4 Mar 2021 20:05:24 +0100
 Subject: [PATCH] platform/surface: aggregator: Make SSAM_DEFINE_SYNC_REQUEST_x
@@ -1721,7 +1721,7 @@ index 02f3e06c0a60..4441ad667c3f 100644
 -- 
 2.31.1
 
-From 5735d958ba853c98ae717fab7a34422e4d751d44 Mon Sep 17 00:00:00 2001
+From f59d83ae545f4c18318b43d1144d1334317cf3b8 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Mon, 8 Mar 2021 19:48:17 +0100
 Subject: [PATCH] platform/surface: Add DTX driver
@@ -3216,7 +3216,7 @@ index 000000000000..0833aab0d819
 -- 
 2.31.1
 
-From 417d833545576dd36bbb06fed755e36df3ce3fd0 Mon Sep 17 00:00:00 2001
+From bc8b498c4f1081aabfa9261e515553f410073d75 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Mon, 8 Mar 2021 19:48:18 +0100
 Subject: [PATCH] platform/surface: dtx: Add support for native SSAM devices
@@ -3360,7 +3360,7 @@ index 1301fab0ea14..85451eb94d98 100644
 -- 
 2.31.1
 
-From 301765a4e7059b8b9f5a5880af86c4d34569e6f4 Mon Sep 17 00:00:00 2001
+From e8c0afe52bc86bfa6a14f2899d5b0fc9e61f3d47 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Mon, 8 Mar 2021 19:48:19 +0100
 Subject: [PATCH] docs: driver-api: Add Surface DTX driver documentation
@@ -4131,7 +4131,7 @@ index 3917e7363520..da1487d672a8 100644
 -- 
 2.31.1
 
-From c261be4c4eeae67003121fea202b82355b22fe77 Mon Sep 17 00:00:00 2001
+From cece957db61033a054636e1ff4b70bc6a8aa054e Mon Sep 17 00:00:00 2001
 From: Wei Yongjun <weiyongjun1@huawei.com>
 Date: Tue, 9 Mar 2021 13:15:00 +0000
 Subject: [PATCH] platform/surface: aggregator_registry: Make symbol
@@ -4172,7 +4172,7 @@ index cdb4a95af3e8..86cff5fce3cd 100644
 -- 
 2.31.1
 
-From 7558be23268e2d43cc2725fbec42c80d91c52d5b Mon Sep 17 00:00:00 2001
+From f074f513475531795dad0bdeb0b2c7cf79e3e9eb Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Tue, 9 Mar 2021 17:25:50 +0100
 Subject: [PATCH] platform/surface: aggregator_registry: Add support for
@@ -4215,7 +4215,7 @@ index 86cff5fce3cd..eccb9d1007cd 100644
 -- 
 2.31.1
 
-From 56e9ce401cedc186252ad15ab362334fbd68d3bd Mon Sep 17 00:00:00 2001
+From 43260dfd900086851f69edcd9b94831c441a9d51 Mon Sep 17 00:00:00 2001
 From: kernel test robot <lkp@intel.com>
 Date: Fri, 19 Mar 2021 13:19:19 +0800
 Subject: [PATCH] platform/surface: fix semicolon.cocci warnings
@@ -4254,7 +4254,7 @@ index 85451eb94d98..1fedacf74050 100644
 -- 
 2.31.1
 
-From f27208707d150ce3b84900b7df258238741bfec4 Mon Sep 17 00:00:00 2001
+From c695dfb0b969183132fd24df40714f7ceca5f206 Mon Sep 17 00:00:00 2001
 From: Dan Carpenter <dan.carpenter@oracle.com>
 Date: Fri, 26 Mar 2021 15:28:48 +0300
 Subject: [PATCH] platform/surface: clean up a variable in surface_dtx_read()
@@ -4287,7 +4287,7 @@ index 1fedacf74050..63ce587e79e3 100644
 -- 
 2.31.1
 
-From be7af3efc60f54e6c4cd21d42be2860633235c4f Mon Sep 17 00:00:00 2001
+From 239774ce54113c05ef8aac87c2ac55a8fa5aac40 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Tue, 6 Apr 2021 01:12:22 +0200
 Subject: [PATCH] platform/surface: aggregator_registry: Give devices time to
@@ -4530,7 +4530,7 @@ index eccb9d1007cd..685d37a7add1 100644
 -- 
 2.31.1
 
-From 36e55444909bf68c59d82835f78aef1a3be0881b Mon Sep 17 00:00:00 2001
+From a82ba318a67ccda352ec4da4e8508444488871b1 Mon Sep 17 00:00:00 2001
 From: Barry Song <song.bao.hua@hisilicon.com>
 Date: Wed, 3 Mar 2021 11:49:15 +1300
 Subject: [PATCH] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
@@ -4632,7 +4632,7 @@ index 21ea370fccda..49288e941365 100644
 -- 
 2.31.1
 
-From d9db3c8d39f1366a9f05862bc65c6eb5e208c3aa Mon Sep 17 00:00:00 2001
+From d85c3cdfefbcd2e1ecbd398772fcd3474bab0661 Mon Sep 17 00:00:00 2001
 From: Tian Tao <tiantao6@hisilicon.com>
 Date: Wed, 7 Apr 2021 15:00:52 +0800
 Subject: [PATCH] platform/surface: aggregator: move to use request_irq by
@@ -4679,7 +4679,7 @@ index 88ec47cae5bf..69e86cd599d3 100644
 -- 
 2.31.1
 
-From e82b875bbb6a4d80eaa5e7022aafcc6f2f590239 Mon Sep 17 00:00:00 2001
+From eda77d8351b45e6c13aacf14a9ea21d0839c1a31 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Wed, 5 May 2021 14:53:45 +0200
 Subject: [PATCH] platform/surface: aggregator: Do not mark interrupt as shared
@@ -4713,7 +4713,7 @@ index 69e86cd599d3..8a70df60142c 100644
 -- 
 2.31.1
 
-From 8534eb8c810e91034f58356fd4dca34d46b32201 Mon Sep 17 00:00:00 2001
+From 2e9b2a7bdfd237c79513ffde0bb969af71ca43ed Mon Sep 17 00:00:00 2001
 From: Arnd Bergmann <arnd@arndb.de>
 Date: Fri, 14 May 2021 22:04:36 +0200
 Subject: [PATCH] platform/surface: aggregator: avoid clang
@@ -4772,7 +4772,7 @@ index 4441ad667c3f..6ff9c58b3e17 100644
 -- 
 2.31.1
 
-From 2f433f0e29771d13fc697b13bad1eb306523c288 Mon Sep 17 00:00:00 2001
+From 5aeaf1c3cca06f4618066090ecb10b546c873665 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Thu, 13 May 2021 15:44:37 +0200
 Subject: [PATCH] platform/surface: dtx: Fix poll function
@@ -4825,7 +4825,7 @@ index 63ce587e79e3..5d9b758a99bb 100644
 -- 
 2.31.1
 
-From a027c734d4863d1245dc0d4f8c1f4cdf40b381ac Mon Sep 17 00:00:00 2001
+From f36b21af1d1bc804d795b88092709c6fefaaed71 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sun, 23 May 2021 14:35:37 +0200
 Subject: [PATCH] platform/surface: aggregator_registry: Update comments for
@@ -4866,7 +4866,7 @@ index 685d37a7add1..bdc09305aab7 100644
 -- 
 2.31.1
 
-From 7bfc49cfe5e74b8855cbb47eadf0b75f976d0d78 Mon Sep 17 00:00:00 2001
+From 33a4abdf331ded09dc8ecabba5299850ccc1bcda Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sun, 23 May 2021 14:36:36 +0200
 Subject: [PATCH] platform/surface: aggregator_registry: Add support for 13"
@@ -4901,7 +4901,7 @@ index bdc09305aab7..ef83461fa536 100644
 -- 
 2.31.1
 
-From 1d2e9c298aa07705bfad5a315bdfad1c1acce683 Mon Sep 17 00:00:00 2001
+From 4c3766c4321c57bb85061182da336015ada24e30 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Sun, 23 May 2021 14:09:42 +0200
 Subject: [PATCH] platform/surface: aggregator_registry: Consolidate node
@@ -5017,7 +5017,43 @@ index ef83461fa536..4428c4330229 100644
 -- 
 2.31.1
 
-From f7e73dd4bed428c2b31057b80158b8057fe38fc1 Mon Sep 17 00:00:00 2001
+From 6622a1d5af0578d429365c6446800995b2185c18 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Thu, 3 Jun 2021 01:48:36 +0200
+Subject: [PATCH] platform/surface: aggregator: Fix event disable function
+
+Disabling events silently fails due to the wrong command ID being used.
+Instead of the command ID for the disable call, the command ID for the
+enable call was being used. This causes the disable call to enable the
+event instead. As the event is already enabled when we call this
+function, the EC silently drops this command and does nothing.
+
+Use the correct command ID for disabling the event to fix this.
+
+Fixes: c167b9c7e3d6 ("platform/surface: Add Surface Aggregator subsystem")
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-sam
+---
+ drivers/platform/surface/aggregator/controller.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
+index 8a70df60142c..a06964aa96e7 100644
+--- a/drivers/platform/surface/aggregator/controller.c
++++ b/drivers/platform/surface/aggregator/controller.c
+@@ -1907,7 +1907,7 @@ static int ssam_ssh_event_disable(struct ssam_controller *ctrl,
+ {
+ 	int status;
+ 
+-	status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags);
++	status = __ssam_ssh_event_request(ctrl, reg, reg.cid_disable, id, flags);
+ 
+ 	if (status < 0 && status != -EINVAL) {
+ 		ssam_err(ctrl,
+-- 
+2.31.1
+
+From 24abeff8201a18003455de6faf654f5d50bde18f Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Wed, 10 Mar 2021 23:53:28 +0100
 Subject: [PATCH] HID: Add support for Surface Aggregator Module HID transport
@@ -5764,7 +5800,7 @@ index 000000000000..4b1a7b57e035
 -- 
 2.31.1
 
-From b5110e05305e02692a39e7d5b2a8f3d5ba9731cd Mon Sep 17 00:00:00 2001
+From 30f692e029bec71885d3a9f2adab1d4cba69d350 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Wed, 10 Mar 2021 23:53:29 +0100
 Subject: [PATCH] HID: surface-hid: Add support for legacy keyboard interface
@@ -6135,7 +6171,7 @@ index 000000000000..0635341bc517
 -- 
 2.31.1
 
-From 19e09ba208abd318e6e56144a8a790f79f33fee0 Mon Sep 17 00:00:00 2001
+From 16a10fc4c1e9bb44e0aa87b2a5a63f8a06ea9f0a Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Fri, 23 Apr 2021 00:51:22 +0200
 Subject: [PATCH] HID: surface-hid: Fix integer endian conversion
@@ -6174,7 +6210,7 @@ index 7b27ec392232..5571e74abe91 100644
 -- 
 2.31.1
 
-From 8ed1e8336e7291c251e922c28f5af6bb0e7e681b Mon Sep 17 00:00:00 2001
+From 92843e081e10746ded52926df2533cb396967b13 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Tue, 6 Apr 2021 01:41:25 +0200
 Subject: [PATCH] power: supply: Add battery driver for Surface Aggregator
@@ -7156,7 +7192,7 @@ index 000000000000..4116dd839ecd
 -- 
 2.31.1
 
-From 546ce7efc021b0f3b3832f2f7df0679da3e18b22 Mon Sep 17 00:00:00 2001
+From da2fad54ff23a696162c443023b3905fd78e52e6 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Tue, 6 Apr 2021 01:41:26 +0200
 Subject: [PATCH] power: supply: Add AC driver for Surface Aggregator Module
@@ -7524,7 +7560,7 @@ index 000000000000..c2dd7e604d14
 -- 
 2.31.1
 
-From d4979bf1aa5ac4d36b5b83fd710bad388ce96b73 Mon Sep 17 00:00:00 2001
+From a53f0e0ac6d9fffc0ed16976ebd3252af61ef4c8 Mon Sep 17 00:00:00 2001
 From: Qiheng Lin <linqiheng@huawei.com>
 Date: Sat, 10 Apr 2021 12:12:46 +0800
 Subject: [PATCH] power: supply: surface-battery: Make some symbols static
@@ -7573,7 +7609,7 @@ index 4116dd839ecd..7efa431a62b2 100644
 -- 
 2.31.1
 
-From aeec7887edda6e9e9b63e1e45acadd2650aea770 Mon Sep 17 00:00:00 2001
+From d68f7c71fba8c1d6dae7c6cb2ef7f78de75bb2b5 Mon Sep 17 00:00:00 2001
 From: Qiheng Lin <linqiheng@huawei.com>
 Date: Sat, 10 Apr 2021 12:12:49 +0800
 Subject: [PATCH] power: supply: surface-charger: Make symbol
@@ -7612,7 +7648,7 @@ index c2dd7e604d14..81a5b79822c9 100644
 -- 
 2.31.1
 
-From aca50ab05b826d30effb105dc71d1569ad795bd8 Mon Sep 17 00:00:00 2001
+From e5fd08390689c8c2144c9aa90188e28ba7372de8 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Tue, 4 May 2021 20:00:46 +0200
 Subject: [PATCH] power: supply: surface_battery: Fix battery event handling
@@ -7669,7 +7705,7 @@ index 7efa431a62b2..5ec2e6bb2465 100644
 -- 
 2.31.1
 
-From 055871eb816bd06b1141b06ce1d3898b5fb4c51a Mon Sep 17 00:00:00 2001
+From 0f1ef7e29d3ba15de0aed8e1edfd12d44eda0dc6 Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
 Date: Tue, 11 May 2021 11:24:21 +0200
 Subject: [PATCH] power: supply: surface-charger: Fix type of integer variable
@@ -7701,152 +7737,1949 @@ index 81a5b79822c9..a060c36c7766 100644
 -- 
 2.31.1
 
-From 255a4caf702eb22a51ac8a58579c4be8986cb9f5 Mon Sep 17 00:00:00 2001
+From a1ff82ee7162a0f5056ac9507e8511823db3ad4d Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
-Date: Wed, 5 May 2021 18:17:04 +0200
-Subject: [PATCH] serial: 8250_dw: Add device HID for new AMD UART controller
-
-Add device HID AMDI0022 to the AMD UART controller driver match table
-and create a platform device for it. This controller can be found on
-Microsoft Surface Laptop 4 devices and seems similar enough that we can
-just copy the existing AMDI0020 entries.
+Date: Wed, 2 Jun 2021 18:27:21 +0200
+Subject: [PATCH] platform/surface: aggregator: Allow registering notifiers
+ without enabling events
+
+Currently, each SSAM event notifier is directly tied to one group of
+events. This makes sense as registering a notifier will automatically
+take care of enabling the corresponding event group and normally drivers
+only need notifications for a very limited number of events, associated
+with different callbacks for each group.
+
+However, there are rare cases, especially for debugging, when we want to
+get notifications for a whole event target category instead of just a
+single group of events in that category. Registering multiple notifiers,
+i.e. one per group, may be infeasible due to two issues: a) we might not
+know every event enable/disable specification as some events are
+auto-enabled by the EC and b) forwarding this to the same callback will
+lead to duplicate events as we might not know the full event
+specification to perform the appropriate filtering.
+
+This commit introduces observer-notifiers, which are notifiers that are
+not tied to a specific event group and do not attempt to manage any
+events. In other words, they can be registered without enabling any
+event group or incrementing the corresponding reference count and just
+act as silent observers, listening to all currently/previously enabled
+events based on their match-specification.
+
+Essentially, this allows us to register one single notifier for a full
+event target category, meaning that we can process all events of that
+target category in a single callback without duplication. Specifically,
+this will be used in the cdev debug interface to forward events to
+user-space via a device file from which the events can be read.
 
-Cc: <stable@vger.kernel.org> # 5.10+
-Tested-by: Sachi King <nakato@nakato.io>
 Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
 Patchset: surface-sam
 ---
- drivers/acpi/acpi_apd.c           | 1 +
- drivers/tty/serial/8250/8250_dw.c | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c
-index 39359ce0eb2c..645e82a66bb0 100644
---- a/drivers/acpi/acpi_apd.c
-+++ b/drivers/acpi/acpi_apd.c
-@@ -226,6 +226,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
- 	{ "AMDI0010", APD_ADDR(wt_i2c_desc) },
- 	{ "AMD0020", APD_ADDR(cz_uart_desc) },
- 	{ "AMDI0020", APD_ADDR(cz_uart_desc) },
-+	{ "AMDI0022", APD_ADDR(cz_uart_desc) },
- 	{ "AMD0030", },
- 	{ "AMD0040", APD_ADDR(fch_misc_desc)},
- 	{ "HYGO0010", APD_ADDR(wt_i2c_desc) },
-diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
-index 9e204f9b799a..a3a0154da567 100644
---- a/drivers/tty/serial/8250/8250_dw.c
-+++ b/drivers/tty/serial/8250/8250_dw.c
-@@ -714,6 +714,7 @@ static const struct acpi_device_id dw8250_acpi_match[] = {
- 	{ "APMC0D08", 0},
- 	{ "AMD0020", 0 },
- 	{ "AMDI0020", 0 },
-+	{ "AMDI0022", 0 },
- 	{ "BRCM2032", 0 },
- 	{ "HISI0031", 0 },
- 	{ },
+ .../platform/surface/aggregator/controller.c  | 69 +++++++++++--------
+ include/linux/surface_aggregator/controller.h | 17 +++++
+ 2 files changed, 58 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
+index a06964aa96e7..cd3a6b77f48d 100644
+--- a/drivers/platform/surface/aggregator/controller.c
++++ b/drivers/platform/surface/aggregator/controller.c
+@@ -2127,9 +2127,15 @@ int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
+  * @ctrl: The controller to register the notifier on.
+  * @n:    The event notifier to register.
+  *
+- * Register an event notifier and increment the usage counter of the
+- * associated SAM event. If the event was previously not enabled, it will be
+- * enabled during this call.
++ * Register an event notifier. Increment the usage counter of the associated
++ * SAM event if the notifier is not marked as an observer. If the event is not
++ * marked as an observer and is currently not enabled, it will be enabled
++ * during this call. If the notifier is marked as an observer, no attempt will
++ * be made at enabling any event and no reference count will be modified.
++ *
++ * Notifiers marked as observers do not need to be associated with one specific
++ * event, i.e. as long as no event matching is performed, only the event target
++ * category needs to be set.
+  *
+  * Return: Returns zero on success, %-ENOSPC if there have already been
+  * %INT_MAX notifiers for the event ID/type associated with the notifier block
+@@ -2138,11 +2144,10 @@ int ssam_ctrl_notif_d0_entry(struct ssam_controller *ctrl)
+  * for the specific associated event, returns the status of the event-enable
+  * EC-command.
+  */
+-int ssam_notifier_register(struct ssam_controller *ctrl,
+-			   struct ssam_event_notifier *n)
++int ssam_notifier_register(struct ssam_controller *ctrl, struct ssam_event_notifier *n)
+ {
+ 	u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
+-	struct ssam_nf_refcount_entry *entry;
++	struct ssam_nf_refcount_entry *entry = NULL;
+ 	struct ssam_nf_head *nf_head;
+ 	struct ssam_nf *nf;
+ 	int status;
+@@ -2155,29 +2160,32 @@ int ssam_notifier_register(struct ssam_controller *ctrl,
+ 
+ 	mutex_lock(&nf->lock);
+ 
+-	entry = ssam_nf_refcount_inc(nf, n->event.reg, n->event.id);
+-	if (IS_ERR(entry)) {
+-		mutex_unlock(&nf->lock);
+-		return PTR_ERR(entry);
+-	}
++	if (!(n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)) {
++		entry = ssam_nf_refcount_inc(nf, n->event.reg, n->event.id);
++		if (IS_ERR(entry)) {
++			mutex_unlock(&nf->lock);
++			return PTR_ERR(entry);
++		}
+ 
+-	ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
+-		 n->event.reg.target_category, n->event.id.target_category,
+-		 n->event.id.instance, entry->refcount);
++		ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
++			 n->event.reg.target_category, n->event.id.target_category,
++			 n->event.id.instance, entry->refcount);
++	}
+ 
+ 	status = ssam_nfblk_insert(nf_head, &n->base);
+ 	if (status) {
+-		entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
+-		if (entry->refcount == 0)
+-			kfree(entry);
++		if (entry) {
++			entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
++			if (entry->refcount == 0)
++				kfree(entry);
++		}
+ 
+ 		mutex_unlock(&nf->lock);
+ 		return status;
+ 	}
+ 
+-	if (entry->refcount == 1) {
+-		status = ssam_ssh_event_enable(ctrl, n->event.reg, n->event.id,
+-					       n->event.flags);
++	if (entry && entry->refcount == 1) {
++		status = ssam_ssh_event_enable(ctrl, n->event.reg, n->event.id, n->event.flags);
+ 		if (status) {
+ 			ssam_nfblk_remove(&n->base);
+ 			kfree(ssam_nf_refcount_dec(nf, n->event.reg, n->event.id));
+@@ -2188,7 +2196,7 @@ int ssam_notifier_register(struct ssam_controller *ctrl,
+ 
+ 		entry->flags = n->event.flags;
+ 
+-	} else if (entry->flags != n->event.flags) {
++	} else if (entry && entry->flags != n->event.flags) {
+ 		ssam_warn(ctrl,
+ 			  "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
+ 			  n->event.flags, entry->flags, n->event.reg.target_category,
+@@ -2205,17 +2213,16 @@ EXPORT_SYMBOL_GPL(ssam_notifier_register);
+  * @ctrl: The controller the notifier has been registered on.
+  * @n:    The event notifier to unregister.
+  *
+- * Unregister an event notifier and decrement the usage counter of the
+- * associated SAM event. If the usage counter reaches zero, the event will be
+- * disabled.
++ * Unregister an event notifier. Decrement the usage counter of the associated
++ * SAM event if the notifier is not marked as an observer. If the usage counter
++ * reaches zero, the event will be disabled.
+  *
+  * Return: Returns zero on success, %-ENOENT if the given notifier block has
+  * not been registered on the controller. If the given notifier block was the
+  * last one associated with its specific event, returns the status of the
+  * event-disable EC-command.
+  */
+-int ssam_notifier_unregister(struct ssam_controller *ctrl,
+-			     struct ssam_event_notifier *n)
++int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_notifier *n)
+ {
+ 	u16 rqid = ssh_tc_to_rqid(n->event.id.target_category);
+ 	struct ssam_nf_refcount_entry *entry;
+@@ -2236,6 +2243,13 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl,
+ 		return -ENOENT;
+ 	}
+ 
++	/*
++	 * If this is an observer notifier, do not attempt to disable the
++	 * event, just remove it.
++	 */
++	if (n->flags & SSAM_EVENT_NOTIFIER_OBSERVER)
++		goto remove;
++
+ 	entry = ssam_nf_refcount_dec(nf, n->event.reg, n->event.id);
+ 	if (WARN_ON(!entry)) {
+ 		/*
+@@ -2260,8 +2274,7 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl,
+ 	}
+ 
+ 	if (entry->refcount == 0) {
+-		status = ssam_ssh_event_disable(ctrl, n->event.reg, n->event.id,
+-						n->event.flags);
++		status = ssam_ssh_event_disable(ctrl, n->event.reg, n->event.id, n->event.flags);
+ 		kfree(entry);
+ 	}
+ 
+diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h
+index 0806796eabcb..cf4bb48a850e 100644
+--- a/include/linux/surface_aggregator/controller.h
++++ b/include/linux/surface_aggregator/controller.h
+@@ -795,6 +795,20 @@ enum ssam_event_mask {
+ #define SSAM_EVENT_REGISTRY_REG \
+ 	SSAM_EVENT_REGISTRY(SSAM_SSH_TC_REG, 0x02, 0x01, 0x02)
+ 
++/**
++ * enum ssam_event_notifier_flags - Flags for event notifiers.
++ * @SSAM_EVENT_NOTIFIER_OBSERVER:
++ *	The corresponding notifier acts as observer. Registering a notifier
++ *	with this flag set will not attempt to enable any event. Equally,
++ *	unregistering will not attempt to disable any event. Note that a
++ *	notifier with this flag may not even correspond to a certain event at
++ *	all, only to a specific event target category. Event matching will not
++ *	be influenced by this flag.
++ */
++enum ssam_event_notifier_flags {
++	SSAM_EVENT_NOTIFIER_OBSERVER = BIT(0),
++};
++
+ /**
+  * struct ssam_event_notifier - Notifier block for SSAM events.
+  * @base:        The base notifier block with callback function and priority.
+@@ -803,6 +817,7 @@ enum ssam_event_mask {
+  * @event.id:    ID specifying the event.
+  * @event.mask:  Flags determining how events are matched to the notifier.
+  * @event.flags: Flags used for enabling the event.
++ * @flags:       Notifier flags (see &enum ssam_event_notifier_flags).
+  */
+ struct ssam_event_notifier {
+ 	struct ssam_notifier_block base;
+@@ -813,6 +828,8 @@ struct ssam_event_notifier {
+ 		enum ssam_event_mask mask;
+ 		u8 flags;
+ 	} event;
++
++	unsigned long flags;
+ };
+ 
+ int ssam_notifier_register(struct ssam_controller *ctrl,
 -- 
 2.31.1
 
-From 3452bbea0ace10d2b26170d74e9eb10321f59ff5 Mon Sep 17 00:00:00 2001
+From 45da405506252340b73f354c271a592851898f3c Mon Sep 17 00:00:00 2001
 From: Maximilian Luz <luzmaximilian@gmail.com>
-Date: Wed, 5 May 2021 18:22:04 +0200
-Subject: [PATCH] pinctrl/amd: Add device HID for new AMD GPIO controller
-
-Add device HID AMDI0031 to the AMD GPIO controller driver match table.
-This controller can be found on Microsoft Surface Laptop 4 devices and
-seems similar enough that we can just copy the existing AMDI0030 entry.
+Date: Wed, 2 Jun 2021 18:34:48 +0200
+Subject: [PATCH] platform/surface: aggregator: Allow enabling of events
+ without notifiers
+
+We can already enable and disable SAM events via one of two ways: either
+via a (non-observer) notifier tied to a specific event group, or a
+generic event enable/disable request. In some instances, however,
+neither method may be desirable.
+
+The first method will tie the event enable request to a specific
+notifier, however, when we want to receive notifications for multiple
+event groups of the same target category and forward this to the same
+notifier callback, we may receive duplicate events, i.e. one event per
+registered notifier. The second method will bypass the internal
+reference counting mechanism, meaning that a disable request will
+disable the event regardless of any other client driver using it, which
+may break the functionality of that driver.
+
+To address this problem, add new functions that allow enabling and
+disabling of events via the event reference counting mechanism built
+into the controller, without needing to register a notifier.
+
+This can then be used in combination with observer notifiers to process
+multiple events of the same target category without duplication in the
+same callback function.
 
-Cc: <stable@vger.kernel.org> # 5.10+
-Tested-by: Sachi King <nakato@nakato.io>
 Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
 Patchset: surface-sam
 ---
- drivers/pinctrl/pinctrl-amd.c | 1 +
- 1 file changed, 1 insertion(+)
+ .../platform/surface/aggregator/controller.c  | 135 ++++++++++++++++++
+ include/linux/surface_aggregator/controller.h |   8 ++
+ 2 files changed, 143 insertions(+)
 
-diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
-index 2d4acf21117c..c5950a3b4e4c 100644
---- a/drivers/pinctrl/pinctrl-amd.c
-+++ b/drivers/pinctrl/pinctrl-amd.c
-@@ -991,6 +991,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
- static const struct acpi_device_id amd_gpio_acpi_match[] = {
- 	{ "AMD0030", 0 },
- 	{ "AMDI0030", 0},
-+	{ "AMDI0031", 0},
- 	{ },
- };
- MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match);
+diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
+index cd3a6b77f48d..49edddea417e 100644
+--- a/drivers/platform/surface/aggregator/controller.c
++++ b/drivers/platform/surface/aggregator/controller.c
+@@ -2287,6 +2287,141 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_not
+ }
+ EXPORT_SYMBOL_GPL(ssam_notifier_unregister);
+ 
++/**
++ * ssam_controller_event_enable() - Enable the specified event.
++ * @ctrl:  The controller to enable the event for.
++ * @reg:   The event registry to use for enabling the event.
++ * @id:    The event ID specifying the event to be enabled.
++ * @flags: The SAM event flags used for enabling the event.
++ *
++ * Increment the event reference count of the specified event. If the event has
++ * not been enabled previously, it will be enabled by this call.
++ *
++ * Note: In general, ssam_notifier_register() with a non-observer notifier
++ * should be preferred for enabling/disabling events, as this will guarantee
++ * proper ordering and event forwarding in case of errors during event
++ * enabling/disabling.
++ *
++ * Return: Returns zero on success, %-ENOSPC if the reference count for the
++ * specified event has reached its maximum, %-ENOMEM if the corresponding event
++ * entry could not be allocated. If this is the first time that this event has
++ * been enabled (i.e. the reference count was incremented from zero to one by
++ * this call), returns the status of the event-enable EC-command.
++ */
++int ssam_controller_event_enable(struct ssam_controller *ctrl,
++				 struct ssam_event_registry reg,
++				 struct ssam_event_id id, u8 flags)
++{
++	u16 rqid = ssh_tc_to_rqid(id.target_category);
++	struct ssam_nf_refcount_entry *entry;
++	struct ssam_nf_head *nf_head;
++	struct ssam_nf *nf;
++	int status;
++
++	if (!ssh_rqid_is_event(rqid))
++		return -EINVAL;
++
++	nf = &ctrl->cplt.event.notif;
++	nf_head = &nf->head[ssh_rqid_to_event(rqid)];
++
++	mutex_lock(&nf->lock);
++
++	entry = ssam_nf_refcount_inc(nf, reg, id);
++	if (IS_ERR(entry)) {
++		mutex_unlock(&nf->lock);
++		return PTR_ERR(entry);
++	}
++
++	ssam_dbg(ctrl, "enabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
++		 reg.target_category, id.target_category, id.instance,
++		 entry->refcount);
++
++	if (entry->refcount == 1) {
++		status = ssam_ssh_event_enable(ctrl, reg, id, flags);
++		if (status) {
++			kfree(ssam_nf_refcount_dec(nf, reg, id));
++			mutex_unlock(&nf->lock);
++			return status;
++		}
++
++		entry->flags = flags;
++
++	} else if (entry->flags != flags) {
++		ssam_warn(ctrl,
++			  "inconsistent flags when enabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
++			  flags, entry->flags, reg.target_category,
++			  id.target_category, id.instance);
++	}
++
++	mutex_unlock(&nf->lock);
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ssam_controller_event_enable);
++
++/**
++ * ssam_controller_event_disable() - Disable the specified event.
++ * @ctrl:  The controller to disable the event for.
++ * @reg:   The event registry to use for disabling the event.
++ * @id:    The event ID specifying the event to be disabled.
++ * @flags: The flags used when enabling the event.
++ *
++ * Decrement the reference count of the specified event. If the reference count
++ * reaches zero, the event will be disabled.
++ *
++ * Note: In general, ssam_notifier_register()/ssam_notifier_unregister() with a
++ * non-observer notifier should be preferred for enabling/disabling events, as
++ * this will guarantee proper ordering and event forwarding in case of errors
++ * during event enabling/disabling.
++ *
++ * Return: Returns zero on success, %-ENOENT if the given event has not been
++ * enabled on the controller. If the reference count of the event reaches zero
++ * during this call, returns the status of the event-disable EC-command.
++ */
++int ssam_controller_event_disable(struct ssam_controller *ctrl,
++				  struct ssam_event_registry reg,
++				  struct ssam_event_id id, u8 flags)
++{
++	u16 rqid = ssh_tc_to_rqid(id.target_category);
++	struct ssam_nf_refcount_entry *entry;
++	struct ssam_nf_head *nf_head;
++	struct ssam_nf *nf;
++	int status = 0;
++
++	if (!ssh_rqid_is_event(rqid))
++		return -EINVAL;
++
++	nf = &ctrl->cplt.event.notif;
++	nf_head = &nf->head[ssh_rqid_to_event(rqid)];
++
++	mutex_lock(&nf->lock);
++
++	entry = ssam_nf_refcount_dec(nf, reg, id);
++	if (WARN_ON(!entry)) {
++		mutex_unlock(&nf->lock);
++		return -ENOENT;
++	}
++
++	ssam_dbg(ctrl, "disabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n",
++		 reg.target_category, id.target_category, id.instance,
++		 entry->refcount);
++
++	if (entry->flags != flags) {
++		ssam_warn(ctrl,
++			  "inconsistent flags when disabling event: got %#04x, expected %#04x (reg: %#04x, tc: %#04x, iid: %#04x)\n",
++			  flags, entry->flags, reg.target_category,
++			  id.target_category, id.instance);
++	}
++
++	if (entry->refcount == 0) {
++		status = ssam_ssh_event_disable(ctrl, reg, id, flags);
++		kfree(entry);
++	}
++
++	mutex_unlock(&nf->lock);
++	return status;
++}
++EXPORT_SYMBOL_GPL(ssam_controller_event_disable);
++
+ /**
+  * ssam_notifier_disable_registered() - Disable events for all registered
+  * notifiers.
+diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h
+index cf4bb48a850e..7965bdc669c5 100644
+--- a/include/linux/surface_aggregator/controller.h
++++ b/include/linux/surface_aggregator/controller.h
+@@ -838,4 +838,12 @@ int ssam_notifier_register(struct ssam_controller *ctrl,
+ int ssam_notifier_unregister(struct ssam_controller *ctrl,
+ 			     struct ssam_event_notifier *n);
+ 
++int ssam_controller_event_enable(struct ssam_controller *ctrl,
++				 struct ssam_event_registry reg,
++				 struct ssam_event_id id, u8 flags);
++
++int ssam_controller_event_disable(struct ssam_controller *ctrl,
++				  struct ssam_event_registry reg,
++				  struct ssam_event_id id, u8 flags);
++
+ #endif /* _LINUX_SURFACE_AGGREGATOR_CONTROLLER_H */
 -- 
 2.31.1
 
-From 2de100520fe38868cbdc3b18a904f947be7e49f4 Mon Sep 17 00:00:00 2001
-From: Sachi King <nakato@nakato.io>
-Date: Sat, 29 May 2021 17:47:38 +1000
-Subject: [PATCH] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7
- override
-
-This patch is the work of Thomas Gleixner <tglx@linutronix.de> and is
-copied from:
-https://lore.kernel.org/lkml/87lf8ddjqx.ffs@nanos.tec.linutronix.de/
-
-This patch adds a quirk to the ACPI setup to patch in the the irq 7 pin
-setup that is missing in the laptops ACPI table.
+From 32c11101ef436969d4af7c478f431ec4293579b6 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Thu, 3 Jun 2021 00:10:38 +0200
+Subject: [PATCH] platform/surface: aggregator: Update copyright
 
-This patch was used for validation of the issue, and is not a proper
-fix, but is probably a better temporary hack than continuing to probe
-the Legacy PIC and run with the PIC in an unknown state.
+It's 2021, update the copyright accordingly.
 
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
 Patchset: surface-sam
 ---
- arch/x86/kernel/acpi/boot.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
-diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
-index 14cd3186dc77..ab3ba60cb6da 100644
---- a/arch/x86/kernel/acpi/boot.c
-+++ b/arch/x86/kernel/acpi/boot.c
-@@ -21,6 +21,7 @@
- #include <linux/efi-bgrt.h>
- #include <linux/serial_core.h>
- #include <linux/pgtable.h>
-+#include <linux/dmi.h>
+ drivers/platform/surface/aggregator/Kconfig             | 2 +-
+ drivers/platform/surface/aggregator/Makefile            | 2 +-
+ drivers/platform/surface/aggregator/bus.c               | 2 +-
+ drivers/platform/surface/aggregator/bus.h               | 2 +-
+ drivers/platform/surface/aggregator/controller.c        | 2 +-
+ drivers/platform/surface/aggregator/controller.h        | 2 +-
+ drivers/platform/surface/aggregator/core.c              | 2 +-
+ drivers/platform/surface/aggregator/ssh_msgb.h          | 2 +-
+ drivers/platform/surface/aggregator/ssh_packet_layer.c  | 2 +-
+ drivers/platform/surface/aggregator/ssh_packet_layer.h  | 2 +-
+ drivers/platform/surface/aggregator/ssh_parser.c        | 2 +-
+ drivers/platform/surface/aggregator/ssh_parser.h        | 2 +-
+ drivers/platform/surface/aggregator/ssh_request_layer.c | 2 +-
+ drivers/platform/surface/aggregator/ssh_request_layer.h | 2 +-
+ drivers/platform/surface/aggregator/trace.h             | 2 +-
+ include/linux/surface_aggregator/controller.h           | 2 +-
+ include/linux/surface_aggregator/device.h               | 2 +-
+ include/linux/surface_aggregator/serial_hub.h           | 2 +-
+ 18 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/platform/surface/aggregator/Kconfig b/drivers/platform/surface/aggregator/Kconfig
+index 3aaeea9f0433..fd6dc452f3e8 100644
+--- a/drivers/platform/surface/aggregator/Kconfig
++++ b/drivers/platform/surface/aggregator/Kconfig
+@@ -1,5 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0+
+-# Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++# Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+ 
+ menuconfig SURFACE_AGGREGATOR
+ 	tristate "Microsoft Surface System Aggregator Module Subsystem and Drivers"
+diff --git a/drivers/platform/surface/aggregator/Makefile b/drivers/platform/surface/aggregator/Makefile
+index c112e2c7112b..c8498c41e758 100644
+--- a/drivers/platform/surface/aggregator/Makefile
++++ b/drivers/platform/surface/aggregator/Makefile
+@@ -1,5 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0+
+-# Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++# Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+ 
+ # For include/trace/define_trace.h to include trace.h
+ CFLAGS_core.o = -I$(src)
+diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c
+index a9b660af0917..0169677c243e 100644
+--- a/drivers/platform/surface/aggregator/bus.c
++++ b/drivers/platform/surface/aggregator/bus.c
+@@ -2,7 +2,7 @@
+ /*
+  * Surface System Aggregator Module bus and device integration.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
  
- #include <asm/e820/api.h>
- #include <asm/irqdomain.h>
-@@ -1155,6 +1156,17 @@ static void __init mp_config_acpi_legacy_irqs(void)
- 	}
- }
+ #include <linux/device.h>
+diff --git a/drivers/platform/surface/aggregator/bus.h b/drivers/platform/surface/aggregator/bus.h
+index 7712baaed6a5..ed032c2cbdb2 100644
+--- a/drivers/platform/surface/aggregator/bus.h
++++ b/drivers/platform/surface/aggregator/bus.h
+@@ -2,7 +2,7 @@
+ /*
+  * Surface System Aggregator Module bus and device integration.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
  
-+static const struct dmi_system_id surface_quirk[] __initconst = {
-+	{
-+		.ident = "Microsoft Surface Laptop 4 (AMD)",
-+		.matches = {
-+			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
-+			DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1952:1953")
-+		},
-+	},
-+	{}
-+};
-+
+ #ifndef _SURFACE_AGGREGATOR_BUS_H
+diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c
+index 49edddea417e..e91ee7e72c14 100644
+--- a/drivers/platform/surface/aggregator/controller.c
++++ b/drivers/platform/surface/aggregator/controller.c
+@@ -2,7 +2,7 @@
  /*
-  * Parse IOAPIC related entries in MADT
-  * returns 0 on success, < 0 on error
-@@ -1212,6 +1224,11 @@ static int __init acpi_parse_madt_ioapic_entries(void)
- 		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
- 				      acpi_gbl_FADT.sci_interrupt);
+  * Main SSAM/SSH controller structure and functionality.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
  
-+	if (dmi_check_system(surface_quirk)) {
-+		pr_warn("Surface hack: Override irq 7\n");
-+		mp_override_legacy_irq(7, 3, 3, 7);
-+	}
-+
- 	/* Fill in identity legacy mappings where no override */
- 	mp_config_acpi_legacy_irqs();
+ #include <linux/acpi.h>
+diff --git a/drivers/platform/surface/aggregator/controller.h b/drivers/platform/surface/aggregator/controller.h
+index 8297d34e7489..a0963c3562ff 100644
+--- a/drivers/platform/surface/aggregator/controller.h
++++ b/drivers/platform/surface/aggregator/controller.h
+@@ -2,7 +2,7 @@
+ /*
+  * Main SSAM/SSH controller structure and functionality.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _SURFACE_AGGREGATOR_CONTROLLER_H
+diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c
+index 8dc2c267bcd6..5d780e55f4a1 100644
+--- a/drivers/platform/surface/aggregator/core.c
++++ b/drivers/platform/surface/aggregator/core.c
+@@ -7,7 +7,7 @@
+  * Handles communication via requests as well as enabling, disabling, and
+  * relaying of events.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #include <linux/acpi.h>
+diff --git a/drivers/platform/surface/aggregator/ssh_msgb.h b/drivers/platform/surface/aggregator/ssh_msgb.h
+index 1221f642dda1..e562958ffdf0 100644
+--- a/drivers/platform/surface/aggregator/ssh_msgb.h
++++ b/drivers/platform/surface/aggregator/ssh_msgb.h
+@@ -2,7 +2,7 @@
+ /*
+  * SSH message builder functions.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _SURFACE_AGGREGATOR_SSH_MSGB_H
+diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c
+index 15d96eac6811..5e08049fc3ac 100644
+--- a/drivers/platform/surface/aggregator/ssh_packet_layer.c
++++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c
+@@ -2,7 +2,7 @@
+ /*
+  * SSH packet transport layer.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #include <asm/unaligned.h>
+diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.h b/drivers/platform/surface/aggregator/ssh_packet_layer.h
+index e8757d03f279..2eb329f0b91a 100644
+--- a/drivers/platform/surface/aggregator/ssh_packet_layer.h
++++ b/drivers/platform/surface/aggregator/ssh_packet_layer.h
+@@ -2,7 +2,7 @@
+ /*
+  * SSH packet transport layer.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H
+diff --git a/drivers/platform/surface/aggregator/ssh_parser.c b/drivers/platform/surface/aggregator/ssh_parser.c
+index e2dead8de94a..b77912f8f13b 100644
+--- a/drivers/platform/surface/aggregator/ssh_parser.c
++++ b/drivers/platform/surface/aggregator/ssh_parser.c
+@@ -2,7 +2,7 @@
+ /*
+  * SSH message parser.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #include <asm/unaligned.h>
+diff --git a/drivers/platform/surface/aggregator/ssh_parser.h b/drivers/platform/surface/aggregator/ssh_parser.h
+index 63c38d350988..3bd6e180fd16 100644
+--- a/drivers/platform/surface/aggregator/ssh_parser.h
++++ b/drivers/platform/surface/aggregator/ssh_parser.h
+@@ -2,7 +2,7 @@
+ /*
+  * SSH message parser.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _SURFACE_AGGREGATOR_SSH_PARSER_H
+diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.c b/drivers/platform/surface/aggregator/ssh_request_layer.c
+index 52a83a8fcf82..bfe1aaf38065 100644
+--- a/drivers/platform/surface/aggregator/ssh_request_layer.c
++++ b/drivers/platform/surface/aggregator/ssh_request_layer.c
+@@ -2,7 +2,7 @@
+ /*
+  * SSH request transport layer.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #include <asm/unaligned.h>
+diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.h b/drivers/platform/surface/aggregator/ssh_request_layer.h
+index cb35815858d1..9c3cbae2d4bd 100644
+--- a/drivers/platform/surface/aggregator/ssh_request_layer.h
++++ b/drivers/platform/surface/aggregator/ssh_request_layer.h
+@@ -2,7 +2,7 @@
+ /*
+  * SSH request transport layer.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H
+diff --git a/drivers/platform/surface/aggregator/trace.h b/drivers/platform/surface/aggregator/trace.h
+index eb332bb53ae4..de64cf169060 100644
+--- a/drivers/platform/surface/aggregator/trace.h
++++ b/drivers/platform/surface/aggregator/trace.h
+@@ -2,7 +2,7 @@
+ /*
+  * Trace points for SSAM/SSH.
+  *
+- * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #undef TRACE_SYSTEM
+diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h
+index 7965bdc669c5..068e1982ad37 100644
+--- a/include/linux/surface_aggregator/controller.h
++++ b/include/linux/surface_aggregator/controller.h
+@@ -6,7 +6,7 @@
+  * managing access and communication to and from the SSAM EC, as well as main
+  * communication structures and definitions.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _LINUX_SURFACE_AGGREGATOR_CONTROLLER_H
+diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h
+index 6ff9c58b3e17..f636c5310321 100644
+--- a/include/linux/surface_aggregator/device.h
++++ b/include/linux/surface_aggregator/device.h
+@@ -7,7 +7,7 @@
+  * Provides support for non-platform/non-ACPI SSAM clients via dedicated
+  * subsystem.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _LINUX_SURFACE_AGGREGATOR_DEVICE_H
+diff --git a/include/linux/surface_aggregator/serial_hub.h b/include/linux/surface_aggregator/serial_hub.h
+index 64276fbfa1d5..c3de43edcffa 100644
+--- a/include/linux/surface_aggregator/serial_hub.h
++++ b/include/linux/surface_aggregator/serial_hub.h
+@@ -6,7 +6,7 @@
+  * Surface System Aggregator Module (SSAM). Provides the interface for basic
+  * packet- and request-based communication with the SSAM EC via SSH.
+  *
+- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _LINUX_SURFACE_AGGREGATOR_SERIAL_HUB_H
+-- 
+2.31.1
+
+From d47f5689f687f6e308b4b3452015c5ee4edfa4a8 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Wed, 2 Jun 2021 19:29:16 +0200
+Subject: [PATCH] platform/surface: aggregator_cdev: Add support for forwarding
+ events to user-space
+
+Currently, debugging unknown events requires writing a custom driver.
+This is somewhat difficult, slow to adapt, and not entirely
+user-friendly for quickly trying to figure out things on devices of some
+third-party user. We can do better. We already have a user-space
+interface intended for debugging SAM EC requests, so let's add support
+for receiving events to that.
+
+This commit provides support for receiving events by reading from the
+controller file. It additionally introduces two new IOCTLs to control
+which event categories will be forwarded. Specifically, a user-space
+client can specify which target categories it wants to receive events
+from by registering the corresponding notifier(s) via the IOCTLs and
+after that, read the received events by reading from the controller
+device.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-sam
+---
+ .../userspace-api/ioctl/ioctl-number.rst      |   2 +-
+ .../surface/surface_aggregator_cdev.c         | 454 +++++++++++++++++-
+ include/uapi/linux/surface_aggregator/cdev.h  |  41 +-
+ 3 files changed, 471 insertions(+), 26 deletions(-)
+
+diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst
+index 1c28b8ef6677..cfd1610e5e95 100644
+--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
++++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
+@@ -325,7 +325,7 @@ Code  Seq#    Include File                                           Comments
+ 0xA3  90-9F  linux/dtlk.h
+ 0xA4  00-1F  uapi/linux/tee.h                                        Generic TEE subsystem
+ 0xA4  00-1F  uapi/asm/sgx.h                                          <mailto:linux-sgx@vger.kernel.org>
+-0xA5  01     linux/surface_aggregator/cdev.h                         Microsoft Surface Platform System Aggregator
++0xA5  01-05  linux/surface_aggregator/cdev.h                         Microsoft Surface Platform System Aggregator
+                                                                      <mailto:luzmaximilian@gmail.com>
+ 0xA5  20-2F  linux/surface_aggregator/dtx.h                          Microsoft Surface DTX driver
+                                                                      <mailto:luzmaximilian@gmail.com>
+diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c
+index 79e28fab7e40..7b27c8ca38a5 100644
+--- a/drivers/platform/surface/surface_aggregator_cdev.c
++++ b/drivers/platform/surface/surface_aggregator_cdev.c
+@@ -3,29 +3,68 @@
+  * Provides user-space access to the SSAM EC via the /dev/surface/aggregator
+  * misc device. Intended for debugging and development.
+  *
+- * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #include <linux/fs.h>
++#include <linux/ioctl.h>
+ #include <linux/kernel.h>
++#include <linux/kfifo.h>
+ #include <linux/kref.h>
+ #include <linux/miscdevice.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/poll.h>
+ #include <linux/rwsem.h>
+ #include <linux/slab.h>
+ #include <linux/uaccess.h>
++#include <linux/vmalloc.h>
+ 
+ #include <linux/surface_aggregator/cdev.h>
+ #include <linux/surface_aggregator/controller.h>
+ 
+ #define SSAM_CDEV_DEVICE_NAME	"surface_aggregator_cdev"
+ 
++
++/* -- Main structures. ------------------------------------------------------ */
++
++enum ssam_cdev_device_state {
++	SSAM_CDEV_DEVICE_SHUTDOWN_BIT = BIT(0),
++};
++
+ struct ssam_cdev {
+ 	struct kref kref;
+ 	struct rw_semaphore lock;
++
++	struct device *dev;
+ 	struct ssam_controller *ctrl;
+ 	struct miscdevice mdev;
++	unsigned long flags;
++
++	struct rw_semaphore client_lock;  /* Guards client list. */
++	struct list_head client_list;
++};
++
++struct ssam_cdev_client;
++
++struct ssam_cdev_notifier {
++	struct ssam_cdev_client *client;
++	struct ssam_event_notifier nf;
++};
++
++struct ssam_cdev_client {
++	struct ssam_cdev *cdev;
++	struct list_head node;
++
++	struct mutex notifier_lock;	/* Guards notifier access for registration */
++	struct ssam_cdev_notifier *notifier[SSH_NUM_EVENTS];
++
++	struct mutex read_lock;		/* Guards FIFO buffer read access */
++	struct mutex write_lock;	/* Guards FIFO buffer write access */
++	DECLARE_KFIFO(buffer, u8, 4096);
++
++	wait_queue_head_t waitq;
++	struct fasync_struct *fasync;
+ };
+ 
+ static void __ssam_cdev_release(struct kref *kref)
+@@ -47,24 +86,167 @@ static void ssam_cdev_put(struct ssam_cdev *cdev)
+ 		kref_put(&cdev->kref, __ssam_cdev_release);
+ }
+ 
+-static int ssam_cdev_device_open(struct inode *inode, struct file *filp)
++
++/* -- Notifier handling. ---------------------------------------------------- */
++
++static u32 ssam_cdev_notifier(struct ssam_event_notifier *nf, const struct ssam_event *in)
+ {
+-	struct miscdevice *mdev = filp->private_data;
+-	struct ssam_cdev *cdev = container_of(mdev, struct ssam_cdev, mdev);
++	struct ssam_cdev_notifier *cdev_nf = container_of(nf, struct ssam_cdev_notifier, nf);
++	struct ssam_cdev_client *client = cdev_nf->client;
++	struct ssam_cdev_event event;
++	size_t n = struct_size(&event, data, in->length);
++
++	/* Translate event. */
++	event.target_category = in->target_category;
++	event.target_id = in->target_id;
++	event.command_id = in->command_id;
++	event.instance_id = in->instance_id;
++	event.length = in->length;
++
++	mutex_lock(&client->write_lock);
++
++	/* Make sure we have enough space. */
++	if (kfifo_avail(&client->buffer) < n) {
++		dev_warn(client->cdev->dev,
++			 "buffer full, dropping event (tc: %#04x, tid: %#04x, cid: %#04x, iid: %#04x)\n",
++			 in->target_category, in->target_id, in->command_id, in->instance_id);
++		mutex_unlock(&client->write_lock);
++		return 0;
++	}
+ 
+-	filp->private_data = ssam_cdev_get(cdev);
+-	return stream_open(inode, filp);
++	/* Copy event header and payload. */
++	kfifo_in(&client->buffer, (const u8 *)&event, struct_size(&event, data, 0));
++	kfifo_in(&client->buffer, &in->data[0], in->length);
++
++	mutex_unlock(&client->write_lock);
++
++	/* Notify waiting readers. */
++	kill_fasync(&client->fasync, SIGIO, POLL_IN);
++	wake_up_interruptible(&client->waitq);
++
++	/*
++	 * Don't mark events as handled, this is the job of a proper driver and
++	 * not the debugging interface.
++	 */
++	return 0;
+ }
+ 
+-static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
++static int ssam_cdev_notifier_register(struct ssam_cdev_client *client, u8 category, int priority)
+ {
+-	ssam_cdev_put(filp->private_data);
+-	return 0;
++	struct ssam_cdev_notifier *nf;
++	int index = ((int)category) - 1;
++	int status;
++
++	/* Validate notifier target category. */
++	if (index < 0 || index >= SSH_NUM_EVENTS)
++		return -EINVAL;
++
++	mutex_lock(&client->notifier_lock);
++
++	/* Check if the notifier has already been registered. */
++	if (client->notifier[index]) {
++		mutex_unlock(&client->notifier_lock);
++		return -EEXIST;
++	}
++
++	/* Allocate new notifier. */
++	nf = kzalloc(sizeof(*nf), GFP_KERNEL);
++	if (!nf) {
++		mutex_unlock(&client->notifier_lock);
++		return -ENOMEM;
++	}
++
++	/*
++	 * Create a dummy notifier with the minimal required fields for
++	 * observer registration. Note that we can skip fully specifying event
++	 * and registry here as we do not need any matching and use silent
++	 * registration, which does not enable the corresponding event.
++	 */
++	nf->client = client;
++	nf->nf.base.fn = ssam_cdev_notifier;
++	nf->nf.base.priority = priority;
++	nf->nf.event.id.target_category = category;
++	nf->nf.event.mask = 0;	/* Do not do any matching. */
++	nf->nf.flags = SSAM_EVENT_NOTIFIER_OBSERVER;
++
++	/* Register notifier. */
++	status = ssam_notifier_register(client->cdev->ctrl, &nf->nf);
++	if (status)
++		kfree(nf);
++	else
++		client->notifier[index] = nf;
++
++	mutex_unlock(&client->notifier_lock);
++	return status;
+ }
+ 
+-static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
++static int ssam_cdev_notifier_unregister(struct ssam_cdev_client *client, u8 category)
++{
++	int index = ((int)category) - 1;
++	int status;
++
++	/* Validate notifier target category. */
++	if (index < 0 || index >= SSH_NUM_EVENTS)
++		return -EINVAL;
++
++	mutex_lock(&client->notifier_lock);
++
++	/* Check if the notifier is currently registered. */
++	if (!client->notifier[index]) {
++		mutex_unlock(&client->notifier_lock);
++		return -ENOENT;
++	}
++
++	/* Unregister and free notifier. */
++	status = ssam_notifier_unregister(client->cdev->ctrl, &client->notifier[index]->nf);
++	kfree(client->notifier[index]);
++	client->notifier[index] = NULL;
++
++	mutex_unlock(&client->notifier_lock);
++	return status;
++}
++
++static void ssam_cdev_notifier_unregister_all(struct ssam_cdev_client *client)
++{
++	int i;
++
++	down_read(&client->cdev->lock);
++
++	/*
++	 * This function may be used during shutdown, thus we need to test for
++	 * cdev->ctrl instead of the SSAM_CDEV_DEVICE_SHUTDOWN_BIT bit.
++	 */
++	if (client->cdev->ctrl) {
++		for (i = 0; i < SSH_NUM_EVENTS; i++)
++			ssam_cdev_notifier_unregister(client, i + 1);
++
++	} else {
++		int count = 0;
++
++		/*
++		 * Device has been shut down. Any notifier remaining is a bug,
++		 * so warn about that as this would otherwise hardly be
++		 * noticeable. Nevertheless, free them as well.
++		 */
++		mutex_lock(&client->notifier_lock);
++		for (i = 0; i < SSH_NUM_EVENTS; i++) {
++			count += !!(client->notifier[i]);
++			kfree(client->notifier[i]);
++			client->notifier[i] = NULL;
++		}
++		mutex_unlock(&client->notifier_lock);
++
++		WARN_ON(count > 0);
++	}
++
++	up_read(&client->cdev->lock);
++}
++
++
++/* -- IOCTL functions. ------------------------------------------------------ */
++
++static long ssam_cdev_request(struct ssam_cdev_client *client, struct ssam_cdev_request __user *r)
+ {
+-	struct ssam_cdev_request __user *r;
+ 	struct ssam_cdev_request rqst;
+ 	struct ssam_request spec = {};
+ 	struct ssam_response rsp = {};
+@@ -72,7 +254,6 @@ static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
+ 	void __user *rspdata;
+ 	int status = 0, ret = 0, tmp;
+ 
+-	r = (struct ssam_cdev_request __user *)arg;
+ 	ret = copy_struct_from_user(&rqst, sizeof(rqst), r, sizeof(*r));
+ 	if (ret)
+ 		goto out;
+@@ -152,7 +333,7 @@ static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
+ 	}
+ 
+ 	/* Perform request. */
+-	status = ssam_request_sync(cdev->ctrl, &spec, &rsp);
++	status = ssam_request_sync(client->cdev->ctrl, &spec, &rsp);
+ 	if (status)
+ 		goto out;
+ 
+@@ -177,48 +358,244 @@ static long ssam_cdev_request(struct ssam_cdev *cdev, unsigned long arg)
+ 	return ret;
+ }
+ 
+-static long __ssam_cdev_device_ioctl(struct ssam_cdev *cdev, unsigned int cmd,
++static long ssam_cdev_notif_register(struct ssam_cdev_client *client,
++				     const struct ssam_cdev_notifier_desc __user *d)
++{
++	struct ssam_cdev_notifier_desc desc;
++	long ret;
++
++	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
++	if (ret)
++		return ret;
++
++	return ssam_cdev_notifier_register(client, desc.target_category, desc.priority);
++}
++
++static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
++				       const struct ssam_cdev_notifier_desc __user *d)
++{
++	struct ssam_cdev_notifier_desc desc;
++	long ret;
++
++	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
++	if (ret)
++		return ret;
++
++	return ssam_cdev_notifier_unregister(client, desc.target_category);
++}
++
++
++/* -- File operations. ------------------------------------------------------ */
++
++static int ssam_cdev_device_open(struct inode *inode, struct file *filp)
++{
++	struct miscdevice *mdev = filp->private_data;
++	struct ssam_cdev_client *client;
++	struct ssam_cdev *cdev = container_of(mdev, struct ssam_cdev, mdev);
++
++	/* Initialize client */
++	client = vzalloc(sizeof(*client));
++	if (!client)
++		return -ENOMEM;
++
++	client->cdev = ssam_cdev_get(cdev);
++
++	INIT_LIST_HEAD(&client->node);
++
++	mutex_init(&client->notifier_lock);
++
++	mutex_init(&client->read_lock);
++	mutex_init(&client->write_lock);
++	INIT_KFIFO(client->buffer);
++	init_waitqueue_head(&client->waitq);
++
++	filp->private_data = client;
++
++	/* Attach client. */
++	down_write(&cdev->client_lock);
++
++	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
++		up_write(&cdev->client_lock);
++		ssam_cdev_put(client->cdev);
++		vfree(client);
++		return -ENODEV;
++	}
++	list_add_tail(&client->node, &cdev->client_list);
++
++	up_write(&cdev->client_lock);
++
++	stream_open(inode, filp);
++	return 0;
++}
++
++static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
++{
++	struct ssam_cdev_client *client = filp->private_data;
++
++	/* Force-unregister all remaining notifiers of this client. */
++	ssam_cdev_notifier_unregister_all(client);
++
++	/* Detach client. */
++	down_write(&client->cdev->client_lock);
++	list_del(&client->node);
++	up_write(&client->cdev->client_lock);
++
++	/* Free client. */
++	mutex_destroy(&client->write_lock);
++	mutex_destroy(&client->read_lock);
++
++	mutex_destroy(&client->notifier_lock);
++
++	ssam_cdev_put(client->cdev);
++	vfree(client);
++
++	return 0;
++}
++
++static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned int cmd,
+ 				     unsigned long arg)
+ {
+ 	switch (cmd) {
+ 	case SSAM_CDEV_REQUEST:
+-		return ssam_cdev_request(cdev, arg);
++		return ssam_cdev_request(client, (struct ssam_cdev_request __user *)arg);
++
++	case SSAM_CDEV_NOTIF_REGISTER:
++		return ssam_cdev_notif_register(client,
++						(struct ssam_cdev_notifier_desc __user *)arg);
++
++	case SSAM_CDEV_NOTIF_UNREGISTER:
++		return ssam_cdev_notif_unregister(client,
++						  (struct ssam_cdev_notifier_desc __user *)arg);
+ 
+ 	default:
+ 		return -ENOTTY;
+ 	}
+ }
+ 
+-static long ssam_cdev_device_ioctl(struct file *file, unsigned int cmd,
+-				   unsigned long arg)
++static long ssam_cdev_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+-	struct ssam_cdev *cdev = file->private_data;
++	struct ssam_cdev_client *client = file->private_data;
+ 	long status;
+ 
+ 	/* Ensure that controller is valid for as long as we need it. */
++	if (down_read_killable(&client->cdev->lock))
++		return -ERESTARTSYS;
++
++	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &client->cdev->flags)) {
++		up_read(&client->cdev->lock);
++		return -ENODEV;
++	}
++
++	status = __ssam_cdev_device_ioctl(client, cmd, arg);
++
++	up_read(&client->cdev->lock);
++	return status;
++}
++
++static ssize_t ssam_cdev_read(struct file *file, char __user *buf, size_t count, loff_t *offs)
++{
++	struct ssam_cdev_client *client = file->private_data;
++	struct ssam_cdev *cdev = client->cdev;
++	unsigned int copied;
++	int status = 0;
++
+ 	if (down_read_killable(&cdev->lock))
+ 		return -ERESTARTSYS;
+ 
+-	if (!cdev->ctrl) {
++	/* Make sure we're not shut down. */
++	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
+ 		up_read(&cdev->lock);
+ 		return -ENODEV;
+ 	}
+ 
+-	status = __ssam_cdev_device_ioctl(cdev, cmd, arg);
++	do {
++		/* Check availability, wait if necessary. */
++		if (kfifo_is_empty(&client->buffer)) {
++			up_read(&cdev->lock);
++
++			if (file->f_flags & O_NONBLOCK)
++				return -EAGAIN;
++
++			status = wait_event_interruptible(client->waitq,
++							  !kfifo_is_empty(&client->buffer) ||
++							  test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT,
++								   &cdev->flags));
++			if (status < 0)
++				return status;
++
++			if (down_read_killable(&cdev->lock))
++				return -ERESTARTSYS;
++
++			/* Need to check that we're not shut down again. */
++			if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags)) {
++				up_read(&cdev->lock);
++				return -ENODEV;
++			}
++		}
++
++		/* Try to read from FIFO. */
++		if (mutex_lock_interruptible(&client->read_lock)) {
++			up_read(&cdev->lock);
++			return -ERESTARTSYS;
++		}
++
++		status = kfifo_to_user(&client->buffer, buf, count, &copied);
++		mutex_unlock(&client->read_lock);
++
++		if (status < 0) {
++			up_read(&cdev->lock);
++			return status;
++		}
++
++		/* We might not have gotten anything, check this here. */
++		if (copied == 0 && (file->f_flags & O_NONBLOCK)) {
++			up_read(&cdev->lock);
++			return -EAGAIN;
++		}
++	} while (copied == 0);
+ 
+ 	up_read(&cdev->lock);
+-	return status;
++	return copied;
++}
++
++static __poll_t ssam_cdev_poll(struct file *file, struct poll_table_struct *pt)
++{
++	struct ssam_cdev_client *client = file->private_data;
++	__poll_t events = 0;
++
++	if (test_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &client->cdev->flags))
++		return EPOLLHUP | EPOLLERR;
++
++	poll_wait(file, &client->waitq, pt);
++
++	if (!kfifo_is_empty(&client->buffer))
++		events |= EPOLLIN | EPOLLRDNORM;
++
++	return events;
++}
++
++static int ssam_cdev_fasync(int fd, struct file *file, int on)
++{
++	struct ssam_cdev_client *client = file->private_data;
++
++	return fasync_helper(fd, file, on, &client->fasync);
+ }
+ 
+ static const struct file_operations ssam_controller_fops = {
+ 	.owner          = THIS_MODULE,
+ 	.open           = ssam_cdev_device_open,
+ 	.release        = ssam_cdev_device_release,
++	.read           = ssam_cdev_read,
++	.poll           = ssam_cdev_poll,
++	.fasync         = ssam_cdev_fasync,
+ 	.unlocked_ioctl = ssam_cdev_device_ioctl,
+ 	.compat_ioctl   = ssam_cdev_device_ioctl,
+-	.llseek         = noop_llseek,
++	.llseek         = no_llseek,
+ };
+ 
++
++/* -- Device and driver setup ----------------------------------------------- */
++
+ static int ssam_dbg_device_probe(struct platform_device *pdev)
+ {
+ 	struct ssam_controller *ctrl;
+@@ -236,6 +613,7 @@ static int ssam_dbg_device_probe(struct platform_device *pdev)
+ 	kref_init(&cdev->kref);
+ 	init_rwsem(&cdev->lock);
+ 	cdev->ctrl = ctrl;
++	cdev->dev = &pdev->dev;
+ 
+ 	cdev->mdev.parent   = &pdev->dev;
+ 	cdev->mdev.minor    = MISC_DYNAMIC_MINOR;
+@@ -243,6 +621,9 @@ static int ssam_dbg_device_probe(struct platform_device *pdev)
+ 	cdev->mdev.nodename = "surface/aggregator";
+ 	cdev->mdev.fops     = &ssam_controller_fops;
+ 
++	init_rwsem(&cdev->client_lock);
++	INIT_LIST_HEAD(&cdev->client_list);
++
+ 	status = misc_register(&cdev->mdev);
+ 	if (status) {
+ 		kfree(cdev);
+@@ -256,8 +637,32 @@ static int ssam_dbg_device_probe(struct platform_device *pdev)
+ static int ssam_dbg_device_remove(struct platform_device *pdev)
+ {
+ 	struct ssam_cdev *cdev = platform_get_drvdata(pdev);
++	struct ssam_cdev_client *client;
+ 
+-	misc_deregister(&cdev->mdev);
++	/*
++	 * Mark device as shut-down. Prevent new clients from being added and
++	 * new operations from being executed.
++	 */
++	set_bit(SSAM_CDEV_DEVICE_SHUTDOWN_BIT, &cdev->flags);
++
++	down_write(&cdev->client_lock);
++
++	/* Remove all notifiers registered by us. */
++	list_for_each_entry(client, &cdev->client_list, node) {
++		ssam_cdev_notifier_unregister_all(client);
++	}
++
++	/* Wake up async clients. */
++	list_for_each_entry(client, &cdev->client_list, node) {
++		kill_fasync(&client->fasync, SIGIO, POLL_HUP);
++	}
++
++	/* Wake up blocking clients. */
++	list_for_each_entry(client, &cdev->client_list, node) {
++		wake_up_interruptible(&client->waitq);
++	}
++
++	up_write(&cdev->client_lock);
+ 
+ 	/*
+ 	 * The controller is only guaranteed to be valid for as long as the
+@@ -266,8 +671,11 @@ static int ssam_dbg_device_remove(struct platform_device *pdev)
+ 	 */
+ 	down_write(&cdev->lock);
+ 	cdev->ctrl = NULL;
++	cdev->dev = NULL;
+ 	up_write(&cdev->lock);
+ 
++	misc_deregister(&cdev->mdev);
++
+ 	ssam_cdev_put(cdev);
+ 	return 0;
+ }
+diff --git a/include/uapi/linux/surface_aggregator/cdev.h b/include/uapi/linux/surface_aggregator/cdev.h
+index fbcce04abfe9..4f393fafc235 100644
+--- a/include/uapi/linux/surface_aggregator/cdev.h
++++ b/include/uapi/linux/surface_aggregator/cdev.h
+@@ -6,7 +6,7 @@
+  * device. This device provides direct user-space access to the SSAM EC.
+  * Intended for debugging and development.
+  *
+- * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com>
++ * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com>
+  */
+ 
+ #ifndef _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H
+@@ -73,6 +73,43 @@ struct ssam_cdev_request {
+ 	} response;
+ } __attribute__((__packed__));
+ 
+-#define SSAM_CDEV_REQUEST	_IOWR(0xA5, 1, struct ssam_cdev_request)
++/**
++ * struct ssam_cdev_notifier_desc - Notifier descriptor.
++ * @priority:        Priority value determining the order in which notifier
++ *                   callbacks will be called. A higher value means higher
++ *                   priority, i.e. the associated callback will be executed
++ *                   earlier than other (lower priority) callbacks.
++ * @target_category: The event target category for which this notifier should
++ *                   receive events.
++ *
++ * Specifies the notifier that should be registered or unregistered,
++ * specifically with which priority and for which target category of events.
++ */
++struct ssam_cdev_notifier_desc {
++	__s32 priority;
++	__u8 target_category;
++} __attribute__((__packed__));
++
++/**
++ * struct ssam_cdev_event - SSAM event sent by the EC.
++ * @target_category: Target category of the event source. See &enum ssam_ssh_tc.
++ * @target_id:       Target ID of the event source.
++ * @command_id:      Command ID of the event.
++ * @instance_id:     Instance ID of the event source.
++ * @length:          Length of the event payload in bytes.
++ * @data:            Event payload data.
++ */
++struct ssam_cdev_event {
++	__u8 target_category;
++	__u8 target_id;
++	__u8 command_id;
++	__u8 instance_id;
++	__u16 length;
++	__u8 data[];
++} __attribute__((__packed__));
++
++#define SSAM_CDEV_REQUEST		_IOWR(0xA5, 1, struct ssam_cdev_request)
++#define SSAM_CDEV_NOTIF_REGISTER	_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)
++#define SSAM_CDEV_NOTIF_UNREGISTER	_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)
+ 
+ #endif /* _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H */
+-- 
+2.31.1
+
+From 27fffb2efe662f4d8342b2720bcfca2a95e9180a Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Wed, 2 Jun 2021 19:30:42 +0200
+Subject: [PATCH] platform/surface: aggregator_cdev: Allow enabling of events
+ from user-space
+
+While events can already be enabled and disabled via the generic request
+IOCTL, this bypasses the internal reference counting mechanism of the
+controller. Due to that, disabling an event will turn it off regardless
+of any other client having requested said event, which may break
+functionality of that client.
+
+To solve this, add IOCTLs wrapping the ssam_controller_event_enable()
+and ssam_controller_event_disable() functions, which have been
+previously introduced for this specific purpose.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-sam
+---
+ .../surface/surface_aggregator_cdev.c         | 58 +++++++++++++++++++
+ include/uapi/linux/surface_aggregator/cdev.h  | 32 ++++++++++
+ 2 files changed, 90 insertions(+)
+
+diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c
+index 7b27c8ca38a5..55bf55c93624 100644
+--- a/drivers/platform/surface/surface_aggregator_cdev.c
++++ b/drivers/platform/surface/surface_aggregator_cdev.c
+@@ -384,6 +384,58 @@ static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
+ 	return ssam_cdev_notifier_unregister(client, desc.target_category);
+ }
+ 
++static long ssam_cdev_event_enable(struct ssam_cdev_client *client,
++				   const struct ssam_cdev_event_desc __user *d)
++{
++	struct ssam_cdev_event_desc desc;
++	struct ssam_event_registry reg;
++	struct ssam_event_id id;
++	long ret;
++
++	/* Read descriptor from user-space. */
++	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
++	if (ret)
++		return ret;
++
++	/* Translate descriptor. */
++	reg.target_category = desc.reg.target_category;
++	reg.target_id = desc.reg.target_id;
++	reg.cid_enable = desc.reg.cid_enable;
++	reg.cid_disable = desc.reg.cid_disable;
++
++	id.target_category = desc.id.target_category;
++	id.instance = desc.id.instance;
++
++	/* Disable event. */
++	return ssam_controller_event_enable(client->cdev->ctrl, reg, id, desc.flags);
++}
++
++static long ssam_cdev_event_disable(struct ssam_cdev_client *client,
++				    const struct ssam_cdev_event_desc __user *d)
++{
++	struct ssam_cdev_event_desc desc;
++	struct ssam_event_registry reg;
++	struct ssam_event_id id;
++	long ret;
++
++	/* Read descriptor from user-space. */
++	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
++	if (ret)
++		return ret;
++
++	/* Translate descriptor. */
++	reg.target_category = desc.reg.target_category;
++	reg.target_id = desc.reg.target_id;
++	reg.cid_enable = desc.reg.cid_enable;
++	reg.cid_disable = desc.reg.cid_disable;
++
++	id.target_category = desc.id.target_category;
++	id.instance = desc.id.instance;
++
++	/* Disable event. */
++	return ssam_controller_event_disable(client->cdev->ctrl, reg, id, desc.flags);
++}
++
+ 
+ /* -- File operations. ------------------------------------------------------ */
+ 
+@@ -467,6 +519,12 @@ static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned i
+ 		return ssam_cdev_notif_unregister(client,
+ 						  (struct ssam_cdev_notifier_desc __user *)arg);
+ 
++	case SSAM_CDEV_EVENT_ENABLE:
++		return ssam_cdev_event_enable(client, (struct ssam_cdev_event_desc __user *)arg);
++
++	case SSAM_CDEV_EVENT_DISABLE:
++		return ssam_cdev_event_disable(client, (struct ssam_cdev_event_desc __user *)arg);
++
+ 	default:
+ 		return -ENOTTY;
+ 	}
+diff --git a/include/uapi/linux/surface_aggregator/cdev.h b/include/uapi/linux/surface_aggregator/cdev.h
+index 4f393fafc235..08f46b60b151 100644
+--- a/include/uapi/linux/surface_aggregator/cdev.h
++++ b/include/uapi/linux/surface_aggregator/cdev.h
+@@ -90,6 +90,36 @@ struct ssam_cdev_notifier_desc {
+ 	__u8 target_category;
+ } __attribute__((__packed__));
+ 
++/**
++ * struct ssam_cdev_event_desc - Event descriptor.
++ * @reg:                 Registry via which the event will be enabled/disabled.
++ * @reg.target_category: Target category for the event registry requests.
++ * @reg.target_id:       Target ID for the event registry requests.
++ * @reg.cid_enable:      Command ID for the event-enable request.
++ * @reg.cid_disable:     Command ID for the event-disable request.
++ * @id:                  ID specifying the event.
++ * @id.target_category:  Target category of the event source.
++ * @id.instance:         Instance ID of the event source.
++ * @flags:               Flags used for enabling the event.
++ *
++ * Specifies which event should be enabled/disabled and how to do that.
++ */
++struct ssam_cdev_event_desc {
++	struct {
++		__u8 target_category;
++		__u8 target_id;
++		__u8 cid_enable;
++		__u8 cid_disable;
++	} reg;
++
++	struct {
++		__u8 target_category;
++		__u8 instance;
++	} id;
++
++	__u8 flags;
++} __attribute__((__packed__));
++
+ /**
+  * struct ssam_cdev_event - SSAM event sent by the EC.
+  * @target_category: Target category of the event source. See &enum ssam_ssh_tc.
+@@ -111,5 +141,7 @@ struct ssam_cdev_event {
+ #define SSAM_CDEV_REQUEST		_IOWR(0xA5, 1, struct ssam_cdev_request)
+ #define SSAM_CDEV_NOTIF_REGISTER	_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)
+ #define SSAM_CDEV_NOTIF_UNREGISTER	_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)
++#define SSAM_CDEV_EVENT_ENABLE		_IOW(0xA5, 4, struct ssam_cdev_event_desc)
++#define SSAM_CDEV_EVENT_DISABLE		_IOW(0xA5, 5, struct ssam_cdev_event_desc)
+ 
+ #endif /* _UAPI_LINUX_SURFACE_AGGREGATOR_CDEV_H */
+-- 
+2.31.1
+
+From 3695fed38f9a0c5ffafc91309a9114cd0b0f7ad9 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Wed, 2 Jun 2021 19:38:07 +0200
+Subject: [PATCH] platform/surface: aggregator_cdev: Add lockdep support
+
+Mark functions with locking requirements via the corresponding lockdep
+calls for debugging and documentary purposes.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-sam
+---
+ .../platform/surface/surface_aggregator_cdev.c   | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c
+index 55bf55c93624..2cad4147645c 100644
+--- a/drivers/platform/surface/surface_aggregator_cdev.c
++++ b/drivers/platform/surface/surface_aggregator_cdev.c
+@@ -137,6 +137,8 @@ static int ssam_cdev_notifier_register(struct ssam_cdev_client *client, u8 categ
+ 	int index = ((int)category) - 1;
+ 	int status;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	/* Validate notifier target category. */
+ 	if (index < 0 || index >= SSH_NUM_EVENTS)
+ 		return -EINVAL;
+@@ -185,6 +187,8 @@ static int ssam_cdev_notifier_unregister(struct ssam_cdev_client *client, u8 cat
+ 	int index = ((int)category) - 1;
+ 	int status;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	/* Validate notifier target category. */
+ 	if (index < 0 || index >= SSH_NUM_EVENTS)
+ 		return -EINVAL;
+@@ -254,6 +258,8 @@ static long ssam_cdev_request(struct ssam_cdev_client *client, struct ssam_cdev_
+ 	void __user *rspdata;
+ 	int status = 0, ret = 0, tmp;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	ret = copy_struct_from_user(&rqst, sizeof(rqst), r, sizeof(*r));
+ 	if (ret)
+ 		goto out;
+@@ -364,6 +370,8 @@ static long ssam_cdev_notif_register(struct ssam_cdev_client *client,
+ 	struct ssam_cdev_notifier_desc desc;
+ 	long ret;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
+ 	if (ret)
+ 		return ret;
+@@ -377,6 +385,8 @@ static long ssam_cdev_notif_unregister(struct ssam_cdev_client *client,
+ 	struct ssam_cdev_notifier_desc desc;
+ 	long ret;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
+ 	if (ret)
+ 		return ret;
+@@ -392,6 +402,8 @@ static long ssam_cdev_event_enable(struct ssam_cdev_client *client,
+ 	struct ssam_event_id id;
+ 	long ret;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	/* Read descriptor from user-space. */
+ 	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
+ 	if (ret)
+@@ -418,6 +430,8 @@ static long ssam_cdev_event_disable(struct ssam_cdev_client *client,
+ 	struct ssam_event_id id;
+ 	long ret;
+ 
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	/* Read descriptor from user-space. */
+ 	ret = copy_struct_from_user(&desc, sizeof(desc), d, sizeof(*d));
+ 	if (ret)
+@@ -507,6 +521,8 @@ static int ssam_cdev_device_release(struct inode *inode, struct file *filp)
+ static long __ssam_cdev_device_ioctl(struct ssam_cdev_client *client, unsigned int cmd,
+ 				     unsigned long arg)
+ {
++	lockdep_assert_held_read(&client->cdev->lock);
++
+ 	switch (cmd) {
+ 	case SSAM_CDEV_REQUEST:
+ 		return ssam_cdev_request(client, (struct ssam_cdev_request __user *)arg);
+-- 
+2.31.1
+
+From f1dc40840a4ce42217c46d4c0a9b37722461ee3f Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Wed, 2 Jun 2021 20:07:47 +0200
+Subject: [PATCH] docs: driver-api: Update Surface Aggregator user-space
+ interface documentation
+
+Update the controller-device user-space interface (cdev) documentation
+for the newly introduced IOCTLs and event interface.
+
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-sam
+---
+ .../surface_aggregator/clients/cdev.rst       | 127 +++++++++++++++++-
+ 1 file changed, 122 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/driver-api/surface_aggregator/clients/cdev.rst b/Documentation/driver-api/surface_aggregator/clients/cdev.rst
+index 248c1372d879..0134a841a079 100644
+--- a/Documentation/driver-api/surface_aggregator/clients/cdev.rst
++++ b/Documentation/driver-api/surface_aggregator/clients/cdev.rst
+@@ -1,9 +1,8 @@
+ .. SPDX-License-Identifier: GPL-2.0+
+ 
+-.. |u8| replace:: :c:type:`u8 <u8>`
+-.. |u16| replace:: :c:type:`u16 <u16>`
+ .. |ssam_cdev_request| replace:: :c:type:`struct ssam_cdev_request <ssam_cdev_request>`
+ .. |ssam_cdev_request_flags| replace:: :c:type:`enum ssam_cdev_request_flags <ssam_cdev_request_flags>`
++.. |ssam_cdev_event| replace:: :c:type:`struct ssam_cdev_event <ssam_cdev_event>`
+ 
+ ==============================
+ User-Space EC Interface (cdev)
+@@ -23,6 +22,40 @@ These IOCTLs and their respective input/output parameter structs are defined in
+ A small python library and scripts for accessing this interface can be found
+ at https://github.com/linux-surface/surface-aggregator-module/tree/master/scripts/ssam.
+ 
++.. contents::
++
++
++Receiving Events
++================
++
++Events can be received by reading from the device-file. The are represented by
++the |ssam_cdev_event| datatype.
++
++Before events are available to be read, however, the desired notifiers must be
++registered via the ``SSAM_CDEV_NOTIF_REGISTER`` IOCTL. Notifiers are, in
++essence, callbacks, called when the EC sends an event. They are, in this
++interface, associated with a specific target category and device-file-instance.
++They forward any event of this category to the buffer of the corresponding
++instance, from which it can then be read.
++
++Notifiers themselves do not enable events on the EC. Thus, it may additionally
++be necessary to enable events via the ``SSAM_CDEV_EVENT_ENABLE`` IOCTL. While
++notifiers work per-client (i.e. per-device-file-instance), events are enabled
++globally, for the EC and all of its clients (regardless of userspace or
++non-userspace). The ``SSAM_CDEV_EVENT_ENABLE`` and ``SSAM_CDEV_EVENT_DISABLE``
++IOCTLs take care of reference counting the events, such that an event is
++enabled as long as there is a client that has requested it.
++
++Note that enabled events are not automatically disabled once the client
++instance is closed. Therefore any client process (or group of processes) should
++balance their event enable calls with the corresponding event disable calls. It
++is, however, perfectly valid to enable and disable events on different client
++instances. For example, it is valid to set up notifiers and read events on
++client instance ``A``, enable those events on instance ``B`` (note that these
++will also be received by A since events are enabled/disabled globally), and
++after no more events are desired, disable the previously enabled events via
++instance ``C``.
++
+ 
+ Controller IOCTLs
+ =================
+@@ -45,9 +78,33 @@ The following IOCTLs are provided:
+      - ``REQUEST``
+      - Perform synchronous SAM request.
+ 
++   * - ``0xA5``
++     - ``2``
++     - ``W``
++     - ``NOTIF_REGISTER``
++     - Register event notifier.
+ 
+-``REQUEST``
+------------
++   * - ``0xA5``
++     - ``3``
++     - ``W``
++     - ``NOTIF_UNREGISTER``
++     - Unregister event notifier.
++
++   * - ``0xA5``
++     - ``4``
++     - ``W``
++     - ``EVENT_ENABLE``
++     - Enable event source.
++
++   * - ``0xA5``
++     - ``5``
++     - ``W``
++     - ``EVENT_DISABLE``
++     - Disable event source.
++
++
++``SSAM_CDEV_REQUEST``
++---------------------
+ 
+ Defined as ``_IOWR(0xA5, 1, struct ssam_cdev_request)``.
+ 
+@@ -82,6 +139,66 @@ submitted, and completed (i.e. handed back to user-space) successfully from
+ inside the IOCTL, but the request ``status`` member may still be negative in
+ case the actual execution of the request failed after it has been submitted.
+ 
+-A full definition of the argument struct is provided below:
++A full definition of the argument struct is provided below.
++
++``SSAM_CDEV_NOTIF_REGISTER``
++----------------------------
++
++Defined as ``_IOW(0xA5, 2, struct ssam_cdev_notifier_desc)``.
++
++Register a notifier for the event target category specified in the given
++notifier description with the specified priority. Notifiers registration is
++required to receive events, but does not enable events themselves. After a
++notifier for a specific target category has been registered, all events of that
++category will be forwarded to the userspace client and can then be read from
++the device file instance. Note that events may have to be enabled, e.g. via the
++``SSAM_CDEV_EVENT_ENABLE`` IOCTL, before the EC will send them.
++
++Only one notifier can be registered per target category and client instance. If
++a notifier has already been registered, this IOCTL will fail with ``-EEXIST``.
++
++Notifiers will automatically be removed when the device file instance is
++closed.
++
++``SSAM_CDEV_NOTIF_UNREGISTER``
++------------------------------
++
++Defined as ``_IOW(0xA5, 3, struct ssam_cdev_notifier_desc)``.
++
++Unregisters the notifier associated with the specified target category. The
++priority field will be ignored by this IOCTL. If no notifier has been
++registered for this client instance and the given category, this IOCTL will
++fail with ``-ENOENT``.
++
++``SSAM_CDEV_EVENT_ENABLE``
++--------------------------
++
++Defined as ``_IOW(0xA5, 4, struct ssam_cdev_event_desc)``.
++
++Enable the event associated with the given event descriptor.
++
++Note that this call will not register a notifier itself, it will only enable
++events on the controller. If you want to receive events by reading from the
++device file, you will need to register the corresponding notifier(s) on that
++instance.
++
++Events are not automatically disabled when the device file is closed. This must
++be done manually, via a call to the ``SSAM_CDEV_EVENT_DISABLE`` IOCTL.
++
++``SSAM_CDEV_EVENT_DISABLE``
++---------------------------
++
++Defined as ``_IOW(0xA5, 5, struct ssam_cdev_event_desc)``.
++
++Disable the event associated with the given event descriptor.
++
++Note that this will not unregister any notifiers. Events may still be received
++and forwarded to user-space after this call. The only safe way of stopping
++events from being received is unregistering all previously registered
++notifiers.
++
++
++Structures and Enums
++====================
+ 
+ .. kernel-doc:: include/uapi/linux/surface_aggregator/cdev.h
+-- 
+2.31.1
+
+From 2b11b38538cd9ed530777a337e83d8b4536c7d7c Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Wed, 5 May 2021 18:22:04 +0200
+Subject: [PATCH] pinctrl/amd: Add device HID for new AMD GPIO controller
+
+Add device HID AMDI0031 to the AMD GPIO controller driver match table.
+This controller can be found on Microsoft Surface Laptop 4 devices and
+seems similar enough that we can just copy the existing AMDI0030 entry.
+
+Cc: <stable@vger.kernel.org> # 5.10+
+Tested-by: Sachi King <nakato@nakato.io>
+Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
+Patchset: surface-sam
+---
+ drivers/pinctrl/pinctrl-amd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
+index 2d4acf21117c..c5950a3b4e4c 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -991,6 +991,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
+ static const struct acpi_device_id amd_gpio_acpi_match[] = {
+ 	{ "AMD0030", 0 },
+ 	{ "AMDI0030", 0},
++	{ "AMDI0031", 0},
+ 	{ },
+ };
+ MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match);
+-- 
+2.31.1
+
+From 86c51bcdc8a49989a21eb0f3e91ce72c6d68d2af Mon Sep 17 00:00:00 2001
+From: Sachi King <nakato@nakato.io>
+Date: Sat, 29 May 2021 17:47:38 +1000
+Subject: [PATCH] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7
+ override
+
+This patch is the work of Thomas Gleixner <tglx@linutronix.de> and is
+copied from:
+https://lore.kernel.org/lkml/87lf8ddjqx.ffs@nanos.tec.linutronix.de/
+
+This patch adds a quirk to the ACPI setup to patch in the the irq 7 pin
+setup that is missing in the laptops ACPI table.
+
+This patch was used for validation of the issue, and is not a proper
+fix, but is probably a better temporary hack than continuing to probe
+the Legacy PIC and run with the PIC in an unknown state.
+
+Patchset: surface-sam
+---
+ arch/x86/kernel/acpi/boot.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index 14cd3186dc77..ab3ba60cb6da 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -21,6 +21,7 @@
+ #include <linux/efi-bgrt.h>
+ #include <linux/serial_core.h>
+ #include <linux/pgtable.h>
++#include <linux/dmi.h>
+ 
+ #include <asm/e820/api.h>
+ #include <asm/irqdomain.h>
+@@ -1155,6 +1156,17 @@ static void __init mp_config_acpi_legacy_irqs(void)
+ 	}
+ }
+ 
++static const struct dmi_system_id surface_quirk[] __initconst = {
++	{
++		.ident = "Microsoft Surface Laptop 4 (AMD)",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
++			DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1952:1953")
++		},
++	},
++	{}
++};
++
+ /*
+  * Parse IOAPIC related entries in MADT
+  * returns 0 on success, < 0 on error
+@@ -1212,6 +1224,11 @@ static int __init acpi_parse_madt_ioapic_entries(void)
+ 		acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+ 				      acpi_gbl_FADT.sci_interrupt);
+ 
++	if (dmi_check_system(surface_quirk)) {
++		pr_warn("Surface hack: Override irq 7\n");
++		mp_override_legacy_irq(7, 3, 3, 7);
++	}
++
+ 	/* Fill in identity legacy mappings where no override */
+ 	mp_config_acpi_legacy_irqs();
+ 
+-- 
+2.31.1
+
+From c16918497e56baadde9e9d5a7168cd628deaf9a7 Mon Sep 17 00:00:00 2001
+From: Maximilian Luz <luzmaximilian@gmail.com>
+Date: Thu, 3 Jun 2021 14:04:26 +0200
+Subject: [PATCH] ACPI: Add AMD 13" Surface Laptop 4 model to irq 7 override
+ quirk
+
+The 13" version of the Surface Laptop 4 has the same problem as the 15"
+version, but uses a different SKU. Add that SKU to the quirk as well.
+
+Patchset: surface-sam
+---
+ arch/x86/kernel/acpi/boot.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index ab3ba60cb6da..fa1dcdd119e5 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -1158,12 +1158,19 @@ static void __init mp_config_acpi_legacy_irqs(void)
+ 
+ static const struct dmi_system_id surface_quirk[] __initconst = {
+ 	{
+-		.ident = "Microsoft Surface Laptop 4 (AMD)",
++		.ident = "Microsoft Surface Laptop 4 (AMD 15\")",
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
+ 			DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1952:1953")
+ 		},
+ 	},
++	{
++		.ident = "Microsoft Surface Laptop 4 (AMD 13\")",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
++			DMI_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1958:1959")
++		},
++	},
+ 	{}
+ };
  
 -- 
 2.31.1
 
-From 6c447f73fba0aa9071801a5bd6f439eabf86b202 Mon Sep 17 00:00:00 2001
+From b401c48588cadfe4e2ffb5ba6c253a015048e2b2 Mon Sep 17 00:00:00 2001
 From: Sachi King <nakato@nakato.io>
 Date: Sat, 29 May 2021 22:27:25 +1000
 Subject: [PATCH] platform/x86: amd-pmc: Add device HID for AMD PMC

+ 1 - 1
patches/5.12/0007-surface-typecover.patch

@@ -1,4 +1,4 @@
-From d047431a3c69b6145376011c3d36140daf3698ac Mon Sep 17 00:00:00 2001
+From 375584e2e66f0720e2718ef898089361164b0f39 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
 Date: Thu, 5 Nov 2020 13:09:45 +0100
 Subject: [PATCH] hid/multitouch: Turn off Type Cover keyboard backlight when

+ 39 - 0
patches/5.12/0008-surface-go-touchscreen.patch

@@ -0,0 +1,39 @@
+From 0becc1c767ddb7c1a80da5ca933d525daab1060c Mon Sep 17 00:00:00 2001
+From: Zoltan Tamas Vajda <zoltan.tamas.vajda@gmail.com>
+Date: Thu, 3 Jun 2021 10:50:55 +0200
+Subject: [PATCH] Added quirk for Surface Go touchscreen
+
+Patchset: surface-go-touchscreen
+---
+ drivers/hid/hid-ids.h   | 1 +
+ drivers/hid/hid-input.c | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index ba338973e968..bb976bb1b1c0 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -396,6 +396,7 @@
+ #define USB_DEVICE_ID_HP_X2_10_COVER	0x0755
+ #define I2C_DEVICE_ID_HP_SPECTRE_X360_15	0x2817
+ #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN	0x2706
++#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN	0x261A
+ 
+ #define USB_VENDOR_ID_ELECOM		0x056e
+ #define USB_DEVICE_ID_ELECOM_BM084	0x0061
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 236bccd37760..cc16f29e27a4 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -326,6 +326,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
+ 	  HID_BATTERY_QUIRK_IGNORE },
+ 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
+ 	  HID_BATTERY_QUIRK_IGNORE },
++ 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
++	  HID_BATTERY_QUIRK_IGNORE },
+ 	{}
+ };
+ 
+-- 
+2.31.1
+

+ 15 - 15
patches/5.12/0008-cameras.patch → patches/5.12/0009-cameras.patch

@@ -1,4 +1,4 @@
-From a00b2c39009fda2b28f428eff2be4bc21b80a2ec Mon Sep 17 00:00:00 2001
+From c252a316ebbf36de29e25085b056e82298b905a1 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:21 +0100
 Subject: [PATCH] ACPI: scan: Extend acpi_walk_dep_device_list()
@@ -220,7 +220,7 @@ index deceed0d76c6..13eb5ac82729 100644
  
  static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
 diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c
-index 8dc2c267bcd6..517f774a6e60 100644
+index 5d780e55f4a1..279d9df19c01 100644
 --- a/drivers/platform/surface/aggregator/core.c
 +++ b/drivers/platform/surface/aggregator/core.c
 @@ -621,8 +621,8 @@ static const struct acpi_gpio_mapping ssam_acpi_gpios[] = {
@@ -380,7 +380,7 @@ index 3bdcfc4401b7..c2da6b8939c0 100644
 -- 
 2.31.1
 
-From cc232390378a8ca6109887fb3e282ee093cd70f7 Mon Sep 17 00:00:00 2001
+From b3041023a204f65ccbff6f7b47330ec891237bc5 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:22 +0100
 Subject: [PATCH] ACPI: scan: Add function to fetch dependent of acpi device
@@ -470,7 +470,7 @@ index 849f3540ed53..b531750eb422 100644
 -- 
 2.31.1
 
-From 40c6548ea4cdf4a9f11e7140d7ff9f5a65a3ece4 Mon Sep 17 00:00:00 2001
+From 548e414f08adeb21da499d223d32a2e0ccb409c7 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:23 +0100
 Subject: [PATCH] i2c: core: Add a format macro for I2C device names
@@ -531,7 +531,7 @@ index a670ae129f4b..a2f6ee71b5be 100644
 -- 
 2.31.1
 
-From d6351ceff5e95f0e177a890952a8cf90028f14ad Mon Sep 17 00:00:00 2001
+From b1a1be0754543aef45fa267de9aa22c21e3a9dc4 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:24 +0100
 Subject: [PATCH] gpiolib: acpi: Export acpi_get_gpiod()
@@ -608,7 +608,7 @@ index c73b25bc9213..566feb56601f 100644
 -- 
 2.31.1
 
-From 2e7ad4003f7d5685b1463a0915977fb9a3284694 Mon Sep 17 00:00:00 2001
+From 42eb8a93ef56c7520c793c244e40544cc0e462c3 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:25 +0100
 Subject: [PATCH] clkdev: Make clkdev_drop() null aware
@@ -640,7 +640,7 @@ index 0f2e3fcf0f19..c082720f8ade 100644
 -- 
 2.31.1
 
-From 0b67f36249f20fa717a74c5d93c7b47d1fcaf5c2 Mon Sep 17 00:00:00 2001
+From b1edaa9264cbe0d5c8b737ae278e6f4b143d5f09 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:26 +0100
 Subject: [PATCH] gpiolib: acpi: Add acpi_gpio_get_io_resource()
@@ -717,7 +717,7 @@ index c2da6b8939c0..07a0044397e1 100644
 -- 
 2.31.1
 
-From e75b76cda1a791e88cf1d069080cbb9c0d78778f Mon Sep 17 00:00:00 2001
+From 5dfbd5ffa9e9082ba4d06506784eae7967d8c8db Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:27 +0100
 Subject: [PATCH] platform/x86: Add intel_skl_int3472 driver
@@ -1818,7 +1818,7 @@ index 000000000000..843eaa27e9da
 -- 
 2.31.1
 
-From 9d50e89e724e5116e44f7179951f7a6646767594 Mon Sep 17 00:00:00 2001
+From ff746a92185d4ab05392230f96a0dac236cbb5b9 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 15:09:28 +0100
 Subject: [PATCH] mfd: tps68470: Remove tps68470 MFD driver
@@ -2014,7 +2014,7 @@ index 4a4df4ffd18c..000000000000
 -- 
 2.31.1
 
-From 97187b4b7a4f3a853a72283f36b898de7dcff09f Mon Sep 17 00:00:00 2001
+From 670edce87dffaea09f7383497b782c936caed7b5 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Mon, 5 Apr 2021 23:56:53 +0100
 Subject: [PATCH] media: ipu3-cio2: Toggle sensor streaming in pm runtime ops
@@ -2074,7 +2074,7 @@ index fecef85bd62e..9dafb9470708 100644
 -- 
 2.31.1
 
-From ec6d1a9e51df9fa9e2c1fb14896faecead7fcda8 Mon Sep 17 00:00:00 2001
+From 654205470488fdc3701d70d10c31fbc97f69f7a4 Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Mon, 5 Apr 2021 23:56:54 +0100
 Subject: [PATCH] media: i2c: Add support for ov5693 sensor
@@ -3717,7 +3717,7 @@ index 000000000000..da2ca99a7ad3
 -- 
 2.31.1
 
-From 6512e02e670560aa19fb8fab312d711a630c03bd Mon Sep 17 00:00:00 2001
+From 3e5f7aa0ff27b6875df6c70e0d82cf7c2e052784 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
 Date: Fri, 22 Jan 2021 20:58:13 +0100
 Subject: [PATCH] cio2-bridge: Parse sensor orientation and rotation
@@ -3880,7 +3880,7 @@ index dd0ffcafa489..924d99d20328 100644
 -- 
 2.31.1
 
-From 64fbb70d5633d2062f4af7d062ea5dd948ef6b0f Mon Sep 17 00:00:00 2001
+From 32174318d4fdf290c75609f13a0e3e96b08d61b0 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
 Date: Sun, 24 Jan 2021 11:07:42 +0100
 Subject: [PATCH] cio2-bridge: Use macros and add warnings
@@ -3984,7 +3984,7 @@ index 924d99d20328..e1e388cc9f45 100644
 -- 
 2.31.1
 
-From bc1238df63e41248525d2cc4318a73d7e237ad6c Mon Sep 17 00:00:00 2001
+From 7551ce0160db4cbae6e554113138008b2be917fa Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
 Date: Thu, 6 May 2021 07:52:44 +0200
 Subject: [PATCH] cio2-bridge: Use correct dev_properties size
@@ -4010,7 +4010,7 @@ index e1e388cc9f45..deaf5804f70d 100644
 -- 
 2.31.1
 
-From f0d17e0d1de48b90e6c886604f70ca832027402b Mon Sep 17 00:00:00 2001
+From 3af4b18551435c9f395b13e693c23447076dda0c Mon Sep 17 00:00:00 2001
 From: Daniel Scally <djrscally@gmail.com>
 Date: Thu, 20 May 2021 23:31:04 +0100
 Subject: [PATCH] media: i2c: Fix vertical flip in ov5693

+ 0 - 1
pkg/arch/kernel/0008-cameras.patch

@@ -1 +0,0 @@
-../../../patches/5.12/0008-cameras.patch

+ 1 - 0
pkg/arch/kernel/0008-surface-go-touchscreen.patch

@@ -0,0 +1 @@
+../../../patches/5.12/0008-surface-go-touchscreen.patch

+ 1 - 0
pkg/arch/kernel/0009-cameras.patch

@@ -0,0 +1 @@
+../../../patches/5.12/0009-cameras.patch

+ 11 - 9
pkg/arch/kernel/PKGBUILD

@@ -34,7 +34,8 @@ source=(
   0005-surface-sam-over-hid.patch
   0006-surface-sam.patch
   0007-surface-typecover.patch
-  0008-cameras.patch
+  0008-surface-go-touchscreen.patch
+  0009-cameras.patch
 )
 validpgpkeys=(
   'ABAF11C65A2970B130ABE3C479BE3E4300411886'  # Linus Torvalds
@@ -45,14 +46,15 @@ sha256sums=('5a0f699d131a108cfa686152fe831d90f85b2aa634075e0c3be87556790500ce'
             '55c4cb76754b1db234a0994806106d8481c171d4e3fead12793f0083a48511d4'
             '252c7a78ffb1efe9751aabc93cc79031ef69dbc95baa7970cbaabcd5474fe7d8'
             '9474de18769968c5558fedda5be354fe0babf1365541d4d0ac8e1ac47d4bbb88'
-            '4169fb8548c78059a31ebc2786bc7e5047b9cdab618a3ea873bff01afe6e9df5'
-            '61b957d2ff82936ca1e16b0f40ffa99b4266437b029094ed7783bd677f183fd1'
-            'b49435e3a5e42d061fdcce1930b7b50b7127523d82c10b8db6dab24141be216f'
-            '08171b61839ba870f722900b218c4a430fe5f07b90ce85e907091a77eb3ee771'
-            'b2cda75a1e1c37628b4ef7f2c2af0cc3ff8768fd0d9cb122f18bf8b7f898dc92'
-            '428d415d3ce28f97ebb0a594a808ed4799047bfab5fee039c25f77954a52cde9'
-            '69021ae0dee9079d0ba9703c9250c3d9886ee3a19fa4b0d58c9da2ac9519e218'
-            '424b05fadd10bd36cad885b42b63acdbd1c40e4343caa03b4ca6cb85c226dbf3')
+            '5cd3a0b006c46b0a028dbcbea403462350c9048ebb0499501ffcbd9569be26d2'
+            '5f03e81efe264e6fa4db3452ec37c6ba286194500db2b06bbef8edc70e3aec51'
+            'c031b9f4892cb399554b1f344d8522f11c42c94a7665018648f0638233682748'
+            '080bfd5a78f069896ba10062001fdf68f8944c4840af6a6d9aa509d4537c285e'
+            '5b2263bee2d0c42362228c05f295fc73787335660e9f771bcd7a33e9956d42a8'
+            '8153c43d5a2b36c66a28381d17bc158dae6e0ef0bbde8bb61a1bd92204d66676'
+            'e55a1cd4a2b50207098f6f7bf9eebe3621395fda2a1c5a1df97ba2cad5032110'
+            '1e39dfaba3279028c955165936a20bf0ba9f1157d15a77694731098ee00944bb'
+            '64ad4ae75e6f30ac9f81766de18185cf6dea31efc300fea7396c8123a17045e8')
 
 
 export KBUILD_BUILD_HOST=archlinux