diff --git a/patches/4.19/0001-surface3-power.patch b/patches/4.19/0001-surface3-power.patch index e6982199a..b8b727fab 100644 --- a/patches/4.19/0001-surface3-power.patch +++ b/patches/4.19/0001-surface3-power.patch @@ -1,4 +1,4 @@ -From 4ef4088eb918b988832417b5b76a2a48c38d5977 Mon Sep 17 00:00:00 2001 +From fc65616571a8911bb4ccc71101b33c6038ff2efa Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 28 Sep 2019 18:00:43 +0200 Subject: [PATCH] platform/x86: Surface 3 battery platform operation region diff --git a/patches/4.19/0002-surface3-touchscreen-dma-fix.patch b/patches/4.19/0002-surface3-touchscreen-dma-fix.patch index 6ee8c21c3..d158fc14e 100644 --- a/patches/4.19/0002-surface3-touchscreen-dma-fix.patch +++ b/patches/4.19/0002-surface3-touchscreen-dma-fix.patch @@ -1,4 +1,4 @@ -From 823340135a823b61dd3af9a899e6deb12fd5146a Mon Sep 17 00:00:00 2001 +From fd4d01ce298960c8d173f3828b921f742e28e56f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Sun, 5 Jul 2020 14:56:20 +0300 Subject: [PATCH] dmaengine: dw: Initialize channel before each transfer diff --git a/patches/4.19/0003-surface3-oemb.patch b/patches/4.19/0003-surface3-oemb.patch index 345766abb..bc327a1b1 100644 --- a/patches/4.19/0003-surface3-oemb.patch +++ b/patches/4.19/0003-surface3-oemb.patch @@ -1,4 +1,4 @@ -From fff841149f0cf5f31f8f14d2801f133d0c594b07 Mon Sep 17 00:00:00 2001 +From 334fd9a32256bddb8f888cfbd94f83ffe9013766 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 18 Oct 2020 16:42:44 +0900 Subject: [PATCH] (surface3-oemb) add DMI matches for Surface 3 with broken DMI diff --git a/patches/4.19/0004-surface-buttons.patch b/patches/4.19/0004-surface-buttons.patch index da46418f2..04ffae306 100644 --- a/patches/4.19/0004-surface-buttons.patch +++ b/patches/4.19/0004-surface-buttons.patch @@ -1,4 +1,4 @@ -From 7905b8aaec93a47b931de6d09e2301d1272a4fac Mon Sep 17 00:00:00 2001 +From f959243b0d3f5fa0e1751569d034ce2331ce158c Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 27 Jul 2019 17:51:37 +0200 Subject: [PATCH] platform/x86: surfacepro3_button: Fix device check @@ -92,7 +92,7 @@ index 1b491690ce07..96627627060e 100644 -- 2.29.2 -From df66c1e7850b925bf65cc414ed55a8a47b52fb6c Mon Sep 17 00:00:00 2001 +From f4f7ee91867315e346f35bab74ea21a68784bd71 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 27 Jul 2019 17:52:01 +0200 Subject: [PATCH] Input: soc_button_array - Add support for newer surface @@ -297,7 +297,7 @@ index 55cd6e0b409c..8f21c062c85d 100644 -- 2.29.2 -From 25b9f918723131fcbb40cd45c252ca7af8c56ab4 Mon Sep 17 00:00:00 2001 +From 272c4184ca0c2fc03eed50ad103369ec7c981d48 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 5 Oct 2019 14:11:58 +0200 Subject: [PATCH] Input: soc_button_array - partial revert of support for newer @@ -386,7 +386,7 @@ index 8f21c062c85d..5983733d78dd 100644 -- 2.29.2 -From 80fe7fb9e21d418bdff697b6a9fd73e72b875ac0 Mon Sep 17 00:00:00 2001 +From 7d2eb03cdbe9fc4e4ce1b731cbd424b50b3f4e4d Mon Sep 17 00:00:00 2001 From: "Tsuchiya Yuto (kitakar5525)" Date: Mon, 11 May 2020 17:40:21 +0900 Subject: [PATCH] Input: soc_button_array - fix Wdiscarded-qualifiers for diff --git a/patches/4.19/0005-suspend.patch b/patches/4.19/0005-suspend.patch index 5bcde7a60..0c58f96f7 100644 --- a/patches/4.19/0005-suspend.patch +++ b/patches/4.19/0005-suspend.patch @@ -1,4 +1,4 @@ -From 5d9722e3203b209f6576fb8605a5c21bc454420a Mon Sep 17 00:00:00 2001 +From f7f26c2b100b72758ff599025055173f3011b973 Mon Sep 17 00:00:00 2001 From: kitakar5525 <34676735+kitakar5525@users.noreply.github.com> Date: Sat, 28 Sep 2019 17:48:21 +0200 Subject: [PATCH] nvme: Backport changes for suspend diff --git a/patches/4.19/0006-ipts.patch b/patches/4.19/0006-ipts.patch index 279562023..87e151bab 100644 --- a/patches/4.19/0006-ipts.patch +++ b/patches/4.19/0006-ipts.patch @@ -1,4 +1,4 @@ -From de784419fd4bd0b5115624a4c2bb93d9edcedbdb Mon Sep 17 00:00:00 2001 +From 08cce4daaed63a3b5a7f6546fc4533416f91ea65 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 28 Sep 2019 17:58:17 +0200 Subject: [PATCH] Add support for Intel IPTS touch devices diff --git a/patches/4.19/0007-wifi.patch b/patches/4.19/0007-wifi.patch index cfb77bff7..5c9fd8c54 100644 --- a/patches/4.19/0007-wifi.patch +++ b/patches/4.19/0007-wifi.patch @@ -1,4 +1,4 @@ -From de2af39d0c0cdf9e70f4640a66439779420cb1d7 Mon Sep 17 00:00:00 2001 +From 0d4668c515d69b1425d954bb188ed7b9bbe20046 Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Wed, 24 Jul 2019 19:27:45 +0800 Subject: [PATCH] mwifiex: pcie: Use dev_get_drvdata @@ -49,7 +49,7 @@ index 991b9cc18000..2aa0436d3548 100644 -- 2.29.2 -From 0c6c63e733d81eda2eb4663fb763a82425f696b1 Mon Sep 17 00:00:00 2001 +From 06e606f7f7bb1c4b78bec41d3e04f20a08cd2b12 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Thu, 24 Sep 2020 18:02:06 +0900 Subject: [PATCH] mwifiex: pcie: skip cancel_work_sync() on reset failure path @@ -206,7 +206,7 @@ index f7ce9b6db6b4..72d0c01ff359 100644 -- 2.29.2 -From 8e7aff966077661602f876020db3f33be0147498 Mon Sep 17 00:00:00 2001 +From 619c5a9856d21b413630a8d6d44367b1c50d3d5f Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Mon, 28 Sep 2020 17:46:49 +0900 Subject: [PATCH] mwifiex: pcie: add DMI-based quirk impl for Surface devices @@ -414,7 +414,7 @@ index 000000000000..5326ae7e5671 -- 2.29.2 -From 188422b0bc6627f5bd37b8f31e7be46b5a9766dc Mon Sep 17 00:00:00 2001 +From 0b7071dff547d65756bb4e0d87cc537ce40fbe6c Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Tue, 29 Sep 2020 17:25:22 +0900 Subject: [PATCH] mwifiex: pcie: add reset_d3cold quirk for Surface gen4+ @@ -615,7 +615,7 @@ index 5326ae7e5671..8b9dcb5070d8 100644 -- 2.29.2 -From fb409a1bcabf27795dbfd44fdb14dbbc28d41691 Mon Sep 17 00:00:00 2001 +From 652460c21b1e3d2f08ee41881b7757fa86b2e42d Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Tue, 29 Sep 2020 17:32:22 +0900 Subject: [PATCH] mwifiex: pcie: add reset_wsid quirk for Surface 3 @@ -794,7 +794,7 @@ index 8b9dcb5070d8..3ef7440418e3 100644 -- 2.29.2 -From 481f2abd50bbb5074783246ed7d1e94e3ec9c533 Mon Sep 17 00:00:00 2001 +From 53b08b7fc89a3c8e021c3626744cb8ec98b3ac04 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Wed, 30 Sep 2020 18:08:24 +0900 Subject: [PATCH] mwifiex: pcie: (OEMB) add quirk for Surface 3 with broken DMI @@ -856,7 +856,7 @@ index f0a6fa0a7ae5..34dcd84f02a6 100644 -- 2.29.2 -From 6ed6489636b5bc94d9f91d58e9e501f03f39bdc9 Mon Sep 17 00:00:00 2001 +From 25ec88c9cffb6780d69bb6a6c9cd412c4f543572 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Thu, 24 Sep 2020 01:56:29 +0900 Subject: [PATCH] mwifiex: fix mwifiex_shutdown_sw() causing sw reset failure @@ -933,7 +933,7 @@ index e48b47f42554..ceac611ef086 100644 -- 2.29.2 -From 4401ad7dd35039b245819a3e6c2952fe2ceb89a8 Mon Sep 17 00:00:00 2001 +From 9e5b0bda24d5f57dc04c3fe1693d3914014bec20 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Thu, 24 Sep 2020 01:56:34 +0900 Subject: [PATCH] mwifiex: pcie: use shutdown_sw()/reinit_sw() on @@ -1075,7 +1075,7 @@ index 290427c98630..d80eb18fb0d1 100644 -- 2.29.2 -From b561737f6bfc200bfa9453ba0c06eb6e39336e91 Mon Sep 17 00:00:00 2001 +From fe963c91f4a3f1ddbca1ce248ed8c5627b31dbdd Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Mon, 24 Aug 2020 17:11:35 +0900 Subject: [PATCH] mwifiex: pcie: add enable_device_dump module parameter @@ -1124,7 +1124,7 @@ index d80eb18fb0d1..ea766584d3b7 100644 -- 2.29.2 -From 67cecf9f5a02ed5f1391ea261273a5b72523fa9f Mon Sep 17 00:00:00 2001 +From fef44e65fdf6b8a853044461818b3623f6a07245 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:11:49 +0900 Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+ @@ -1279,7 +1279,7 @@ index 3ef7440418e3..a95ebac06e13 100644 -- 2.29.2 -From 1f21e92e5b364891db05a5e4e35b6d8493e1c482 Mon Sep 17 00:00:00 2001 +From cc0c05dad2910e400a0d9c8a543ceb7455403118 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:25:48 +0900 Subject: [PATCH] mwifiex: add allow_ps_mode module parameter @@ -1341,7 +1341,7 @@ index 650191db25cb..dd1f08a2325f 100644 -- 2.29.2 -From f891fc82ba096d0e4d6ae52e27130ea32137768b Mon Sep 17 00:00:00 2001 +From d431aa4c5c63347c34b80279a807c4b8e1cb3530 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:38:48 +0900 Subject: [PATCH] mwifiex: print message when changing ps_mode @@ -1376,7 +1376,7 @@ index dd1f08a2325f..ee88da92b97c 100644 -- 2.29.2 -From 353a81e8459639b7dfdea92b645d97cdd5e22be9 Mon Sep 17 00:00:00 2001 +From bac89bdb52443cb6f459ec34b22086d31ade4006 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:59:37 +0900 Subject: [PATCH] mwifiex: disable ps_mode explicitly by default instead diff --git a/patches/4.19/0008-surface-gpe.patch b/patches/4.19/0008-surface-gpe.patch index 8859e2144..d04f83f32 100644 --- a/patches/4.19/0008-surface-gpe.patch +++ b/patches/4.19/0008-surface-gpe.patch @@ -1,4 +1,4 @@ -From f64a4ddf2c9d9322f2659cb94f3a7fc2f8fd58bb Mon Sep 17 00:00:00 2001 +From dff056745af83439ff1fe38c14a72134103aba76 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sun, 16 Aug 2020 23:39:56 +0200 Subject: [PATCH] platform/x86: Add Driver to set up lid GPEs on MS Surface diff --git a/patches/4.19/0009-surface-sam-over-hid.patch b/patches/4.19/0009-surface-sam-over-hid.patch index 0a096ebae..bc79f9c87 100644 --- a/patches/4.19/0009-surface-sam-over-hid.patch +++ b/patches/4.19/0009-surface-sam-over-hid.patch @@ -1,4 +1,4 @@ -From 1658dd6952a8f2bb863a1d2e6e5cd509c34c6eb8 Mon Sep 17 00:00:00 2001 +From 6ce72ae5499eb0209b24c975dc50562db586af5f Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 25 Jul 2020 17:19:53 +0200 Subject: [PATCH] i2c: acpi: Implement RawBytes read access @@ -109,7 +109,7 @@ index 8ba4122fb340..f9a24b56fec0 100644 -- 2.29.2 -From 425743d6ee6bd69cd2431ca9c6e91b1c97e06ec8 Mon Sep 17 00:00:00 2001 +From dc55c219aaf66f139e225aeac473557689a23523 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sun, 6 Sep 2020 04:01:19 +0200 Subject: [PATCH] platform/x86: Add driver for Surface Book 1 dGPU switch diff --git a/patches/4.19/0010-surface-sam.patch b/patches/4.19/0010-surface-sam.patch index 0bca79ed2..d0af7303b 100644 --- a/patches/4.19/0010-surface-sam.patch +++ b/patches/4.19/0010-surface-sam.patch @@ -1,4 +1,4 @@ -From 1642fa0e39646fffe44a62ac4c85db07c201140f Mon Sep 17 00:00:00 2001 +From e5396b65d0a5db6ffad8ffd9290217c34aa5fb6a Mon Sep 17 00:00:00 2001 From: qzed Date: Mon, 26 Aug 2019 01:15:40 +0200 Subject: [PATCH] ACPI: Fix buffer/integer type mismatch @@ -81,7 +81,7 @@ index b272c329d45d..cf547883a993 100644 -- 2.29.2 -From ee9ad4dc36b919066f564f4785fd41bd3364e2ca Mon Sep 17 00:00:00 2001 +From 98e7c4795fe586f76f3800c200d91f94b94988f8 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Tue, 24 Sep 2019 17:38:12 +0200 Subject: [PATCH] serdev: Add ACPI devices by ResourceSource field @@ -269,7 +269,7 @@ index c66a04d24f1d..1b18d12d217f 100644 -- 2.29.2 -From 56358d3c4d2d76b39f5c39c0291adc91a757845e Mon Sep 17 00:00:00 2001 +From 59903a6f376692bc4400f26a70223ce8efb52571 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Tue, 31 Jul 2018 07:50:37 +0200 Subject: [PATCH] PCI: pciehp: Differentiate between surprise and safe removal @@ -468,7 +468,7 @@ index 5c58c22e0c08..18f83e554c73 100644 -- 2.29.2 -From 2db3f53f53596e61c6694e408a75d997ca8b7f9b Mon Sep 17 00:00:00 2001 +From 705add1ff08aa86accb5ca7616f401f481ced186 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 19 Aug 2018 16:29:00 +0200 Subject: [PATCH] PCI: pciehp: Drop unnecessary includes @@ -607,7 +607,7 @@ index 18f83e554c73..c512b2ed85ed 100644 -- 2.29.2 -From d70c5e1f17d56de44f426c935e5629320354c285 Mon Sep 17 00:00:00 2001 +From e6974b233a290d13909f6919fc8e4c95da3b7e7c Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 19 Aug 2018 16:29:00 +0200 Subject: [PATCH] PCI: pciehp: Drop hotplug_slot_ops wrappers @@ -820,7 +820,7 @@ index d4b7049cbc70..576362d0b1cd 100644 -- 2.29.2 -From 582d48793180cc0535d49ff74c1101e4d0b6be22 Mon Sep 17 00:00:00 2001 +From 7d0738319b444c496478de604bf671962dbca9da Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 8 Sep 2018 09:59:01 +0200 Subject: [PATCH] PCI: pciehp: Tolerate Presence Detect hardwired to zero @@ -1018,7 +1018,7 @@ index 576362d0b1cd..7f4173d6771a 100644 -- 2.29.2 -From 38cb19634777dba2afebad3e7a91a8042118f8f4 Mon Sep 17 00:00:00 2001 +From 7e9a7201ec48619094e26251a84428e273a9fb28 Mon Sep 17 00:00:00 2001 From: Patrick Talbert Date: Wed, 5 Sep 2018 09:12:53 +0200 Subject: [PATCH] PCI/ASPM: Do not initialize link state when aspm_disabled is @@ -1063,7 +1063,7 @@ index cb474338f39d..18aa830e79e4 100644 -- 2.29.2 -From 3f01a0a388f501669a75beba433fcbb849f76d75 Mon Sep 17 00:00:00 2001 +From 5669402f43f49197d35a1a6656fd6ab9d5de1a8d Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sun, 19 Aug 2018 16:29:00 +0200 Subject: [PATCH] PCI: Simplify disconnected marking @@ -1149,7 +1149,7 @@ index 2c3b5bd59b18..dee5a7507403 100644 -- 2.29.2 -From ee87234a7192ca9f9482700890ef27929f43a833 Mon Sep 17 00:00:00 2001 +From 8ecc289079e5f3b6f3880d31406f015e2f1d7576 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Tue, 18 Sep 2018 21:46:17 +0200 Subject: [PATCH] PCI: pciehp: Unify controller and slot structs @@ -2341,7 +2341,7 @@ index 8da87931bd45..b9c1396db6fe 100644 -- 2.29.2 -From 59185f8003d6fd1fc7a4799804a5f58b43ba61d9 Mon Sep 17 00:00:00 2001 +From bdb3c9c2e2c6cc604e4b08538f6d3145c73d8b13 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 8 Sep 2018 09:59:01 +0200 Subject: [PATCH] PCI: pciehp: Rename controller struct members for clarity @@ -2648,7 +2648,7 @@ index 4a17d71e15d3..e4d6ec960630 100644 -- 2.29.2 -From 95cb9168fe1905516f8814cf67a1809500f39f95 Mon Sep 17 00:00:00 2001 +From 918f28611928ad1d248d6d2a076858414b0f02fb Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 8 Sep 2018 09:59:01 +0200 Subject: [PATCH] PCI: pciehp: Reshuffle controller struct for clarity @@ -2779,7 +2779,7 @@ index 2499489158cc..df82a0335515 100644 -- 2.29.2 -From f3ac643412e55fb9213c876815b37f366389a5ab Mon Sep 17 00:00:00 2001 +From 8d8f50f10db4c1fd6bd8f07c7e3a5e5c0b934c3e Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 20 Sep 2018 10:27:17 -0600 Subject: [PATCH] PCI: Make link active reporting detection generic @@ -2976,7 +2976,7 @@ index ec6c48ecd7d5..74c8e9190fed 100644 -- 2.29.2 -From 997d0193313b98d78848a2be7bcaaa81a6aec3ed Mon Sep 17 00:00:00 2001 +From 5e95ad37389c12aff9587734ebb68750026234d7 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:53:53 -0500 Subject: [PATCH] PCI: Do not skip power-managed bridges in pci_enable_wake() @@ -3027,7 +3027,7 @@ index 99292b338401..2898b7c1ac4b 100644 -- 2.29.2 -From 6d1fce6779d1dc4d49460fe64ae96b44ea9d464e Mon Sep 17 00:00:00 2001 +From 8f3ebf19d5a222171f13bdf5609917aff243e461 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:38:19 -0500 Subject: [PATCH] PCI: pciehp: Disable hotplug interrupt during suspend @@ -3141,7 +3141,7 @@ index 0693870a9e24..b5c7f5ef597a 100644 -- 2.29.2 -From a99ae35fe8be366fbfe9429d9847da1471aff1df Mon Sep 17 00:00:00 2001 +From ee4527979ffd3e8233e646fa9fc0489b515e4fea Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:41:46 -0500 Subject: [PATCH] PCI: pciehp: Do not handle events if interrupts are masked @@ -3183,7 +3183,7 @@ index b5c7f5ef597a..242b9f30210a 100644 -- 2.29.2 -From eef861fbf94163feea477cd49e156e4496af7cfd Mon Sep 17 00:00:00 2001 +From 904c645dfbc3561571e83466c37405d0596f0744 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:41:47 -0500 Subject: [PATCH] PCI/portdrv: Resume upon exit from system suspend if left @@ -3236,7 +3236,7 @@ index 23a5a0c2c3fe..5badf8a1ce0a 100644 -- 2.29.2 -From 7cc0751b85d3c88691cf9af6442f4419e1dddecd Mon Sep 17 00:00:00 2001 +From 457fdf1cbc4dedb77510da9782a67ada2ef47ca1 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:41:48 -0500 Subject: [PATCH] PCI/portdrv: Add runtime PM hooks for port service drivers @@ -3348,7 +3348,7 @@ index 5badf8a1ce0a..59d2567e2db2 100644 -- 2.29.2 -From fe1bb6f78f5fd1fbca45179cbf13c1b19ed252c6 Mon Sep 17 00:00:00 2001 +From d6d430577d1761fd648f6f8830b5f484f636495b Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:41:49 -0500 Subject: [PATCH] PCI: pciehp: Implement runtime PM callbacks @@ -3405,7 +3405,7 @@ index 8e6e4ce869fb..e5de25ebc4cf 100644 -- 2.29.2 -From cc23d7ff4f57b1197447240dc72ece2856a53c38 Mon Sep 17 00:00:00 2001 +From d8bca9ae8cb084e39851819309ba001ad86a6d93 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:57:05 -0500 Subject: [PATCH] ACPI / property: Allow multiple property compatible _DSD @@ -3700,7 +3700,7 @@ index cd412817654f..4e2e30e340fe 100644 -- 2.29.2 -From 59ffa38fe09a49b0a4cb0a382a82c0918825989c Mon Sep 17 00:00:00 2001 +From 733f9fb9c82bef870602742234425e8086489b9f Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 27 Sep 2018 16:57:14 -0500 Subject: [PATCH] PCI / ACPI: Whitelist D3 for more PCIe hotplug ports @@ -3865,7 +3865,7 @@ index e9ede82ee2c2..0a5efc437bd1 100644 -- 2.29.2 -From 9d072cfa21cd8ca5275f43824e628df333285758 Mon Sep 17 00:00:00 2001 +From fdcc28601697d39255b44928cfd4f209c9a89997 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 7 Jan 2019 16:09:40 +0300 Subject: [PATCH] PCI: pciehp: Assign ctrl->slot_ctrl before writing it to @@ -3919,7 +3919,7 @@ index 242b9f30210a..7074d4923811 100644 -- 2.29.2 -From 009b4e3ba015aa419bb45cdf3f2bf4ca13ee449a Mon Sep 17 00:00:00 2001 +From 3d155f1fbae37bff815ae3f9ec5c3370ddcc4ec0 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 31 Jan 2019 20:07:46 +0300 Subject: [PATCH] PCI: pciehp: Disable Data Link Layer State Changed event on @@ -4008,7 +4008,7 @@ index 7074d4923811..a37ff79a6e9e 100644 -- 2.29.2 -From 9d79f638e0ad9724c604bc62247ca2319ff3a6c4 Mon Sep 17 00:00:00 2001 +From 30fd6451a7e698ca9737934ae5b342a37ec82485 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Thu, 29 Oct 2020 22:04:38 +0100 Subject: [PATCH] PCI: Allow D3cold for hot-plug ports on Surface Books @@ -4093,7 +4093,7 @@ index b53a6772ee09..70af1713767f 100644 -- 2.29.2 -From 0765854a166b10c957ffcd8e23dc40d0096adcb7 Mon Sep 17 00:00:00 2001 +From 8988054398da2c235fca6474a35f0823365e17f6 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 9 Nov 2020 14:23:00 +0100 Subject: [PATCH] PCI: Run platform power transition on initial D0 entry @@ -4155,7 +4155,7 @@ index 70af1713767f..18caa27c774f 100644 -- 2.29.2 -From 0fe01d41c2c1e5bf8e13dd3b8ef94b74c439d67a Mon Sep 17 00:00:00 2001 +From 4d21b52ee8ecea64a6fcbf9c352ee16fecdc24d3 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 31 Oct 2020 20:46:33 +0100 Subject: [PATCH] PCI: Add sysfs attribute for PCI device power state @@ -4229,7 +4229,7 @@ index 1edf5a1836ea..ee1518650d55 100644 -- 2.29.2 -From f42652cc71110412a8bf56bbe5e4066e63dd0b95 Mon Sep 17 00:00:00 2001 +From b55b8c88e1961416ce386643cfa6698753c6f224 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 17 Aug 2020 01:23:20 +0200 Subject: [PATCH] misc: surface_sam: Add file2alias support for Surface SAM @@ -4331,7 +4331,7 @@ index 7f40b6aab689..76e3b1d7db45 100644 -- 2.29.2 -From c0351366e0dc802829d59a509d8aeac451a155a1 Mon Sep 17 00:00:00 2001 +From f1c189cea64a6d9bb46b2879e85c225a00bf7ade Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 17 Aug 2020 01:44:30 +0200 Subject: [PATCH] misc: Add support for Surface System Aggregator Module @@ -4364,7 +4364,7 @@ Patchset: surface-sam drivers/misc/Makefile | 1 + drivers/misc/surface_aggregator/Kconfig | 67 + drivers/misc/surface_aggregator/Makefile | 18 + - drivers/misc/surface_aggregator/bus.c | 424 +++ + drivers/misc/surface_aggregator/bus.c | 425 +++ drivers/misc/surface_aggregator/bus.h | 27 + .../misc/surface_aggregator/clients/Kconfig | 151 + .../misc/surface_aggregator/clients/Makefile | 11 + @@ -4372,31 +4372,31 @@ Patchset: surface-sam .../clients/surface_aggregator_cdev.c | 299 ++ .../clients/surface_aggregator_registry.c | 609 ++++ .../clients/surface_battery.c | 1188 ++++++++ - .../surface_aggregator/clients/surface_dtx.c | 1277 ++++++++ - .../surface_aggregator/clients/surface_hid.c | 916 ++++++ + .../surface_aggregator/clients/surface_dtx.c | 1276 ++++++++ + .../surface_aggregator/clients/surface_hid.c | 915 ++++++ .../clients/surface_hotplug.c | 269 ++ .../clients/surface_perfmode.c | 122 + - drivers/misc/surface_aggregator/controller.c | 2555 +++++++++++++++++ + drivers/misc/surface_aggregator/controller.c | 2570 +++++++++++++++++ drivers/misc/surface_aggregator/controller.h | 288 ++ - drivers/misc/surface_aggregator/core.c | 842 ++++++ - drivers/misc/surface_aggregator/ssh_msgb.h | 201 ++ - .../surface_aggregator/ssh_packet_layer.c | 2009 +++++++++++++ - .../surface_aggregator/ssh_packet_layer.h | 175 ++ + drivers/misc/surface_aggregator/core.c | 841 ++++++ + drivers/misc/surface_aggregator/ssh_msgb.h | 198 ++ + .../surface_aggregator/ssh_packet_layer.c | 2060 +++++++++++++ + .../surface_aggregator/ssh_packet_layer.h | 189 ++ drivers/misc/surface_aggregator/ssh_parser.c | 229 ++ drivers/misc/surface_aggregator/ssh_parser.h | 157 + - .../surface_aggregator/ssh_request_layer.c | 1254 ++++++++ + .../surface_aggregator/ssh_request_layer.c | 1264 ++++++++ .../surface_aggregator/ssh_request_layer.h | 142 + - drivers/misc/surface_aggregator/trace.h | 625 ++++ + drivers/misc/surface_aggregator/trace.h | 648 +++++ include/linux/mod_devicetable.h | 5 +- include/linux/surface_acpi_notify.h | 39 + include/linux/surface_aggregator/controller.h | 832 ++++++ include/linux/surface_aggregator/device.h | 430 +++ - include/linux/surface_aggregator/serial_hub.h | 655 +++++ + include/linux/surface_aggregator/serial_hub.h | 671 +++++ include/uapi/linux/surface_aggregator/cdev.h | 58 + include/uapi/linux/surface_aggregator/dtx.h | 150 + scripts/mod/devicetable-offsets.c | 3 +- scripts/mod/file2alias.c | 10 +- - 48 files changed, 18769 insertions(+), 7 deletions(-) + 48 files changed, 18893 insertions(+), 7 deletions(-) create mode 100644 Documentation/driver-api/surface_aggregator/client-api.rst create mode 100644 Documentation/driver-api/surface_aggregator/client.rst create mode 100644 Documentation/driver-api/surface_aggregator/clients/cdev.rst @@ -6488,10 +6488,10 @@ index 000000000000..b48ffc37ab52 +endif diff --git a/drivers/misc/surface_aggregator/bus.c b/drivers/misc/surface_aggregator/bus.c new file mode 100644 -index 000000000000..5e734bbd18cd +index 000000000000..231e41bc84e5 --- /dev/null +++ b/drivers/misc/surface_aggregator/bus.c -@@ -0,0 +1,424 @@ +@@ -0,0 +1,425 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Surface System Aggregator Module bus and device integration. @@ -6514,7 +6514,8 @@ index 000000000000..5e734bbd18cd +{ + struct ssam_device *sdev = to_ssam_device(dev); + -+ return snprintf(buf, PAGE_SIZE - 1, "ssam:d%02Xc%02Xt%02Xi%02xf%02X\n", ++ // FIXME: we should use sysfs_emit here, but that's not available on < 5.10 ++ return scnprintf(buf, PAGE_SIZE, "ssam:d%02Xc%02Xt%02Xi%02xf%02X\n", + sdev->uid.domain, sdev->uid.category, sdev->uid.target, + sdev->uid.instance, sdev->uid.function); +} @@ -6595,8 +6596,8 @@ index 000000000000..5e734bbd18cd + * @sdev: The SSAM client device to be added. + * + * Added client devices must be guaranteed to always have a valid and active -+ * controller. Thus, this function will fail with %-ENXIO if the controller of -+ * the device has not been initialized yet, has been suspended, or has been ++ * controller. Thus, this function will fail with %-ENODEV if the controller ++ * of the device has not been initialized yet, has been suspended, or has been + * shut down. + * + * The caller of this function should ensure that the corresponding call to @@ -6607,7 +6608,7 @@ index 000000000000..5e734bbd18cd + * By default, the controller device will become the parent of the newly + * created client device. The parent may be changed before ssam_device_add is + * called, but care must be taken that a) the correct suspend/resume ordering -+ * is guaranteed and b) the client device does not oultive the controller, ++ * is guaranteed and b) the client device does not outlive the controller, + * i.e. that the device is removed before the controller is being shut down. + * In case these guarantees have to be manually enforced, please refer to the + * ssam_client_link() and ssam_client_bind() functions, which are intended to @@ -6640,7 +6641,7 @@ index 000000000000..5e734bbd18cd + + if (sdev->ctrl->state != SSAM_CONTROLLER_STARTED) { + ssam_controller_stateunlock(sdev->ctrl); -+ return -ENXIO; ++ return -ENODEV; + } + + status = device_add(&sdev->dev); @@ -6769,7 +6770,7 @@ index 000000000000..5e734bbd18cd +EXPORT_SYMBOL_GPL(ssam_device_get_match); + +/** -+ * ssam_device_get_match_data() - Find the ID matching the device in hte ++ * ssam_device_get_match_data() - Find the ID matching the device in the + * ID table of the bound driver and return its ``driver_data`` member. + * @dev: The device for which to get the match data. + * @@ -6883,7 +6884,7 @@ index 000000000000..5e734bbd18cd + * @ctrl: The controller to remove all direct clients for. + * + * Remove all SSAM client devices registered as direct children under the -+ * given controller. Note that this only accounts for direct children ot the ++ * given controller. Note that this only accounts for direct children of the + * controller device. This does not take care of any client devices where the + * parent device has been manually set before calling ssam_device_add. Refer + * to ssam_device_add()/ssam_device_remove() for more details on those cases. @@ -7125,7 +7126,7 @@ index 000000000000..7320922ba755 +obj-$(CONFIG_SURFACE_PERFMODE) += surface_perfmode.o diff --git a/drivers/misc/surface_aggregator/clients/surface_acpi_notify.c b/drivers/misc/surface_aggregator/clients/surface_acpi_notify.c new file mode 100644 -index 000000000000..7a5b8f280036 +index 000000000000..c7fc3eb7ea0e --- /dev/null +++ b/drivers/misc/surface_aggregator/clients/surface_acpi_notify.c @@ -0,0 +1,884 @@ @@ -7211,7 +7212,7 @@ index 000000000000..7a5b8f280036 + * The link will be automatically removed once the client device's driver is + * unbound. + * -+ * Return: Returns zero on succes, %-ENXIO if the SAN interface has not been ++ * Return: Returns zero on success, %-ENXIO if the SAN interface has not been + * set up yet, and %-ENOMEM if device link creation failed. + */ +int san_client_link(struct device *client) @@ -7347,9 +7348,9 @@ index 000000000000..7a5b8f280036 + return status; + + /* -+ * Enusre that the battery states get updated correctly. -+ * When the battery is fully charged and an adapter is plugged in, it -+ * sometimes is not updated correctly, instead showing it as charging. ++ * Ensure that the battery states get updated correctly. When the ++ * battery is fully charged and an adapter is plugged in, it sometimes ++ * is not updated correctly, instead showing it as charging. + * Explicitly trigger battery updates to fix this. + */ + @@ -7405,7 +7406,7 @@ index 000000000000..7a5b8f280036 + switch (cid) { + case SAM_EVENT_CID_BAT_ADP: + /* -+ * Wait for battery state to update before signalling adapter ++ * Wait for battery state to update before signaling adapter + * change. + */ + return msecs_to_jiffies(5000); @@ -7934,9 +7935,9 @@ index 000000000000..7a5b8f280036 + acpi_status astatus; + int status; + -+ status = ssam_client_bind(&pdev->dev, &ctrl); -+ if (status) -+ return status == -ENXIO ? -EPROBE_DEFER : status; ++ ctrl = ssam_client_bind(&pdev->dev); ++ if (IS_ERR(ctrl)) ++ return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + status = san_consumer_links_setup(pdev); + if (status) @@ -8015,7 +8016,7 @@ index 000000000000..7a5b8f280036 +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/surface_aggregator/clients/surface_aggregator_cdev.c b/drivers/misc/surface_aggregator/clients/surface_aggregator_cdev.c new file mode 100644 -index 000000000000..7ebd0977fb37 +index 000000000000..13eaa05bda56 --- /dev/null +++ b/drivers/misc/surface_aggregator/clients/surface_aggregator_cdev.c @@ -0,0 +1,299 @@ @@ -8223,9 +8224,9 @@ index 000000000000..7ebd0977fb37 + struct ssam_cdev *cdev; + int status; + -+ status = ssam_client_bind(&pdev->dev, &ctrl); -+ if (status) -+ return status == -ENXIO ? -EPROBE_DEFER : status; ++ ctrl = ssam_client_bind(&pdev->dev); ++ if (IS_ERR(ctrl)) ++ return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + if (!cdev) @@ -8320,7 +8321,7 @@ index 000000000000..7ebd0977fb37 +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/surface_aggregator/clients/surface_aggregator_registry.c b/drivers/misc/surface_aggregator/clients/surface_aggregator_registry.c new file mode 100644 -index 000000000000..215308c79666 +index 000000000000..a3bb7e4cc85c --- /dev/null +++ b/drivers/misc/surface_aggregator/clients/surface_aggregator_registry.c @@ -0,0 +1,609 @@ @@ -8635,7 +8636,8 @@ index 000000000000..215308c79666 + connected = hub->state == SSAM_BASE_HUB_CONNECTED; + mutex_unlock(&hub->lock); + -+ return snprintf(buf, PAGE_SIZE - 1, "%d\n", connected); ++ // FIXME: we should use sysfs_emit here, but that's not available on < 5.10 ++ return scnprintf(buf, PAGE_SIZE, "%d\n", connected); +} + +static struct device_attribute ssam_base_hub_attr_state = @@ -8855,7 +8857,6 @@ index 000000000000..215308c79666 +{ + const struct ssam_hub_desc *desc; + struct ssam_controller *ctrl; -+ int status; + + desc = acpi_device_get_match_data(&pdev->dev); + if (!desc) @@ -8868,9 +8869,9 @@ index 000000000000..215308c79666 + * controller is removed. This also guarantees proper ordering for + * suspend/resume of the devices on this hub. + */ -+ status = ssam_client_bind(&pdev->dev, &ctrl); -+ if (status) -+ return status == -ENXIO ? -EPROBE_DEFER : status; ++ ctrl = ssam_client_bind(&pdev->dev); ++ if (IS_ERR(ctrl)) ++ return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + return ssam_hub_add_devices(&pdev->dev, ctrl, desc); +} @@ -10129,10 +10130,10 @@ index 000000000000..0a4e48754afc +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/surface_aggregator/clients/surface_dtx.c b/drivers/misc/surface_aggregator/clients/surface_dtx.c new file mode 100644 -index 000000000000..46e340229dc5 +index 000000000000..15cc61ef1c22 --- /dev/null +++ b/drivers/misc/surface_aggregator/clients/surface_dtx.c -@@ -0,0 +1,1277 @@ +@@ -0,0 +1,1276 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Surface Book (gen. 2 and later) detachment system (DTX) driver. @@ -11282,12 +11283,11 @@ index 000000000000..46e340229dc5 +{ + struct ssam_controller *ctrl; + struct sdtx_device *ddev; -+ int status; + + // link to EC -+ status = ssam_client_bind(&pdev->dev, &ctrl); -+ if (status) -+ return status == -ENXIO ? -EPROBE_DEFER : status; ++ ctrl = ssam_client_bind(&pdev->dev); ++ if (IS_ERR(ctrl)) ++ return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + ddev = sdtx_device_setup(&pdev->dev, ctrl); + if (IS_ERR(ddev)) @@ -11412,10 +11412,10 @@ index 000000000000..46e340229dc5 +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/surface_aggregator/clients/surface_hid.c b/drivers/misc/surface_aggregator/clients/surface_hid.c new file mode 100644 -index 000000000000..3fead99ee583 +index 000000000000..8bca14d4d26f --- /dev/null +++ b/drivers/misc/surface_aggregator/clients/surface_hid.c -@@ -0,0 +1,916 @@ +@@ -0,0 +1,915 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Surface System Aggregator Module (SSAM) HID device driver. @@ -12242,12 +12242,11 @@ index 000000000000..3fead99ee583 +{ + struct ssam_controller *ctrl; + struct surface_hid_device *shid; -+ int status; + + // add device link to EC -+ status = ssam_client_bind(&pdev->dev, &ctrl); -+ if (status) -+ return status == -ENXIO ? -EPROBE_DEFER : status; ++ ctrl = ssam_client_bind(&pdev->dev); ++ if (IS_ERR(ctrl)) ++ return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); + + shid = devm_kzalloc(&pdev->dev, sizeof(*shid), GFP_KERNEL); + if (!shid) @@ -12737,10 +12736,10 @@ index 000000000000..e13f4995b28b +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/surface_aggregator/controller.c b/drivers/misc/surface_aggregator/controller.c new file mode 100644 -index 000000000000..5b0c65437b70 +index 000000000000..74d116bb2c9e --- /dev/null +++ b/drivers/misc/surface_aggregator/controller.c -@@ -0,0 +1,2555 @@ +@@ -0,0 +1,2570 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Main SSAM/SSH controller structure and functionality. @@ -12754,6 +12753,7 @@ index 000000000000..5b0c65437b70 +#include +#include +#include ++#include +#include +#include +#include @@ -12790,7 +12790,7 @@ index 000000000000..5b0c65437b70 + * ssh_seq_next() - Get next sequence ID. + * @c: The counter providing the sequence IDs. + * -+ * Return: Retunrs the next sequence ID of the counter. ++ * Return: Returns the next sequence ID of the counter. + */ +static u8 ssh_seq_next(struct ssh_seq_counter *c) +{ @@ -12841,32 +12841,31 @@ index 000000000000..5b0c65437b70 +/* + * The notifier system is based on linux/notifier.h, specifically the SRCU + * implementation. The difference to that is, that some bits of the notifier -+ * call return value can be tracked across multiple calls. This is done so that -+ * handling of events can be tracked and a warning can be issued in case an -+ * event goes unhandled. The idea of that waring is that it should help discover -+ * and identify new/currently unimplemented features. ++ * call return value can be tracked across multiple calls. This is done so ++ * that handling of events can be tracked and a warning can be issued in case ++ * an event goes unhandled. The idea of that warning is that it should help ++ * discover and identify new/currently unimplemented features. + */ + + +/** -+ * ssam_event_matches_notifier() - Test if an event matches a notifier; ++ * ssam_event_matches_notifier() - Test if an event matches a notifier. + * @notif: The event notifier to test against. + * @event: The event to test. + * + * Return: Returns %true iff the given event matches the given notifier + * according to the rules set in the notifier's event mask, %false otherwise. + */ -+static bool ssam_event_matches_notifier( -+ const struct ssam_event_notifier *notif, -+ const struct ssam_event *event) ++static bool ssam_event_matches_notifier(const struct ssam_event_notifier *n, ++ const struct ssam_event *event) +{ -+ bool match = notif->event.id.target_category == event->target_category; ++ bool match = n->event.id.target_category == event->target_category; + -+ if (notif->event.mask & SSAM_EVENT_MASK_TARGET) -+ match &= notif->event.reg.target_id == event->target_id; ++ if (n->event.mask & SSAM_EVENT_MASK_TARGET) ++ match &= n->event.reg.target_id == event->target_id; + -+ if (notif->event.mask & SSAM_EVENT_MASK_INSTANCE) -+ match &= notif->event.id.instance == event->instance_id; ++ if (n->event.mask & SSAM_EVENT_MASK_INSTANCE) ++ match &= n->event.id.instance == event->instance_id; + + return match; +} @@ -12922,17 +12921,17 @@ index 000000000000..5b0c65437b70 + * Note: This function must be synchronized by the caller with respect to other + * insert and/or remove calls. + * -+ * Return: Returns zero on success, %-EINVAL if the notifier block has already ++ * Return: Returns zero on success, %-EEXIST if the notifier block has already + * been registered. + */ +static int __ssam_nfblk_insert(struct ssam_nf_head *nh, struct ssam_notifier_block *nb) +{ + struct ssam_notifier_block **link = &nh->head; + -+ while ((*link) != NULL) { -+ if (unlikely((*link) == nb)) { ++ while (*link) { ++ if (unlikely(*link == nb)) { + WARN(1, "double register detected"); -+ return -EINVAL; ++ return -EEXIST; + } + + if (nb->priority > (*link)->priority) @@ -12949,7 +12948,7 @@ index 000000000000..5b0c65437b70 + +/** + * __ssam_nfblk_find_link() - Find a notifier block link on the given list. -+ * @nh: The notifier head on wich the search should be conducted. ++ * @nh: The notifier head on which the search should be conducted. + * @nb: The notifier block to search for. + * + * Note: This function must be synchronized by the caller with respect to @@ -12964,8 +12963,8 @@ index 000000000000..5b0c65437b70 +{ + struct ssam_notifier_block **link = &nh->head; + -+ while ((*link) != NULL) { -+ if ((*link) == nb) ++ while (*link) { ++ if (*link == nb) + return link; + + link = &((*link)->next); @@ -13058,7 +13057,7 @@ index 000000000000..5b0c65437b70 +}; + +/** -+ * struct ssam_nf_refcount_entry - RB-tree entry for referecnce counting event ++ * struct ssam_nf_refcount_entry - RB-tree entry for reference counting event + * activations. + * @node: The node of this entry in the rb-tree. + * @key: The key of the event. @@ -13084,9 +13083,14 @@ index 000000000000..5b0c65437b70 + * event type/ID, allocating a new entry for this event ID if necessary. A + * newly allocated entry will have a refcount of one. + * -+ * Return: Returns the refcount entry on success. Returns ``ERR_PTR(-ENOSPC)`` -+ * if there have already been %INT_MAX events of the specified ID and type -+ * registered, or ``ERR_PTR(-ENOMEM)`` if the entry could not be allocated. ++ * Note: Must be synchronized by the caller with regards to other ++ * ssam_nf_refcount_inc() and ssam_nf_refcount_dec() calls, e.g. via ++ * ``nf->lock``. Note that this lock should also be used to ensure the ++ * corresponding EC requests are sent, if necessary. ++ * ++ * Return: Returns the refcount entry on success. Returns an error pointer ++ * with %-ENOSPC if there have already been %INT_MAX events of the specified ++ * ID and type registered, or %-ENOMEM if the entry could not be allocated. + */ +static struct ssam_nf_refcount_entry *ssam_nf_refcount_inc( + struct ssam_nf *nf, struct ssam_event_registry reg, @@ -13142,6 +13146,11 @@ index 000000000000..5b0c65437b70 + * returning its entry. If the returned entry has a refcount of zero, the + * caller is responsible for freeing it using kfree(). + * ++ * Note: Must be synchronized by the caller with regards to other ++ * ssam_nf_refcount_inc() and ssam_nf_refcount_dec() calls, e.g. via ++ * ``nf->lock``. Note that this lock should also be used to ensure the ++ * corresponding EC requests are sent, if necessary. ++ * + * Return: Returns the refcount entry on success or %NULL if the entry has not + * been found. + */ @@ -13194,9 +13203,9 @@ index 000000000000..5b0c65437b70 + * @rqid: The request ID of the event. + * @event: The event provided to the callbacks. + * -+ * Executa registered callbacks in order of their priority until either no -+ * callback is left or a callback returned a value with the %SSAM_NOTIF_STOP -+ * bit set. Note that this bit is set automatically when converting non.zero ++ * Execute registered callbacks in order of their priority until either no ++ * callback is left or a callback returns a value with the %SSAM_NOTIF_STOP ++ * bit set. Note that this bit is set automatically when converting non-zero + * error values via ssam_notifier_from_errno() to notifier values. + * + * Also note that any callback that could handle an event should return a value @@ -13251,7 +13260,7 @@ index 000000000000..5b0c65437b70 + } + + if (status) { -+ for (i = i - 1; i >= 0; i--) ++ while (i--) + ssam_nf_head_destroy(&nf->head[i]); + + return status; @@ -13281,6 +13290,13 @@ index 000000000000..5b0c65437b70 +#define SSAM_CPLT_WQ_NAME "ssam_cpltq" + +/* ++ * SSAM_CPLT_WQ_BATCH - Maximum number of event item completions executed per ++ * work execution. Used to prevent livelocking of the workqueue. Value chosen ++ * via educated guess, may be adjusted. ++ */ ++#define SSAM_CPLT_WQ_BATCH 10 ++ ++/* + * SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN - Maximum payload length for a cached + * &struct ssam_event_item. + * @@ -13357,13 +13373,13 @@ index 000000000000..5b0c65437b70 + struct ssam_event_item *item; + + if (len <= SSAM_EVENT_ITEM_CACHE_PAYLOAD_LEN) { -+ item = kmem_cache_alloc(ssam_event_item_cache, GFP_KERNEL); ++ item = kmem_cache_alloc(ssam_event_item_cache, flags); + if (!item) + return NULL; + + item->ops.free = __ssam_event_item_free_cached; + } else { -+ item = kzalloc(sizeof(*item) + len, GFP_KERNEL); ++ item = kzalloc(struct_size(item, event.data, len), flags); + if (!item) + return NULL; + @@ -13456,7 +13472,7 @@ index 000000000000..5b0c65437b70 +} + +/** -+ * ssam_cplt_submit() - Submit a work item to the compeltion system workqueue. ++ * ssam_cplt_submit() - Submit a work item to the completion system workqueue. + * @cplt: The completion system. + * @work: The work item to submit. + */ @@ -13506,7 +13522,7 @@ index 000000000000..5b0c65437b70 + * This operation is only intended to, during normal operation prior to + * shutdown, try to complete most events and requests to get them out of the + * system while the system is still fully operational. It does not aim to -+ * provide any guraantee that all of them have been handled. ++ * provide any guarantee that all of them have been handled. + */ +static void ssam_cplt_flush(struct ssam_cplt *cplt) +{ @@ -13519,21 +13535,21 @@ index 000000000000..5b0c65437b70 + struct ssam_event_item *item; + struct ssam_nf *nf; + struct device *dev; -+ int i; ++ unsigned int iterations = SSAM_CPLT_WQ_BATCH; + + queue = container_of(work, struct ssam_event_queue, work); + nf = &queue->cplt->event.notif; + dev = queue->cplt->dev; + + // limit number of processed events to avoid livelocking -+ for (i = 0; i < 10; i++) { ++ do { + item = ssam_event_queue_pop(queue); -+ if (item == NULL) ++ if (!item) + return; + + ssam_nf_call(nf, dev, item->rqid, &item->event); + ssam_event_item_free(item); -+ } ++ } while (--iterations); + + if (!ssam_event_queue_is_empty(queue)) + ssam_cplt_submit(queue->cplt, &queue->work); @@ -13733,7 +13749,8 @@ index 000000000000..5b0c65437b70 + item->event.instance_id = cmd->iid; + memcpy(&item->event.data[0], data->ptr, data->len); + -+ WARN_ON(ssam_cplt_submit_event(&ctrl->cplt, item)); ++ if (WARN_ON(ssam_cplt_submit_event(&ctrl->cplt, item))) ++ ssam_event_item_free(item); +} + +static const struct ssh_rtl_ops ssam_rtl_ops = { @@ -13741,13 +13758,16 @@ index 000000000000..5b0c65437b70 +}; + + -+static bool ssam_notifier_empty(struct ssam_controller *ctrl); ++static bool ssam_notifier_is_empty(struct ssam_controller *ctrl); +static void ssam_notifier_unregister_all(struct ssam_controller *ctrl); + + +#define SSAM_SSH_DSM_REVISION 0 -+static const guid_t SSAM_SSH_DSM_GUID = GUID_INIT(0xd5e383e1, 0xd892, 0x4a76, -+ 0x89, 0xfc, 0xf6, 0xaa, 0xae, 0x7e, 0xd5, 0xb5); ++ ++/* d5e383e1-d892-4a76-89fc-f6aaae7ed5b5 */ ++static const guid_t SSAM_SSH_DSM_GUID = ++ GUID_INIT(0xd5e383e1, 0xd892, 0x4a76, ++ 0x89, 0xfc, 0xf6, 0xaa, 0xae, 0x7e, 0xd5, 0xb5); + +enum ssh_dsm_fn { + SSH_DSM_FN_SSH_POWER_PROFILE = 0x05, @@ -13772,12 +13792,12 @@ index 000000000000..5b0c65437b70 + SSAM_SSH_DSM_REVISION, 0, NULL, + ACPI_TYPE_BUFFER); + if (!obj) -+ return -EFAULT; ++ return -EIO; + + for (i = 0; i < obj->buffer.length && i < 8; i++) + mask |= (((u64)obj->buffer.pointer[i]) << (i * 8)); + -+ if (mask & 0x01) ++ if (mask & BIT(0)) + *funcs = mask; + + ACPI_FREE(obj); @@ -13796,7 +13816,7 @@ index 000000000000..5b0c65437b70 + SSAM_SSH_DSM_REVISION, func, NULL, + ACPI_TYPE_INTEGER); + if (!obj) -+ return -EFAULT; ++ return -EIO; + + val = obj->integer.value; + ACPI_FREE(obj); @@ -13828,11 +13848,11 @@ index 000000000000..5b0c65437b70 + int status; + + // set defaults -+ caps->ssh_power_profile = (u32)-1; -+ caps->screen_on_sleep_idle_timeout = (u32)-1; -+ caps->screen_off_sleep_idle_timeout = (u32)-1; ++ caps->ssh_power_profile = U32_MAX; ++ caps->screen_on_sleep_idle_timeout = U32_MAX; ++ caps->screen_off_sleep_idle_timeout = U32_MAX; + caps->d3_closes_handle = false; -+ caps->ssh_buffer_size = (u32)-1; ++ caps->ssh_buffer_size = U32_MAX; + + status = ssam_dsm_get_functions(handle, &funcs); + if (status) @@ -13938,9 +13958,9 @@ index 000000000000..5b0c65437b70 + * controller. + * @ctrl: The controller. + * -+ * Note: When this function is called, the controller shouldbe properly hooked -+ * up to the serdev core via &struct serdev_device_ops. Please refert to -+ * ssam_controller_init() for more details on controller initialization. ++ * Note: When this function is called, the controller should be properly ++ * hooked up to the serdev core via &struct serdev_device_ops. Please refer ++ * to ssam_controller_init() for more details on controller initialization. + * + * This function must be called from an exclusive context with regards to the + * state, if necessary, by locking the controller via ssam_controller_lock(). @@ -13965,6 +13985,16 @@ index 000000000000..5b0c65437b70 + return 0; +} + ++/* ++ * SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT - Timeout for flushing requests during ++ * shutdown. ++ * ++ * Chosen to be larger than one full request timeout, including packets timing ++ * out. This value should give ample time to complete any outstanding requests ++ * during normal operation and account for the odd package timeout. ++ */ ++#define SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT msecs_to_jiffies(5000) ++ +/** + * ssam_controller_shutdown() - Shut down the controller. + * @ctrl: The controller. @@ -13976,13 +14006,13 @@ index 000000000000..5b0c65437b70 + * + * In the course of this shutdown procedure, all currently registered + * notifiers will be unregistered. It is, however, strongly recommended to not -+ * rely on this behavior, and instead the party registring the notifier should -+ * unregister it before the controller gets shut down, e.g. via the SSAM bus -+ * which guarantees client devices to be removed before a shutdown. ++ * rely on this behavior, and instead the party registering the notifier ++ * should unregister it before the controller gets shut down, e.g. via the ++ * SSAM bus which guarantees client devices to be removed before a shutdown. + * -+ * Note that events may still be pending after this call, but due to the -+ * notifiers being unregistered, the will be dropped when the controller is -+ * subsequently being destroyed via ssam_controller_destroy(). ++ * Note that events may still be pending after this call, but, due to the ++ * notifiers being unregistered, these events will be dropped when the ++ * controller is subsequently destroyed via ssam_controller_destroy(). + * + * This function must be called from an exclusive context with regards to the + * state, if necessary, by locking the controller via ssam_controller_lock(). @@ -13996,7 +14026,7 @@ index 000000000000..5b0c65437b70 + return; + + // try to flush pending events and requests while everything still works -+ status = ssh_rtl_flush(&ctrl->rtl, msecs_to_jiffies(5000)); ++ status = ssh_rtl_flush(&ctrl->rtl, SSAM_CTRL_SHUTDOWN_FLUSH_TIMEOUT); + if (status) { + ssam_err(ctrl, "failed to flush request transport layer: %d\n", + status); @@ -14010,7 +14040,7 @@ index 000000000000..5b0c65437b70 + * driver that set them up at this point. If this warning occurs, some + * client driver has not done that... + */ -+ WARN_ON(!ssam_notifier_empty(ctrl)); ++ WARN_ON(!ssam_notifier_is_empty(ctrl)); + + /* + * Nevertheless, we should still take care of drivers that don't behave @@ -14037,7 +14067,7 @@ index 000000000000..5b0c65437b70 + * Ensures that all resources associated with the controller get freed. This + * function should only be called after the controller has been stopped via + * ssam_controller_shutdown(). In general, this function should not be called -+ * directly. The only valid place to call this function direclty is during ++ * directly. The only valid place to call this function directly is during + * initialization, before the controller has been fully initialized and passed + * to other processes. This function is called automatically when the + * reference count of the controller reaches zero. @@ -14273,7 +14303,7 @@ index 000000000000..5b0c65437b70 + +/** + * ssam_request_sync_free() - Free a synchronous request. -+ * @rqst: The request to free. ++ * @rqst: The request to be freed. + * + * Free a synchronous request and its corresponding buffer allocated with + * ssam_request_sync_alloc(). Do not use for requests allocated on the stack @@ -14351,7 +14381,7 @@ index 000000000000..5b0c65437b70 + */ + if (WARN_ON(READ_ONCE(ctrl->state) != SSAM_CONTROLLER_STARTED)) { + ssh_request_put(&rqst->base); -+ return -ENXIO; ++ return -ENODEV; + } + + status = ssh_rtl_submit(&ctrl->rtl, &rqst->base); @@ -14368,9 +14398,9 @@ index 000000000000..5b0c65437b70 + * @rsp: The response buffer. + * + * Allocates a synchronous request with its message data buffer on the heap -+ * via ssam_request_sync_alloc(), fully intializes it via the provided request -+ * specification, submits it, and finally waits for its completion before -+ * freeing it and returning its status. ++ * via ssam_request_sync_alloc(), fully initializes it via the provided ++ * request specification, submits it, and finally waits for its completion ++ * before freeing it and returning its status. + * + * Return: Returns the status of the request or any failure during setup. + */ @@ -14409,7 +14439,7 @@ index 000000000000..5b0c65437b70 + +/** + * ssam_request_sync_with_buffer() - Execute a synchronous request with the -+ * provided buffer as backend for the message buffer. ++ * provided buffer as back-end for the message buffer. + * @ctrl: The controller via which the request will be submitted. + * @spec: The request specification and payload. + * @rsp: The response buffer. @@ -14417,7 +14447,7 @@ index 000000000000..5b0c65437b70 + * + * Allocates a synchronous request struct on the stack, fully initializes it + * using the provided buffer as message data buffer, submits it, and then -+ * waits for its completion before returning its staus. The ++ * waits for its completion before returning its status. The + * SSH_COMMAND_MESSAGE_LENGTH() macro can be used to compute the required + * message buffer size. + * @@ -14509,25 +14539,9 @@ index 000000000000..5b0c65437b70 + u8 instance_id; +} __packed; + -+/** -+ * ssam_ssh_event_enable() - Enable SSH event. -+ * @ctrl: The controller for which to enable the event. -+ * @reg: The event registry describing what request to use for enabling and -+ * disabling the event. -+ * @id: The event identifier. -+ * @flags: The event flags. -+ * -+ * This is a wrapper for the raw SAM request to enable an event, thus it does -+ * not handle referecnce counting for enable/disable of events. If an event -+ * has already been enabled, the EC will ignore this request. -+ * -+ * Return: Returns the status of the executed SAM request (zero on success and -+ * negative on direct failure) or %-EPROTO if the request response indicates a -+ * failure. -+ */ -+static int ssam_ssh_event_enable(struct ssam_controller *ctrl, -+ struct ssam_event_registry reg, -+ struct ssam_event_id id, u8 flags) ++static int __ssam_ssh_event_request(struct ssam_controller *ctrl, ++ struct ssam_event_registry reg, u8 cid, ++ struct ssam_event_id id, u8 flags) +{ + struct ssh_notification_params params; + struct ssam_request rqst; @@ -14535,7 +14549,7 @@ index 000000000000..5b0c65437b70 + int status; + + u16 rqid = ssh_tc_to_rqid(id.target_category); -+ u8 buf[1] = { 0x00 }; ++ u8 buf = 0; + + // only allow RQIDs that lie within event spectrum + if (!ssh_rqid_is_event(rqid)) @@ -14548,34 +14562,62 @@ index 000000000000..5b0c65437b70 + + rqst.target_category = reg.target_category; + rqst.target_id = reg.target_id; -+ rqst.command_id = reg.cid_enable; ++ rqst.command_id = cid; + rqst.instance_id = 0x00; + rqst.flags = SSAM_REQUEST_HAS_RESPONSE; + rqst.length = sizeof(params); + rqst.payload = (u8 *)¶ms; + -+ result.capacity = ARRAY_SIZE(buf); ++ result.capacity = sizeof(buf); + result.length = 0; -+ result.pointer = buf; ++ result.pointer = &buf; + + status = ssam_retry(ssam_request_sync_onstack, ctrl, &rqst, &result, + sizeof(params)); -+ if (status) { ++ ++ return status < 0 ? status : buf; ++} ++ ++/** ++ * ssam_ssh_event_enable() - Enable SSH event. ++ * @ctrl: The controller for which to enable the event. ++ * @reg: The event registry describing what request to use for enabling and ++ * disabling the event. ++ * @id: The event identifier. ++ * @flags: The event flags. ++ * ++ * Enables the specified event on the EC. This function does not manage ++ * reference counting of enabled events and is basically only a wrapper for ++ * the raw EC request. If the specified event is already enabled, the EC will ++ * ignore this request. ++ * ++ * Return: Returns the status of the executed SAM request (zero on success and ++ * negative on direct failure) or %-EPROTO if the request response indicates a ++ * failure. ++ */ ++static int ssam_ssh_event_enable(struct ssam_controller *ctrl, ++ struct ssam_event_registry reg, ++ struct ssam_event_id id, u8 flags) ++{ ++ int status; ++ ++ status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags); ++ ++ if (status < 0 && status != -EINVAL) { + ssam_err(ctrl, "failed to enable event source (tc: 0x%02x, " + "iid: 0x%02x, reg: 0x%02x)\n", id.target_category, + id.instance, reg.target_category); + } + -+ if (buf[0] != 0x00) { ++ if (status > 0) { + ssam_err(ctrl, "unexpected result while enabling event source: " + "0x%02x (tc: 0x%02x, iid: 0x%02x, reg: 0x%02x)\n", -+ buf[0], id.target_category, id.instance, ++ status, id.target_category, id.instance, + reg.target_category); + return -EPROTO; + } + + return status; -+ +} + +/** @@ -14586,9 +14628,10 @@ index 000000000000..5b0c65437b70 + * @id: The event identifier. + * @flags: The event flags (likely ignored for disabling of events). + * -+ * This is a wrapper for the raw SAM request to disable an event, thus it does -+ * not handle reference counting for enable/disable of events. If an event has -+ * already been disabled, the EC will ignore this request. ++ * Disables the specified event on the EC. This function does not manage ++ * reference counting of enabled events and is basically only a wrapper for ++ * the raw EC request. If the specified event is already disabled, the EC will ++ * ignore this request. + * + * Return: Returns the status of the executed SAM request (zero on success and + * negative on direct failure) or %-EPROTO if the request response indicates a @@ -14598,47 +14641,20 @@ index 000000000000..5b0c65437b70 + struct ssam_event_registry reg, + struct ssam_event_id id, u8 flags) +{ -+ struct ssh_notification_params params; -+ struct ssam_request rqst; -+ struct ssam_response result; + int status; + -+ u16 rqid = ssh_tc_to_rqid(id.target_category); -+ u8 buf[1] = { 0x00 }; ++ status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags); + -+ // only allow RQIDs that lie within event spectrum -+ if (!ssh_rqid_is_event(rqid)) -+ return -EINVAL; -+ -+ params.target_category = id.target_category; -+ params.instance_id = id.instance; -+ params.flags = flags; -+ put_unaligned_le16(rqid, ¶ms.request_id); -+ -+ rqst.target_category = reg.target_category; -+ rqst.target_id = reg.target_id; -+ rqst.command_id = reg.cid_disable; -+ rqst.instance_id = 0x00; -+ rqst.flags = SSAM_REQUEST_HAS_RESPONSE; -+ rqst.length = sizeof(params); -+ rqst.payload = (u8 *)¶ms; -+ -+ result.capacity = ARRAY_SIZE(buf); -+ result.length = 0; -+ result.pointer = buf; -+ -+ status = ssam_retry(ssam_request_sync_onstack, ctrl, &rqst, &result, -+ sizeof(params)); -+ if (status) { ++ if (status < 0 && status != -EINVAL) { + ssam_err(ctrl, "failed to disable event source (tc: 0x%02x, " + "iid: 0x%02x, reg: 0x%02x)\n", id.target_category, + id.instance, reg.target_category); + } + -+ if (buf[0] != 0x00) { ++ if (status > 0) { + ssam_err(ctrl, "unexpected result while disabling event source: " + "0x%02x (tc: 0x%02x, iid: 0x%02x, reg: 0x%02x)\n", -+ buf[0], id.target_category, id.instance, ++ status, id.target_category, id.instance, + reg.target_category); + return -EPROTO; + } @@ -14688,8 +14704,8 @@ index 000000000000..5b0c65437b70 + * backlight will be turned off by this call. + * + * This function will only send the display-off notification command if -+ * display noticications are supported by the EC. Currently all known devices -+ * support these notification. ++ * display notifications are supported by the EC. Currently all known devices ++ * support these notifications. + * + * Use ssam_ctrl_notif_display_on() to reverse the effects of this function. + * @@ -14727,8 +14743,8 @@ index 000000000000..5b0c65437b70 + * reverse its effects, including resetting events to their default behavior. + * + * This function will only send the display-on notification command if display -+ * noticications are supported by the EC. Currently all known devices support -+ * these notification. ++ * notifications are supported by the EC. Currently all known devices support ++ * these notifications. + * + * See ssam_ctrl_notif_display_off() for more details. + * @@ -14766,7 +14782,7 @@ index 000000000000..5b0c65437b70 + * EC are currently unknown. + * + * This function will only send the D0-exit notification command if D0-state -+ * noticications are supported by the EC. Only newer Surface generations ++ * notifications are supported by the EC. Only newer Surface generations + * support these notifications. + * + * Use ssam_ctrl_notif_d0_entry() to reverse the effects of this function. @@ -14790,8 +14806,8 @@ index 000000000000..5b0c65437b70 + return status; + + if (response != 0) { -+ ssam_err(ctrl, "unexpected response from D0-exit notification:" -+ " 0x%02x\n", response); ++ ssam_err(ctrl, "unexpected response from D0-exit notification: 0x%02x\n", ++ response); + return -EPROTO; + } + @@ -14808,7 +14824,7 @@ index 000000000000..5b0c65437b70 + * currently unknown. + * + * This function will only send the D0-entry notification command if D0-state -+ * noticications are supported by the EC. Only newer Surface generations ++ * notifications are supported by the EC. Only newer Surface generations + * support these notifications. + * + * See ssam_ctrl_notif_d0_exit() for more details. @@ -14832,8 +14848,8 @@ index 000000000000..5b0c65437b70 + return status; + + if (response != 0) { -+ ssam_err(ctrl, "unexpected response from D0-entry notification:" -+ " 0x%02x\n", response); ++ ssam_err(ctrl, "unexpected response from D0-entry notification: 0x%02x\n", ++ response); + return -EPROTO; + } + @@ -14882,10 +14898,9 @@ index 000000000000..5b0c65437b70 + return PTR_ERR(entry); + } + -+ ssam_dbg(ctrl, "enabling event (reg: 0x%02x, tc: 0x%02x, iid: 0x%02x," -+ " 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: 0x%02x, tc: 0x%02x, iid: 0x%02x, 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) { @@ -14967,10 +14982,9 @@ index 000000000000..5b0c65437b70 + return -ENOENT; + } + -+ ssam_dbg(ctrl, "disabling event (reg: 0x%02x, tc: 0x%02x, iid: 0x%02x," -+ " rc: %d)\n", n->event.reg.target_category, -+ n->event.id.target_category, n->event.id.instance, -+ entry->refcount); ++ ssam_dbg(ctrl, "disabling event (reg: 0x%02x, tc: 0x%02x, iid: 0x%02x, rc: %d)\n", ++ n->event.reg.target_category, n->event.id.target_category, ++ n->event.id.instance, entry->refcount); + + if (entry->flags != n->event.flags) { + ssam_warn(ctrl, "inconsistent flags when enabling event: got 0x%02x," @@ -15002,7 +15016,7 @@ index 000000000000..5b0c65437b70 + * (EC command failing), all previously disabled events will be restored and + * the error code returned. + * -+ * This function is intended to disable all events prior to hibenration entry. ++ * This function is intended to disable all events prior to hibernation entry. + * See ssam_notifier_restore_registered() to restore/re-enable all events + * disabled with this function. + * @@ -15077,13 +15091,13 @@ index 000000000000..5b0c65437b70 +} + +/** -+ * ssam_notifier_empty() - Check if there are any registered notifiers. ++ * ssam_notifier_is_empty() - Check if there are any registered notifiers. + * @ctrl: The controller to check on. + * + * Return: Returns %true if there are currently no notifiers registered on the + * controller, %false otherwise. + */ -+static bool ssam_notifier_empty(struct ssam_controller *ctrl) ++static bool ssam_notifier_is_empty(struct ssam_controller *ctrl) +{ + struct ssam_nf *nf = &ctrl->cplt.event.notif; + bool result; @@ -15101,7 +15115,7 @@ index 000000000000..5b0c65437b70 + * @ctrl: The controller to unregister the notifiers on. + * + * Unregisters all currently registered notifiers. This function is used to -+ * ensure that all notifiers will be unregistered and assocaited ++ * ensure that all notifiers will be unregistered and associated + * entries/resources freed when the controller is being shut down. + */ +static void ssam_notifier_unregister_all(struct ssam_controller *ctrl) @@ -15298,7 +15312,7 @@ index 000000000000..5b0c65437b70 +} diff --git a/drivers/misc/surface_aggregator/controller.h b/drivers/misc/surface_aggregator/controller.h new file mode 100644 -index 000000000000..96e2b87a25d9 +index 000000000000..cfb0f658d66c --- /dev/null +++ b/drivers/misc/surface_aggregator/controller.h @@ -0,0 +1,288 @@ @@ -15368,7 +15382,7 @@ index 000000000000..96e2b87a25d9 + * registration and deregistration. + * @refcount: The root of the RB-tree used for reference-counting enabled + * events/notifications. -+ * @head: The list of notifier heads for event/notifiaction callbacks. ++ * @head: The list of notifier heads for event/notification callbacks. + */ +struct ssam_nf { + struct mutex lock; @@ -15557,7 +15571,7 @@ index 000000000000..96e2b87a25d9 + */ +static inline void ssam_controller_write_wakeup(struct ssam_controller *ctrl) +{ -+ ssh_ptl_tx_wakeup(&ctrl->rtl.ptl); ++ ssh_ptl_tx_wakeup_transfer(&ctrl->rtl.ptl); +} + + @@ -15592,10 +15606,10 @@ index 000000000000..96e2b87a25d9 +#endif /* _SURFACE_AGGREGATOR_CONTROLLER_H */ diff --git a/drivers/misc/surface_aggregator/core.c b/drivers/misc/surface_aggregator/core.c new file mode 100644 -index 000000000000..8b694c4ba6a4 +index 000000000000..64056da39e9f --- /dev/null +++ b/drivers/misc/surface_aggregator/core.c -@@ -0,0 +1,842 @@ +@@ -0,0 +1,841 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Surface Serial Hub (SSH) driver for communication with the Surface/System @@ -15672,7 +15686,7 @@ index 000000000000..8b694c4ba6a4 + * Set the main controller reference to the given pointer if the reference + * hasn't been set already. + * -+ * Return: Returns zero on success or %-EBUSY if the reference has already ++ * Return: Returns zero on success or %-EEXIST if the reference has already + * been set. + */ +static int ssam_try_set_controller(struct ssam_controller *ctrl) @@ -15683,7 +15697,7 @@ index 000000000000..8b694c4ba6a4 + if (!__ssam_controller) + __ssam_controller = ctrl; + else -+ status = -EBUSY; ++ status = -EEXIST; + spin_unlock(&__ssam_controller_lock); + + return status; @@ -15718,7 +15732,7 @@ index 000000000000..8b694c4ba6a4 + * The device link does not have to be destructed manually. It is removed + * automatically once the driver of the client device unbinds. + * -+ * Return: Returns zero on success, %-ENXIO if the controller is not ready or ++ * Return: Returns zero on success, %-ENODEV if the controller is not ready or + * going to be removed soon, or %-ENOMEM if the device link could not be + * created for other reasons. + */ @@ -15732,13 +15746,13 @@ index 000000000000..8b694c4ba6a4 + + if (c->state != SSAM_CONTROLLER_STARTED) { + ssam_controller_stateunlock(c); -+ return -ENXIO; ++ return -ENODEV; + } + + ctrldev = ssam_controller_device(c); + if (!ctrldev) { + ssam_controller_stateunlock(c); -+ return -ENXIO; ++ return -ENODEV; + } + + link = device_link_add(client, ctrldev, flags); @@ -15748,14 +15762,14 @@ index 000000000000..8b694c4ba6a4 + } + + /* -+ * Return -ENXIO if supplier driver is on its way to be removed. In this -+ * case, the controller won't be around for much longer and the device -+ * link is not going to save us any more, as unbinding is already in -+ * progress. ++ * Return -ENODEV if supplier driver is on its way to be removed. In ++ * this case, the controller won't be around for much longer and the ++ * device link is not going to save us any more, as unbinding is ++ * already in progress. + */ + if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) { + ssam_controller_stateunlock(c); -+ return -ENXIO; ++ return -ENODEV; + } + + ssam_controller_stateunlock(c); @@ -15766,7 +15780,6 @@ index 000000000000..8b694c4ba6a4 +/** + * ssam_client_bind() - Bind an arbitrary client device to the controller. + * @client: The client device. -+ * @ctrl: A pointer to where the controller reference should be returned. + * + * Link an arbitrary client device to the controller by creating a device link + * between it as consumer and the main controller device as provider. This @@ -15776,10 +15789,10 @@ index 000000000000..8b694c4ba6a4 + * + * This function does essentially the same as ssam_client_link(), except that + * it first fetches the main controller reference, then creates the link, and -+ * finally returns this reference in the @ctrl parameter. Note that this -+ * function does not increment the reference counter of the controller, as, -+ * due to the link, the controller lifetime is assured as long as the driver -+ * of the client device is bound. ++ * finally returns this reference. Note that this function does not increment ++ * the reference counter of the controller, as, due to the link, the ++ * controller lifetime is assured as long as the driver of the client device ++ * is bound. + * + * It is not valid to use the controller reference obtained by this method + * outside of the driver bound to the client device at the time of calling @@ -15795,18 +15808,18 @@ index 000000000000..8b694c4ba6a4 + * The created device link does not have to be destructed manually. It is + * removed automatically once the driver of the client device unbinds. + * -+ * Return: Returns zero on success, %-ENXIO if the controller is not present, -+ * not ready or going to be removed soon, or %-ENOMEM if the device link could -+ * not be created for other reasons. ++ * Return: Returns the controller on success, an error pointer with %-ENODEV ++ * if the controller is not present, not ready or going to be removed soon, or ++ * %-ENOMEM if the device link could not be created for other reasons. + */ -+int ssam_client_bind(struct device *client, struct ssam_controller **ctrl) ++struct ssam_controller *ssam_client_bind(struct device *client) +{ + struct ssam_controller *c; + int status; + + c = ssam_get_controller(); + if (!c) -+ return -ENXIO; ++ return ERR_PTR(-ENODEV); + + status = ssam_client_link(c, client); + @@ -15819,8 +15832,7 @@ index 000000000000..8b694c4ba6a4 + */ + ssam_controller_put(c); + -+ *ctrl = status == 0 ? c : NULL; -+ return status; ++ return status >= 0 ? c : ERR_PTR(status); +} +EXPORT_SYMBOL_GPL(ssam_client_bind); + @@ -15881,13 +15893,14 @@ index 000000000000..8b694c4ba6a4 + b = ((version >> 8) & 0xffff); + c = version & 0xff; + -+ return snprintf(buf, PAGE_SIZE - 1, "%u.%u.%u\n", a, b, c); ++ // FIXME: we should use sysfs_emit here, but that's not available on < 5.10 ++ return scnprintf(buf, PAGE_SIZE, "%u.%u.%u\n", a, b, c); +} +static DEVICE_ATTR_RO(firmware_version); + +static struct attribute *ssam_sam_attrs[] = { + &dev_attr_firmware_version.attr, -+ NULL, ++ NULL +}; + +static const struct attribute_group ssam_sam_group = { @@ -15947,8 +15960,8 @@ index 000000000000..8b694c4ba6a4 + } + + if (status) { -+ dev_err(&serdev->dev, "setup: failed to set parity (value: 0x%02x," -+ " error: %d)\n", uart->parity, status); ++ dev_err(&serdev->dev, "setup: failed to set parity (value: 0x%02x, error: %d)\n", ++ uart->parity, status); + return AE_ERROR; + } + @@ -16003,9 +16016,9 @@ index 000000000000..8b694c4ba6a4 + /* + * Try to signal display-off, This will quiesce events. + * -+ * Note: Signalling display-off/display-on should normally be done from -+ * some sort of display state notifier. As that is not available, signal -+ * it here. ++ * Note: Signaling display-off/display-on should normally be done from ++ * some sort of display state notifier. As that is not available, ++ * signal it here. + */ + + status = ssam_ctrl_notif_display_off(c); @@ -16023,9 +16036,9 @@ index 000000000000..8b694c4ba6a4 + /* + * Try to signal display-on. This will restore events. + * -+ * Note: Signalling display-off/display-on should normally be done from -+ * some sort of display state notifier. As that is not available, signal -+ * it here. ++ * Note: Signaling display-off/display-on should normally be done from ++ * some sort of display state notifier. As that is not available, ++ * signal it here. + */ + + status = ssam_ctrl_notif_display_on(c); @@ -16075,9 +16088,9 @@ index 000000000000..8b694c4ba6a4 + * case of errors, log them and try to restore normal operation state + * as far as possible. + * -+ * Note: Signalling display-off/display-on should normally be done from -+ * some sort of display state notifier. As that is not available, signal -+ * it here. ++ * Note: Signaling display-off/display-on should normally be done from ++ * some sort of display state notifier. As that is not available, ++ * signal it here. + */ + + ssam_irq_disarm_wakeup(c); @@ -16440,10 +16453,10 @@ index 000000000000..8b694c4ba6a4 +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/surface_aggregator/ssh_msgb.h b/drivers/misc/surface_aggregator/ssh_msgb.h new file mode 100644 -index 000000000000..7c29e7d7028a +index 000000000000..1bfdf045b4a7 --- /dev/null +++ b/drivers/misc/surface_aggregator/ssh_msgb.h -@@ -0,0 +1,201 @@ +@@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * SSH message builder functions. @@ -16553,17 +16566,16 @@ index 000000000000..7c29e7d7028a + */ +static inline void msgb_push_frame(struct msgbuf *msgb, u8 ty, u16 len, u8 seq) +{ -+ struct ssh_frame *frame = (struct ssh_frame *)msgb->ptr; -+ const u8 *const begin = msgb->ptr; ++ u8 *const begin = msgb->ptr; + -+ if (WARN_ON(msgb->ptr + sizeof(*frame) > msgb->end)) ++ if (WARN_ON(msgb->ptr + sizeof(struct ssh_frame) > msgb->end)) + return; + -+ frame->type = ty; -+ put_unaligned_le16(len, &frame->len); -+ frame->seq = seq; ++ put_unaligned(ty, begin + offsetof(struct ssh_frame, type)); ++ put_unaligned(len, begin + offsetof(struct ssh_frame, len)); ++ put_unaligned(seq, begin + offsetof(struct ssh_frame, seq)); + -+ msgb->ptr += sizeof(*frame); ++ msgb->ptr += sizeof(struct ssh_frame); + msgb_push_crc(msgb, begin, msgb->ptr - begin); +} + @@ -16610,47 +16622,45 @@ index 000000000000..7c29e7d7028a +static inline void msgb_push_cmd(struct msgbuf *msgb, u8 seq, u16 rqid, + const struct ssam_request *rqst) +{ -+ struct ssh_command *cmd; -+ const u8 *cmd_begin; + const u8 type = SSH_FRAME_TYPE_DATA_SEQ; ++ u8 *p; + + // SYN + msgb_push_syn(msgb); + + // command frame + crc -+ msgb_push_frame(msgb, type, sizeof(*cmd) + rqst->length, seq); ++ msgb_push_frame(msgb, type, sizeof(struct ssh_command) + rqst->length, seq); + + // frame payload: command struct + payload -+ if (WARN_ON(msgb->ptr + sizeof(*cmd) > msgb->end)) ++ if (WARN_ON(msgb->ptr + sizeof(struct ssh_command) > msgb->end)) + return; + -+ cmd_begin = msgb->ptr; -+ cmd = (struct ssh_command *)msgb->ptr; ++ p = msgb->ptr; + -+ cmd->type = SSH_PLD_TYPE_CMD; -+ cmd->tc = rqst->target_category; -+ cmd->tid_out = rqst->target_id; -+ cmd->tid_in = 0x00; -+ cmd->iid = rqst->instance_id; -+ put_unaligned_le16(rqid, &cmd->rqid); -+ cmd->cid = rqst->command_id; ++ put_unaligned(SSH_PLD_TYPE_CMD, p + offsetof(struct ssh_command, type)); ++ put_unaligned(rqst->target_category, p + offsetof(struct ssh_command, tc)); ++ put_unaligned(rqst->target_id, p + offsetof(struct ssh_command, tid_out)); ++ put_unaligned(0x00, p + offsetof(struct ssh_command, tid_in)); ++ put_unaligned(rqst->instance_id, p + offsetof(struct ssh_command, iid)); ++ put_unaligned(rqid, p + offsetof(struct ssh_command, rqid)); ++ put_unaligned(rqst->command_id, p + offsetof(struct ssh_command, cid)); + -+ msgb->ptr += sizeof(*cmd); ++ msgb->ptr += sizeof(struct ssh_command); + + // command payload + msgb_push_buf(msgb, rqst->payload, rqst->length); + + // crc for command struct + payload -+ msgb_push_crc(msgb, cmd_begin, msgb->ptr - cmd_begin); ++ msgb_push_crc(msgb, p, msgb->ptr - p); +} + +#endif /* _SURFACE_AGGREGATOR_SSH_MSGB_H */ diff --git a/drivers/misc/surface_aggregator/ssh_packet_layer.c b/drivers/misc/surface_aggregator/ssh_packet_layer.c new file mode 100644 -index 000000000000..2951d245359c +index 000000000000..5f4e4963a261 --- /dev/null +++ b/drivers/misc/surface_aggregator/ssh_packet_layer.c -@@ -0,0 +1,2009 @@ +@@ -0,0 +1,2060 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * SSH packet transport layer. @@ -16716,16 +16726,16 @@ index 000000000000..2951d245359c + * - the timeout work item. + * + * Normal operation is as follows: The initial reference of the packet is -+ * obtained by submitting the packet and queueing it. The receiver thread -+ * takes packets from the queue. By doing this, it does not increment the -+ * refcount but takes over the reference (removing it from the queue). If the -+ * packet is sequenced (i.e. needs to be ACKed by the client), the transmitter -+ * thread sets-up the timeout and adds the packet to the pending set before -+ * starting to transmit it. As the timeout is handled by a reaper task, no -+ * additional reference for it is needed. After the transmit is done, the -+ * reference held by the transmitter thread is dropped. If the packet is -+ * unsequenced (i.e. does not need an ACK), the packet is completed by the -+ * transmitter thread before dropping that reference. ++ * obtained by submitting the packet and queuing it. The receiver thread takes ++ * packets from the queue. By doing this, it does not increment the refcount ++ * but takes over the reference (removing it from the queue). If the packet is ++ * sequenced (i.e. needs to be ACKed by the client), the transmitter thread ++ * sets-up the timeout and adds the packet to the pending set before starting ++ * to transmit it. As the timeout is handled by a reaper task, no additional ++ * reference for it is needed. After the transmit is done, the reference held ++ * by the transmitter thread is dropped. If the packet is unsequenced (i.e. ++ * does not need an ACK), the packet is completed by the transmitter thread ++ * before dropping that reference. + * + * On receival of an ACK, the receiver thread removes and obtains the + * reference to the packet from the pending set. The receiver thread will then @@ -16816,8 +16826,13 @@ index 000000000000..2951d245359c + * + * >> General Notes << + * -+ * To avoid deadlocks, if both queue and pending locks are required, the -+ * pending lock must be acquired before the queue lock. ++ * - To avoid deadlocks, if both queue and pending locks are required, the ++ * pending lock must be acquired before the queue lock. ++ * ++ * - The packet priority must be accessed only while holding the queue lock. ++ * ++ * - The packet timestamp must be accessed only while holding the pending ++ * lock. + */ + +/* @@ -16831,7 +16846,16 @@ index 000000000000..2951d245359c +#define SSH_PTL_MAX_PACKET_TRIES 3 + +/* -+ * SSH_PTL_PACKET_TIMEOUT - Packet timeout. ++ * SSH_PTL_TX_TIMEOUT - Packet transmission timeout. ++ * ++ * Timeout in jiffies for packet transmission via the underlying serial ++ * device. If transmitting the packet takes longer than this timeout, the ++ * packet will be completed with -ETIMEDOUT. It will not be re-submitted. ++ */ ++#define SSH_PTL_TX_TIMEOUT HZ ++ ++/* ++ * SSH_PTL_PACKET_TIMEOUT - Packet response timeout. + * + * Timeout as ktime_t delta for ACKs. If we have not received an ACK in this + * time-frame after starting transmission, the packet will be re-submitted. @@ -16872,8 +16896,8 @@ index 000000000000..2951d245359c + * ssh_ptl_should_drop_ack_packet() - Error injection hook to drop ACK packets. + * + * Useful to test detection and handling of automated re-transmits by the EC. -+ * Specifically of packets that the EC consideres not-ACKed but the driver -+ * already consideres ACKed (due to dropped ACK). In this case, the EC ++ * Specifically of packets that the EC considers not-ACKed but the driver ++ * already considers ACKed (due to dropped ACK). In this case, the EC + * re-transmits the packet-to-be-ACKed and the driver should detect it as + * duplicate/already handled. Note that the driver should still send an ACK + * for the re-transmitted packet. @@ -16924,7 +16948,7 @@ index 000000000000..2951d245359c +ALLOW_ERROR_INJECTION(ssh_ptl_should_fail_write, ERRNO); + +/** -+ * ssh_ptl_should_corrupt_tx_data() - Error injection hook to simualte invalid ++ * ssh_ptl_should_corrupt_tx_data() - Error injection hook to simulate invalid + * data being sent to the EC. + * + * Hook to simulate corrupt/invalid data being sent from host (driver) to EC. @@ -17080,7 +17104,7 @@ index 000000000000..2951d245359c + if (likely(!ssh_ptl_should_corrupt_rx_syn())) + return; + -+ trace_ssam_ei_rx_corrupt_syn("data_length", data->len); ++ trace_ssam_ei_rx_corrupt_syn(data->len); + + data->ptr[1] = 0xb3; // set second byte of SYN to "random" value +} @@ -17326,33 +17350,17 @@ index 000000000000..2951d245359c + mod_delayed_work(system_wq, &ptl->rtx_timeout.reaper, delta); +} + -+static void ssh_ptl_timeout_start(struct ssh_packet *packet) -+{ -+ struct ssh_ptl *ptl = packet->ptl; -+ ktime_t timestamp = ktime_get_coarse_boottime(); -+ ktime_t timeout = ptl->rtx_timeout.timeout; -+ -+ if (test_bit(SSH_PACKET_SF_LOCKED_BIT, &packet->state)) -+ return; -+ -+ WRITE_ONCE(packet->timestamp, timestamp); -+ /* -+ * Ensure timestamp is set before starting the reaper. Paired with -+ * implicit barrier following check on ssh_packet_get_expiration() in -+ * ssh_ptl_timeout_reap(). -+ */ -+ smp_mb__after_atomic(); -+ -+ ssh_ptl_timeout_reaper_mod(packet->ptl, timestamp, timestamp + timeout); -+} -+ -+ ++/* must be called with queue lock held */ +static void ssh_packet_next_try(struct ssh_packet *p) +{ -+ u8 priority = READ_ONCE(p->priority); -+ u8 base = ssh_packet_priority_get_base(priority); -+ u8 try = ssh_packet_priority_get_try(priority); ++ u8 base = ssh_packet_priority_get_base(p->priority); ++ u8 try = ssh_packet_priority_get_try(p->priority); + ++ /* ++ * Ensure that we write the priority in one go via WRITE_ONCE() so we ++ * can access it via READ_ONCE() for tracing. Note that other access ++ * is guarded by the queue lock, so no need to use READ_ONCE() there. ++ */ + WRITE_ONCE(p->priority, __SSH_PACKET_PRIORITY(base, try + 1)); +} + @@ -17360,40 +17368,39 @@ index 000000000000..2951d245359c +static struct list_head *__ssh_ptl_queue_find_entrypoint(struct ssh_packet *p) +{ + struct list_head *head; -+ u8 priority = READ_ONCE(p->priority); ++ struct ssh_packet *q; + + /* -+ * We generally assume that there are less control (ACK/NAK) packets and -+ * re-submitted data packets as there are normal data packets (at least -+ * in situations in which many packets are queued; if there aren't many -+ * packets queued the decision on how to iterate should be basically -+ * irrellevant; the number of control/data packets is more or less -+ * limited via the maximum number of pending packets). Thus, when -+ * inserting a control or re-submitted data packet, (determined by their -+ * priority), we search from front to back. Normal data packets are, -+ * usually queued directly at the tail of the queue, so for those search -+ * from back to front. ++ * We generally assume that there are less control (ACK/NAK) packets ++ * and re-submitted data packets as there are normal data packets (at ++ * least in situations in which many packets are queued; if there ++ * aren't many packets queued the decision on how to iterate should be ++ * basically irrelevant; the number of control/data packets is more or ++ * less limited via the maximum number of pending packets). Thus, when ++ * inserting a control or re-submitted data packet, (determined by ++ * their priority), we search from front to back. Normal data packets ++ * are, usually queued directly at the tail of the queue, so for those ++ * search from back to front. + */ + -+ if (priority > SSH_PACKET_PRIORITY(DATA, 0)) { ++ if (p->priority > SSH_PACKET_PRIORITY(DATA, 0)) { + list_for_each(head, &p->ptl->queue.head) { -+ p = list_entry(head, struct ssh_packet, queue_node); ++ q = list_entry(head, struct ssh_packet, queue_node); + -+ if (READ_ONCE(p->priority) < priority) ++ if (q->priority < p->priority) + break; + } + } else { + list_for_each_prev(head, &p->ptl->queue.head) { -+ p = list_entry(head, struct ssh_packet, queue_node); ++ q = list_entry(head, struct ssh_packet, queue_node); + -+ if (READ_ONCE(p->priority) >= priority) { ++ if (q->priority >= p->priority) { + head = head->next; + break; + } + } + } + -+ + return head; +} + @@ -17407,7 +17414,7 @@ index 000000000000..2951d245359c + if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT, &ptl->state)) + return -ESHUTDOWN; + -+ // avoid further transitions when cancelling/completing ++ // avoid further transitions when canceling/completing + if (test_bit(SSH_PACKET_SF_LOCKED_BIT, &packet->state)) + return -EINVAL; + @@ -17453,10 +17460,19 @@ index 000000000000..2951d245359c +static void ssh_ptl_pending_push(struct ssh_packet *packet) +{ + struct ssh_ptl *ptl = packet->ptl; ++ const ktime_t timestamp = ktime_get_coarse_boottime(); ++ const ktime_t timeout = ptl->rtx_timeout.timeout; ++ ++ /* ++ * Note: We can get the time for the timestamp before acquiring the ++ * lock as this is the only place we're setting it and this function ++ * is called only from the transmitter thread. Thus it is not possible ++ * to overwrite the timestamp with an outdated value below. ++ */ + + spin_lock(&ptl->pending.lock); + -+ // if we are cancelling/completing this packet, do not add it ++ // if we are canceling/completing this packet, do not add it + if (test_bit(SSH_PACKET_SF_LOCKED_BIT, &packet->state)) { + spin_unlock(&ptl->pending.lock); + return; @@ -17468,10 +17484,15 @@ index 000000000000..2951d245359c + return; + } + ++ packet->timestamp = timestamp; ++ + atomic_inc(&ptl->pending.count); + list_add_tail(&ssh_packet_get(packet)->pending_node, &ptl->pending.head); + + spin_unlock(&ptl->pending.lock); ++ ++ // arm/update timeout reaper ++ ssh_ptl_timeout_reaper_mod(packet->ptl, timestamp, timestamp + timeout); +} + +static void ssh_ptl_pending_remove(struct ssh_packet *packet) @@ -17535,7 +17556,7 @@ index 000000000000..2951d245359c + if (test_bit(SSH_PACKET_TY_FLUSH_BIT, &packet->state)) + return !atomic_read(&ptl->pending.count); + -+ // we can alwas process non-blocking packets ++ // we can always process non-blocking packets + if (!test_bit(SSH_PACKET_TY_BLOCKING_BIT, &packet->state)) + return true; + @@ -17555,7 +17576,7 @@ index 000000000000..2951d245359c + spin_lock(&ptl->queue.lock); + list_for_each_entry_safe(p, n, &ptl->queue.head, queue_node) { + /* -+ * If we are cancelling or completing this packet, ignore it. ++ * If we are canceling or completing this packet, ignore it. + * It's going to be removed from this queue shortly. + */ + if (test_bit(SSH_PACKET_SF_LOCKED_BIT, &p->state)) @@ -17573,10 +17594,7 @@ index 000000000000..2951d245359c + + /* + * We are allowed to change the state now. Remove it from the -+ * queue and mark it as being transmitted. Note that we cannot -+ * add it to the set of pending packets yet, as queue locks must -+ * always be acquired before packet locks (otherwise we might -+ * run into a deadlock). ++ * queue and mark it as being transmitted. + */ + + list_del(&p->queue_node); @@ -17586,6 +17604,15 @@ index 000000000000..2951d245359c + smp_mb__before_atomic(); + clear_bit(SSH_PACKET_SF_QUEUED_BIT, &p->state); + ++ /* ++ * Update number of tries. This directly influences the ++ * priority in case the packet is re-submitted (e.g. via ++ * timeout/NAK). Note that all reads and writes to the ++ * priority after the first submission are guarded by the ++ * queue lock. ++ */ ++ ssh_packet_next_try(p); ++ + packet = p; + break; + } @@ -17605,19 +17632,10 @@ index 000000000000..2951d245359c + if (test_bit(SSH_PACKET_TY_SEQUENCED_BIT, &p->state)) { + ptl_dbg(ptl, "ptl: transmitting sequenced packet %p\n", p); + ssh_ptl_pending_push(p); -+ ssh_ptl_timeout_start(p); + } else { + ptl_dbg(ptl, "ptl: transmitting non-sequenced packet %p\n", p); + } + -+ /* -+ * Update number of tries. This directly influences the priority in case -+ * the packet is re-submitted (e.g. via timeout/NAK). Note that this is -+ * the only place where we update the priority in-flight. As this runs -+ * only on the tx-thread, this read-modify-write procedure is safe. -+ */ -+ ssh_packet_next_try(p); -+ + return p; +} + @@ -17666,104 +17684,134 @@ index 000000000000..2951d245359c + wake_up_all(&packet->ptl->tx.packet_wq); +} + -+static void ssh_ptl_tx_threadfn_wait(struct ssh_ptl *ptl) ++static long ssh_ptl_tx_wait_packet(struct ssh_ptl *ptl) +{ -+ wait_event_interruptible(ptl->tx.thread_wq, -+ READ_ONCE(ptl->tx.thread_signal) || kthread_should_stop()); -+ WRITE_ONCE(ptl->tx.thread_signal, false); ++ int status; ++ ++ status = wait_for_completion_interruptible(&ptl->tx.thread_cplt_pkt); ++ ++ reinit_completion(&ptl->tx.thread_cplt_pkt); ++ ++ /* ++ * Ensure completion is cleared before continuing to avoid lost update ++ * problems. ++ */ ++ smp_mb__after_atomic(); ++ ++ return status; ++} ++ ++static long ssh_ptl_tx_wait_transfer(struct ssh_ptl *ptl, long timeout) ++{ ++ long status; ++ ++ status = wait_for_completion_interruptible_timeout( ++ &ptl->tx.thread_cplt_tx, timeout); ++ ++ reinit_completion(&ptl->tx.thread_cplt_tx); ++ ++ /* ++ * Ensure completion is cleared before continuing to avoid lost update ++ * problems. ++ */ ++ smp_mb__after_atomic(); ++ ++ return status; ++} ++ ++static int ssh_ptl_tx_packet(struct ssh_ptl *ptl, struct ssh_packet *packet) ++{ ++ long timeout = SSH_PTL_TX_TIMEOUT; ++ size_t offset = 0; ++ ++ // note: flush-packets don't have any data ++ if (unlikely(!packet->data.ptr)) ++ return 0; ++ ++ // error injection: drop packet to simulate transmission problem ++ if (ssh_ptl_should_drop_packet(packet)) ++ return 0; ++ ++ // error injection: simulate invalid packet data ++ ssh_ptl_tx_inject_invalid_data(packet); ++ ++ ptl_dbg(ptl, "tx: sending data (length: %zu)\n", packet->data.len); ++ print_hex_dump_debug("tx: ", DUMP_PREFIX_OFFSET, 16, 1, ++ packet->data.ptr, packet->data.len, false); ++ ++ do { ++ ssize_t status, len; ++ u8 *buf; ++ ++ buf = packet->data.ptr + offset; ++ len = packet->data.len - offset; ++ ++ status = ssh_ptl_write_buf(ptl, packet, buf, len); ++ if (status < 0) ++ return status; ++ ++ if (status == len) ++ return 0; ++ ++ offset += status; ++ ++ timeout = ssh_ptl_tx_wait_transfer(ptl, timeout); ++ if (kthread_should_stop() || !atomic_read(&ptl->tx.running)) ++ return -ESHUTDOWN; ++ ++ if (timeout < 0) ++ return -EINTR; ++ ++ if (timeout == 0) ++ return -ETIMEDOUT; ++ } while (true); +} + +static int ssh_ptl_tx_threadfn(void *data) +{ + struct ssh_ptl *ptl = data; + -+ while (!kthread_should_stop()) { -+ unsigned char *buf; -+ bool drop = false; -+ size_t len = 0; -+ int status = 0; ++ while (!kthread_should_stop() && atomic_read(&ptl->tx.running)) { ++ struct ssh_packet *packet; ++ int status; + -+ // if we don't have a packet, get the next and add it to pending -+ if (IS_ERR_OR_NULL(ptl->tx.packet)) { -+ ptl->tx.packet = ssh_ptl_tx_next(ptl); -+ ptl->tx.offset = 0; ++ // try to get the next packet ++ packet = ssh_ptl_tx_next(ptl); + -+ // if no packet can be processed, we are done -+ if (IS_ERR(ptl->tx.packet)) { -+ ssh_ptl_tx_threadfn_wait(ptl); -+ continue; -+ } ++ // if no packet can be processed, we are done ++ if (IS_ERR(packet)) { ++ ssh_ptl_tx_wait_packet(ptl); ++ continue; + } + -+ // error injection: drop packet to simulate transmission problem -+ if (ptl->tx.offset == 0) -+ drop = ssh_ptl_should_drop_packet(ptl->tx.packet); ++ // transfer and complete packet ++ status = ssh_ptl_tx_packet(ptl, packet); ++ if (status) ++ ssh_ptl_tx_compl_error(packet, status); ++ else ++ ssh_ptl_tx_compl_success(packet); + -+ // error injection: simulate invalid packet data -+ if (ptl->tx.offset == 0 && !drop) -+ ssh_ptl_tx_inject_invalid_data(ptl->tx.packet); -+ -+ // note: flush-packets don't have any data -+ if (likely(ptl->tx.packet->data.ptr && !drop)) { -+ buf = ptl->tx.packet->data.ptr + ptl->tx.offset; -+ len = ptl->tx.packet->data.len - ptl->tx.offset; -+ -+ ptl_dbg(ptl, "tx: sending data (length: %zu)\n", len); -+ print_hex_dump_debug("tx: ", DUMP_PREFIX_OFFSET, 16, 1, -+ buf, len, false); -+ -+ status = ssh_ptl_write_buf(ptl, ptl->tx.packet, buf, len); -+ } -+ -+ if (status < 0) { -+ // complete packet with error -+ ssh_ptl_tx_compl_error(ptl->tx.packet, status); -+ ssh_packet_put(ptl->tx.packet); -+ ptl->tx.packet = NULL; -+ -+ } else if (status == len) { -+ // complete packet and/or mark as transmitted -+ ssh_ptl_tx_compl_success(ptl->tx.packet); -+ ssh_packet_put(ptl->tx.packet); -+ ptl->tx.packet = NULL; -+ -+ } else { // need more buffer space -+ ptl->tx.offset += status; -+ ssh_ptl_tx_threadfn_wait(ptl); -+ } -+ } -+ -+ // cancel active packet before we actually stop -+ if (!IS_ERR_OR_NULL(ptl->tx.packet)) { -+ ssh_ptl_tx_compl_error(ptl->tx.packet, -ESHUTDOWN); -+ ssh_packet_put(ptl->tx.packet); -+ ptl->tx.packet = NULL; ++ ssh_packet_put(packet); + } + + return 0; +} + +/** -+ * ssh_ptl_tx_wakeup() - Wake up packet transmitter thread. ++ * ssh_ptl_tx_wakeup_packet() - Wake up packet transmitter thread for new ++ * packet. + * @ptl: The packet transport layer. + * -+ * Wakes up the packet transmitter thread. If the packet transport layer has -+ * been shut down, calls to this function will be ignored. ++ * Wakes up the packet transmitter thread, notifying it that a new packet has ++ * arrived and is ready for transfer. If the packet transport layer has been ++ * shut down, calls to this function will be ignored. + */ -+void ssh_ptl_tx_wakeup(struct ssh_ptl *ptl) ++static void ssh_ptl_tx_wakeup_packet(struct ssh_ptl *ptl) +{ + if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT, &ptl->state)) + return; + -+ WRITE_ONCE(ptl->tx.thread_signal, true); -+ /* -+ * Ensure that the signal is set before we wake the transmitter -+ * thread to prevent lost updates: If the signal is not set, -+ * when the thread checks it in ssh_ptl_tx_threadfn_wait(), it -+ * may go back to sleep. -+ */ -+ smp_mb__after_atomic(); -+ wake_up(&ptl->tx.thread_wq); ++ complete(&ptl->tx.thread_cplt_pkt); +} + +/** @@ -17774,8 +17822,9 @@ index 000000000000..2951d245359c + */ +int ssh_ptl_tx_start(struct ssh_ptl *ptl) +{ -+ ptl->tx.thread = kthread_run(ssh_ptl_tx_threadfn, ptl, -+ "ssam_serial_hub-tx"); ++ atomic_set_release(&ptl->tx.running, 1); ++ ++ ptl->tx.thread = kthread_run(ssh_ptl_tx_threadfn, ptl, "ssam_serial_hub-tx"); + if (IS_ERR(ptl->tx.thread)) + return PTR_ERR(ptl->tx.thread); + @@ -17792,7 +17841,19 @@ index 000000000000..2951d245359c +{ + int status = 0; + -+ if (ptl->tx.thread) { ++ if (!IS_ERR_OR_NULL(ptl->tx.thread)) { ++ /* Tell thread to stop. */ ++ atomic_set_release(&ptl->tx.running, 0); ++ ++ /* ++ * Wake up thread in case it is paused. Do not use wakeup ++ * helpers as this may be called when the shutdown bit has ++ * already been set. ++ */ ++ complete(&ptl->tx.thread_cplt_pkt); ++ complete(&ptl->tx.thread_cplt_tx); ++ ++ /* Finally, wait for thread to stop. */ + status = kthread_stop(ptl->tx.thread); + ptl->tx.thread = NULL; + } @@ -17855,7 +17916,6 @@ index 000000000000..2951d245359c +static void ssh_ptl_acknowledge(struct ssh_ptl *ptl, u8 seq) +{ + struct ssh_packet *p; -+ int status = 0; + + p = ssh_ptl_ack_pop(ptl, seq); + if (IS_ERR(p)) { @@ -17882,9 +17942,11 @@ index 000000000000..2951d245359c + * has not been updated from "transmitting" to "transmitted" yet. + * In that case, we need to wait for this transition to occur in order + * to determine between success or failure. ++ * ++ * On transmission failure, the packet will be locked after this call. ++ * On success, the transmitted bit will be set. + */ -+ if (test_bit(SSH_PACKET_SF_TRANSMITTING_BIT, &p->state)) -+ ssh_ptl_wait_until_transmitted(p); ++ ssh_ptl_wait_until_transmitted(p); + + /* + * The packet will already be locked in case of a transmission error or @@ -17892,20 +17954,18 @@ index 000000000000..2951d245359c + * packet. + */ + if (unlikely(test_and_set_bit(SSH_PACKET_SF_LOCKED_BIT, &p->state))) { ++ if (unlikely(!test_bit(SSH_PACKET_SF_TRANSMITTED_BIT, &p->state))) ++ ptl_err(ptl, "ptl: received ACK before packet had been fully transmitted\n"); ++ + ssh_packet_put(p); + return; + } + -+ if (unlikely(!test_bit(SSH_PACKET_SF_TRANSMITTED_BIT, &p->state))) { -+ ptl_err(ptl, "ptl: received ACK before packet had been fully transmitted\n"); -+ status = -EREMOTEIO; -+ } -+ -+ ssh_ptl_remove_and_complete(p, status); ++ ssh_ptl_remove_and_complete(p, 0); + ssh_packet_put(p); + + if (atomic_read(&ptl->pending.count) < SSH_PTL_MAX_PENDING) -+ ssh_ptl_tx_wakeup(ptl); ++ ssh_ptl_tx_wakeup_packet(ptl); +} + + @@ -17940,6 +18000,9 @@ index 000000000000..2951d245359c + /* + * The ptl reference only gets set on or before the first submission. + * After the first submission, it has to be read-only. ++ * ++ * Note that ptl may already be set from upper-layer request ++ * submission, thus we cannot expect it to be NULL. + */ + ptl_old = READ_ONCE(p->ptl); + if (ptl_old == NULL) @@ -17953,20 +18016,39 @@ index 000000000000..2951d245359c + + if (!test_bit(SSH_PACKET_TY_BLOCKING_BIT, &p->state) + || (atomic_read(&ptl->pending.count) < SSH_PTL_MAX_PENDING)) -+ ssh_ptl_tx_wakeup(ptl); ++ ssh_ptl_tx_wakeup_packet(ptl); + + return 0; +} + -+/* must be called with pending lock held */ ++/* ++ * __ssh_ptl_resubmit() - Re-submit a packet to the transport layer. ++ * @packet: The packet to re-submit. ++ * ++ * Re-submits the given packet: Checks if it can be re-submitted and queues it ++ * if it can, resetting the packet timestamp in the process. Must be called ++ * with the pending lock held. ++ * ++ * Return: Returns %-ECANCELED if the packet has exceeded its number of tries, ++ * %-EINVAL if the packet has been locked, %-EALREADY if the packet is already ++ * on the queue, and %-ESHUTDOWN if the transmission layer has been shut down. ++ */ +static int __ssh_ptl_resubmit(struct ssh_packet *packet) +{ + int status; ++ u8 try; + + trace_ssam_packet_resubmit(packet); + + spin_lock(&packet->ptl->queue.lock); + ++ /* Check if the packet is out of tries. */ ++ try = ssh_packet_priority_get_try(packet->priority); ++ if (try >= SSH_PTL_MAX_PACKET_TRIES) { ++ spin_unlock(&packet->ptl->queue.lock); ++ return -ECANCELED; ++ } ++ + status = __ssh_ptl_queue_push(packet); + if (status) { + /* @@ -17978,13 +18060,7 @@ index 000000000000..2951d245359c + return status; + } + -+ /* -+ * Reset the timestamp. This must be called and executed before the -+ * pending lock is released. The lock release should be a sufficient -+ * barrier for this operation, thus there is no need to manually add -+ * one here. -+ */ -+ WRITE_ONCE(packet->timestamp, KTIME_MAX); ++ packet->timestamp = KTIME_MAX; + + spin_unlock(&packet->ptl->queue.lock); + return 0; @@ -17994,7 +18070,6 @@ index 000000000000..2951d245359c +{ + struct ssh_packet *p; + bool resub = false; -+ u8 try; + + /* + * Note: We deliberately do not remove/attempt to cancel and complete @@ -18011,19 +18086,10 @@ index 000000000000..2951d245359c + + // re-queue all pending packets + list_for_each_entry(p, &ptl->pending.head, pending_node) { -+ // avoid further transitions if locked -+ if (test_bit(SSH_PACKET_SF_LOCKED_BIT, &p->state)) -+ continue; -+ -+ // do not re-schedule if packet is out of tries -+ try = ssh_packet_priority_get_try(READ_ONCE(p->priority)); -+ if (try >= SSH_PTL_MAX_PACKET_TRIES) -+ continue; -+ + /* -+ * Submission fails if the packet has been locked, is already -+ * queued, or the layer is being shut down. No need to -+ * re-schedule tx-thread in those cases. ++ * Re-submission fails if the packet is out of tries, has been ++ * locked, is already queued, or the layer is being shut down. ++ * No need to re-schedule tx-thread in those cases. + */ + if (!__ssh_ptl_resubmit(p)) + resub = true; @@ -18032,7 +18098,7 @@ index 000000000000..2951d245359c + spin_unlock(&ptl->pending.lock); + + if (resub) -+ ssh_ptl_tx_wakeup(ptl); ++ ssh_ptl_tx_wakeup_packet(ptl); +} + +/** @@ -18043,11 +18109,11 @@ index 000000000000..2951d245359c + * callbacks will be called. This may occur during execution of this function + * or may occur at any point later. + * -+ * Note that it is not guaranteed that the packet will actually be cancelled -+ * if the packet is concurrently completed by another process. The only -+ * guarantee of this function is that the packet will be completed (with -+ * success, failure, or cancellation) and released from the transport layer in -+ * a reasonable time-frame. ++ * Note that it is not guaranteed that the packet will actually be canceled if ++ * the packet is concurrently completed by another process. The only guarantee ++ * of this function is that the packet will be completed (with success, ++ * failure, or cancellation) and released from the transport layer in a ++ * reasonable time-frame. + * + * May be called before the packet has been submitted, in which case any later + * packet submission fails. @@ -18084,20 +18150,18 @@ index 000000000000..2951d245359c + ssh_ptl_remove_and_complete(p, -ECANCELED); + + if (atomic_read(&p->ptl->pending.count) < SSH_PTL_MAX_PENDING) -+ ssh_ptl_tx_wakeup(p->ptl); ++ ssh_ptl_tx_wakeup_packet(p->ptl); + + } else if (!test_and_set_bit(SSH_PACKET_SF_COMPLETED_BIT, &p->state)) { + __ssh_ptl_complete(p, -ECANCELED); + } +} + -+ ++/* must be called with pending lock held */ +static ktime_t ssh_packet_get_expiration(struct ssh_packet *p, ktime_t timeout) +{ -+ ktime_t timestamp = READ_ONCE(p->timestamp); -+ -+ if (timestamp != KTIME_MAX) -+ return ktime_add(timestamp, timeout); ++ if (p->timestamp != KTIME_MAX) ++ return ktime_add(p->timestamp, timeout); + else + return KTIME_MAX; +} @@ -18111,8 +18175,9 @@ index 000000000000..2951d245359c + ktime_t timeout = ptl->rtx_timeout.timeout; + ktime_t next = KTIME_MAX; + bool resub = false; ++ int status; + -+ trace_ssam_ptl_timeout_reap("pending", atomic_read(&ptl->pending.count)); ++ trace_ssam_ptl_timeout_reap(atomic_read(&ptl->pending.count)); + + /* + * Mark reaper as "not pending". This is done before checking any @@ -18131,7 +18196,6 @@ index 000000000000..2951d245359c + + list_for_each_entry_safe(p, n, &ptl->pending.head, pending_node) { + ktime_t expires = ssh_packet_get_expiration(p, timeout); -+ u8 try; + + /* + * Check if the timeout hasn't expired yet. Find out next @@ -18142,21 +18206,21 @@ index 000000000000..2951d245359c + continue; + } + -+ // check if we still have some tries left -+ try = ssh_packet_priority_get_try(READ_ONCE(p->priority)); -+ if (likely(try < SSH_PTL_MAX_PACKET_TRIES)) { -+ trace_ssam_packet_timeout(p); ++ trace_ssam_packet_timeout(p); + -+ /* -+ * Submission fails if the packet has been locked, is -+ * already queued, or the layer is being shut down. -+ * No need to re-schedule tx-thread in those cases. -+ */ -+ if (!__ssh_ptl_resubmit(p)) -+ resub = true; ++ status = __ssh_ptl_resubmit(p); + ++ /* ++ * Re-submission fails if the packet is out of tries, has been ++ * locked, is already queued, or the layer is being shut down. ++ * No need to re-schedule tx-thread in those cases. ++ */ ++ if (!status) ++ resub = true; ++ ++ /* Go to next packet if this packet is not out of tries. */ ++ if (status != -ECANCELED) + continue; -+ } + + // no more tries left: cancel the packet + @@ -18164,8 +18228,6 @@ index 000000000000..2951d245359c + if (test_and_set_bit(SSH_PACKET_SF_LOCKED_BIT, &p->state)) + continue; + -+ trace_ssam_packet_timeout(p); -+ + /* + * We have now marked the packet as locked. Thus it cannot be + * added to the pending list again after we've removed it here. @@ -18201,7 +18263,7 @@ index 000000000000..2951d245359c + ssh_ptl_timeout_reaper_mod(ptl, now, next); + + if (resub) -+ ssh_ptl_tx_wakeup(ptl); ++ ssh_ptl_tx_wakeup_packet(ptl); +} + + @@ -18218,7 +18280,7 @@ index 000000000000..2951d245359c + return true; + } + -+ // update list of blocked seuence IDs ++ // update list of blocked sequence IDs + ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = seq; + ptl->rx.blocked.offset = (ptl->rx.blocked.offset + 1) + % ARRAY_SIZE(ptl->rx.blocked.seqs); @@ -18310,12 +18372,12 @@ index 000000000000..2951d245359c + * detected when handling data frames. + * - This path will also be executed on invalid CRCs: When an + * invalid CRC is encountered, the code below will skip data -+ * until direclty after the SYN. This causes the search for ++ * until directly after the SYN. This causes the search for + * the next SYN, which is generally not placed directly after + * the last one. + * + * Open question: Should we send this in case of invalid -+ * payload CRCs if the frame-type is nonsequential (current ++ * payload CRCs if the frame-type is non-sequential (current + * implementation) or should we drop that frame without + * telling the EC? + */ @@ -18454,7 +18516,7 @@ index 000000000000..2951d245359c + * @n: Size of the data to push to the layer, in bytes. + * + * Pushes data from a lower-layer transport to the receiver fifo buffer of the -+ * packet layer and notifies the reveiver thread. Calls to this function are ++ * packet layer and notifies the receiver thread. Calls to this function are + * ignored once the packet layer has been shut down. + * + * Return: Returns the number of bytes transferred (positive or zero) on @@ -18501,7 +18563,7 @@ index 000000000000..2951d245359c + * Ensure that the layer gets marked as shut-down before actually + * stopping it. In combination with the check in ssh_ptl_queue_push(), + * this guarantees that no new packets can be added and all already -+ * queued packets are properly cancelled. In combination with the check ++ * queued packets are properly canceled. In combination with the check + * in ssh_ptl_rx_rcvbuf(), this guarantees that received data is + * properly cut off. + */ @@ -18523,14 +18585,14 @@ index 000000000000..2951d245359c + * and pending set. + * + * Note: We still need locks here because someone could still be -+ * cancelling packets. ++ * canceling packets. + * + * Note 2: We can re-use queue_node (or pending_node) if we mark the + * packet as locked an then remove it from the queue (or pending set -+ * respecitvely). Marking the packet as locked avoids re-queueing ++ * respectively). Marking the packet as locked avoids re-queuing + * (which should already be prevented by having stopped the treads...) + * and not setting QUEUED_BIT (or PENDING_BIT) prevents removal from a -+ * new list via other threads (e.g. canellation). ++ * new list via other threads (e.g. cancellation). + * + * Note 3: There may be overlap between complete_p and complete_q. + * This is handled via test_and_set_bit() on the "completed" flag @@ -18615,10 +18677,9 @@ index 000000000000..2951d245359c + atomic_set_release(&ptl->pending.count, 0); + + ptl->tx.thread = NULL; -+ ptl->tx.thread_signal = false; -+ ptl->tx.packet = NULL; -+ ptl->tx.offset = 0; -+ init_waitqueue_head(&ptl->tx.thread_wq); ++ atomic_set(&ptl->tx.running, 0); ++ init_completion(&ptl->tx.thread_cplt_pkt); ++ init_completion(&ptl->tx.thread_cplt_tx); + init_waitqueue_head(&ptl->tx.packet_wq); + + ptl->rx.thread = NULL; @@ -18662,10 +18723,10 @@ index 000000000000..2951d245359c +} diff --git a/drivers/misc/surface_aggregator/ssh_packet_layer.h b/drivers/misc/surface_aggregator/ssh_packet_layer.h new file mode 100644 -index 000000000000..f3d8a85389d5 +index 000000000000..fd9bd2aa2028 --- /dev/null +++ b/drivers/misc/surface_aggregator/ssh_packet_layer.h -@@ -0,0 +1,175 @@ +@@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * SSH packet transport layer. @@ -18723,12 +18784,11 @@ index 000000000000..f3d8a85389d5 + * @pending.head: List-head of the pending set/list. + * @pending.count: Number of currently pending packets. + * @tx: Transmitter subsystem. -+ * @tx.thread_signal: Signal notifying transmitter thread of data to be sent. ++ * @tx.running: Flag indicating (desired) transmitter thread state. + * @tx.thread: Transmitter thread. -+ * @tx.thread_wq: Waitqueue-head for transmitter thread. ++ * @tx.thread_cplt_tx: Completion for transmitter thread waiting on transfer. ++ * @tx.thread_cplt_pkt: Completion for transmitter thread waiting on packets. + * @tx.packet_wq: Waitqueue-head for packet transmit completion. -+ * @tx.packet: Currently sent packet. -+ * @tx.offset: Data-offset into the packet currently being transmitted. + * @rx: Receiver subsystem. + * @rx.thread: Receiver thread. + * @rx.wq: Waitqueue-head for receiver thread. @@ -18738,7 +18798,7 @@ index 000000000000..f3d8a85389d5 + * @rx.blocked.seqs: Array of blocked sequence IDs. + * @rx.blocked.offset: Offset indicating where a new ID should be inserted. + * @rtx_timeout: Retransmission timeout subsystem. -+ * @rtx_timeout.timeout: Timeout inverval for retransmission. ++ * @rtx_timeout.timeout: Timeout interval for retransmission. + * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled. + * @rtx_timeout.reaper: Work performing timeout checks and subsequent actions. + * @ops: Packet layer operations. @@ -18759,12 +18819,11 @@ index 000000000000..f3d8a85389d5 + } pending; + + struct { -+ bool thread_signal; ++ atomic_t running; + struct task_struct *thread; -+ struct wait_queue_head thread_wq; ++ struct completion thread_cplt_tx; ++ struct completion thread_cplt_pkt; + struct wait_queue_head packet_wq; -+ struct ssh_packet *packet; -+ size_t offset; + } tx; + + struct { @@ -18791,8 +18850,8 @@ index 000000000000..f3d8a85389d5 + +#define __ssam_prcond(func, p, fmt, ...) \ + do { \ -+ if ((p)) \ -+ func((p), fmt, ##__VA_ARGS__); \ ++ if (p) \ ++ func(p, fmt, ##__VA_ARGS__); \ + } while (0) + +#define ptl_dbg(p, fmt, ...) dev_dbg(&(p)->serdev->dev, fmt, ##__VA_ARGS__) @@ -18832,7 +18891,23 @@ index 000000000000..f3d8a85389d5 +void ssh_ptl_cancel(struct ssh_packet *p); + +int ssh_ptl_rx_rcvbuf(struct ssh_ptl *ptl, const u8 *buf, size_t n); -+void ssh_ptl_tx_wakeup(struct ssh_ptl *ptl); ++ ++/** ++ * ssh_ptl_tx_wakeup_transfer() - Wake up packet transmitter thread for ++ * transfer. ++ * @ptl: The packet transport layer. ++ * ++ * Wakes up the packet transmitter thread, notifying it that the underlying ++ * transport has more space for data to be transmitted. If the packet ++ * transport layer has been shut down, calls to this function will be ignored. ++ */ ++static inline void ssh_ptl_tx_wakeup_transfer(struct ssh_ptl *ptl) ++{ ++ if (test_bit(SSH_PTL_SF_SHUTDOWN_BIT, &ptl->state)) ++ return; ++ ++ complete(&ptl->tx.thread_cplt_tx); ++} + +void ssh_packet_init(struct ssh_packet *packet, unsigned long type, + u8 priority, const struct ssh_packet_ops *ops); @@ -18843,7 +18918,7 @@ index 000000000000..f3d8a85389d5 +#endif /* _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H */ diff --git a/drivers/misc/surface_aggregator/ssh_parser.c b/drivers/misc/surface_aggregator/ssh_parser.c new file mode 100644 -index 000000000000..575cbc039ad7 +index 000000000000..0e52344bcc7a --- /dev/null +++ b/drivers/misc/surface_aggregator/ssh_parser.c @@ -0,0 +1,229 @@ @@ -18901,9 +18976,9 @@ index 000000000000..575cbc039ad7 + * + * Search for SSH SYN bytes in the given source span. If found, set the @rem + * span to the remaining data, starting with the first SYN bytes and capped by -+ * the source span length, and return %true. This function does not copy -+ * any data, but rather only sets pointers to the respecitve start addresses -+ * and length values. ++ * the source span length, and return %true. This function does not copy any ++ * data, but rather only sets pointers to the respective start addresses and ++ * length values. + * + * If no SSH SYN bytes could be found, set the @rem span to the zero-length + * span at the end of the source span and return %false. @@ -18913,7 +18988,7 @@ index 000000000000..575cbc039ad7 + * source span, and return %false. This function should then be re-run once + * more data is available. + * -+ * Return: Returns %true iff a complete SSG SYN sequence could be found, ++ * Return: Returns %true iff a complete SSH SYN sequence could be found, + * %false otherwise. + */ +bool sshp_find_syn(const struct ssam_span *src, struct ssam_span *rem) @@ -18961,7 +19036,7 @@ index 000000000000..575cbc039ad7 + * + * Return: Returns zero on success or if the frame is incomplete, %-ENOMSG if + * the start of the message is invalid, %-EBADMSG if any (frame-header or -+ * payload) CRC is ivnalid, or %-EMSGSIZE if the SSH message is bigger than ++ * payload) CRC is invalid, or %-EMSGSIZE if the SSH message is bigger than + * the maximum message length specified in the @maxlen parameter. + */ +int sshp_parse_frame(const struct device *dev, const struct ssam_span *source, @@ -18999,9 +19074,9 @@ index 000000000000..575cbc039ad7 + + // ensure packet does not exceed maximum length + sp.len = get_unaligned_le16(&((struct ssh_frame *)sf.ptr)->len); -+ if (unlikely(sp.len + SSH_MESSAGE_LENGTH(0) > maxlen)) { -+ dev_warn(dev, "rx: parser: frame too large: %u bytes\n", -+ ((struct ssh_frame *)sf.ptr)->len); ++ if (unlikely(SSH_MESSAGE_LENGTH(sp.len) > maxlen)) { ++ dev_warn(dev, "rx: parser: frame too large: %llu bytes\n", ++ SSH_MESSAGE_LENGTH(sp.len)); + return -EMSGSIZE; + } + @@ -19241,10 +19316,10 @@ index 000000000000..71c43ab07bf6 +#endif /* _SURFACE_AGGREGATOR_SSH_PARSER_h */ diff --git a/drivers/misc/surface_aggregator/ssh_request_layer.c b/drivers/misc/surface_aggregator/ssh_request_layer.c new file mode 100644 -index 000000000000..f47bd949b6c3 +index 000000000000..9188526278e2 --- /dev/null +++ b/drivers/misc/surface_aggregator/ssh_request_layer.c -@@ -0,0 +1,1254 @@ +@@ -0,0 +1,1264 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * SSH request transport layer. @@ -19257,6 +19332,7 @@ index 000000000000..f47bd949b6c3 +#include +#include +#include ++#include +#include +#include +#include @@ -19334,7 +19410,7 @@ index 000000000000..f47bd949b6c3 +static u32 ssh_request_get_rqid_safe(struct ssh_request *rqst) +{ + if (!rqst->packet.data.ptr) -+ return (u32)-1; ++ return U32_MAX; + + return ssh_request_get_rqid(rqst); +} @@ -19418,7 +19494,7 @@ index 000000000000..f47bd949b6c3 + + trace_ssam_request_complete(rqst, status); + -+ // rtl/ptl may not be set if we're cancelling before submitting ++ // rtl/ptl may not be set if we're canceling before submitting + rtl_dbg_cond(rtl, "rtl: completing request (rqid: 0x%04x, status: %d)\n", + ssh_request_get_rqid_safe(rqst), status); + @@ -19528,13 +19604,14 @@ index 000000000000..f47bd949b6c3 + } else if (status) { + /* + * If submitting the packet failed and the packet layer isn't -+ * shutting down, the packet has either been submmitted/queued -+ * before (-EALREADY, which cannot happen as we have guaranteed -+ * that requests cannot be re-submitted), or the packet was -+ * marked as locked (-EINVAL). To mark the packet locked at this -+ * stage, the request, and thus the packets itself, had to have -+ * been canceled. Simply drop the reference. Cancellation itself -+ * will remove it from the set of pending requests. ++ * shutting down, the packet has either been submitted/queued ++ * before (-EALREADY, which cannot happen as we have ++ * guaranteed that requests cannot be re-submitted), or the ++ * packet was marked as locked (-EINVAL). To mark the packet ++ * locked at this stage, the request, and thus the packets ++ * itself, had to have been canceled. Simply drop the ++ * reference. Cancellation itself will remove it from the set ++ * of pending requests. + */ + + WARN_ON(status != -EINVAL); @@ -19699,6 +19776,10 @@ index 000000000000..f47bd949b6c3 + if (test_bit(SSH_REQUEST_SF_LOCKED_BIT, &rqst->state)) + return; + ++ /* ++ * Note: The timestamp gets set only once. This happens on the packet ++ * callback. All other access to it is read-only. ++ */ + WRITE_ONCE(rqst->timestamp, timestamp); + /* + * Ensure timestamp is set before starting the reaper. Paired with @@ -19847,10 +19928,10 @@ index 000000000000..f47bd949b6c3 + * from the queue, where we are now guaranteed that the packet is or has + * been due to the critical section. + * -+ * Note that if the CMPXCHG fails, we are guaranteed that ptl has ++ * Note that if the cmpxchg() fails, we are guaranteed that ptl has + * been set and is non-NULL, as states can only be nonzero after this -+ * has been set. Also note that we need to fetch the static (type) flags -+ * to ensure that they don't cause the cmpxchg to fail. ++ * has been set. Also note that we need to fetch the static (type) ++ * flags to ensure that they don't cause the cmpxchg() to fail. + */ + fixed = READ_ONCE(r->state) & SSH_REQUEST_FLAGS_TY_MASK; + flags = cmpxchg(&r->state, fixed, SSH_REQUEST_SF_LOCKED_BIT); @@ -19876,10 +19957,10 @@ index 000000000000..f47bd949b6c3 + spin_lock(&rtl->queue.lock); + + /* -+ * Note: 1) Requests cannot be re-submitted. 2) If a request is queued, -+ * it cannot be "transmitting"/"pending" yet. Thus, if we successfully -+ * remove the request here, we have removed all its occurences in the -+ * system. ++ * Note: 1) Requests cannot be re-submitted. 2) If a request is ++ * queued, it cannot be "transmitting"/"pending" yet. Thus, if we ++ * successfully remove the request here, we have removed all its ++ * occurrences in the system. + */ + + remove = test_and_clear_bit(SSH_REQUEST_SF_QUEUED_BIT, &r->state); @@ -19910,7 +19991,7 @@ index 000000000000..f47bd949b6c3 + + /* + * Now that we have locked the packet, we have guaranteed that it can't -+ * be added to the system any more. If ptl is zero, the locked ++ * be added to the system any more. If ptl is NULL, the locked + * check in ssh_rtl_submit() has not been run and any submission, + * currently in progress or called later, won't add the packet. Thus we + * can directly complete it. @@ -20008,11 +20089,11 @@ index 000000000000..f47bd949b6c3 + return; + + /* -+ * The packet may get cancelled even though it has not been ++ * The packet may get canceled even though it has not been + * submitted yet. The request may still be queued. Check the + * queue and remove it if necessary. As the timeout would have -+ * been started in this function on success, there's no need to -+ * cancel it here. ++ * been started in this function on success, there's no need ++ * to cancel it here. + */ + ssh_rtl_queue_remove(r); + ssh_rtl_pending_remove(r); @@ -20030,6 +20111,10 @@ index 000000000000..f47bd949b6c3 + + // if we expect a response, we just need to start the timeout + if (test_bit(SSH_REQUEST_TY_HAS_RESPONSE_BIT, &r->state)) { ++ /* ++ * Note: This is the only place where the timestamp gets set, ++ * all other access to it is read-only. ++ */ + ssh_rtl_timeout_start(r); + return; + } @@ -20072,7 +20157,7 @@ index 000000000000..f47bd949b6c3 + ktime_t timeout = rtl->rtx_timeout.timeout; + ktime_t next = KTIME_MAX; + -+ trace_ssam_rtl_timeout_reap("pending", atomic_read(&rtl->pending.count)); ++ trace_ssam_rtl_timeout_reap(atomic_read(&rtl->pending.count)); + + /* + * Mark reaper as "not pending". This is done before checking any @@ -20364,8 +20449,8 @@ index 000000000000..f47bd949b6c3 + * a special flush packet, meaning that upon completion, also the underlying + * packet transport layer has been flushed. + * -+ * Flushing the request layer gurarantees that all previously submitted -+ * requests have been fully completed before this call returns. Additinally, ++ * Flushing the request layer guarantees that all previously submitted ++ * requests have been fully completed before this call returns. Additionally, + * flushing blocks execution of all later submitted requests until the flush + * has been completed. + * @@ -20434,9 +20519,9 @@ index 000000000000..f47bd949b6c3 + set_bit(SSH_RTL_SF_SHUTDOWN_BIT, &rtl->state); + /* + * Ensure that the layer gets marked as shut-down before actually -+ * stopping it. In combination with the check in ssh_rtl_sunmit(), this -+ * guarantees that no new requests can be added and all already queued -+ * requests are properly cancelled. ++ * stopping it. In combination with the check in ssh_rtl_submit(), ++ * this guarantees that no new requests can be added and all already ++ * queued requests are properly canceled. + */ + smp_mb__after_atomic(); + @@ -20468,9 +20553,9 @@ index 000000000000..f47bd949b6c3 + cancel_delayed_work_sync(&rtl->rtx_timeout.reaper); + + /* -+ * Shutting down the packet layer should also have caneled all requests. -+ * Thus the pending set should be empty. Attempt to handle this -+ * gracefully anyways, even though this should be dead code. ++ * Shutting down the packet layer should also have canceled all ++ * requests. Thus the pending set should be empty. Attempt to handle ++ * this gracefully anyways, even though this should be dead code. + */ + + pending = atomic_read(&rtl->pending.count); @@ -20501,7 +20586,7 @@ index 000000000000..f47bd949b6c3 +} diff --git a/drivers/misc/surface_aggregator/ssh_request_layer.h b/drivers/misc/surface_aggregator/ssh_request_layer.h new file mode 100644 -index 000000000000..e945e0532628 +index 000000000000..4fcdd0bda4d4 --- /dev/null +++ b/drivers/misc/surface_aggregator/ssh_request_layer.h @@ -0,0 +1,142 @@ @@ -20564,7 +20649,7 @@ index 000000000000..e945e0532628 + * @tx: Transmitter subsystem. + * @tx.work: Transmitter work item. + * @rtx_timeout: Retransmission timeout subsystem. -+ * @rtx_timeout.timeout: Timeout inverval for retransmission. ++ * @rtx_timeout.timeout: Timeout interval for retransmission. + * @rtx_timeout.expires: Time specifying when the reaper work is next scheduled. + * @rtx_timeout.reaper: Work performing timeout checks and subsequent actions. + * @ops: Request layer operations. @@ -20649,10 +20734,10 @@ index 000000000000..e945e0532628 +#endif /* _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H */ diff --git a/drivers/misc/surface_aggregator/trace.h b/drivers/misc/surface_aggregator/trace.h new file mode 100644 -index 000000000000..232bf1142aae +index 000000000000..fdf415205089 --- /dev/null +++ b/drivers/misc/surface_aggregator/trace.h -@@ -0,0 +1,625 @@ +@@ -0,0 +1,648 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Trace points for SSAM/SSH. @@ -20765,6 +20850,8 @@ index 000000000000..232bf1142aae +{ + char buf[2 * sizeof(void *) + 1]; + ++ BUILD_BUG_ON(ARRAY_SIZE(buf) < SSAM_PTR_UID_LEN); ++ + snprintf(buf, ARRAY_SIZE(buf), "%p", ptr); + memcpy(uid_str, &buf[ARRAY_SIZE(buf) - SSAM_PTR_UID_LEN], + SSAM_PTR_UID_LEN); @@ -20820,8 +20907,8 @@ index 000000000000..232bf1142aae +#endif /* _SURFACE_AGGREGATOR_TRACE_HELPERS */ + +#define ssam_trace_get_command_field_u8(packet, field) \ -+ ((!packet || packet->data.len < SSH_COMMAND_MESSAGE_LENGTH(0)) \ -+ ? 0 : p->data.ptr[SSH_MSGOFFSET_COMMAND(field)]) ++ ((!(packet) || (packet)->data.len < SSH_COMMAND_MESSAGE_LENGTH(0)) \ ++ ? 0 : (packet)->data.ptr[SSH_MSGOFFSET_COMMAND(field)]) + +#define ssam_show_generic_u8_field(value) \ + __print_symbolic(value, \ @@ -21210,28 +21297,49 @@ index 000000000000..232bf1142aae + ) + + -+DECLARE_EVENT_CLASS(ssam_generic_uint_class, -+ TP_PROTO(const char *property, unsigned int value), ++DECLARE_EVENT_CLASS(ssam_pending_class, ++ TP_PROTO(unsigned int pending), + -+ TP_ARGS(property, value), ++ TP_ARGS(pending), + + TP_STRUCT__entry( -+ __field(unsigned int, value) -+ __string(property, property) ++ __field(unsigned int, pending) + ), + + TP_fast_assign( -+ __entry->value = value; -+ __assign_str(property, property); ++ __entry->pending = pending; + ), + -+ TP_printk("%s=%u", __get_str(property), __entry->value) ++ TP_printk("pending=%u", __entry->pending) +); + -+#define DEFINE_SSAM_GENERIC_UINT_EVENT(name) \ -+ DEFINE_EVENT(ssam_generic_uint_class, ssam_##name, \ -+ TP_PROTO(const char *property, unsigned int value), \ -+ TP_ARGS(property, value) \ ++#define DEFINE_SSAM_PENDING_EVENT(name) \ ++ DEFINE_EVENT(ssam_pending_class, ssam_##name, \ ++ TP_PROTO(unsigned int pending), \ ++ TP_ARGS(pending) \ ++ ) ++ ++ ++DECLARE_EVENT_CLASS(ssam_data_class, ++ TP_PROTO(size_t length), ++ ++ TP_ARGS(length), ++ ++ TP_STRUCT__entry( ++ __field(size_t, length) ++ ), ++ ++ TP_fast_assign( ++ __entry->length = length; ++ ), ++ ++ TP_printk("length=%zu", __entry->length) ++); ++ ++#define DEFINE_SSAM_DATA_EVENT(name) \ ++ DEFINE_EVENT(ssam_data_class, ssam_##name, \ ++ TP_PROTO(size_t length), \ ++ TP_ARGS(length) \ + ) + + @@ -21245,20 +21353,20 @@ index 000000000000..232bf1142aae +DEFINE_SSAM_PACKET_EVENT(packet_timeout); +DEFINE_SSAM_PACKET_EVENT(packet_cancel); +DEFINE_SSAM_PACKET_STATUS_EVENT(packet_complete); -+DEFINE_SSAM_GENERIC_UINT_EVENT(ptl_timeout_reap); ++DEFINE_SSAM_PENDING_EVENT(ptl_timeout_reap); + +DEFINE_SSAM_REQUEST_EVENT(request_submit); +DEFINE_SSAM_REQUEST_EVENT(request_timeout); +DEFINE_SSAM_REQUEST_EVENT(request_cancel); +DEFINE_SSAM_REQUEST_STATUS_EVENT(request_complete); -+DEFINE_SSAM_GENERIC_UINT_EVENT(rtl_timeout_reap); ++DEFINE_SSAM_PENDING_EVENT(rtl_timeout_reap); + +DEFINE_SSAM_PACKET_EVENT(ei_tx_drop_ack_packet); +DEFINE_SSAM_PACKET_EVENT(ei_tx_drop_nak_packet); +DEFINE_SSAM_PACKET_EVENT(ei_tx_drop_dsq_packet); +DEFINE_SSAM_PACKET_STATUS_EVENT(ei_tx_fail_write); +DEFINE_SSAM_PACKET_EVENT(ei_tx_corrupt_data); -+DEFINE_SSAM_GENERIC_UINT_EVENT(ei_rx_corrupt_syn); ++DEFINE_SSAM_DATA_EVENT(ei_rx_corrupt_syn); +DEFINE_SSAM_FRAME_EVENT(ei_rx_corrupt_data); +DEFINE_SSAM_REQUEST_EVENT(ei_rx_drop_response); + @@ -21348,7 +21456,7 @@ index 000000000000..8e3e86c7d78c +#endif /* _LINUX_SURFACE_ACPI_NOTIFY_H */ diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h new file mode 100644 -index 000000000000..d128c68c04e0 +index 000000000000..75a6c6440cdc --- /dev/null +++ b/include/linux/surface_aggregator/controller.h @@ -0,0 +1,832 @@ @@ -21461,8 +21569,8 @@ index 000000000000..d128c68c04e0 + + +struct ssam_controller *ssam_get_controller(void); ++struct ssam_controller *ssam_client_bind(struct device *client); +int ssam_client_link(struct ssam_controller *ctrl, struct device *client); -+int ssam_client_bind(struct device *client, struct ssam_controller **ctrl); + +struct device *ssam_controller_device(struct ssam_controller *c); + @@ -21526,9 +21634,9 @@ index 000000000000..d128c68c04e0 + * @rqst: The request. + * @resp: The response buffer. + * -+ * Sets the response buffer ot a synchronous request. This buffer will store -+ * the response of the request after it has been completed. May be %NULL if -+ * no response is expected. ++ * Sets the response buffer of a synchronous request. This buffer will store ++ * the response of the request after it has been completed. May be %NULL if no ++ * response is expected. + */ +static inline void ssam_request_sync_set_resp(struct ssam_request_sync *rqst, + struct ssam_response *resp) @@ -21580,10 +21688,10 @@ index 000000000000..d128c68c04e0 + * @payload_len: The (maximum) request payload length. + * + * Allocates a synchronous request with specified payload length on the stack, -+ * fully intializes it via the provided request specification, submits it, and -+ * finally waits for its completion before returning its status. This helper -+ * macro essentially allocates the request message buffer on the stack and -+ * then calls ssam_request_sync_with_buffer(). ++ * fully initializes it via the provided request specification, submits it, ++ * and finally waits for its completion before returning its status. This ++ * helper macro essentially allocates the request message buffer on the stack ++ * and then calls ssam_request_sync_with_buffer(). + * + * Note: The @payload_len parameter specifies the maximum payload length, used + * for buffer allocation. The actual payload length may be smaller. @@ -21606,7 +21714,7 @@ index 000000000000..d128c68c04e0 + * @args: Arguments for the request function. + * + * Executes the given request function, i.e. calls @request. In case the -+ * request returns %-EREMOTEIO (indicates I/O error) or -%ETIMEDOUT (request ++ * request returns %-EREMOTEIO (indicates I/O error) or %-ETIMEDOUT (request + * or underlying packet timed out), @request will be re-executed again, up to + * @n times in total. + * @@ -22186,7 +22294,7 @@ index 000000000000..d128c68c04e0 +#endif /* _LINUX_SURFACE_AGGREGATOR_CONTROLLER_H */ diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h new file mode 100644 -index 000000000000..64b1299d7bd8 +index 000000000000..fcbc9ed25433 --- /dev/null +++ b/include/linux/surface_aggregator/device.h @@ -0,0 +1,430 @@ @@ -22217,7 +22325,7 @@ index 000000000000..64b1299d7bd8 +/** + * enum ssam_device_domain - SAM device domain. + * @SSAM_DOMAIN_VIRTUAL: Virtual device. -+ * @SSAM_DOMAIN_SERIALHUB: Physical dovice connected via Surface Serial Hub. ++ * @SSAM_DOMAIN_SERIALHUB: Physical device connected via Surface Serial Hub. + */ +enum ssam_device_domain { + SSAM_DOMAIN_VIRTUAL = 0x00, @@ -22510,8 +22618,8 @@ index 000000000000..64b1299d7bd8 + * @drv: The driver managed by this module. + * + * Helper macro to register a SSAM device driver via module_init() and -+ * module_exit(). This macro may only be used once per module and replaces -+ * the afforementioned definitions. ++ * module_exit(). This macro may only be used once per module and replaces the ++ * aforementioned definitions. + */ +#define module_ssam_device_driver(drv) \ + module_driver(drv, ssam_device_driver_register, \ @@ -22622,10 +22730,10 @@ index 000000000000..64b1299d7bd8 +#endif /* _LINUX_SURFACE_AGGREGATOR_DEVICE_H */ diff --git a/include/linux/surface_aggregator/serial_hub.h b/include/linux/surface_aggregator/serial_hub.h new file mode 100644 -index 000000000000..3974535796ca +index 000000000000..e8a51057d098 --- /dev/null +++ b/include/linux/surface_aggregator/serial_hub.h -@@ -0,0 +1,655 @@ +@@ -0,0 +1,671 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Surface Serial Hub (SSH) protocol and communication interface. @@ -22673,8 +22781,8 @@ index 000000000000..3974535796ca +enum ssh_frame_type { + SSH_FRAME_TYPE_DATA_SEQ = 0x80, + SSH_FRAME_TYPE_DATA_NSQ = 0x00, -+ SSH_FRAME_TYPE_ACK = 0x40, -+ SSH_FRAME_TYPE_NAK = 0x04, ++ SSH_FRAME_TYPE_ACK = 0x40, ++ SSH_FRAME_TYPE_NAK = 0x04, +}; + +/** @@ -22757,7 +22865,7 @@ index 000000000000..3974535796ca +#define SSH_MSG_LEN_CTRL SSH_MSG_LEN_BASE + +/** -+ * SSH_MESSAGE_LENGTH() - Comute length of SSH message. ++ * SSH_MESSAGE_LENGTH() - Compute length of SSH message. + * @payload_size: Length of the payload inside the SSH frame. + * + * Return: Returns the length of a SSH message with payload of specified size. @@ -22780,7 +22888,8 @@ index 000000000000..3974535796ca + * @field: The field for which the offset should be computed. + * + * Return: Returns the offset of the specified &struct ssh_frame field in the -+ * raw SSH message data as. ++ * raw SSH message data as. Takes SYN bytes (u16) preceding the frame into ++ * account. + */ +#define SSH_MSGOFFSET_FRAME(field) \ + (sizeof(u16) + offsetof(struct ssh_frame, field)) @@ -22791,7 +22900,8 @@ index 000000000000..3974535796ca + * @field: The field for which the offset should be computed. + * + * Return: Returns the offset of the specified &struct ssh_command field in -+ * the raw SSH message data. ++ * the raw SSH message data. Takes SYN bytes (u16) preceding the frame and the ++ * frame CRC (u16) between frame and command into account. + */ +#define SSH_MSGOFFSET_COMMAND(field) \ + (2ull * sizeof(u16) + sizeof(struct ssh_frame) \ @@ -22902,8 +23012,18 @@ index 000000000000..3974535796ca + size_t len; +}; + ++/* ++ * Known SSH/EC target categories. ++ * ++ * List of currently known target category values; "Known" as in we know they ++ * exist and are valid on at least some device/model. Detailed functionality ++ * or the full category name is only known for some of these categories and ++ * is detailed in the respective comment below. ++ * ++ * These values and abbreviations have been extracted from strings inside the ++ * Windows driver. ++ */ +enum ssam_ssh_tc { -+ /* Known SSH/EC target categories. */ + // category 0x00 is invalid for EC use + SSAM_SSH_TC_SAM = 0x01, // generic system functionality, real-time clock + SSAM_SSH_TC_BAT = 0x02, // battery/power subsystem @@ -22937,7 +23057,7 @@ index 000000000000..3974535796ca + SSAM_SSH_TC_AUD = 0x1e, + SSAM_SSH_TC_SMC = 0x1f, + SSAM_SSH_TC_KPD = 0x20, -+ SSAM_SSH_TC_REG = 0x21, ++ SSAM_SSH_TC_REG = 0x21, // extended event registry +}; + + @@ -22946,7 +23066,7 @@ index 000000000000..3974535796ca +/** + * enum ssh_packet_base_priority - Base priorities for &struct ssh_packet. + * @SSH_PACKET_PRIORITY_FLUSH: Base priority for flush packets. -+ * @SSH_PACKET_PRIORITY_DATA: Base priority for normal data paackets. ++ * @SSH_PACKET_PRIORITY_DATA: Base priority for normal data packets. + * @SSH_PACKET_PRIORITY_NAK: Base priority for NAK packets. + * @SSH_PACKET_PRIORITY_ACK: Base priority for ACK packets. + */ @@ -23066,7 +23186,8 @@ index 000000000000..3974535796ca + * (or enclosing request) has not been submitted yet. + * @refcnt: Reference count of the packet. + * @priority: Priority of the packet. Must be computed via -+ * SSH_PACKET_PRIORITY(). ++ * SSH_PACKET_PRIORITY(). Must only be accessed while holding the ++ * queue lock after first submission. + * @data: Raw message data. + * @data.len: Length of the raw message data. + * @data.ptr: Pointer to the raw message data buffer. @@ -23076,7 +23197,8 @@ index 000000000000..3974535796ca + * @timestamp: Timestamp specifying when the latest transmission of a + * currently pending packet has been started. May be %KTIME_MAX + * before or in-between transmission attempts. Used for the packet -+ * timeout implementation. ++ * timeout implementation. Must only be accessed while holding the ++ * pending lock after first submission. + * @queue_node: The list node for the packet queue. + * @pending_node: The list node for the set of pending packets. + * @ops: Packet operations. @@ -23181,7 +23303,8 @@ index 000000000000..3974535796ca + * + * In case of failure, the reason for the failure is indicated by + * the value of the provided status code argument (``status``). This -+ * value will be zero in case of success. ++ * value will be zero in case of success and a regular errno ++ * otherwise. + * + * Note that a call to this callback does not guarantee that the + * request is not in use by the transport systems any more. @@ -23200,10 +23323,11 @@ index 000000000000..3974535796ca + * @state: State and type flags describing current request state (dynamic) + * and type (static). See &enum ssh_request_flags for possible + * options. -+ * @timestamp: Timestamp specifying when we start waiting on the respnse of the -+ * request. This is set once the underlying packet has been completed -+ * and may be %KTIME_MAX before that, or when the request does not -+ * expect a response. Used for the request timeout implementation. ++ * @timestamp: Timestamp specifying when we start waiting on the response of ++ * the request. This is set once the underlying packet has been ++ * completed and may be %KTIME_MAX before that, or when the request ++ * does not expect a response. Used for the request timeout ++ * implementation. + * @ops: Request Operations. + */ +struct ssh_request { diff --git a/patches/4.19/0011-surface-typecover.patch b/patches/4.19/0011-surface-typecover.patch index da0d58d42..e681e0a0f 100644 --- a/patches/4.19/0011-surface-typecover.patch +++ b/patches/4.19/0011-surface-typecover.patch @@ -1,4 +1,4 @@ -From 07fc8b6e4a810e568d172a4ea2242d137c310ac5 Mon Sep 17 00:00:00 2001 +From 642ebdc94d0a5fb0b8b462b8caa8430a7b2ca101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Thu, 5 Nov 2020 13:09:45 +0100 Subject: [PATCH] hid/multitouch: Turn off Type Cover keyboard backlight when diff --git a/pkg/arch/kernel-lts/PKGBUILD b/pkg/arch/kernel-lts/PKGBUILD index c10dc02ed..89cca6aec 100644 --- a/pkg/arch/kernel-lts/PKGBUILD +++ b/pkg/arch/kernel-lts/PKGBUILD @@ -42,17 +42,17 @@ sha256sums=('76dca365255c1a13778c3b24f0eae14f4e66bc12fe79f5e6592b116fc57ef755' '4e68572e7cc4c5368f0236e0792660ae8498373988625dca46e509399a7eaea6' 'a13581d3c6dc595206e4fe7fcf6b542e7a1bdbe96101f0f010fc5be49f99baf2' 'dacf6a14239e151bae71587e6e604faeadd1e63975edeba4bb8033806b68c67a' - 'ef2157a661b4cfc7def5bf6f519b8f6b6c186692e6e79f46eb3ee9221ced80db' - '1b764e7da8cea17f4ca9665318bb7a073ba24367d83212d55ddd379af9d457d5' - 'ffd0ee8c0b5a30ca9f2c14903061306bc1e631c90d658fbed6ad7a4d8879c614' - 'cf2692dfcd9034cef980492e75e42e222a72a2fde671e4f08b273ead4fa43ecf' - '6b9d3a1d65d584614dc8f514eead41ee1438af66f8cede987f419ef68d8ff885' - 'dbfcc9f2eaf7c6e0a5b4e7a8b90a9e7b426625b7a6080e4fa49fd8fade9b1813' - 'd97bf509b99e2a430369b93671ab439b9f42da545b3cd2bae594793ff20c74d0' - '4305fd940d8d60c3430f0a1b14026b38ece42a6d6fc7bde25d47d39ada6f3dcd' - 'd4dd34ca7ccfa8def7e619b2729afe71b31207757a95e87719bf37aeae0cec47' - '7be80483baf332f3905b9ce8d81312299428bd53a6b247b42be582b454bf7174' - 'e547e7b175aac69282d902fc06e36c8901dcf0d36417a8563eb8d63467eb5ab0') + '0c3a8f6579e9f127858352eed815325a06056fc22fef18fa2aee208b3d27f990' + 'fe942c357e4d45bbf00f53107888e2523eb2edd85ecac00877bb60ae153b0f3d' + 'f9c577a0ad181d621af2e1022b5ddd7979f3e0b2b94e63ce0d7056aaa887697e' + 'f7efc66bd4db55226138bee4f85c9f16fa39351476e6843d1450fc8aa10a183b' + 'b92983fe29871fe4f722390c8d54c10724980a74070d38338eeb693dd91d26cd' + '50675406cc820aa8a96beb9645d1f14a3f1e31a534bdefd8620cee34fb6ffbbf' + '0272246c9e2730ddf46fb23f5f2ad971d42899fbeec532a6b2c15b07ed78045d' + '7afbd27556c12c6cb54534fd7bf696c8f7857d8ccef09a6b1c7a9f8ef5d0842e' + 'ae22f9b1de06f2ee356abb0e8cb442506c6f2566be3ed878289c061159f8b76a' + '22dd597a01a837e21e6d938934512c490f74871b5b1263f82cb69fc24c730d71' + '5645a2e1f6112b90cbd08813046e43660408689d0f760851a39366142af8bbbe') export KBUILD_BUILD_HOST=archlinux export KBUILD_BUILD_USER=$pkgbase