diff options
Diffstat (limited to 'SOURCES/linux-surface.patch')
-rw-r--r-- | SOURCES/linux-surface.patch | 5051 |
1 files changed, 154 insertions, 4897 deletions
diff --git a/SOURCES/linux-surface.patch b/SOURCES/linux-surface.patch index 5ce705e..64a1d73 100644 --- a/SOURCES/linux-surface.patch +++ b/SOURCES/linux-surface.patch @@ -1,4 +1,4 @@ -From 15edbfd10d016c0003cccf20365043ab8dd7ed77 Mon Sep 17 00:00:00 2001 +From cf081f3ccc47f650f1fa8c2f0a35bacf5b177766 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto <kitakar@gmail.com> Date: Sun, 18 Oct 2020 16:42:44 +0900 Subject: [PATCH] (surface3-oemb) add DMI matches for Surface 3 with broken DMI @@ -58,10 +58,10 @@ index ca4602bcc7de..490b9731068a 100644 { } }; diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c -index 507aba8de3cc..1f8570e04083 100644 +index 8635bc6567dc..436c9ef78cca 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c -@@ -3718,6 +3718,15 @@ static const struct dmi_system_id dmi_platform_data[] = { +@@ -3717,6 +3717,15 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&intel_braswell_platform_data, }, @@ -97,9 +97,9 @@ index 6beb00858c33..d82d77387a0a 100644 }; -- -2.37.3 +2.38.0 -From 09e192fcba3cb0f58014cbc37bbd24fdf0a0f6c7 Mon Sep 17 00:00:00 2001 +From 7877f4ebb43da4625e635c5f1ce491422a50a05a Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto <kitakar@gmail.com> Date: Tue, 29 Sep 2020 17:32:22 +0900 Subject: [PATCH] mwifiex: pcie: add reset_wsid quirk for Surface 3 @@ -129,10 +129,10 @@ Patchset: mwifiex 3 files changed, 99 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c -index d5fb29400bad..033648526f16 100644 +index f7f9277602a5..56ae323ca3b5 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c -@@ -2993,6 +2993,16 @@ static void mwifiex_pcie_card_reset_work(struct mwifiex_adapter *adapter) +@@ -2981,6 +2981,16 @@ static void mwifiex_pcie_card_reset_work(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; @@ -150,12 +150,12 @@ index d5fb29400bad..033648526f16 100644 * can't grab the device lock, maybe we'll get another chance later. */ diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -index 0234cf3c2974..563dd0d5ac79 100644 +index dd6d21f1dbfd..2175358dc65d 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -@@ -15,10 +15,21 @@ - * this warranty disclaimer. - */ +@@ -1,10 +1,21 @@ + // SPDX-License-Identifier: GPL-2.0-only + // NXP Wireless LAN device driver: PCIE and platform specific quirks +#include <linux/acpi.h> #include <linux/dmi.h> @@ -175,7 +175,7 @@ index 0234cf3c2974..563dd0d5ac79 100644 /* quirk table based on DMI matching */ static const struct dmi_system_id mwifiex_quirk_table[] = { { -@@ -87,6 +98,14 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -73,6 +84,14 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { }, .driver_data = (void *)QUIRK_FW_RST_D3COLD, }, @@ -190,7 +190,7 @@ index 0234cf3c2974..563dd0d5ac79 100644 {} }; -@@ -103,6 +122,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) +@@ -89,6 +108,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) dev_info(&pdev->dev, "no quirks enabled\n"); if (card->quirks & QUIRK_FW_RST_D3COLD) dev_info(&pdev->dev, "quirk reset_d3cold enabled\n"); @@ -200,7 +200,7 @@ index 0234cf3c2974..563dd0d5ac79 100644 } static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev) -@@ -159,3 +181,64 @@ int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev) +@@ -145,3 +167,64 @@ int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev) return 0; } @@ -266,10 +266,10 @@ index 0234cf3c2974..563dd0d5ac79 100644 + return 0; +} diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -index 8ec4176d698f..25370c5a4f59 100644 +index d6ff964aec5b..40c95ab24bd7 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -@@ -19,5 +19,11 @@ +@@ -5,5 +5,11 @@ #define QUIRK_FW_RST_D3COLD BIT(0) @@ -282,9 +282,9 @@ index 8ec4176d698f..25370c5a4f59 100644 int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev); +int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev); -- -2.37.3 +2.38.0 -From 7d7aa81c79552938fcab366108fd6cea0d4e1391 Mon Sep 17 00:00:00 2001 +From a752cce0b4ff03b78c53f4f9889a707bf706f9bc Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto <kitakar@gmail.com> Date: Wed, 30 Sep 2020 18:08:24 +0900 Subject: [PATCH] mwifiex: pcie: (OEMB) add quirk for Surface 3 with broken DMI @@ -324,10 +324,10 @@ Patchset: mwifiex 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -index 563dd0d5ac79..32e2f000e57b 100644 +index 2175358dc65d..aec48547a88a 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -@@ -106,6 +106,15 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -92,6 +92,15 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { }, .driver_data = (void *)QUIRK_FW_RST_WSID_S3, }, @@ -344,9 +344,9 @@ index 563dd0d5ac79..32e2f000e57b 100644 }; -- -2.37.3 +2.38.0 -From eac54025ccde2f859610996f4eff5c140551cc02 Mon Sep 17 00:00:00 2001 +From e651da0b596b34da881f2eddb924a36cb31f8ec0 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto <kitakar@gmail.com> Date: Sun, 4 Oct 2020 00:11:49 +0900 Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+ @@ -368,10 +368,10 @@ Patchset: mwifiex 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c -index 033648526f16..ca6bcbe4794c 100644 +index 56ae323ca3b5..3b9a1d97f16e 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c -@@ -380,6 +380,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, +@@ -368,6 +368,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct pcie_service_card *card; @@ -379,7 +379,7 @@ index 033648526f16..ca6bcbe4794c 100644 int ret; pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", -@@ -421,6 +422,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, +@@ -409,6 +410,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, return -1; } @@ -393,10 +393,10 @@ index 033648526f16..ca6bcbe4794c 100644 } diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -index 32e2f000e57b..356401bab59c 100644 +index aec48547a88a..842980db998f 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -@@ -38,7 +38,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -24,7 +24,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"), }, @@ -406,7 +406,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Pro 5", -@@ -47,7 +48,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -33,7 +34,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"), }, @@ -416,7 +416,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Pro 5 (LTE)", -@@ -56,7 +58,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -42,7 +44,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"), }, @@ -426,7 +426,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Pro 6", -@@ -64,7 +67,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -50,7 +53,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"), }, @@ -436,7 +436,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Book 1", -@@ -72,7 +76,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -58,7 +62,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"), }, @@ -446,7 +446,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Book 2", -@@ -80,7 +85,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -66,7 +71,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"), }, @@ -456,7 +456,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Laptop 1", -@@ -88,7 +94,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -74,7 +80,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"), }, @@ -466,7 +466,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface Laptop 2", -@@ -96,7 +103,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -82,7 +89,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"), }, @@ -476,7 +476,7 @@ index 32e2f000e57b..356401bab59c 100644 }, { .ident = "Surface 3", -@@ -134,6 +142,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) +@@ -120,6 +128,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) if (card->quirks & QUIRK_FW_RST_WSID_S3) dev_info(&pdev->dev, "quirk reset_wsid for Surface 3 enabled\n"); @@ -487,10 +487,10 @@ index 32e2f000e57b..356401bab59c 100644 static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -index 25370c5a4f59..a1de111ad1db 100644 +index 40c95ab24bd7..0162eee0ee3c 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -@@ -23,6 +23,7 @@ +@@ -9,6 +9,7 @@ * be handled differently. Currently, only S3 is supported. */ #define QUIRK_FW_RST_WSID_S3 BIT(1) @@ -499,9 +499,9 @@ index 25370c5a4f59..a1de111ad1db 100644 void mwifiex_initialize_quirks(struct pcie_service_card *card); int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev); -- -2.37.3 +2.38.0 -From 009a7560924e5e43ac5a196af1757cf38ae6644f Mon Sep 17 00:00:00 2001 +From 3bcb56b5f40e4b16ca8eab0b4548008982c93264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl> Date: Tue, 3 Nov 2020 13:28:04 +0100 Subject: [PATCH] mwifiex: Add quirk resetting the PCI bridge on MS Surface @@ -535,10 +535,10 @@ Patchset: mwifiex 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c -index ca6bcbe4794c..24bcd22a2618 100644 +index 3b9a1d97f16e..f2ced269b543 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c -@@ -1781,9 +1781,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) +@@ -1769,9 +1769,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; @@ -561,10 +561,10 @@ index ca6bcbe4794c..24bcd22a2618 100644 if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr | tx_wrap)) { diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -index 356401bab59c..6437f067d07a 100644 +index 842980db998f..dd914393ffcb 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c -@@ -39,7 +39,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -25,7 +25,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -574,7 +574,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Pro 5", -@@ -49,7 +50,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -35,7 +36,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -584,7 +584,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Pro 5 (LTE)", -@@ -59,7 +61,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -45,7 +47,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -594,7 +594,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Pro 6", -@@ -68,7 +71,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -54,7 +57,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -604,7 +604,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Book 1", -@@ -77,7 +81,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -63,7 +67,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -614,7 +614,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Book 2", -@@ -86,7 +91,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -72,7 +77,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -624,7 +624,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Laptop 1", -@@ -95,7 +101,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -81,7 +87,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -634,7 +634,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface Laptop 2", -@@ -104,7 +111,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { +@@ -90,7 +97,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"), }, .driver_data = (void *)(QUIRK_FW_RST_D3COLD | @@ -644,7 +644,7 @@ index 356401bab59c..6437f067d07a 100644 }, { .ident = "Surface 3", -@@ -145,6 +153,8 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) +@@ -131,6 +139,8 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card) if (card->quirks & QUIRK_NO_BRIDGE_D3) dev_info(&pdev->dev, "quirk no_brigde_d3 enabled\n"); @@ -654,10 +654,10 @@ index 356401bab59c..6437f067d07a 100644 static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -index a1de111ad1db..0e429779bb04 100644 +index 0162eee0ee3c..1b7c1e63ac5d 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h -@@ -24,6 +24,7 @@ +@@ -10,6 +10,7 @@ */ #define QUIRK_FW_RST_WSID_S3 BIT(1) #define QUIRK_NO_BRIDGE_D3 BIT(2) @@ -666,9 +666,9 @@ index a1de111ad1db..0e429779bb04 100644 void mwifiex_initialize_quirks(struct pcie_service_card *card); int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev); -- -2.37.3 +2.38.0 -From 65831ef257597e8460c5597705a4f9fab4e40ff1 Mon Sep 17 00:00:00 2001 +From 01adfefa9e7c14a7e77be36d3c5374d252b5de24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl> Date: Thu, 25 Mar 2021 11:33:02 +0100 Subject: [PATCH] Bluetooth: btusb: Lower passive lescan interval on Marvell @@ -704,7 +704,7 @@ Patchset: mwifiex 1 file changed, 15 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c -index aaba2d737178..5d29e592cd34 100644 +index 1bb46cbff0fa..8aa8db5d4cde 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -63,6 +63,7 @@ static struct usb_driver btusb_driver; @@ -723,7 +723,7 @@ index aaba2d737178..5d29e592cd34 100644 /* Intel Bluetooth devices */ { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED }, -@@ -3803,6 +3805,19 @@ static int btusb_probe(struct usb_interface *intf, +@@ -3842,6 +3844,19 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_MARVELL) hdev->set_bdaddr = btusb_set_bdaddr_marvell; @@ -744,9 +744,9 @@ index aaba2d737178..5d29e592cd34 100644 (id->driver_info & BTUSB_MEDIATEK)) { hdev->setup = btusb_mtk_setup; -- -2.37.3 +2.38.0 -From c120646a78579db5f700103fc45631153885d055 Mon Sep 17 00:00:00 2001 +From c2ed6cb8f8ff11bb1571797542ae1f863024d2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl> Date: Tue, 10 Nov 2020 12:49:56 +0100 Subject: [PATCH] mwifiex: Use non-posted PCI register writes @@ -784,10 +784,10 @@ Patchset: mwifiex 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c -index 24bcd22a2618..b4ad0113a035 100644 +index f2ced269b543..68f827d34b76 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c -@@ -238,6 +238,12 @@ static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data) +@@ -226,6 +226,12 @@ static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data) iowrite32(data, card->pci_mmap1 + reg); @@ -801,9 +801,9 @@ index 24bcd22a2618..b4ad0113a035 100644 } -- -2.37.3 +2.38.0 -From 8d94818d00f7a3703981bf10a7b915e906d71c05 Mon Sep 17 00:00:00 2001 +From 850913cd3d364fa006bbc63167ee8a044ac10444 Mon Sep 17 00:00:00 2001 From: Maximilian Luz <luzmaximilian@gmail.com> Date: Sat, 27 Feb 2021 00:45:52 +0100 Subject: [PATCH] ath10k: Add module parameters to override board files @@ -825,12 +825,12 @@ Patchset: ath10k 1 file changed, 58 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c -index 688177453b07..e400a0318838 100644 +index d1ac64026cb3..5c883a12d9f8 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -36,6 +36,9 @@ static bool skip_otp; - static bool rawmode; - static bool fw_diag_log; +@@ -38,6 +38,9 @@ static bool fw_diag_log; + /* frame mode values are mapped as per enum ath10k_hw_txrx_mode */ + unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI; +static char *override_board = ""; +static char *override_board2 = ""; @@ -838,8 +838,8 @@ index 688177453b07..e400a0318838 100644 unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) | BIT(ATH10K_FW_CRASH_DUMP_CE_DATA); -@@ -48,6 +51,9 @@ module_param(rawmode, bool, 0644); - module_param(fw_diag_log, bool, 0644); +@@ -50,6 +53,9 @@ module_param(fw_diag_log, bool, 0644); + module_param_named(frame_mode, ath10k_frame_mode, uint, 0644); module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444); +module_param(override_board, charp, 0644); @@ -848,7 +848,7 @@ index 688177453b07..e400a0318838 100644 MODULE_PARM_DESC(debug_mask, "Debugging mask"); MODULE_PARM_DESC(uart_print, "Uart target debugging"); MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); -@@ -56,6 +62,9 @@ MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath"); +@@ -59,6 +65,9 @@ MODULE_PARM_DESC(frame_mode, MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); @@ -858,7 +858,7 @@ index 688177453b07..e400a0318838 100644 static const struct ath10k_hw_params ath10k_hw_params_list[] = { { .id = QCA988X_HW_2_0_VERSION, -@@ -876,6 +885,42 @@ static int ath10k_init_configure_target(struct ath10k *ar) +@@ -895,6 +904,42 @@ static int ath10k_init_configure_target(struct ath10k *ar) return 0; } @@ -901,7 +901,7 @@ index 688177453b07..e400a0318838 100644 static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, const char *dir, const char *file) -@@ -890,6 +935,19 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, +@@ -909,6 +954,19 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, if (dir == NULL) dir = "."; @@ -922,9 +922,9 @@ index 688177453b07..e400a0318838 100644 ret = firmware_request_nowarn(&fw, filename, ar->dev); ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n", -- -2.37.3 +2.38.0 -From 6b96d12b88e324b0f3a69b3c10a1b9e148269729 Mon Sep 17 00:00:00 2001 +From d6c7ff8753ac6460d826d755f1f3e6386105004e Mon Sep 17 00:00:00 2001 From: Dorian Stoll <dorian.stoll@tmsp.io> Date: Thu, 30 Jul 2020 13:21:53 +0200 Subject: [PATCH] misc: mei: Add missing IPTS device IDs @@ -960,9 +960,9 @@ index 5435604327a7..1165ee4f5928 100644 {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)}, -- -2.37.3 +2.38.0 -From 90a5b4768859cfa8beeedb10a3000eb17425171c Mon Sep 17 00:00:00 2001 +From 19a643df0c2269755fe50e53f2bda8bbf02382d4 Mon Sep 17 00:00:00 2001 From: Dorian Stoll <dorian.stoll@tmsp.io> Date: Thu, 6 Aug 2020 11:20:41 +0200 Subject: [PATCH] misc: Add support for Intel Precise Touch & Stylus @@ -973,7 +973,7 @@ Signed-off-by: Dorian Stoll <dorian.stoll@tmsp.io> Patchset: ipts --- drivers/misc/Kconfig | 1 + - drivers/misc/Makefile | 1 + + drivers/misc/Makefile | 3 +- drivers/misc/ipts/Kconfig | 17 ++ drivers/misc/ipts/Makefile | 12 ++ drivers/misc/ipts/context.h | 47 +++++ @@ -987,7 +987,7 @@ Patchset: ipts drivers/misc/ipts/resources.h | 17 ++ drivers/misc/ipts/uapi.c | 208 ++++++++++++++++++++ drivers/misc/ipts/uapi.h | 47 +++++ - 15 files changed, 1327 insertions(+) + 15 files changed, 1328 insertions(+), 1 deletion(-) create mode 100644 drivers/misc/ipts/Kconfig create mode 100644 drivers/misc/ipts/Makefile create mode 100644 drivers/misc/ipts/context.h @@ -1003,23 +1003,26 @@ Patchset: ipts create mode 100644 drivers/misc/ipts/uapi.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 41d2bb0ae23a..effb258d4848 100644 +index 94e9fb4cdd76..12230c71fcf3 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig -@@ -500,4 +500,5 @@ source "drivers/misc/cardreader/Kconfig" +@@ -513,4 +513,5 @@ source "drivers/misc/cardreader/Kconfig" source "drivers/misc/habanalabs/Kconfig" source "drivers/misc/uacce/Kconfig" source "drivers/misc/pvpanic/Kconfig" +source "drivers/misc/ipts/Kconfig" endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 70e800e9127f..a8d1e9447025 100644 +index 2be8542616dd..9e1a97b8c57e 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile -@@ -60,3 +60,4 @@ obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o +@@ -60,4 +60,5 @@ obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o obj-$(CONFIG_OPEN_DICE) += open-dice.o +-obj-$(CONFIG_VCPU_STALL_DETECTOR) += vcpu_stall_detector.o +\ No newline at end of file ++obj-$(CONFIG_VCPU_STALL_DETECTOR) += vcpu_stall_detector.o +obj-$(CONFIG_MISC_IPTS) += ipts/ diff --git a/drivers/misc/ipts/Kconfig b/drivers/misc/ipts/Kconfig new file mode 100644 @@ -2425,9 +2428,9 @@ index 000000000000..53fb86a88f97 + +#endif /* _IPTS_UAPI_H_ */ -- -2.37.3 +2.38.0 -From 44d9467e52b85dfec0b7f18bae811813852b93ff Mon Sep 17 00:00:00 2001 +From 3f3b7b3bf8c60a9212c0cc2c2cf31d9ca763e1cd Mon Sep 17 00:00:00 2001 From: Liban Hannan <liban.p@gmail.com> Date: Tue, 12 Apr 2022 23:31:12 +0100 Subject: [PATCH] iommu: ipts: use IOMMU passthrough mode for IPTS @@ -2449,7 +2452,7 @@ Patchset: ipts 1 file changed, 24 insertions(+) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c -index 5c0dce78586a..825b524e81f3 100644 +index 31bc50e538a3..d8ecca292f93 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -37,6 +37,8 @@ @@ -2461,7 +2464,7 @@ index 5c0dce78586a..825b524e81f3 100644 #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) #define IOAPIC_RANGE_START (0xfee00000) -@@ -307,12 +309,14 @@ int intel_iommu_enabled = 0; +@@ -281,12 +283,14 @@ int intel_iommu_enabled = 0; EXPORT_SYMBOL_GPL(intel_iommu_enabled); static int dmar_map_gfx = 1; @@ -2474,9 +2477,9 @@ index 5c0dce78586a..825b524e81f3 100644 #define IDENTMAP_AZALIA 4 +#define IDENTMAP_IPTS 16 - int intel_iommu_gfx_mapped; - EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped); -@@ -2659,6 +2663,9 @@ static int device_def_domain_type(struct device *dev) + const struct iommu_ops intel_iommu_ops; + +@@ -2602,6 +2606,9 @@ static int device_def_domain_type(struct device *dev) if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev)) return IOMMU_DOMAIN_IDENTITY; @@ -2486,7 +2489,7 @@ index 5c0dce78586a..825b524e81f3 100644 } return 0; -@@ -3095,6 +3102,9 @@ static int __init init_dmars(void) +@@ -2991,6 +2998,9 @@ static int __init init_dmars(void) if (!dmar_map_gfx) iommu_identity_mapping |= IDENTMAP_GFX; @@ -2496,7 +2499,7 @@ index 5c0dce78586a..825b524e81f3 100644 check_tylersburg_isoch(); ret = si_domain_init(hw_pass_through); -@@ -4923,6 +4933,17 @@ static void quirk_iommu_igfx(struct pci_dev *dev) +@@ -4788,6 +4798,17 @@ static void quirk_iommu_igfx(struct pci_dev *dev) dmar_map_gfx = 0; } @@ -2514,7 +2517,7 @@ index 5c0dce78586a..825b524e81f3 100644 /* G4x/GM45 integrated gfx dmar support is totally busted. */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx); -@@ -4958,6 +4979,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); +@@ -4823,6 +4844,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); @@ -2525,4712 +2528,9 @@ index 5c0dce78586a..825b524e81f3 100644 { if (risky_device(dev)) -- -2.37.3 - -From 343924460b3a9020c8e118da7047eaae33043983 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:36 +0200 -Subject: [PATCH] platform/surface: aggregator: Allow is_ssam_device() to be - used when CONFIG_SURFACE_AGGREGATOR_BUS is disabled - -In SSAM subsystem drivers that handle both ACPI and SSAM-native client -devices, we may want to check whether we have a SSAM (native) client -device. Further, we may want to do this even when instantiation thereof -cannot happen due to CONFIG_SURFACE_AGGREGATOR_BUS=n. Currently, doing -so causes an error due to an undefined reference error due to -ssam_device_type being placed in the bus source unit. - -Therefore, if CONFIG_SURFACE_AGGREGATOR_BUS is not defined, simply let -is_ssam_device() return false to prevent this error. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-2-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - include/linux/surface_aggregator/device.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h -index cc257097eb05..62b38b4487eb 100644 ---- a/include/linux/surface_aggregator/device.h -+++ b/include/linux/surface_aggregator/device.h -@@ -177,6 +177,8 @@ struct ssam_device_driver { - void (*remove)(struct ssam_device *sdev); - }; - -+#ifdef CONFIG_SURFACE_AGGREGATOR_BUS -+ - extern struct bus_type ssam_bus_type; - extern const struct device_type ssam_device_type; - -@@ -193,6 +195,15 @@ static inline bool is_ssam_device(struct device *d) - return d->type == &ssam_device_type; - } - -+#else /* CONFIG_SURFACE_AGGREGATOR_BUS */ -+ -+static inline bool is_ssam_device(struct device *d) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_SURFACE_AGGREGATOR_BUS */ -+ - /** - * to_ssam_device() - Casts the given device to a SSAM client device. - * @d: The device to cast. --- -2.37.3 - -From 81b69bf07ee898a7ad0f458e8310f322ac8606e1 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:37 +0200 -Subject: [PATCH] platform/surface: aggregator: Allow devices to be marked as - hot-removed - -Some SSAM devices, notably the keyboard cover (keyboard and touchpad) on -the Surface Pro 8, can be hot-removed. When this occurs, communication -with the device may fail and time out. This timeout can unnecessarily -block and slow down device removal and even cause issues when the -devices are detached and re-attached quickly. Thus, communication should -generally be avoided once hot-removal is detected. - -While we already remove a device as soon as we detect its (hot-)removal, -the corresponding device driver may still attempt to communicate with -the device during teardown. This is especially critical as communication -failure may also extend to disabling of events, which is typically done -at that stage. - -Add a flag to allow marking devices as hot-removed. This can then be -used during client driver teardown to check if any communication -attempts should be avoided. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-3-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - include/linux/surface_aggregator/device.h | 48 +++++++++++++++++++++-- - 1 file changed, 45 insertions(+), 3 deletions(-) - -diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h -index 62b38b4487eb..6df7c8d4e50e 100644 ---- a/include/linux/surface_aggregator/device.h -+++ b/include/linux/surface_aggregator/device.h -@@ -148,17 +148,30 @@ struct ssam_device_uid { - #define SSAM_SDEV(cat, tid, iid, fun) \ - SSAM_DEVICE(SSAM_DOMAIN_SERIALHUB, SSAM_SSH_TC_##cat, tid, iid, fun) - -+/* -+ * enum ssam_device_flags - Flags for SSAM client devices. -+ * @SSAM_DEVICE_HOT_REMOVED_BIT: -+ * The device has been hot-removed. Further communication with it may time -+ * out and should be avoided. -+ */ -+enum ssam_device_flags { -+ SSAM_DEVICE_HOT_REMOVED_BIT = 0, -+}; -+ - /** - * struct ssam_device - SSAM client device. -- * @dev: Driver model representation of the device. -- * @ctrl: SSAM controller managing this device. -- * @uid: UID identifying the device. -+ * @dev: Driver model representation of the device. -+ * @ctrl: SSAM controller managing this device. -+ * @uid: UID identifying the device. -+ * @flags: Device state flags, see &enum ssam_device_flags. - */ - struct ssam_device { - struct device dev; - struct ssam_controller *ctrl; - - struct ssam_device_uid uid; -+ -+ unsigned long flags; - }; - - /** -@@ -251,6 +264,35 @@ struct ssam_device *ssam_device_alloc(struct ssam_controller *ctrl, - int ssam_device_add(struct ssam_device *sdev); - void ssam_device_remove(struct ssam_device *sdev); - -+/** -+ * ssam_device_mark_hot_removed() - Mark the given device as hot-removed. -+ * @sdev: The device to mark as hot-removed. -+ * -+ * Mark the device as having been hot-removed. This signals drivers using the -+ * device that communication with the device should be avoided and may lead to -+ * timeouts. -+ */ -+static inline void ssam_device_mark_hot_removed(struct ssam_device *sdev) -+{ -+ dev_dbg(&sdev->dev, "marking device as hot-removed\n"); -+ set_bit(SSAM_DEVICE_HOT_REMOVED_BIT, &sdev->flags); -+} -+ -+/** -+ * ssam_device_is_hot_removed() - Check if the given device has been -+ * hot-removed. -+ * @sdev: The device to check. -+ * -+ * Checks if the given device has been marked as hot-removed. See -+ * ssam_device_mark_hot_removed() for more details. -+ * -+ * Return: Returns ``true`` if the device has been marked as hot-removed. -+ */ -+static inline bool ssam_device_is_hot_removed(struct ssam_device *sdev) -+{ -+ return test_bit(SSAM_DEVICE_HOT_REMOVED_BIT, &sdev->flags); -+} -+ - /** - * ssam_device_get() - Increment reference count of SSAM client device. - * @sdev: The device to increment the reference count of. --- -2.37.3 - -From 8541ae8819b1d7461fc970542261345446e82b7e Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:38 +0200 -Subject: [PATCH] platform/surface: aggregator: Allow notifiers to avoid - communication on unregistering - -When SSAM client devices have been (physically) hot-removed, -communication attempts with those devices may fail and time out. This -can even extend to event notifiers, due to which timeouts may occur -during device removal, slowing down that process. - -Add a parameter to the notifier unregister function that allows skipping -communication with the EC to prevent this. Furthermore, add wrappers for -registering and unregistering notifiers belonging to SSAM client devices -that automatically check if the device has been marked as hot-removed -and communication should be avoided. - -Note that non-SSAM client devices can generally not be hot-removed, so -also add a convenience wrapper for those, defaulting to allow -communication. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-4-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - .../driver-api/surface_aggregator/client.rst | 6 +- - .../platform/surface/aggregator/controller.c | 53 ++++++++++----- - include/linux/surface_aggregator/controller.h | 24 ++++++- - include/linux/surface_aggregator/device.h | 66 +++++++++++++++++++ - 4 files changed, 128 insertions(+), 21 deletions(-) - -diff --git a/Documentation/driver-api/surface_aggregator/client.rst b/Documentation/driver-api/surface_aggregator/client.rst -index e519d374c378..27f95abdbe99 100644 ---- a/Documentation/driver-api/surface_aggregator/client.rst -+++ b/Documentation/driver-api/surface_aggregator/client.rst -@@ -17,6 +17,8 @@ - .. |SSAM_DEVICE| replace:: :c:func:`SSAM_DEVICE` - .. |ssam_notifier_register| replace:: :c:func:`ssam_notifier_register` - .. |ssam_notifier_unregister| replace:: :c:func:`ssam_notifier_unregister` -+.. |ssam_device_notifier_register| replace:: :c:func:`ssam_device_notifier_register` -+.. |ssam_device_notifier_unregister| replace:: :c:func:`ssam_device_notifier_unregister` - .. |ssam_request_sync| replace:: :c:func:`ssam_request_sync` - .. |ssam_event_mask| replace:: :c:type:`enum ssam_event_mask <ssam_event_mask>` - -@@ -312,7 +314,9 @@ Handling Events - To receive events from the SAM EC, an event notifier must be registered for - the desired event via |ssam_notifier_register|. The notifier must be - unregistered via |ssam_notifier_unregister| once it is not required any --more. -+more. For |ssam_device| type clients, the |ssam_device_notifier_register| and -+|ssam_device_notifier_unregister| wrappers should be preferred as they properly -+handle hot-removal of client devices. - - Event notifiers are registered by providing (at minimum) a callback to call - in case an event has been received, the registry specifying how the event -diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c -index b8c377b3f932..6de834b52b63 100644 ---- a/drivers/platform/surface/aggregator/controller.c -+++ b/drivers/platform/surface/aggregator/controller.c -@@ -2199,16 +2199,26 @@ static int ssam_nf_refcount_enable(struct ssam_controller *ctrl, - } - - /** -- * ssam_nf_refcount_disable_free() - Disable event for reference count entry if it is -- * no longer in use and free the corresponding entry. -+ * ssam_nf_refcount_disable_free() - Disable event for reference count entry if -+ * it is no longer in use and free the corresponding entry. - * @ctrl: The controller to disable the event on. - * @entry: The reference count entry for the event to be disabled. - * @flags: The flags used for enabling the event on the EC. -+ * @ec: Flag specifying if the event should actually be disabled on the EC. - * -- * If the reference count equals zero, i.e. the event is no longer requested by -- * any client, the event will be disabled and the corresponding reference count -- * entry freed. The reference count entry must not be used any more after a -- * call to this function. -+ * If ``ec`` equals ``true`` and the reference count equals zero (i.e. the -+ * event is no longer requested by any client), the specified event will be -+ * disabled on the EC via the corresponding request. -+ * -+ * If ``ec`` equals ``false``, no request will be sent to the EC and the event -+ * can be considered in a detached state (i.e. no longer used but still -+ * enabled). Disabling an event via this method may be required for -+ * hot-removable devices, where event disable requests may time out after the -+ * device has been physically removed. -+ * -+ * In both cases, if the reference count equals zero, the corresponding -+ * reference count entry will be freed. The reference count entry must not be -+ * used any more after a call to this function. - * - * Also checks if the flags used for disabling the event match the flags used - * for enabling the event and warns if they do not (regardless of reference -@@ -2223,7 +2233,7 @@ static int ssam_nf_refcount_enable(struct ssam_controller *ctrl, - * returns the status of the event-enable EC command. - */ - static int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl, -- struct ssam_nf_refcount_entry *entry, u8 flags) -+ struct ssam_nf_refcount_entry *entry, u8 flags, bool ec) - { - const struct ssam_event_registry reg = entry->key.reg; - const struct ssam_event_id id = entry->key.id; -@@ -2232,8 +2242,9 @@ static int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl, - - lockdep_assert_held(&nf->lock); - -- ssam_dbg(ctrl, "disabling event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n", -- reg.target_category, id.target_category, id.instance, entry->refcount); -+ ssam_dbg(ctrl, "%s event (reg: %#04x, tc: %#04x, iid: %#04x, rc: %d)\n", -+ ec ? "disabling" : "detaching", reg.target_category, id.target_category, -+ id.instance, entry->refcount); - - if (entry->flags != flags) { - ssam_warn(ctrl, -@@ -2242,7 +2253,7 @@ static int ssam_nf_refcount_disable_free(struct ssam_controller *ctrl, - id.instance); - } - -- if (entry->refcount == 0) { -+ if (ec && entry->refcount == 0) { - status = ssam_ssh_event_disable(ctrl, reg, id, flags); - kfree(entry); - } -@@ -2322,20 +2333,26 @@ int ssam_notifier_register(struct ssam_controller *ctrl, struct ssam_event_notif - EXPORT_SYMBOL_GPL(ssam_notifier_register); - - /** -- * ssam_notifier_unregister() - Unregister an event notifier. -- * @ctrl: The controller the notifier has been registered on. -- * @n: The event notifier to unregister. -+ * __ssam_notifier_unregister() - Unregister an event notifier. -+ * @ctrl: The controller the notifier has been registered on. -+ * @n: The event notifier to unregister. -+ * @disable: Whether to disable the corresponding event on the EC. - * - * Unregister an event notifier. Decrement the usage counter of the associated - * SAM event if the notifier is not marked as an observer. If the usage counter -- * reaches zero, the event will be disabled. -+ * reaches zero and ``disable`` equals ``true``, the event will be disabled. -+ * -+ * Useful for hot-removable devices, where communication may fail once the -+ * device has been physically removed. In that case, specifying ``disable`` as -+ * ``false`` avoids communication with the EC. - * - * Return: Returns zero on success, %-ENOENT if the given notifier block has - * not been registered on the controller. If the given notifier block was the - * last one associated with its specific event, returns the status of the - * event-disable EC-command. - */ --int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_notifier *n) -+int __ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_notifier *n, -+ bool disable) - { - u16 rqid = ssh_tc_to_rqid(n->event.id.target_category); - struct ssam_nf_refcount_entry *entry; -@@ -2373,7 +2390,7 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_not - goto remove; - } - -- status = ssam_nf_refcount_disable_free(ctrl, entry, n->event.flags); -+ status = ssam_nf_refcount_disable_free(ctrl, entry, n->event.flags, disable); - } - - remove: -@@ -2383,7 +2400,7 @@ int ssam_notifier_unregister(struct ssam_controller *ctrl, struct ssam_event_not - - return status; - } --EXPORT_SYMBOL_GPL(ssam_notifier_unregister); -+EXPORT_SYMBOL_GPL(__ssam_notifier_unregister); - - /** - * ssam_controller_event_enable() - Enable the specified event. -@@ -2477,7 +2494,7 @@ int ssam_controller_event_disable(struct ssam_controller *ctrl, - return -ENOENT; - } - -- status = ssam_nf_refcount_disable_free(ctrl, entry, flags); -+ status = ssam_nf_refcount_disable_free(ctrl, entry, flags, true); - - mutex_unlock(&nf->lock); - return status; -diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h -index 74bfdffaf7b0..50a2b4926c06 100644 ---- a/include/linux/surface_aggregator/controller.h -+++ b/include/linux/surface_aggregator/controller.h -@@ -835,8 +835,28 @@ struct ssam_event_notifier { - int ssam_notifier_register(struct ssam_controller *ctrl, - struct ssam_event_notifier *n); - --int ssam_notifier_unregister(struct ssam_controller *ctrl, -- struct ssam_event_notifier *n); -+int __ssam_notifier_unregister(struct ssam_controller *ctrl, -+ struct ssam_event_notifier *n, bool disable); -+ -+/** -+ * ssam_notifier_unregister() - Unregister an event notifier. -+ * @ctrl: The controller the notifier has been registered on. -+ * @n: The event notifier to unregister. -+ * -+ * Unregister an event notifier. Decrement the usage counter of the associated -+ * SAM event if the notifier is not marked as an observer. If the usage counter -+ * reaches zero, the event will be disabled. -+ * -+ * Return: Returns zero on success, %-ENOENT if the given notifier block has -+ * not been registered on the controller. If the given notifier block was the -+ * last one associated with its specific event, returns the status of the -+ * event-disable EC-command. -+ */ -+static inline int ssam_notifier_unregister(struct ssam_controller *ctrl, -+ struct ssam_event_notifier *n) -+{ -+ return __ssam_notifier_unregister(ctrl, n, true); -+} - - int ssam_controller_event_enable(struct ssam_controller *ctrl, - struct ssam_event_registry reg, -diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h -index 6df7c8d4e50e..c418f7f2732d 100644 ---- a/include/linux/surface_aggregator/device.h -+++ b/include/linux/surface_aggregator/device.h -@@ -483,4 +483,70 @@ static inline void ssam_remove_clients(struct device *dev) {} - sdev->uid.instance, ret); \ - } - -+ -+/* -- Helpers for client-device notifiers. ---------------------------------- */ -+ -+/** -+ * ssam_device_notifier_register() - Register an event notifier for the -+ * specified client device. -+ * @sdev: The device the notifier should be registered on. -+ * @n: The event notifier to register. -+ * -+ * Register an event notifier. Increment the usage counter of the associated -+ * SAM event if the notifier is not marked as an observer. If the event is not -+ * marked as an observer and is currently not enabled, it will be enabled -+ * during this call. If the notifier is marked as an observer, no attempt will -+ * be made at enabling any event and no reference count will be modified. -+ * -+ * Notifiers marked as observers do not need to be associated with one specific -+ * event, i.e. as long as no event matching is performed, only the event target -+ * category needs to be set. -+ * -+ * Return: Returns zero on success, %-ENOSPC if there have already been -+ * %INT_MAX notifiers for the event ID/type associated with the notifier block -+ * registered, %-ENOMEM if the corresponding event entry could not be -+ * allocated, %-ENODEV if the device is marked as hot-removed. If this is the -+ * first time that a notifier block is registered for the specific associated -+ * event, returns the status of the event-enable EC-command. -+ */ -+static inline int ssam_device_notifier_register(struct ssam_device *sdev, -+ struct ssam_event_notifier *n) -+{ -+ /* -+ * Note that this check does not provide any guarantees whatsoever as -+ * hot-removal could happen at any point and we can't protect against -+ * it. Nevertheless, if we can detect hot-removal, bail early to avoid -+ * communication timeouts. -+ */ -+ if (ssam_device_is_hot_removed(sdev)) -+ return -ENODEV; -+ -+ return ssam_notifier_register(sdev->ctrl, n); -+} -+ -+/** -+ * ssam_device_notifier_unregister() - Unregister an event notifier for the -+ * specified client device. -+ * @sdev: The device the notifier has been registered on. -+ * @n: The event notifier to unregister. -+ * -+ * Unregister an event notifier. Decrement the usage counter of the associated -+ * SAM event if the notifier is not marked as an observer. If the usage counter -+ * reaches zero, the event will be disabled. -+ * -+ * In case the device has been marked as hot-removed, the event will not be -+ * disabled on the EC, as in those cases any attempt at doing so may time out. -+ * -+ * Return: Returns zero on success, %-ENOENT if the given notifier block has -+ * not been registered on the controller. If the given notifier block was the -+ * last one associated with its specific event, returns the status of the -+ * event-disable EC-command. -+ */ -+static inline int ssam_device_notifier_unregister(struct ssam_device *sdev, -+ struct ssam_event_notifier *n) -+{ -+ return __ssam_notifier_unregister(sdev->ctrl, n, -+ !ssam_device_is_hot_removed(sdev)); -+} -+ - #endif /* _LINUX_SURFACE_AGGREGATOR_DEVICE_H */ --- -2.37.3 - -From 5327cf4cbc40cf7a654ed1d826634a565709c73f Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:39 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Use client device - wrappers for notifier registration - -Use newly introduced client device wrapper functions for notifier -registration and unregistration. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-5-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/surface_aggregator_registry.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index ce2bd88feeaa..9f630e890ff7 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -468,7 +468,7 @@ static int ssam_base_hub_probe(struct ssam_device *sdev) - - ssam_device_set_drvdata(sdev, hub); - -- status = ssam_notifier_register(sdev->ctrl, &hub->notif); -+ status = ssam_device_notifier_register(sdev, &hub->notif); - if (status) - return status; - -@@ -480,7 +480,7 @@ static int ssam_base_hub_probe(struct ssam_device *sdev) - return 0; - - err: -- ssam_notifier_unregister(sdev->ctrl, &hub->notif); -+ ssam_device_notifier_unregister(sdev, &hub->notif); - cancel_delayed_work_sync(&hub->update_work); - ssam_remove_clients(&sdev->dev); - return status; -@@ -492,7 +492,7 @@ static void ssam_base_hub_remove(struct ssam_device *sdev) - - sysfs_remove_group(&sdev->dev.kobj, &ssam_base_hub_group); - -- ssam_notifier_unregister(sdev->ctrl, &hub->notif); -+ ssam_device_notifier_unregister(sdev, &hub->notif); - cancel_delayed_work_sync(&hub->update_work); - ssam_remove_clients(&sdev->dev); - } --- -2.37.3 - -From 7e1e2cbb7b039e420c6c55052404417c5bcb14df Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:40 +0200 -Subject: [PATCH] power/supply: surface_charger: Use client device wrappers for - notifier registration - -Use newly introduced client device wrapper functions for notifier -registration and unregistration. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-6-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/power/supply/surface_charger.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/power/supply/surface_charger.c b/drivers/power/supply/surface_charger.c -index a060c36c7766..59182d55742d 100644 ---- a/drivers/power/supply/surface_charger.c -+++ b/drivers/power/supply/surface_charger.c -@@ -216,7 +216,7 @@ static int spwr_ac_register(struct spwr_ac_device *ac) - if (IS_ERR(ac->psy)) - return PTR_ERR(ac->psy); - -- return ssam_notifier_register(ac->sdev->ctrl, &ac->notif); -+ return ssam_device_notifier_register(ac->sdev, &ac->notif); - } - - -@@ -251,7 +251,7 @@ static void surface_ac_remove(struct ssam_device *sdev) - { - struct spwr_ac_device *ac = ssam_device_get_drvdata(sdev); - -- ssam_notifier_unregister(sdev->ctrl, &ac->notif); -+ ssam_device_notifier_unregister(sdev, &ac->notif); - } - - static const struct spwr_psy_properties spwr_psy_props_adp1 = { --- -2.37.3 - -From 6f4e94f193ff0af818c95b26f6ff9fa2ba801480 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:41 +0200 -Subject: [PATCH] power/supply: surface_battery: Use client device wrappers for - notifier registration - -Use newly introduced client device wrapper functions for notifier -registration and unregistration. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-7-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/power/supply/surface_battery.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/power/supply/surface_battery.c b/drivers/power/supply/surface_battery.c -index 5ec2e6bb2465..540707882bb0 100644 ---- a/drivers/power/supply/surface_battery.c -+++ b/drivers/power/supply/surface_battery.c -@@ -802,7 +802,7 @@ static int spwr_battery_register(struct spwr_battery_device *bat) - if (IS_ERR(bat->psy)) - return PTR_ERR(bat->psy); - -- return ssam_notifier_register(bat->sdev->ctrl, &bat->notif); -+ return ssam_device_notifier_register(bat->sdev, &bat->notif); - } - - -@@ -837,7 +837,7 @@ static void surface_battery_remove(struct ssam_device *sdev) - { - struct spwr_battery_device *bat = ssam_device_get_drvdata(sdev); - -- ssam_notifier_unregister(sdev->ctrl, &bat->notif); -+ ssam_device_notifier_unregister(sdev, &bat->notif); - cancel_delayed_work_sync(&bat->update_work); - } - --- -2.37.3 - -From 895fb2dab19c9ab2fe25968f88afe9e250d25e40 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:42 +0200 -Subject: [PATCH] HID: surface-hid: Add support for hot-removal - -Add support for hot-removal of SSAM HID client devices. - -Once a device has been hot-removed, further communication with it should -be avoided as it may fail and time out. While the device will be removed -as soon as we detect hot-removal, communication may still occur during -teardown, especially when unregistering notifiers. - -While hot-removal is a surprise event that can happen at any time, try -to avoid communication as much as possible once it has been detected to -prevent timeouts that can slow down device removal and cause issues, -e.g. when quickly re-attaching the device. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-8-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/hid/surface-hid/surface_hid_core.c | 38 +++++++++++++++++++++- - 1 file changed, 37 insertions(+), 1 deletion(-) - -diff --git a/drivers/hid/surface-hid/surface_hid_core.c b/drivers/hid/surface-hid/surface_hid_core.c -index e46330b2e561..87637f813de2 100644 ---- a/drivers/hid/surface-hid/surface_hid_core.c -+++ b/drivers/hid/surface-hid/surface_hid_core.c -@@ -19,12 +19,30 @@ - #include "surface_hid_core.h" - - -+/* -- Utility functions. ---------------------------------------------------- */ -+ -+static bool surface_hid_is_hot_removed(struct surface_hid_device *shid) -+{ -+ /* -+ * Non-ssam client devices, i.e. platform client devices, cannot be -+ * hot-removed. -+ */ -+ if (!is_ssam_device(shid->dev)) -+ return false; -+ -+ return ssam_device_is_hot_removed(to_ssam_device(shid->dev)); -+} -+ -+ - /* -- Device descriptor access. --------------------------------------------- */ - - static int surface_hid_load_hid_descriptor(struct surface_hid_device *shid) - { - int status; - -+ if (surface_hid_is_hot_removed(shid)) -+ return -ENODEV; -+ - status = shid->ops.get_descriptor(shid, SURFACE_HID_DESC_HID, - (u8 *)&shid->hid_desc, sizeof(shid->hid_desc)); - if (status) -@@ -61,6 +79,9 @@ static int surface_hid_load_device_attributes(struct surface_hid_device *shid) - { - int status; - -+ if (surface_hid_is_hot_removed(shid)) -+ return -ENODEV; -+ - status = shid->ops.get_descriptor(shid, SURFACE_HID_DESC_ATTRS, - (u8 *)&shid->attrs, sizeof(shid->attrs)); - if (status) -@@ -88,9 +109,18 @@ static int surface_hid_start(struct hid_device *hid) - static void surface_hid_stop(struct hid_device *hid) - { - struct surface_hid_device *shid = hid->driver_data; -+ bool hot_removed; -+ -+ /* -+ * Communication may fail for devices that have been hot-removed. This -+ * also includes unregistration of HID events, so we need to check this -+ * here. Only if the device has not been marked as hot-removed, we can -+ * safely disable events. -+ */ -+ hot_removed = surface_hid_is_hot_removed(shid); - - /* Note: This call will log errors for us, so ignore them here. */ -- ssam_notifier_unregister(shid->ctrl, &shid->notif); -+ __ssam_notifier_unregister(shid->ctrl, &shid->notif, !hot_removed); - } - - static int surface_hid_open(struct hid_device *hid) -@@ -109,6 +139,9 @@ static int surface_hid_parse(struct hid_device *hid) - u8 *buf; - int status; - -+ if (surface_hid_is_hot_removed(shid)) -+ return -ENODEV; -+ - buf = kzalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; -@@ -126,6 +159,9 @@ static int surface_hid_raw_request(struct hid_device *hid, unsigned char reportn - { - struct surface_hid_device *shid = hid->driver_data; - -+ if (surface_hid_is_hot_removed(shid)) -+ return -ENODEV; -+ - if (rtype == HID_OUTPUT_REPORT && reqtype == HID_REQ_SET_REPORT) - return shid->ops.output_report(shid, reportnum, buf, len); - --- -2.37.3 - -From 2a2d9f4bd42194af647055b3e176ecb9ec7aeeec Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:43 +0200 -Subject: [PATCH] platform/surface: aggregator: Add comment for KIP subsystem - category - -The KIP subsystem (full name unknown, abbreviation has been obtained -through reverse engineering) handles detachable peripherals such as the -keyboard cover on the Surface Pro X and Surface Pro 8. - -It is currently not entirely clear what this subsystem entails, but at -the very least it provides event notifications for when the keyboard -cover on the Surface Pro X and Surface Pro 8 have been detached or -re-attached, as well as the state that the keyboard cover is currently -in (e.g. folded-back, folded laptop-like, closed, etc.). - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-9-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - include/linux/surface_aggregator/serial_hub.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/linux/surface_aggregator/serial_hub.h b/include/linux/surface_aggregator/serial_hub.h -index c3de43edcffa..26b95ec12733 100644 ---- a/include/linux/surface_aggregator/serial_hub.h -+++ b/include/linux/surface_aggregator/serial_hub.h -@@ -306,7 +306,7 @@ enum ssam_ssh_tc { - SSAM_SSH_TC_LPC = 0x0b, - SSAM_SSH_TC_TCL = 0x0c, - SSAM_SSH_TC_SFL = 0x0d, -- SSAM_SSH_TC_KIP = 0x0e, -+ SSAM_SSH_TC_KIP = 0x0e, /* Manages detachable peripherals (Pro X/8 keyboard cover) */ - SSAM_SSH_TC_EXT = 0x0f, - SSAM_SSH_TC_BLD = 0x10, - SSAM_SSH_TC_BAS = 0x11, /* Detachment system (Surface Book 2/3). */ --- -2.37.3 - -From a5c7fa614688bf6a42b2391d87f9709a30c62d45 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:44 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Generify subsystem hub - functionality - -The Surface System Aggregator Module (SSAM) has multiple subsystems that -can manage detachable devices. At the moment, we only support the "base" -(BAS/0x11) subsystem, which is used on the Surface Book 3 to manage -devices (including keyboard, touchpad, and secondary battery) connected -to the base of the device. - -The Surface Pro 8 has a new type-cover with keyboard and touchpad, which -is managed via the KIP/0x0e subsystem. The general procedure is the -same, but with slightly different events and setup. To make -implementation of the KIP hub easier and prevent duplication, generify -the parts of the base hub that we can use for the KIP hub (or any -potential future subsystem hubs). - -This also switches over to use the newly introduced "hot-remove" -functionality, which should prevent communication issues when devices -have been detached. - -Lastly, also drop the undocumented and unused sysfs "state" attribute of -the base hub. It has at best been useful for debugging. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-10-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - .../surface/surface_aggregator_registry.c | 269 ++++++++++-------- - 1 file changed, 153 insertions(+), 116 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 9f630e890ff7..09cbeee2428b 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -308,30 +308,159 @@ static int ssam_hub_register_clients(struct device *parent, struct ssam_controll - } - - --/* -- SSAM base-hub driver. ------------------------------------------------- */ -+/* -- SSAM generic subsystem hub driver framework. -------------------------- */ - --/* -- * Some devices (especially battery) may need a bit of time to be fully usable -- * after being (re-)connected. This delay has been determined via -- * experimentation. -- */ --#define SSAM_BASE_UPDATE_CONNECT_DELAY msecs_to_jiffies(2500) -+enum ssam_hub_state { -+ SSAM_HUB_UNINITIALIZED, /* Only set during initialization. */ -+ SSAM_HUB_CONNECTED, -+ SSAM_HUB_DISCONNECTED, -+}; - --enum ssam_base_hub_state { -- SSAM_BASE_HUB_UNINITIALIZED, -- SSAM_BASE_HUB_CONNECTED, -- SSAM_BASE_HUB_DISCONNECTED, -+enum ssam_hub_flags { -+ SSAM_HUB_HOT_REMOVED, - }; - --struct ssam_base_hub { -+struct ssam_hub { - struct ssam_device *sdev; - -- enum ssam_base_hub_state state; -+ enum ssam_hub_state state; -+ unsigned long flags; -+ - struct delayed_work update_work; -+ unsigned long connect_delay; - - struct ssam_event_notifier notif; -+ -+ int (*get_state)(struct ssam_hub *hub, enum ssam_hub_state *state); - }; - -+static void ssam_hub_update_workfn(struct work_struct *work) -+{ -+ struct ssam_hub *hub = container_of(work, struct ssam_hub, update_work.work); -+ struct fwnode_handle *node = dev_fwnode(&hub->sdev->dev); -+ enum ssam_hub_state state; -+ int status = 0; -+ -+ status = hub->get_state(hub, &state); -+ if (status) -+ return; -+ -+ /* -+ * There is a small possibility that hub devices were hot-removed and -+ * re-added before we were able to remove them here. In that case, both -+ * the state returned by get_state() and the state of the hub will -+ * equal SSAM_HUB_CONNECTED and we would bail early below, which would -+ * leave child devices without proper (re-)initialization and the -+ * hot-remove flag set. -+ * -+ * Therefore, we check whether devices have been hot-removed via an -+ * additional flag on the hub and, in this case, override the returned -+ * hub state. In case of a missed disconnect (i.e. get_state returned -+ * "connected"), we further need to re-schedule this work (with the -+ * appropriate delay) as the actual connect work submission might have -+ * been merged with this one. -+ * -+ * This then leads to one of two cases: Either we submit an unnecessary -+ * work item (which will get ignored via either the queue or the state -+ * checks) or, in the unlikely case that the work is actually required, -+ * double the normal connect delay. -+ */ -+ if (test_and_clear_bit(SSAM_HUB_HOT_REMOVED, &hub->flags)) { -+ if (state == SSAM_HUB_CONNECTED) -+ schedule_delayed_work(&hub->update_work, hub->connect_delay); -+ -+ state = SSAM_HUB_DISCONNECTED; -+ } -+ -+ if (hub->state == state) -+ return; -+ hub->state = state; -+ -+ if (hub->state == SSAM_HUB_CONNECTED) -+ status = ssam_hub_register_clients(&hub->sdev->dev, hub->sdev->ctrl, node); -+ else -+ ssam_remove_clients(&hub->sdev->dev); -+ -+ if (status) -+ dev_err(&hub->sdev->dev, "failed to update hub child devices: %d\n", status); -+} -+ -+static int ssam_hub_mark_hot_removed(struct device *dev, void *_data) -+{ -+ struct ssam_device *sdev = to_ssam_device(dev); -+ -+ if (is_ssam_device(dev)) -+ ssam_device_mark_hot_removed(sdev); -+ -+ return 0; -+} -+ -+static void ssam_hub_update(struct ssam_hub *hub, bool connected) -+{ -+ unsigned long delay; -+ -+ /* Mark devices as hot-removed before we remove any. */ -+ if (!connected) { -+ set_bit(SSAM_HUB_HOT_REMOVED, &hub->flags); -+ device_for_each_child_reverse(&hub->sdev->dev, NULL, ssam_hub_mark_hot_removed); -+ } -+ -+ /* -+ * Delay update when the base/keyboard cover is being connected to give -+ * devices/EC some time to set up. -+ */ -+ delay = connected ? hub->connect_delay : 0; -+ -+ schedule_delayed_work(&hub->update_work, delay); -+} -+ -+static int __maybe_unused ssam_hub_resume(struct device *dev) -+{ -+ struct ssam_hub *hub = dev_get_drvdata(dev); -+ -+ schedule_delayed_work(&hub->update_work, 0); -+ return 0; -+} -+static SIMPLE_DEV_PM_OPS(ssam_hub_pm_ops, NULL, ssam_hub_resume); -+ -+static int ssam_hub_setup(struct ssam_device *sdev, struct ssam_hub *hub) -+{ -+ int status; -+ -+ hub->sdev = sdev; -+ hub->state = SSAM_HUB_UNINITIALIZED; -+ -+ INIT_DELAYED_WORK(&hub->update_work, ssam_hub_update_workfn); -+ -+ ssam_device_set_drvdata(sdev, hub); -+ -+ status = ssam_device_notifier_register(sdev, &hub->notif); -+ if (status) -+ return status; -+ -+ schedule_delayed_work(&hub->update_work, 0); -+ return 0; -+} -+ -+static void ssam_hub_remove(struct ssam_device *sdev) -+{ -+ struct ssam_hub *hub = ssam_device_get_drvdata(sdev); -+ -+ ssam_device_notifier_unregister(sdev, &hub->notif); -+ cancel_delayed_work_sync(&hub->update_work); -+ ssam_remove_clients(&sdev->dev); -+} -+ -+ -+/* -- SSAM base-hub driver. ------------------------------------------------- */ -+ -+/* -+ * Some devices (especially battery) may need a bit of time to be fully usable -+ * after being (re-)connected. This delay has been determined via -+ * experimentation. -+ */ -+#define SSAM_BASE_UPDATE_CONNECT_DELAY msecs_to_jiffies(2500) -+ - SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_query_opmode, u8, { - .target_category = SSAM_SSH_TC_BAS, - .target_id = 0x01, -@@ -342,7 +471,7 @@ SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_query_opmode, u8, { - #define SSAM_BAS_OPMODE_TABLET 0x00 - #define SSAM_EVENT_BAS_CID_CONNECTION 0x0c - --static int ssam_base_hub_query_state(struct ssam_base_hub *hub, enum ssam_base_hub_state *state) -+static int ssam_base_hub_query_state(struct ssam_hub *hub, enum ssam_hub_state *state) - { - u8 opmode; - int status; -@@ -354,62 +483,16 @@ static int ssam_base_hub_query_state(struct ssam_base_hub *hub, enum ssam_base_h - } - - if (opmode != SSAM_BAS_OPMODE_TABLET) -- *state = SSAM_BASE_HUB_CONNECTED; -+ *state = SSAM_HUB_CONNECTED; - else -- *state = SSAM_BASE_HUB_DISCONNECTED; -+ *state = SSAM_HUB_DISCONNECTED; - - return 0; - } - --static ssize_t ssam_base_hub_state_show(struct device *dev, struct device_attribute *attr, -- char *buf) --{ -- struct ssam_base_hub *hub = dev_get_drvdata(dev); -- bool connected = hub->state == SSAM_BASE_HUB_CONNECTED; -- -- return sysfs_emit(buf, "%d\n", connected); --} -- --static struct device_attribute ssam_base_hub_attr_state = -- __ATTR(state, 0444, ssam_base_hub_state_show, NULL); -- --static struct attribute *ssam_base_hub_attrs[] = { -- &ssam_base_hub_attr_state.attr, -- NULL, --}; -- --static const struct attribute_group ssam_base_hub_group = { -- .attrs = ssam_base_hub_attrs, --}; -- --static void ssam_base_hub_update_workfn(struct work_struct *work) --{ -- struct ssam_base_hub *hub = container_of(work, struct ssam_base_hub, update_work.work); -- struct fwnode_handle *node = dev_fwnode(&hub->sdev->dev); -- enum ssam_base_hub_state state; -- int status = 0; -- -- status = ssam_base_hub_query_state(hub, &state); -- if (status) -- return; -- -- if (hub->state == state) -- return; -- hub->state = state; -- -- if (hub->state == SSAM_BASE_HUB_CONNECTED) -- status = ssam_hub_register_clients(&hub->sdev->dev, hub->sdev->ctrl, node); -- else -- ssam_remove_clients(&hub->sdev->dev); -- -- if (status) -- dev_err(&hub->sdev->dev, "failed to update base-hub devices: %d\n", status); --} -- - static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) - { -- struct ssam_base_hub *hub = container_of(nf, struct ssam_base_hub, notif); -- unsigned long delay; -+ struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif); - - if (event->command_id != SSAM_EVENT_BAS_CID_CONNECTION) - return 0; -@@ -419,13 +502,7 @@ static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam - return 0; - } - -- /* -- * Delay update when the base is being connected to give devices/EC -- * some time to set up. -- */ -- delay = event->data[0] ? SSAM_BASE_UPDATE_CONNECT_DELAY : 0; -- -- schedule_delayed_work(&hub->update_work, delay); -+ ssam_hub_update(hub, event->data[0]); - - /* - * Do not return SSAM_NOTIF_HANDLED: The event should be picked up and -@@ -435,27 +512,14 @@ static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam - return 0; - } - --static int __maybe_unused ssam_base_hub_resume(struct device *dev) --{ -- struct ssam_base_hub *hub = dev_get_drvdata(dev); -- -- schedule_delayed_work(&hub->update_work, 0); -- return 0; --} --static SIMPLE_DEV_PM_OPS(ssam_base_hub_pm_ops, NULL, ssam_base_hub_resume); -- - static int ssam_base_hub_probe(struct ssam_device *sdev) - { -- struct ssam_base_hub *hub; -- int status; -+ struct ssam_hub *hub; - - hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL); - if (!hub) - return -ENOMEM; - -- hub->sdev = sdev; -- hub->state = SSAM_BASE_HUB_UNINITIALIZED; -- - hub->notif.base.priority = INT_MAX; /* This notifier should run first. */ - hub->notif.base.fn = ssam_base_hub_notif; - hub->notif.event.reg = SSAM_EVENT_REGISTRY_SAM; -@@ -464,37 +528,10 @@ static int ssam_base_hub_probe(struct ssam_device *sdev) - hub->notif.event.mask = SSAM_EVENT_MASK_NONE; - hub->notif.event.flags = SSAM_EVENT_SEQUENCED; - -- INIT_DELAYED_WORK(&hub->update_work, ssam_base_hub_update_workfn); -- -- ssam_device_set_drvdata(sdev, hub); -- -- status = ssam_device_notifier_register(sdev, &hub->notif); -- if (status) -- return status; -- -- status = sysfs_create_group(&sdev->dev.kobj, &ssam_base_hub_group); -- if (status) -- goto err; -- -- schedule_delayed_work(&hub->update_work, 0); -- return 0; -+ hub->connect_delay = SSAM_BASE_UPDATE_CONNECT_DELAY; -+ hub->get_state = ssam_base_hub_query_state; - --err: -- ssam_device_notifier_unregister(sdev, &hub->notif); -- cancel_delayed_work_sync(&hub->update_work); -- ssam_remove_clients(&sdev->dev); -- return status; --} -- --static void ssam_base_hub_remove(struct ssam_device *sdev) --{ -- struct ssam_base_hub *hub = ssam_device_get_drvdata(sdev); -- -- sysfs_remove_group(&sdev->dev.kobj, &ssam_base_hub_group); -- -- ssam_device_notifier_unregister(sdev, &hub->notif); -- cancel_delayed_work_sync(&hub->update_work); -- ssam_remove_clients(&sdev->dev); -+ return ssam_hub_setup(sdev, hub); - } - - static const struct ssam_device_id ssam_base_hub_match[] = { -@@ -504,12 +541,12 @@ static const struct ssam_device_id ssam_base_hub_match[] = { - - static struct ssam_device_driver ssam_base_hub_driver = { - .probe = ssam_base_hub_probe, -- .remove = ssam_base_hub_remove, -+ .remove = ssam_hub_remove, - .match_table = ssam_base_hub_match, - .driver = { - .name = "surface_aggregator_base_hub", - .probe_type = PROBE_PREFER_ASYNCHRONOUS, -- .pm = &ssam_base_hub_pm_ops, -+ .pm = &ssam_hub_pm_ops, - }, - }; - --- -2.37.3 - -From 914afdc9a4ddd402904039546ac2f1161a5535a2 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:45 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Change device ID for - base hub - -Use the target category of the (base) hub as instance id in the -(virtual) hub device UID. This makes association of the hub with the -respective subsystem easier. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-11-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/surface_aggregator_registry.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 09cbeee2428b..b11ce87c7184 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -43,7 +43,7 @@ static const struct software_node ssam_node_root = { - - /* Base device hub (devices attached to Surface Book 3 base). */ - static const struct software_node ssam_node_hub_base = { -- .name = "ssam:00:00:02:00:00", -+ .name = "ssam:00:00:02:11:00", - .parent = &ssam_node_root, - }; - -@@ -535,7 +535,7 @@ static int ssam_base_hub_probe(struct ssam_device *sdev) - } - - static const struct ssam_device_id ssam_base_hub_match[] = { -- { SSAM_VDEV(HUB, 0x02, SSAM_ANY_IID, 0x00) }, -+ { SSAM_VDEV(HUB, 0x02, SSAM_SSH_TC_BAS, 0x00) }, - { }, - }; - --- -2.37.3 - -From 07bb747d9ad79840bef5b2f922cc0691ffa3db7e Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:46 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Add KIP device hub - -Add a Surface System Aggregator Module (SSAM) client device hub for -hot-removable devices managed via the KIP subsystem. - -The KIP subsystem (full name unknown, abbreviation has been obtained -through reverse engineering) is a subsystem that manages hot-removable -SSAM client devices. Specifically, it manages HID input devices -contained in the detachable keyboard cover of the Surface Pro 8 and -Surface Pro X. - -The KIP subsystem handles a single group of devices (e.g. all devices -contained in the keyboard cover) and cannot handle devices individually. -Thus we model it as a client device hub, which (hot-)removes all devices -contained under it once removal of the hub (e.g. keyboard cover) has -been detected and (re-)adds all devices once the physical hub device has -been (re-)attached. To do this, use the previously generified SSAM -subsystem hub framework. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-12-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - .../surface/surface_aggregator_registry.c | 103 +++++++++++++++++- - 1 file changed, 101 insertions(+), 2 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index b11ce87c7184..f15cef60630f 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -551,6 +551,93 @@ static struct ssam_device_driver ssam_base_hub_driver = { - }; - - -+/* -- SSAM KIP-subsystem hub driver. ---------------------------------------- */ -+ -+/* -+ * Some devices may need a bit of time to be fully usable after being -+ * (re-)connected. This delay has been determined via experimentation. -+ */ -+#define SSAM_KIP_UPDATE_CONNECT_DELAY msecs_to_jiffies(250) -+ -+#define SSAM_EVENT_KIP_CID_CONNECTION 0x2c -+ -+SSAM_DEFINE_SYNC_REQUEST_R(__ssam_kip_get_connection_state, u8, { -+ .target_category = SSAM_SSH_TC_KIP, -+ .target_id = 0x01, -+ .command_id = 0x2c, -+ .instance_id = 0x00, -+}); -+ -+static int ssam_kip_get_connection_state(struct ssam_hub *hub, enum ssam_hub_state *state) -+{ -+ int status; -+ u8 connected; -+ -+ status = ssam_retry(__ssam_kip_get_connection_state, hub->sdev->ctrl, &connected); -+ if (status < 0) { -+ dev_err(&hub->sdev->dev, "failed to query KIP connection state: %d\n", status); -+ return status; -+ } -+ -+ *state = connected ? SSAM_HUB_CONNECTED : SSAM_HUB_DISCONNECTED; -+ return 0; -+} -+ -+static u32 ssam_kip_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) -+{ -+ struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif); -+ -+ if (event->command_id != SSAM_EVENT_KIP_CID_CONNECTION) -+ return 0; /* Return "unhandled". */ -+ -+ if (event->length < 1) { -+ dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length); -+ return 0; -+ } -+ -+ ssam_hub_update(hub, event->data[0]); -+ return SSAM_NOTIF_HANDLED; -+} -+ -+static int ssam_kip_hub_probe(struct ssam_device *sdev) -+{ -+ struct ssam_hub *hub; -+ -+ hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL); -+ if (!hub) -+ return -ENOMEM; -+ -+ hub->notif.base.priority = INT_MAX; /* This notifier should run first. */ -+ hub->notif.base.fn = ssam_kip_hub_notif; -+ hub->notif.event.reg = SSAM_EVENT_REGISTRY_SAM; -+ hub->notif.event.id.target_category = SSAM_SSH_TC_KIP, -+ hub->notif.event.id.instance = 0, -+ hub->notif.event.mask = SSAM_EVENT_MASK_TARGET; -+ hub->notif.event.flags = SSAM_EVENT_SEQUENCED; -+ -+ hub->connect_delay = SSAM_KIP_UPDATE_CONNECT_DELAY; -+ hub->get_state = ssam_kip_get_connection_state; -+ -+ return ssam_hub_setup(sdev, hub); -+} -+ -+static const struct ssam_device_id ssam_kip_hub_match[] = { -+ { SSAM_VDEV(HUB, 0x01, SSAM_SSH_TC_KIP, 0x00) }, -+ { }, -+}; -+ -+static struct ssam_device_driver ssam_kip_hub_driver = { -+ .probe = ssam_kip_hub_probe, -+ .remove = ssam_hub_remove, -+ .match_table = ssam_kip_hub_match, -+ .driver = { -+ .name = "surface_kip_hub", -+ .probe_type = PROBE_PREFER_ASYNCHRONOUS, -+ .pm = &ssam_hub_pm_ops, -+ }, -+}; -+ -+ - /* -- SSAM platform/meta-hub driver. ---------------------------------------- */ - - static const struct acpi_device_id ssam_platform_hub_match[] = { -@@ -673,18 +760,30 @@ static int __init ssam_device_hub_init(void) - - status = platform_driver_register(&ssam_platform_hub_driver); - if (status) -- return status; -+ goto err_platform; - - status = ssam_device_driver_register(&ssam_base_hub_driver); - if (status) -- platform_driver_unregister(&ssam_platform_hub_driver); -+ goto err_base; -+ -+ status = ssam_device_driver_register(&ssam_kip_hub_driver); -+ if (status) -+ goto err_kip; - -+ return 0; -+ -+err_kip: -+ ssam_device_driver_unregister(&ssam_base_hub_driver); -+err_base: -+ platform_driver_unregister(&ssam_platform_hub_driver); -+err_platform: - return status; - } - module_init(ssam_device_hub_init); - - static void __exit ssam_device_hub_exit(void) - { -+ ssam_device_driver_unregister(&ssam_kip_hub_driver); - ssam_device_driver_unregister(&ssam_base_hub_driver); - platform_driver_unregister(&ssam_platform_hub_driver); - } --- -2.37.3 - -From 33f616b388ac8845bdd3aadb8c1a5e41e5eb86d8 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 27 May 2022 04:34:47 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Add support for - keyboard cover on Surface Pro 8 - -Add support for the detachable keyboard cover on the Surface Pro 8. - -The keyboard cover on the Surface Pro 8 is, unlike the keyboard covers -of earlier Surface Pro generations, handled via the Surface System -Aggregator Module (SSAM). The keyboard and touchpad (as well as other -HID input devices) of this cover are standard SSAM HID client devices -(just like keyboard and touchpad on e.g. the Surface Laptop 3 and 4), -however, some care needs to be taken as they can be physically detached -(similarly to the Surface Book 3). Specifically, the respective SSAM -client devices need to be removed when the keyboard cover has been -detached and (re-)initialized when the keyboard cover has been -(re-)attached. - -On the Surface Pro 8, detachment of the keyboard cover (and by extension -its devices) is managed via the KIP subsystem. Therefore, said devices -need to be registered under the KIP device hub, which in turn will -remove and re-create/re-initialize those devices as needed. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220527023447.2460025-13-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - .../surface/surface_aggregator_registry.c | 37 ++++++++++++++++++- - 1 file changed, 36 insertions(+), 1 deletion(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index f15cef60630f..bf3303f1aa71 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -41,6 +41,12 @@ static const struct software_node ssam_node_root = { - .name = "ssam_platform_hub", - }; - -+/* KIP device hub (connects keyboard cover devices on Surface Pro 8). */ -+static const struct software_node ssam_node_hub_kip = { -+ .name = "ssam:00:00:01:0e:00", -+ .parent = &ssam_node_root, -+}; -+ - /* Base device hub (devices attached to Surface Book 3 base). */ - static const struct software_node ssam_node_hub_base = { - .name = "ssam:00:00:02:11:00", -@@ -155,6 +161,30 @@ static const struct software_node ssam_node_hid_base_iid6 = { - .parent = &ssam_node_hub_base, - }; - -+/* HID keyboard (KIP hub). */ -+static const struct software_node ssam_node_hid_kip_keyboard = { -+ .name = "ssam:01:15:02:01:00", -+ .parent = &ssam_node_hub_kip, -+}; -+ -+/* HID pen stash (KIP hub; pen taken / stashed away evens). */ -+static const struct software_node ssam_node_hid_kip_penstash = { -+ .name = "ssam:01:15:02:02:00", -+ .parent = &ssam_node_hub_kip, -+}; -+ -+/* HID touchpad (KIP hub). */ -+static const struct software_node ssam_node_hid_kip_touchpad = { -+ .name = "ssam:01:15:02:03:00", -+ .parent = &ssam_node_hub_kip, -+}; -+ -+/* HID device instance 5 (KIP hub, unknown HID device). */ -+static const struct software_node ssam_node_hid_kip_iid5 = { -+ .name = "ssam:01:15:02:05:00", -+ .parent = &ssam_node_hub_kip, -+}; -+ - /* - * Devices for 5th- and 6th-generations models: - * - Surface Book 2, -@@ -230,10 +260,15 @@ static const struct software_node *ssam_node_group_sp7[] = { - - static const struct software_node *ssam_node_group_sp8[] = { - &ssam_node_root, -+ &ssam_node_hub_kip, - &ssam_node_bat_ac, - &ssam_node_bat_main, - &ssam_node_tmp_pprof, -- /* TODO: Add support for keyboard cover. */ -+ &ssam_node_hid_kip_keyboard, -+ &ssam_node_hid_kip_penstash, -+ &ssam_node_hid_kip_touchpad, -+ &ssam_node_hid_kip_iid5, -+ /* TODO: Add support for tablet mode switch. */ - NULL, - }; - --- -2.37.3 - -From e52704dc9d78c8c7bc2cb192063f0498a10e8655 Mon Sep 17 00:00:00 2001 -From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> -Date: Fri, 10 Jun 2022 14:41:58 +0900 -Subject: [PATCH] platform/surface: avoid flush_scheduled_work() usage - -Use local wq in order to avoid flush_scheduled_work() usage. - -Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> -Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com> -Tested-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/63ec2d45-c67c-1134-f6d3-490c8ba67a01@I-love.SAKURA.ne.jp -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - .../platform/surface/surface_acpi_notify.c | 27 ++++++++++++++++--- - 1 file changed, 24 insertions(+), 3 deletions(-) - -diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c -index 7b758f8cc137..c0e12f0b9b79 100644 ---- a/drivers/platform/surface/surface_acpi_notify.c -+++ b/drivers/platform/surface/surface_acpi_notify.c -@@ -37,6 +37,7 @@ struct san_data { - #define to_san_data(ptr, member) \ - container_of(ptr, struct san_data, member) - -+static struct workqueue_struct *san_wq; - - /* -- dGPU notifier interface. ---------------------------------------------- */ - -@@ -356,7 +357,7 @@ static u32 san_evt_bat_nf(struct ssam_event_notifier *nf, - - memcpy(&work->event, event, sizeof(struct ssam_event) + event->length); - -- schedule_delayed_work(&work->work, delay); -+ queue_delayed_work(san_wq, &work->work, delay); - return SSAM_NOTIF_HANDLED; - } - -@@ -861,7 +862,7 @@ static int san_remove(struct platform_device *pdev) - * We have unregistered our event sources. Now we need to ensure that - * all delayed works they may have spawned are run to completion. - */ -- flush_scheduled_work(); -+ flush_workqueue(san_wq); - - return 0; - } -@@ -881,7 +882,27 @@ static struct platform_driver surface_acpi_notify = { - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - }, - }; --module_platform_driver(surface_acpi_notify); -+ -+static int __init san_init(void) -+{ -+ int ret; -+ -+ san_wq = alloc_workqueue("san_wq", 0, 0); -+ if (!san_wq) -+ return -ENOMEM; -+ ret = platform_driver_register(&surface_acpi_notify); -+ if (ret) -+ destroy_workqueue(san_wq); -+ return ret; -+} -+module_init(san_init); -+ -+static void __exit san_exit(void) -+{ -+ platform_driver_unregister(&surface_acpi_notify); -+ destroy_workqueue(san_wq); -+} -+module_exit(san_exit); - - MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); - MODULE_DESCRIPTION("Surface ACPI Notify driver for Surface System Aggregator Module"); --- -2.37.3 - -From 23b3d5bdf836ab4e155c9c95d860e35822aabd7e Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Tue, 14 Jun 2022 21:41:17 +0200 -Subject: [PATCH] platform/surface: aggregator: Reserve more event- and - target-categories - -With the introduction of the Surface Laptop Studio, more event- and -target categories have been added. Therefore, increase the number of -reserved events and extend the enum of know target categories to -accommodate this. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220614194117.4118897-1-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/aggregator/trace.h | 80 +++++++++++-------- - include/linux/surface_aggregator/serial_hub.h | 75 +++++++++-------- - 2 files changed, 85 insertions(+), 70 deletions(-) - -diff --git a/drivers/platform/surface/aggregator/trace.h b/drivers/platform/surface/aggregator/trace.h -index de64cf169060..cc9e73fbc18e 100644 ---- a/drivers/platform/surface/aggregator/trace.h -+++ b/drivers/platform/surface/aggregator/trace.h -@@ -76,7 +76,7 @@ TRACE_DEFINE_ENUM(SSAM_SSH_TC_HID); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_TCH); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_BKL); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_TAM); --TRACE_DEFINE_ENUM(SSAM_SSH_TC_ACC); -+TRACE_DEFINE_ENUM(SSAM_SSH_TC_ACC0); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_UFI); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_USC); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_PEN); -@@ -85,6 +85,11 @@ TRACE_DEFINE_ENUM(SSAM_SSH_TC_AUD); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_SMC); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_KPD); - TRACE_DEFINE_ENUM(SSAM_SSH_TC_REG); -+TRACE_DEFINE_ENUM(SSAM_SSH_TC_SPT); -+TRACE_DEFINE_ENUM(SSAM_SSH_TC_SYS); -+TRACE_DEFINE_ENUM(SSAM_SSH_TC_ACC1); -+TRACE_DEFINE_ENUM(SSAM_SSH_TC_SHB); -+TRACE_DEFINE_ENUM(SSAM_SSH_TC_POS); - - #define SSAM_PTR_UID_LEN 9 - #define SSAM_U8_FIELD_NOT_APPLICABLE ((u16)-1) -@@ -229,40 +234,45 @@ static inline u32 ssam_trace_get_request_tc(const struct ssh_packet *p) - - #define ssam_show_ssh_tc(rqid) \ - __print_symbolic(rqid, \ -- { SSAM_SSH_TC_NOT_APPLICABLE, "N/A" }, \ -- { SSAM_SSH_TC_SAM, "SAM" }, \ -- { SSAM_SSH_TC_BAT, "BAT" }, \ -- { SSAM_SSH_TC_TMP, "TMP" }, \ -- { SSAM_SSH_TC_PMC, "PMC" }, \ -- { SSAM_SSH_TC_FAN, "FAN" }, \ -- { SSAM_SSH_TC_PoM, "PoM" }, \ -- { SSAM_SSH_TC_DBG, "DBG" }, \ -- { SSAM_SSH_TC_KBD, "KBD" }, \ -- { SSAM_SSH_TC_FWU, "FWU" }, \ -- { SSAM_SSH_TC_UNI, "UNI" }, \ -- { SSAM_SSH_TC_LPC, "LPC" }, \ -- { SSAM_SSH_TC_TCL, "TCL" }, \ -- { SSAM_SSH_TC_SFL, "SFL" }, \ -- { SSAM_SSH_TC_KIP, "KIP" }, \ -- { SSAM_SSH_TC_EXT, "EXT" }, \ -- { SSAM_SSH_TC_BLD, "BLD" }, \ -- { SSAM_SSH_TC_BAS, "BAS" }, \ -- { SSAM_SSH_TC_SEN, "SEN" }, \ -- { SSAM_SSH_TC_SRQ, "SRQ" }, \ -- { SSAM_SSH_TC_MCU, "MCU" }, \ -- { SSAM_SSH_TC_HID, "HID" }, \ -- { SSAM_SSH_TC_TCH, "TCH" }, \ -- { SSAM_SSH_TC_BKL, "BKL" }, \ -- { SSAM_SSH_TC_TAM, "TAM" }, \ -- { SSAM_SSH_TC_ACC, "ACC" }, \ -- { SSAM_SSH_TC_UFI, "UFI" }, \ -- { SSAM_SSH_TC_USC, "USC" }, \ -- { SSAM_SSH_TC_PEN, "PEN" }, \ -- { SSAM_SSH_TC_VID, "VID" }, \ -- { SSAM_SSH_TC_AUD, "AUD" }, \ -- { SSAM_SSH_TC_SMC, "SMC" }, \ -- { SSAM_SSH_TC_KPD, "KPD" }, \ -- { SSAM_SSH_TC_REG, "REG" } \ -+ { SSAM_SSH_TC_NOT_APPLICABLE, "N/A" }, \ -+ { SSAM_SSH_TC_SAM, "SAM" }, \ -+ { SSAM_SSH_TC_BAT, "BAT" }, \ -+ { SSAM_SSH_TC_TMP, "TMP" }, \ -+ { SSAM_SSH_TC_PMC, "PMC" }, \ -+ { SSAM_SSH_TC_FAN, "FAN" }, \ -+ { SSAM_SSH_TC_PoM, "PoM" }, \ -+ { SSAM_SSH_TC_DBG, "DBG" }, \ -+ { SSAM_SSH_TC_KBD, "KBD" }, \ -+ { SSAM_SSH_TC_FWU, "FWU" }, \ -+ { SSAM_SSH_TC_UNI, "UNI" }, \ -+ { SSAM_SSH_TC_LPC, "LPC" }, \ -+ { SSAM_SSH_TC_TCL, "TCL" }, \ -+ { SSAM_SSH_TC_SFL, "SFL" }, \ -+ { SSAM_SSH_TC_KIP, "KIP" }, \ -+ { SSAM_SSH_TC_EXT, "EXT" }, \ -+ { SSAM_SSH_TC_BLD, "BLD" }, \ -+ { SSAM_SSH_TC_BAS, "BAS" }, \ -+ { SSAM_SSH_TC_SEN, "SEN" }, \ -+ { SSAM_SSH_TC_SRQ, "SRQ" }, \ -+ { SSAM_SSH_TC_MCU, "MCU" }, \ -+ { SSAM_SSH_TC_HID, "HID" }, \ -+ { SSAM_SSH_TC_TCH, "TCH" }, \ -+ { SSAM_SSH_TC_BKL, "BKL" }, \ -+ { SSAM_SSH_TC_TAM, "TAM" }, \ -+ { SSAM_SSH_TC_ACC0, "ACC0" }, \ -+ { SSAM_SSH_TC_UFI, "UFI" }, \ -+ { SSAM_SSH_TC_USC, "USC" }, \ -+ { SSAM_SSH_TC_PEN, "PEN" }, \ -+ { SSAM_SSH_TC_VID, "VID" }, \ -+ { SSAM_SSH_TC_AUD, "AUD" }, \ -+ { SSAM_SSH_TC_SMC, "SMC" }, \ -+ { SSAM_SSH_TC_KPD, "KPD" }, \ -+ { SSAM_SSH_TC_REG, "REG" }, \ -+ { SSAM_SSH_TC_SPT, "SPT" }, \ -+ { SSAM_SSH_TC_SYS, "SYS" }, \ -+ { SSAM_SSH_TC_ACC1, "ACC1" }, \ -+ { SSAM_SSH_TC_SHB, "SMB" }, \ -+ { SSAM_SSH_TC_POS, "POS" } \ - ) - - DECLARE_EVENT_CLASS(ssam_frame_class, -diff --git a/include/linux/surface_aggregator/serial_hub.h b/include/linux/surface_aggregator/serial_hub.h -index 26b95ec12733..45501b6e54e8 100644 ---- a/include/linux/surface_aggregator/serial_hub.h -+++ b/include/linux/surface_aggregator/serial_hub.h -@@ -201,7 +201,7 @@ static inline u16 ssh_crc(const u8 *buf, size_t len) - * exception of zero, which is not an event ID. Thus, this is also the - * absolute maximum number of event handlers that can be registered. - */ --#define SSH_NUM_EVENTS 34 -+#define SSH_NUM_EVENTS 38 - - /* - * SSH_NUM_TARGETS - The number of communication targets used in the protocol. -@@ -292,40 +292,45 @@ struct ssam_span { - * Windows driver. - */ - enum ssam_ssh_tc { -- /* 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. */ -- SSAM_SSH_TC_TMP = 0x03, /* Thermal subsystem. */ -- SSAM_SSH_TC_PMC = 0x04, -- SSAM_SSH_TC_FAN = 0x05, -- SSAM_SSH_TC_PoM = 0x06, -- SSAM_SSH_TC_DBG = 0x07, -- SSAM_SSH_TC_KBD = 0x08, /* Legacy keyboard (Laptop 1/2). */ -- SSAM_SSH_TC_FWU = 0x09, -- SSAM_SSH_TC_UNI = 0x0a, -- SSAM_SSH_TC_LPC = 0x0b, -- SSAM_SSH_TC_TCL = 0x0c, -- SSAM_SSH_TC_SFL = 0x0d, -- SSAM_SSH_TC_KIP = 0x0e, /* Manages detachable peripherals (Pro X/8 keyboard cover) */ -- SSAM_SSH_TC_EXT = 0x0f, -- SSAM_SSH_TC_BLD = 0x10, -- SSAM_SSH_TC_BAS = 0x11, /* Detachment system (Surface Book 2/3). */ -- SSAM_SSH_TC_SEN = 0x12, -- SSAM_SSH_TC_SRQ = 0x13, -- SSAM_SSH_TC_MCU = 0x14, -- SSAM_SSH_TC_HID = 0x15, /* Generic HID input subsystem. */ -- SSAM_SSH_TC_TCH = 0x16, -- SSAM_SSH_TC_BKL = 0x17, -- SSAM_SSH_TC_TAM = 0x18, -- SSAM_SSH_TC_ACC = 0x19, -- SSAM_SSH_TC_UFI = 0x1a, -- SSAM_SSH_TC_USC = 0x1b, -- SSAM_SSH_TC_PEN = 0x1c, -- SSAM_SSH_TC_VID = 0x1d, -- SSAM_SSH_TC_AUD = 0x1e, -- SSAM_SSH_TC_SMC = 0x1f, -- SSAM_SSH_TC_KPD = 0x20, -- SSAM_SSH_TC_REG = 0x21, /* Extended event registry. */ -+ /* 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. */ -+ SSAM_SSH_TC_TMP = 0x03, /* Thermal subsystem. */ -+ SSAM_SSH_TC_PMC = 0x04, -+ SSAM_SSH_TC_FAN = 0x05, -+ SSAM_SSH_TC_PoM = 0x06, -+ SSAM_SSH_TC_DBG = 0x07, -+ SSAM_SSH_TC_KBD = 0x08, /* Legacy keyboard (Laptop 1/2). */ -+ SSAM_SSH_TC_FWU = 0x09, -+ SSAM_SSH_TC_UNI = 0x0a, -+ SSAM_SSH_TC_LPC = 0x0b, -+ SSAM_SSH_TC_TCL = 0x0c, -+ SSAM_SSH_TC_SFL = 0x0d, -+ SSAM_SSH_TC_KIP = 0x0e, /* Manages detachable peripherals (Pro X/8 keyboard cover) */ -+ SSAM_SSH_TC_EXT = 0x0f, -+ SSAM_SSH_TC_BLD = 0x10, -+ SSAM_SSH_TC_BAS = 0x11, /* Detachment system (Surface Book 2/3). */ -+ SSAM_SSH_TC_SEN = 0x12, -+ SSAM_SSH_TC_SRQ = 0x13, -+ SSAM_SSH_TC_MCU = 0x14, -+ SSAM_SSH_TC_HID = 0x15, /* Generic HID input subsystem. */ -+ SSAM_SSH_TC_TCH = 0x16, -+ SSAM_SSH_TC_BKL = 0x17, -+ SSAM_SSH_TC_TAM = 0x18, -+ SSAM_SSH_TC_ACC0 = 0x19, -+ SSAM_SSH_TC_UFI = 0x1a, -+ SSAM_SSH_TC_USC = 0x1b, -+ SSAM_SSH_TC_PEN = 0x1c, -+ SSAM_SSH_TC_VID = 0x1d, -+ SSAM_SSH_TC_AUD = 0x1e, -+ SSAM_SSH_TC_SMC = 0x1f, -+ SSAM_SSH_TC_KPD = 0x20, -+ SSAM_SSH_TC_REG = 0x21, /* Extended event registry. */ -+ SSAM_SSH_TC_SPT = 0x22, -+ SSAM_SSH_TC_SYS = 0x23, -+ SSAM_SSH_TC_ACC1 = 0x24, -+ SSAM_SSH_TC_SHB = 0x25, -+ SSAM_SSH_TC_POS = 0x26, /* For obtaining Laptop Studio screen position. */ - }; - - --- -2.37.3 - -From c7d12cb78b2beb6cac2ccea84707dbcc4111b3d6 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 20:36:39 +0200 -Subject: [PATCH] platform/surface: aggregator: Add helper macros for requests - with argument and return value - -Add helper macros for synchronous stack-allocated Surface Aggregator -request with both argument and return value, similar to the current -argument-only and return-value-only ones. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624183642.910893-2-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - include/linux/surface_aggregator/controller.h | 125 ++++++++++++++++++ - include/linux/surface_aggregator/device.h | 36 +++++ - 2 files changed, 161 insertions(+) - -diff --git a/include/linux/surface_aggregator/controller.h b/include/linux/surface_aggregator/controller.h -index 50a2b4926c06..d11a1c6e3186 100644 ---- a/include/linux/surface_aggregator/controller.h -+++ b/include/linux/surface_aggregator/controller.h -@@ -469,6 +469,67 @@ struct ssam_request_spec_md { - return 0; \ - } - -+/** -+ * SSAM_DEFINE_SYNC_REQUEST_WR() - Define synchronous SAM request function with -+ * both argument and return value. -+ * @name: Name of the generated function. -+ * @atype: Type of the request's argument. -+ * @rtype: Type of the request's return value. -+ * @spec: Specification (&struct ssam_request_spec) defining the request. -+ * -+ * Defines a function executing the synchronous SAM request specified by @spec, -+ * with the request taking an argument of type @atype and having a return value -+ * of type @rtype. The generated function takes care of setting up the request -+ * and response structs, buffer allocation, as well as execution of the request -+ * itself, returning once the request has been fully completed. The required -+ * transport buffer will be allocated on the stack. -+ * -+ * The generated function is defined as ``static int name(struct -+ * ssam_controller *ctrl, const atype *arg, rtype *ret)``, returning the status -+ * of the request, which is zero on success and negative on failure. The -+ * ``ctrl`` parameter is the controller via which the request is sent. The -+ * request argument is specified via the ``arg`` pointer. The request's return -+ * value is written to the memory pointed to by the ``ret`` parameter. -+ * -+ * Refer to ssam_request_sync_onstack() for more details on the behavior of -+ * the generated function. -+ */ -+#define SSAM_DEFINE_SYNC_REQUEST_WR(name, atype, rtype, spec...) \ -+ static int name(struct ssam_controller *ctrl, const atype *arg, rtype *ret) \ -+ { \ -+ struct ssam_request_spec s = (struct ssam_request_spec)spec; \ -+ struct ssam_request rqst; \ -+ struct ssam_response rsp; \ -+ int status; \ -+ \ -+ rqst.target_category = s.target_category; \ -+ rqst.target_id = s.target_id; \ -+ rqst.command_id = s.command_id; \ -+ rqst.instance_id = s.instance_id; \ -+ rqst.flags = s.flags | SSAM_REQUEST_HAS_RESPONSE; \ -+ rqst.length = sizeof(atype); \ -+ rqst.payload = (u8 *)arg; \ -+ \ -+ rsp.capacity = sizeof(rtype); \ -+ rsp.length = 0; \ -+ rsp.pointer = (u8 *)ret; \ -+ \ -+ status = ssam_request_sync_onstack(ctrl, &rqst, &rsp, sizeof(atype)); \ -+ if (status) \ -+ return status; \ -+ \ -+ if (rsp.length != sizeof(rtype)) { \ -+ struct device *dev = ssam_controller_device(ctrl); \ -+ dev_err(dev, \ -+ "rqst: invalid response length, expected %zu, got %zu (tc: %#04x, cid: %#04x)", \ -+ sizeof(rtype), rsp.length, rqst.target_category,\ -+ rqst.command_id); \ -+ return -EIO; \ -+ } \ -+ \ -+ return 0; \ -+ } -+ - /** - * SSAM_DEFINE_SYNC_REQUEST_MD_N() - Define synchronous multi-device SAM - * request function with neither argument nor return value. -@@ -613,6 +674,70 @@ struct ssam_request_spec_md { - return 0; \ - } - -+/** -+ * SSAM_DEFINE_SYNC_REQUEST_MD_WR() - Define synchronous multi-device SAM -+ * request function with both argument and return value. -+ * @name: Name of the generated function. -+ * @atype: Type of the request's argument. -+ * @rtype: Type of the request's return value. -+ * @spec: Specification (&struct ssam_request_spec_md) defining the request. -+ * -+ * Defines a function executing the synchronous SAM request specified by @spec, -+ * with the request taking an argument of type @atype and having a return value -+ * of type @rtype. Device specifying parameters are not hard-coded, but instead -+ * must be provided to the function. The generated function takes care of -+ * setting up the request and response structs, buffer allocation, as well as -+ * execution of the request itself, returning once the request has been fully -+ * completed. The required transport buffer will be allocated on the stack. -+ * -+ * The generated function is defined as ``static int name(struct -+ * ssam_controller *ctrl, u8 tid, u8 iid, const atype *arg, rtype *ret)``, -+ * returning the status of the request, which is zero on success and negative -+ * on failure. The ``ctrl`` parameter is the controller via which the request -+ * is sent, ``tid`` the target ID for the request, and ``iid`` the instance ID. -+ * The request argument is specified via the ``arg`` pointer. The request's -+ * return value is written to the memory pointed to by the ``ret`` parameter. -+ * -+ * Refer to ssam_request_sync_onstack() for more details on the behavior of -+ * the generated function. -+ */ -+#define SSAM_DEFINE_SYNC_REQUEST_MD_WR(name, atype, rtype, spec...) \ -+ static int name(struct ssam_controller *ctrl, u8 tid, u8 iid, \ -+ const atype *arg, rtype *ret) \ -+ { \ -+ struct ssam_request_spec_md s = (struct ssam_request_spec_md)spec; \ -+ struct ssam_request rqst; \ -+ struct ssam_response rsp; \ -+ int status; \ -+ \ -+ rqst.target_category = s.target_category; \ -+ rqst.target_id = tid; \ -+ rqst.command_id = s.command_id; \ -+ rqst.instance_id = iid; \ -+ rqst.flags = s.flags | SSAM_REQUEST_HAS_RESPONSE; \ -+ rqst.length = sizeof(atype); \ -+ rqst.payload = (u8 *)arg; \ -+ \ -+ rsp.capacity = sizeof(rtype); \ -+ rsp.length = 0; \ -+ rsp.pointer = (u8 *)ret; \ -+ \ -+ status = ssam_request_sync_onstack(ctrl, &rqst, &rsp, sizeof(atype)); \ -+ if (status) \ -+ return status; \ -+ \ -+ if (rsp.length != sizeof(rtype)) { \ -+ struct device *dev = ssam_controller_device(ctrl); \ -+ dev_err(dev, \ -+ "rqst: invalid response length, expected %zu, got %zu (tc: %#04x, cid: %#04x)", \ -+ sizeof(rtype), rsp.length, rqst.target_category,\ -+ rqst.command_id); \ -+ return -EIO; \ -+ } \ -+ \ -+ return 0; \ -+ } -+ - - /* -- Event notifier/callbacks. --------------------------------------------- */ - -diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h -index c418f7f2732d..6cf7e80312d5 100644 ---- a/include/linux/surface_aggregator/device.h -+++ b/include/linux/surface_aggregator/device.h -@@ -483,6 +483,42 @@ static inline void ssam_remove_clients(struct device *dev) {} - sdev->uid.instance, ret); \ - } - -+/** -+ * SSAM_DEFINE_SYNC_REQUEST_CL_WR() - Define synchronous client-device SAM -+ * request function with argument and return value. -+ * @name: Name of the generated function. -+ * @atype: Type of the request's argument. -+ * @rtype: Type of the request's return value. -+ * @spec: Specification (&struct ssam_request_spec_md) defining the request. -+ * -+ * Defines a function executing the synchronous SAM request specified by @spec, -+ * with the request taking an argument of type @atype and having a return value -+ * of type @rtype. Device specifying parameters are not hard-coded, but instead -+ * are provided via the client device, specifically its UID, supplied when -+ * calling this function. The generated function takes care of setting up the -+ * request struct, buffer allocation, as well as execution of the request -+ * itself, returning once the request has been fully completed. The required -+ * transport buffer will be allocated on the stack. -+ * -+ * The generated function is defined as ``static int name(struct ssam_device -+ * *sdev, const atype *arg, rtype *ret)``, returning the status of the request, -+ * which is zero on success and negative on failure. The ``sdev`` parameter -+ * specifies both the target device of the request and by association the -+ * controller via which the request is sent. The request's argument is -+ * specified via the ``arg`` pointer. The request's return value is written to -+ * the memory pointed to by the ``ret`` parameter. -+ * -+ * Refer to ssam_request_sync_onstack() for more details on the behavior of -+ * the generated function. -+ */ -+#define SSAM_DEFINE_SYNC_REQUEST_CL_WR(name, atype, rtype, spec...) \ -+ SSAM_DEFINE_SYNC_REQUEST_MD_WR(__raw_##name, atype, rtype, spec) \ -+ static int name(struct ssam_device *sdev, const atype *arg, rtype *ret) \ -+ { \ -+ return __raw_##name(sdev->ctrl, sdev->uid.target, \ -+ sdev->uid.instance, arg, ret); \ -+ } -+ - - /* -- Helpers for client-device notifiers. ---------------------------------- */ - --- -2.37.3 - -From c133afbb407d272327b236ec809e025407335165 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 20:36:40 +0200 -Subject: [PATCH] platform/surface: Add KIP/POS tablet-mode switch driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a driver providing a tablet-mode switch input device for Microsoft -Surface devices using the Surface Aggregator KIP subsystem (to manage -detachable peripherals) or POS subsystem (to obtain device posture -information). - -The KIP (full name unknown, abbreviation found through reverse -engineering) subsystem is used on the Surface Pro 8 and Surface Pro X to -manage the keyboard cover. Among other things, it provides information -on the positioning (posture) of the cover (closed, laptop-style, -detached, folded-back, ...), which can be used to implement an input -device providing the SW_TABLET_MODE event. Similarly, the POS (posture -information) subsystem provides such information on the Surface Laptop -Studio, with the difference being that the keyboard is not detachable. - -As implementing the tablet-mode switch for both subsystems is largely -similar, the driver proposed in this commit, in large, acts as a generic -tablet mode switch driver framework for the Surface Aggregator Module. -Specific implementations using this framework are provided for the KIP -and POS subsystems, adding tablet-mode switch support to the -aforementioned devices. - -A few more notes on the Surface Laptop Studio: - -A peculiarity of the Surface Laptop Studio is its "slate/tent" mode -(symbolized: user> _/\). In this mode, the screen covers the keyboard -but leaves the touchpad exposed. This is essentially a mode in-between -tablet and laptop, and it is debatable whether tablet-mode should be -enabled in this mode. We therefore let the user decide this via a module -parameter. - -In particular, tablet-mode may bring up the on-screen touch keyboard -more easily, which would be desirable in this mode. However, some -user-space software currently also decides to disable keyboard and, more -importantly, touchpad input, while the touchpad is still accessible in -the "slate/tent" mode. Furthermore, this mode shares its identifier with -"slate/flipped" mode where the screen is flipped 180° and the keyboard -points away from the user (symbolized: user> /_). In this mode we would -like to enable auto-rotation, something that user-space software may -only do when tablet-mode is enabled. We therefore default to the -slate-mode enabling the tablet-mode switch. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624183642.910893-3-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - .../sysfs-bus-surface_aggregator-tabletsw | 57 ++ - MAINTAINERS | 6 + - drivers/platform/surface/Kconfig | 23 + - drivers/platform/surface/Makefile | 1 + - .../surface/surface_aggregator_tabletsw.c | 533 ++++++++++++++++++ - 5 files changed, 620 insertions(+) - create mode 100644 Documentation/ABI/testing/sysfs-bus-surface_aggregator-tabletsw - create mode 100644 drivers/platform/surface/surface_aggregator_tabletsw.c - -diff --git a/Documentation/ABI/testing/sysfs-bus-surface_aggregator-tabletsw b/Documentation/ABI/testing/sysfs-bus-surface_aggregator-tabletsw -new file mode 100644 -index 000000000000..74cd9d754e60 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-bus-surface_aggregator-tabletsw -@@ -0,0 +1,57 @@ -+What: /sys/bus/surface_aggregator/devices/01:0e:01:00:01/state -+Date: July 2022 -+KernelVersion: 5.20 -+Contact: Maximilian Luz <luzmaximilian@gmail.com> -+Description: -+ This attribute returns a string with the current type-cover -+ or device posture, as indicated by the embedded controller. -+ Currently returned posture states are: -+ -+ - "disconnected": The type-cover has been disconnected. -+ -+ - "closed": The type-cover has been folded closed and lies on -+ top of the display. -+ -+ - "laptop": The type-cover is open and in laptop-mode, i.e., -+ ready for normal use. -+ -+ - "folded-canvas": The type-cover has been folded back -+ part-ways, but does not lie flush with the back side of the -+ device. In general, this means that the kick-stand is used -+ and extended atop of the cover. -+ -+ - "folded-back": The type cover has been fully folded back and -+ lies flush with the back side of the device. -+ -+ - "<unknown>": The current state is unknown to the driver, for -+ example due to newer as-of-yet unsupported hardware. -+ -+ New states may be introduced with new hardware. Users therefore -+ must not rely on this list of states being exhaustive and -+ gracefully handle unknown states. -+ -+What: /sys/bus/surface_aggregator/devices/01:26:01:00:01/state -+Date: July 2022 -+KernelVersion: 5.20 -+Contact: Maximilian Luz <luzmaximilian@gmail.com> -+Description: -+ This attribute returns a string with the current device posture, as indicated by the embedded controller. Currently -+ returned posture states are: -+ -+ - "closed": The lid of the device is closed. -+ -+ - "laptop": The lid of the device is opened and the device -+ operates as a normal laptop. -+ -+ - "slate": The screen covers the keyboard or has been flipped -+ back and the device operates mainly based on touch input. -+ -+ - "tablet": The device operates as tablet and exclusively -+ relies on touch input (or external peripherals). -+ -+ - "<unknown>": The current state is unknown to the driver, for -+ example due to newer as-of-yet unsupported hardware. -+ -+ New states may be introduced with new hardware. Users therefore -+ must not rely on this list of states being exhaustive and -+ gracefully handle unknown states. -diff --git a/MAINTAINERS b/MAINTAINERS -index 08620b9a44fc..773eb8387f4a 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13299,6 +13299,12 @@ F: drivers/scsi/smartpqi/smartpqi*.[ch] - F: include/linux/cciss*.h - F: include/uapi/linux/cciss*.h - -+MICROSOFT SURFACE AGGREGATOR TABLET-MODE SWITCH -+M: Maximilian Luz <luzmaximilian@gmail.com> -+L: platform-driver-x86@vger.kernel.org -+S: Maintained -+F: drivers/platform/surface/surface_aggregator_tablet_switch.c -+ - MICROSOFT SURFACE BATTERY AND AC DRIVERS - M: Maximilian Luz <luzmaximilian@gmail.com> - L: linux-pm@vger.kernel.org -diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig -index eb79fbed8059..b152e930cc84 100644 ---- a/drivers/platform/surface/Kconfig -+++ b/drivers/platform/surface/Kconfig -@@ -99,6 +99,29 @@ config SURFACE_AGGREGATOR_REGISTRY - the respective client devices. Drivers for these devices still need to - be selected via the other options. - -+config SURFACE_AGGREGATOR_TABLET_SWITCH -+ tristate "Surface Aggregator Generic Tablet-Mode Switch Driver" -+ depends on SURFACE_AGGREGATOR -+ depends on SURFACE_AGGREGATOR_BUS -+ depends on INPUT -+ help -+ Provides a tablet-mode switch input device on Microsoft Surface models -+ using the KIP subsystem for detachable keyboards (e.g. keyboard covers) -+ or the POS subsystem for device/screen posture changes. -+ -+ The KIP subsystem is used on newer Surface generations to handle -+ detachable input peripherals, specifically the keyboard cover (containing -+ keyboard and touchpad) on the Surface Pro 8 and Surface Pro X. The POS -+ subsystem is used for device posture change notifications on the Surface -+ Laptop Studio. This module provides a driver to let user-space know when -+ the device should be considered in tablet-mode due to the keyboard cover -+ being detached or folded back (essentially signaling when the keyboard is -+ not available for input). It does so by creating a tablet-mode switch -+ input device, sending the standard SW_TABLET_MODE event on mode change. -+ -+ Select M or Y here, if you want to provide tablet-mode switch input -+ events on the Surface Pro 8, Surface Pro X, and Surface Laptop Studio. -+ - config SURFACE_DTX - tristate "Surface DTX (Detachment System) Driver" - depends on SURFACE_AGGREGATOR -diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile -index 0fc9cd3e4dd9..18b27898543e 100644 ---- a/drivers/platform/surface/Makefile -+++ b/drivers/platform/surface/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_SURFACE_ACPI_NOTIFY) += surface_acpi_notify.o - obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/ - obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o - obj-$(CONFIG_SURFACE_AGGREGATOR_REGISTRY) += surface_aggregator_registry.o -+obj-$(CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH) += surface_aggregator_tabletsw.o - obj-$(CONFIG_SURFACE_DTX) += surface_dtx.o - obj-$(CONFIG_SURFACE_GPE) += surface_gpe.o - obj-$(CONFIG_SURFACE_HOTPLUG) += surface_hotplug.o -diff --git a/drivers/platform/surface/surface_aggregator_tabletsw.c b/drivers/platform/surface/surface_aggregator_tabletsw.c -new file mode 100644 -index 000000000000..596ca6c80681 ---- /dev/null -+++ b/drivers/platform/surface/surface_aggregator_tabletsw.c -@@ -0,0 +1,533 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Surface System Aggregator Module (SSAM) tablet mode switch driver. -+ * -+ * Copyright (C) 2022 Maximilian Luz <luzmaximilian@gmail.com> -+ */ -+ -+#include <asm/unaligned.h> -+#include <linux/input.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/types.h> -+#include <linux/workqueue.h> -+ -+#include <linux/surface_aggregator/controller.h> -+#include <linux/surface_aggregator/device.h> -+ -+ -+/* -- SSAM generic tablet switch driver framework. -------------------------- */ -+ -+struct ssam_tablet_sw; -+ -+struct ssam_tablet_sw_ops { -+ int (*get_state)(struct ssam_tablet_sw *sw, u32 *state); -+ const char *(*state_name)(struct ssam_tablet_sw *sw, u32 state); -+ bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw, u32 state); -+}; -+ -+struct ssam_tablet_sw { -+ struct ssam_device *sdev; -+ -+ u32 state; -+ struct work_struct update_work; -+ struct input_dev *mode_switch; -+ -+ struct ssam_tablet_sw_ops ops; -+ struct ssam_event_notifier notif; -+}; -+ -+struct ssam_tablet_sw_desc { -+ struct { -+ const char *name; -+ const char *phys; -+ } dev; -+ -+ struct { -+ u32 (*notify)(struct ssam_event_notifier *nf, const struct ssam_event *event); -+ int (*get_state)(struct ssam_tablet_sw *sw, u32 *state); -+ const char *(*state_name)(struct ssam_tablet_sw *sw, u32 state); -+ bool (*state_is_tablet_mode)(struct ssam_tablet_sw *sw, u32 state); -+ } ops; -+ -+ struct { -+ struct ssam_event_registry reg; -+ struct ssam_event_id id; -+ enum ssam_event_mask mask; -+ u8 flags; -+ } event; -+}; -+ -+static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct ssam_tablet_sw *sw = dev_get_drvdata(dev); -+ const char *state = sw->ops.state_name(sw, sw->state); -+ -+ return sysfs_emit(buf, "%s\n", state); -+} -+static DEVICE_ATTR_RO(state); -+ -+static struct attribute *ssam_tablet_sw_attrs[] = { -+ &dev_attr_state.attr, -+ NULL, -+}; -+ -+static const struct attribute_group ssam_tablet_sw_group = { -+ .attrs = ssam_tablet_sw_attrs, -+}; -+ -+static void ssam_tablet_sw_update_workfn(struct work_struct *work) -+{ -+ struct ssam_tablet_sw *sw = container_of(work, struct ssam_tablet_sw, update_work); -+ int tablet, status; -+ u32 state; -+ -+ status = sw->ops.get_state(sw, &state); -+ if (status) -+ return; -+ -+ if (sw->state == state) -+ return; -+ sw->state = state; -+ -+ /* Send SW_TABLET_MODE event. */ -+ tablet = sw->ops.state_is_tablet_mode(sw, state); -+ input_report_switch(sw->mode_switch, SW_TABLET_MODE, tablet); -+ input_sync(sw->mode_switch); -+} -+ -+static int __maybe_unused ssam_tablet_sw_resume(struct device *dev) -+{ -+ struct ssam_tablet_sw *sw = dev_get_drvdata(dev); -+ -+ schedule_work(&sw->update_work); -+ return 0; -+} -+static SIMPLE_DEV_PM_OPS(ssam_tablet_sw_pm_ops, NULL, ssam_tablet_sw_resume); -+ -+static int ssam_tablet_sw_probe(struct ssam_device *sdev) -+{ -+ const struct ssam_tablet_sw_desc *desc; -+ struct ssam_tablet_sw *sw; -+ int tablet, status; -+ -+ desc = ssam_device_get_match_data(sdev); -+ if (!desc) { -+ WARN(1, "no driver match data specified"); -+ return -EINVAL; -+ } -+ -+ sw = devm_kzalloc(&sdev->dev, sizeof(*sw), GFP_KERNEL); -+ if (!sw) -+ return -ENOMEM; -+ -+ sw->sdev = sdev; -+ -+ sw->ops.get_state = desc->ops.get_state; -+ sw->ops.state_name = desc->ops.state_name; -+ sw->ops.state_is_tablet_mode = desc->ops.state_is_tablet_mode; -+ -+ INIT_WORK(&sw->update_work, ssam_tablet_sw_update_workfn); -+ -+ ssam_device_set_drvdata(sdev, sw); -+ -+ /* Get initial state. */ -+ status = sw->ops.get_state(sw, &sw->state); -+ if (status) -+ return status; -+ -+ /* Set up tablet mode switch. */ -+ sw->mode_switch = devm_input_allocate_device(&sdev->dev); -+ if (!sw->mode_switch) -+ return -ENOMEM; -+ -+ sw->mode_switch->name = desc->dev.name; -+ sw->mode_switch->phys = desc->dev.phys; -+ sw->mode_switch->id.bustype = BUS_HOST; -+ sw->mode_switch->dev.parent = &sdev->dev; -+ -+ tablet = sw->ops.state_is_tablet_mode(sw, sw->state); -+ input_set_capability(sw->mode_switch, EV_SW, SW_TABLET_MODE); -+ input_report_switch(sw->mode_switch, SW_TABLET_MODE, tablet); -+ -+ status = input_register_device(sw->mode_switch); -+ if (status) -+ return status; -+ -+ /* Set up notifier. */ -+ sw->notif.base.priority = 0; -+ sw->notif.base.fn = desc->ops.notify; -+ sw->notif.event.reg = desc->event.reg; -+ sw->notif.event.id = desc->event.id; -+ sw->notif.event.mask = desc->event.mask; -+ sw->notif.event.flags = SSAM_EVENT_SEQUENCED; -+ -+ status = ssam_device_notifier_register(sdev, &sw->notif); -+ if (status) -+ return status; -+ -+ status = sysfs_create_group(&sdev->dev.kobj, &ssam_tablet_sw_group); -+ if (status) -+ goto err; -+ -+ /* We might have missed events during setup, so check again. */ -+ schedule_work(&sw->update_work); -+ return 0; -+ -+err: -+ ssam_device_notifier_unregister(sdev, &sw->notif); -+ cancel_work_sync(&sw->update_work); -+ return status; -+} -+ -+static void ssam_tablet_sw_remove(struct ssam_device *sdev) -+{ -+ struct ssam_tablet_sw *sw = ssam_device_get_drvdata(sdev); -+ -+ sysfs_remove_group(&sdev->dev.kobj, &ssam_tablet_sw_group); -+ -+ ssam_device_notifier_unregister(sdev, &sw->notif); -+ cancel_work_sync(&sw->update_work); -+} -+ -+ -+/* -- SSAM KIP tablet switch implementation. -------------------------------- */ -+ -+#define SSAM_EVENT_KIP_CID_COVER_STATE_CHANGED 0x1d -+ -+enum ssam_kip_cover_state { -+ SSAM_KIP_COVER_STATE_DISCONNECTED = 0x01, -+ SSAM_KIP_COVER_STATE_CLOSED = 0x02, -+ SSAM_KIP_COVER_STATE_LAPTOP = 0x03, -+ SSAM_KIP_COVER_STATE_FOLDED_CANVAS = 0x04, -+ SSAM_KIP_COVER_STATE_FOLDED_BACK = 0x05, -+}; -+ -+static const char *ssam_kip_cover_state_name(struct ssam_tablet_sw *sw, u32 state) -+{ -+ switch (state) { -+ case SSAM_KIP_COVER_STATE_DISCONNECTED: -+ return "disconnected"; -+ -+ case SSAM_KIP_COVER_STATE_CLOSED: -+ return "closed"; -+ -+ case SSAM_KIP_COVER_STATE_LAPTOP: -+ return "laptop"; -+ -+ case SSAM_KIP_COVER_STATE_FOLDED_CANVAS: -+ return "folded-canvas"; -+ -+ case SSAM_KIP_COVER_STATE_FOLDED_BACK: -+ return "folded-back"; -+ -+ default: -+ dev_warn(&sw->sdev->dev, "unknown KIP cover state: %u\n", state); -+ return "<unknown>"; -+ } -+} -+ -+static bool ssam_kip_cover_state_is_tablet_mode(struct ssam_tablet_sw *sw, u32 state) -+{ -+ switch (state) { -+ case SSAM_KIP_COVER_STATE_DISCONNECTED: -+ case SSAM_KIP_COVER_STATE_FOLDED_CANVAS: -+ case SSAM_KIP_COVER_STATE_FOLDED_BACK: -+ return true; -+ -+ case SSAM_KIP_COVER_STATE_CLOSED: -+ case SSAM_KIP_COVER_STATE_LAPTOP: -+ return false; -+ -+ default: -+ dev_warn(&sw->sdev->dev, "unknown KIP cover state: %d\n", sw->state); -+ return true; -+ } -+} -+ -+SSAM_DEFINE_SYNC_REQUEST_R(__ssam_kip_get_cover_state, u8, { -+ .target_category = SSAM_SSH_TC_KIP, -+ .target_id = 0x01, -+ .command_id = 0x1d, -+ .instance_id = 0x00, -+}); -+ -+static int ssam_kip_get_cover_state(struct ssam_tablet_sw *sw, u32 *state) -+{ -+ int status; -+ u8 raw; -+ -+ status = ssam_retry(__ssam_kip_get_cover_state, sw->sdev->ctrl, &raw); -+ if (status < 0) { -+ dev_err(&sw->sdev->dev, "failed to query KIP lid state: %d\n", status); -+ return status; -+ } -+ -+ *state = raw; -+ return 0; -+} -+ -+static u32 ssam_kip_sw_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) -+{ -+ struct ssam_tablet_sw *sw = container_of(nf, struct ssam_tablet_sw, notif); -+ -+ if (event->command_id != SSAM_EVENT_KIP_CID_COVER_STATE_CHANGED) -+ return 0; /* Return "unhandled". */ -+ -+ if (event->length < 1) -+ dev_warn(&sw->sdev->dev, "unexpected payload size: %u\n", event->length); -+ -+ schedule_work(&sw->update_work); -+ return SSAM_NOTIF_HANDLED; -+} -+ -+static const struct ssam_tablet_sw_desc ssam_kip_sw_desc = { -+ .dev = { -+ .name = "Microsoft Surface KIP Tablet Mode Switch", -+ .phys = "ssam/01:0e:01:00:01/input0", -+ }, -+ .ops = { -+ .notify = ssam_kip_sw_notif, -+ .get_state = ssam_kip_get_cover_state, -+ .state_name = ssam_kip_cover_state_name, -+ .state_is_tablet_mode = ssam_kip_cover_state_is_tablet_mode, -+ }, -+ .event = { -+ .reg = SSAM_EVENT_REGISTRY_SAM, -+ .id = { -+ .target_category = SSAM_SSH_TC_KIP, -+ .instance = 0, -+ }, -+ .mask = SSAM_EVENT_MASK_TARGET, -+ }, -+}; -+ -+ -+/* -- SSAM POS tablet switch implementation. -------------------------------- */ -+ -+static bool tablet_mode_in_slate_state = true; -+module_param(tablet_mode_in_slate_state, bool, 0644); -+MODULE_PARM_DESC(tablet_mode_in_slate_state, "Enable tablet mode in slate device posture, default is 'true'"); -+ -+#define SSAM_EVENT_POS_CID_POSTURE_CHANGED 0x03 -+#define SSAM_POS_MAX_SOURCES 4 -+ -+enum ssam_pos_state { -+ SSAM_POS_POSTURE_LID_CLOSED = 0x00, -+ SSAM_POS_POSTURE_LAPTOP = 0x01, -+ SSAM_POS_POSTURE_SLATE = 0x02, -+ SSAM_POS_POSTURE_TABLET = 0x03, -+}; -+ -+struct ssam_sources_list { -+ __le32 count; -+ __le32 id[SSAM_POS_MAX_SOURCES]; -+} __packed; -+ -+static const char *ssam_pos_state_name(struct ssam_tablet_sw *sw, u32 state) -+{ -+ switch (state) { -+ case SSAM_POS_POSTURE_LID_CLOSED: -+ return "closed"; -+ -+ case SSAM_POS_POSTURE_LAPTOP: -+ return "laptop"; -+ -+ case SSAM_POS_POSTURE_SLATE: -+ return "slate"; -+ -+ case SSAM_POS_POSTURE_TABLET: -+ return "tablet"; -+ -+ default: -+ dev_warn(&sw->sdev->dev, "unknown device posture: %u\n", state); -+ return "<unknown>"; -+ } -+} -+ -+static bool ssam_pos_state_is_tablet_mode(struct ssam_tablet_sw *sw, u32 state) -+{ -+ switch (state) { -+ case SSAM_POS_POSTURE_LAPTOP: -+ case SSAM_POS_POSTURE_LID_CLOSED: -+ return false; -+ -+ case SSAM_POS_POSTURE_SLATE: -+ return tablet_mode_in_slate_state; -+ -+ case SSAM_POS_POSTURE_TABLET: -+ return true; -+ -+ default: -+ dev_warn(&sw->sdev->dev, "unknown device posture: %u\n", state); -+ return true; -+ } -+} -+ -+static int ssam_pos_get_sources_list(struct ssam_tablet_sw *sw, struct ssam_sources_list *sources) -+{ -+ struct ssam_request rqst; -+ struct ssam_response rsp; -+ int status; -+ -+ rqst.target_category = SSAM_SSH_TC_POS; -+ rqst.target_id = 0x01; -+ rqst.command_id = 0x01; -+ rqst.instance_id = 0x00; -+ rqst.flags = SSAM_REQUEST_HAS_RESPONSE; -+ rqst.length = 0; -+ rqst.payload = NULL; -+ -+ rsp.capacity = sizeof(*sources); -+ rsp.length = 0; -+ rsp.pointer = (u8 *)sources; -+ -+ status = ssam_retry(ssam_request_sync_onstack, sw->sdev->ctrl, &rqst, &rsp, 0); -+ if (status) -+ return status; -+ -+ /* We need at least the 'sources->count' field. */ -+ if (rsp.length < sizeof(__le32)) { -+ dev_err(&sw->sdev->dev, "received source list response is too small\n"); -+ return -EPROTO; -+ } -+ -+ /* Make sure 'sources->count' matches with the response length. */ -+ if (get_unaligned_le32(&sources->count) * sizeof(__le32) + sizeof(__le32) != rsp.length) { -+ dev_err(&sw->sdev->dev, "mismatch between number of sources and response size\n"); -+ return -EPROTO; -+ } -+ -+ return 0; -+} -+ -+static int ssam_pos_get_source(struct ssam_tablet_sw *sw, u32 *source_id) -+{ -+ struct ssam_sources_list sources = {}; -+ int status; -+ -+ status = ssam_pos_get_sources_list(sw, &sources); -+ if (status) -+ return status; -+ -+ if (sources.count == 0) { -+ dev_err(&sw->sdev->dev, "no posture sources found\n"); -+ return -ENODEV; -+ } -+ -+ /* -+ * We currently don't know what to do with more than one posture -+ * source. At the moment, only one source seems to be used/provided. -+ * The WARN_ON() here should hopefully let us know quickly once there -+ * is a device that provides multiple sources, at which point we can -+ * then try to figure out how to handle them. -+ */ -+ WARN_ON(sources.count > 1); -+ -+ *source_id = get_unaligned_le32(&sources.id[0]); -+ return 0; -+} -+ -+SSAM_DEFINE_SYNC_REQUEST_WR(__ssam_pos_get_posture_for_source, __le32, __le32, { -+ .target_category = SSAM_SSH_TC_POS, -+ .target_id = 0x01, -+ .command_id = 0x02, -+ .instance_id = 0x00, -+}); -+ -+static int ssam_pos_get_posture_for_source(struct ssam_tablet_sw *sw, u32 source_id, u32 *posture) -+{ -+ __le32 source_le = cpu_to_le32(source_id); -+ __le32 rspval_le = 0; -+ int status; -+ -+ status = ssam_retry(__ssam_pos_get_posture_for_source, sw->sdev->ctrl, -+ &source_le, &rspval_le); -+ if (status) -+ return status; -+ -+ *posture = le32_to_cpu(rspval_le); -+ return 0; -+} -+ -+static int ssam_pos_get_posture(struct ssam_tablet_sw *sw, u32 *state) -+{ -+ u32 source_id; -+ int status; -+ -+ status = ssam_pos_get_source(sw, &source_id); -+ if (status) { -+ dev_err(&sw->sdev->dev, "failed to get posture source ID: %d\n", status); -+ return status; -+ } -+ -+ status = ssam_pos_get_posture_for_source(sw, source_id, state); -+ if (status) { -+ dev_err(&sw->sdev->dev, "failed to get posture value for source %u: %d\n", -+ source_id, status); -+ return status; -+ } -+ -+ return 0; -+} -+ -+static u32 ssam_pos_sw_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) -+{ -+ struct ssam_tablet_sw *sw = container_of(nf, struct ssam_tablet_sw, notif); -+ -+ if (event->command_id != SSAM_EVENT_POS_CID_POSTURE_CHANGED) -+ return 0; /* Return "unhandled". */ -+ -+ if (event->length != sizeof(__le32) * 3) -+ dev_warn(&sw->sdev->dev, "unexpected payload size: %u\n", event->length); -+ -+ schedule_work(&sw->update_work); -+ return SSAM_NOTIF_HANDLED; -+} -+ -+static const struct ssam_tablet_sw_desc ssam_pos_sw_desc = { -+ .dev = { -+ .name = "Microsoft Surface POS Tablet Mode Switch", -+ .phys = "ssam/01:26:01:00:01/input0", -+ }, -+ .ops = { -+ .notify = ssam_pos_sw_notif, -+ .get_state = ssam_pos_get_posture, -+ .state_name = ssam_pos_state_name, -+ .state_is_tablet_mode = ssam_pos_state_is_tablet_mode, -+ }, -+ .event = { -+ .reg = SSAM_EVENT_REGISTRY_SAM, -+ .id = { -+ .target_category = SSAM_SSH_TC_POS, -+ .instance = 0, -+ }, -+ .mask = SSAM_EVENT_MASK_TARGET, -+ }, -+}; -+ -+ -+/* -- Driver registration. -------------------------------------------------- */ -+ -+static const struct ssam_device_id ssam_tablet_sw_match[] = { -+ { SSAM_SDEV(KIP, 0x01, 0x00, 0x01), (unsigned long)&ssam_kip_sw_desc }, -+ { SSAM_SDEV(POS, 0x01, 0x00, 0x01), (unsigned long)&ssam_pos_sw_desc }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(ssam, ssam_tablet_sw_match); -+ -+static struct ssam_device_driver ssam_tablet_sw_driver = { -+ .probe = ssam_tablet_sw_probe, -+ .remove = ssam_tablet_sw_remove, -+ .match_table = ssam_tablet_sw_match, -+ .driver = { -+ .name = "surface_aggregator_tablet_mode_switch", -+ .probe_type = PROBE_PREFER_ASYNCHRONOUS, -+ .pm = &ssam_tablet_sw_pm_ops, -+ }, -+}; -+module_ssam_device_driver(ssam_tablet_sw_driver); -+ -+MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); -+MODULE_DESCRIPTION("Tablet mode switch driver for Surface devices using the Surface Aggregator Module"); -+MODULE_LICENSE("GPL"); --- -2.37.3 - -From 4c7ffca61c7b8d0e61817a7b3b33a1de211e7fe0 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 20:36:41 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Add support for tablet - mode switch on Surface Pro 8 - -Add a KIP subsystem tablet-mode switch device for the Surface Pro 8. -The respective driver for this device provides SW_TABLET_MODE input -events for user-space based on the state of the keyboard cover (e.g. -detached, folded-back, normal/laptop mode). - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624183642.910893-4-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/surface_aggregator_registry.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index bf3303f1aa71..8f249df673a4 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -77,6 +77,12 @@ static const struct software_node ssam_node_tmp_pprof = { - .parent = &ssam_node_root, - }; - -+/* Tablet-mode switch via KIP subsystem. */ -+static const struct software_node ssam_node_kip_tablet_switch = { -+ .name = "ssam:01:0e:01:00:01", -+ .parent = &ssam_node_root, -+}; -+ - /* DTX / detachment-system device (Surface Book 3). */ - static const struct software_node ssam_node_bas_dtx = { - .name = "ssam:01:11:01:00:00", -@@ -264,11 +270,11 @@ static const struct software_node *ssam_node_group_sp8[] = { - &ssam_node_bat_ac, - &ssam_node_bat_main, - &ssam_node_tmp_pprof, -+ &ssam_node_kip_tablet_switch, - &ssam_node_hid_kip_keyboard, - &ssam_node_hid_kip_penstash, - &ssam_node_hid_kip_touchpad, - &ssam_node_hid_kip_iid5, -- /* TODO: Add support for tablet mode switch. */ - NULL, - }; - --- -2.37.3 - -From 6ba6d1fcf6051cb53a77699f48c16eae657af1da Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 20:36:42 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Add support for tablet - mode switch on Surface Laptop Studio - -Add a POS subsystem tablet-mode switch device for the Surface Laptop -Studio. The respective driver for this device provides SW_TABLET_MODE -input events for user-space based on the posture of the screen. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624183642.910893-5-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/surface_aggregator_registry.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 8f249df673a4..f1c5905f1c16 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -191,6 +191,12 @@ static const struct software_node ssam_node_hid_kip_iid5 = { - .parent = &ssam_node_hub_kip, - }; - -+/* Tablet-mode switch via POS subsystem. */ -+static const struct software_node ssam_node_pos_tablet_switch = { -+ .name = "ssam:01:26:01:00:01", -+ .parent = &ssam_node_root, -+}; -+ - /* - * Devices for 5th- and 6th-generations models: - * - Surface Book 2, -@@ -237,6 +243,7 @@ static const struct software_node *ssam_node_group_sls[] = { - &ssam_node_bat_ac, - &ssam_node_bat_main, - &ssam_node_tmp_pprof, -+ &ssam_node_pos_tablet_switch, - &ssam_node_hid_tid1_keyboard, - &ssam_node_hid_tid1_penstash, - &ssam_node_hid_tid1_touchpad, --- -2.37.3 - -From cc428a2c4526883ee235656522c24e5db1a1ed0c Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 22:57:58 +0200 -Subject: [PATCH] platform/surface: aggregator: Move device registry helper - functions to core module - -Move helper functions for client device registration to the core module. -This simplifies addition of future DT/OF support and also allows us to -split out the device hub drivers into their own module. - -At the same time, also improve device node validation a bit by not -silently skipping devices with invalid device UID specifiers. Further, -ensure proper lifetime management for the firmware/software nodes -associated with the added devices. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624205800.1355621-2-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/aggregator/bus.c | 149 ++++++++++++++++-- - .../surface/surface_aggregator_registry.c | 75 +-------- - include/linux/surface_aggregator/device.h | 52 ++++++ - 3 files changed, 187 insertions(+), 89 deletions(-) - -diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c -index abbbb5b08b07..e0b0381a2834 100644 ---- a/drivers/platform/surface/aggregator/bus.c -+++ b/drivers/platform/surface/aggregator/bus.c -@@ -6,6 +6,7 @@ - */ - - #include <linux/device.h> -+#include <linux/property.h> - #include <linux/slab.h> - - #include <linux/surface_aggregator/controller.h> -@@ -14,6 +15,9 @@ - #include "bus.h" - #include "controller.h" - -+ -+/* -- Device and bus functions. --------------------------------------------- */ -+ - static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, - char *buf) - { -@@ -46,6 +50,7 @@ static void ssam_device_release(struct device *dev) - struct ssam_device *sdev = to_ssam_device(dev); - - ssam_controller_put(sdev->ctrl); -+ fwnode_handle_put(sdev->dev.fwnode); - kfree(sdev); - } - -@@ -363,6 +368,134 @@ void ssam_device_driver_unregister(struct ssam_device_driver *sdrv) - } - EXPORT_SYMBOL_GPL(ssam_device_driver_unregister); - -+ -+/* -- Bus registration. ----------------------------------------------------- */ -+ -+/** -+ * ssam_bus_register() - Register and set-up the SSAM client device bus. -+ */ -+int ssam_bus_register(void) -+{ -+ return bus_register(&ssam_bus_type); -+} -+ -+/** -+ * ssam_bus_unregister() - Unregister the SSAM client device bus. -+ */ -+void ssam_bus_unregister(void) -+{ -+ return bus_unregister(&ssam_bus_type); -+} -+ -+ -+/* -- Helpers for controller and hub devices. ------------------------------- */ -+ -+static int ssam_device_uid_from_string(const char *str, struct ssam_device_uid *uid) -+{ -+ u8 d, tc, tid, iid, fn; -+ int n; -+ -+ n = sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx", &d, &tc, &tid, &iid, &fn); -+ if (n != 5) -+ return -EINVAL; -+ -+ uid->domain = d; -+ uid->category = tc; -+ uid->target = tid; -+ uid->instance = iid; -+ uid->function = fn; -+ -+ return 0; -+} -+ -+static int ssam_get_uid_for_node(struct fwnode_handle *node, struct ssam_device_uid *uid) -+{ -+ const char *str = fwnode_get_name(node); -+ -+ /* -+ * To simplify definitions of firmware nodes, we set the device name -+ * based on the UID of the device, prefixed with "ssam:". -+ */ -+ if (strncmp(str, "ssam:", strlen("ssam:")) != 0) -+ return -ENODEV; -+ -+ str += strlen("ssam:"); -+ return ssam_device_uid_from_string(str, uid); -+} -+ -+static int ssam_add_client_device(struct device *parent, struct ssam_controller *ctrl, -+ struct fwnode_handle *node) -+{ -+ struct ssam_device_uid uid; -+ struct ssam_device *sdev; -+ int status; -+ -+ status = ssam_get_uid_for_node(node, &uid); -+ if (status) -+ return status; -+ -+ sdev = ssam_device_alloc(ctrl, uid); -+ if (!sdev) -+ return -ENOMEM; -+ -+ sdev->dev.parent = parent; -+ sdev->dev.fwnode = fwnode_handle_get(node); -+ -+ status = ssam_device_add(sdev); -+ if (status) -+ ssam_device_put(sdev); -+ -+ return status; -+} -+ -+/** -+ * __ssam_register_clients() - Register client devices defined under the -+ * given firmware node as children of the given device. -+ * @parent: The parent device under which clients should be registered. -+ * @ctrl: The controller with which client should be registered. -+ * @node: The firmware node holding definitions of the devices to be added. -+ * -+ * Register all clients that have been defined as children of the given root -+ * firmware node as children of the given parent device. The respective child -+ * firmware nodes will be associated with the correspondingly created child -+ * devices. -+ * -+ * The given controller will be used to instantiate the new devices. See -+ * ssam_device_add() for details. -+ * -+ * Note that, generally, the use of either ssam_device_register_clients() or -+ * ssam_register_clients() should be preferred as they directly use the -+ * firmware node and/or controller associated with the given device. This -+ * function is only intended for use when different device specifications (e.g. -+ * ACPI and firmware nodes) need to be combined (as is done in the platform hub -+ * of the device registry). -+ * -+ * Return: Returns zero on success, nonzero on failure. -+ */ -+int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl, -+ struct fwnode_handle *node) -+{ -+ struct fwnode_handle *child; -+ int status; -+ -+ fwnode_for_each_child_node(node, child) { -+ /* -+ * Try to add the device specified in the firmware node. If -+ * this fails with -ENODEV, the node does not specify any SSAM -+ * device, so ignore it and continue with the next one. -+ */ -+ status = ssam_add_client_device(parent, ctrl, child); -+ if (status && status != -ENODEV) -+ goto err; -+ } -+ -+ return 0; -+err: -+ ssam_remove_clients(parent); -+ return status; -+} -+EXPORT_SYMBOL_GPL(__ssam_register_clients); -+ - static int ssam_remove_device(struct device *dev, void *_data) - { - struct ssam_device *sdev = to_ssam_device(dev); -@@ -387,19 +520,3 @@ void ssam_remove_clients(struct device *dev) - device_for_each_child_reverse(dev, NULL, ssam_remove_device); - } - EXPORT_SYMBOL_GPL(ssam_remove_clients); -- --/** -- * ssam_bus_register() - Register and set-up the SSAM client device bus. -- */ --int ssam_bus_register(void) --{ -- return bus_register(&ssam_bus_type); --} -- --/** -- * ssam_bus_unregister() - Unregister the SSAM client device bus. -- */ --void ssam_bus_unregister(void) --{ -- return bus_unregister(&ssam_bus_type); --} -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index f1c5905f1c16..c680792a037e 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -286,76 +286,6 @@ static const struct software_node *ssam_node_group_sp8[] = { - }; - - --/* -- Device registry helper functions. ------------------------------------- */ -- --static int ssam_uid_from_string(const char *str, struct ssam_device_uid *uid) --{ -- u8 d, tc, tid, iid, fn; -- int n; -- -- n = sscanf(str, "ssam:%hhx:%hhx:%hhx:%hhx:%hhx", &d, &tc, &tid, &iid, &fn); -- if (n != 5) -- return -EINVAL; -- -- uid->domain = d; -- uid->category = tc; -- uid->target = tid; -- uid->instance = iid; -- uid->function = fn; -- -- return 0; --} -- --static int ssam_hub_add_device(struct device *parent, struct ssam_controller *ctrl, -- struct fwnode_handle *node) --{ -- struct ssam_device_uid uid; -- struct ssam_device *sdev; -- int status; -- -- status = ssam_uid_from_string(fwnode_get_name(node), &uid); -- if (status) -- return status; -- -- sdev = ssam_device_alloc(ctrl, uid); -- if (!sdev) -- return -ENOMEM; -- -- sdev->dev.parent = parent; -- sdev->dev.fwnode = node; -- -- status = ssam_device_add(sdev); -- if (status) -- ssam_device_put(sdev); -- -- return status; --} -- --static int ssam_hub_register_clients(struct device *parent, struct ssam_controller *ctrl, -- struct fwnode_handle *node) --{ -- struct fwnode_handle *child; -- int status; -- -- fwnode_for_each_child_node(node, child) { -- /* -- * Try to add the device specified in the firmware node. If -- * this fails with -EINVAL, the node does not specify any SSAM -- * device, so ignore it and continue with the next one. -- */ -- -- status = ssam_hub_add_device(parent, ctrl, child); -- if (status && status != -EINVAL) -- goto err; -- } -- -- return 0; --err: -- ssam_remove_clients(parent); -- return status; --} -- -- - /* -- SSAM generic subsystem hub driver framework. -------------------------- */ - - enum ssam_hub_state { -@@ -385,7 +315,6 @@ struct ssam_hub { - static void ssam_hub_update_workfn(struct work_struct *work) - { - struct ssam_hub *hub = container_of(work, struct ssam_hub, update_work.work); -- struct fwnode_handle *node = dev_fwnode(&hub->sdev->dev); - enum ssam_hub_state state; - int status = 0; - -@@ -425,7 +354,7 @@ static void ssam_hub_update_workfn(struct work_struct *work) - hub->state = state; - - if (hub->state == SSAM_HUB_CONNECTED) -- status = ssam_hub_register_clients(&hub->sdev->dev, hub->sdev->ctrl, node); -+ status = ssam_device_register_clients(hub->sdev); - else - ssam_remove_clients(&hub->sdev->dev); - -@@ -769,7 +698,7 @@ static int ssam_platform_hub_probe(struct platform_device *pdev) - - set_secondary_fwnode(&pdev->dev, root); - -- status = ssam_hub_register_clients(&pdev->dev, ctrl, root); -+ status = __ssam_register_clients(&pdev->dev, ctrl, root); - if (status) { - set_secondary_fwnode(&pdev->dev, NULL); - software_node_unregister_node_group(nodes); -diff --git a/include/linux/surface_aggregator/device.h b/include/linux/surface_aggregator/device.h -index 6cf7e80312d5..46c45d1b6368 100644 ---- a/include/linux/surface_aggregator/device.h -+++ b/include/linux/surface_aggregator/device.h -@@ -15,6 +15,7 @@ - - #include <linux/device.h> - #include <linux/mod_devicetable.h> -+#include <linux/property.h> - #include <linux/types.h> - - #include <linux/surface_aggregator/controller.h> -@@ -375,11 +376,62 @@ void ssam_device_driver_unregister(struct ssam_device_driver *d); - /* -- Helpers for controller and hub devices. ------------------------------- */ - - #ifdef CONFIG_SURFACE_AGGREGATOR_BUS -+ -+int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl, -+ struct fwnode_handle *node); - void ssam_remove_clients(struct device *dev); -+ - #else /* CONFIG_SURFACE_AGGREGATOR_BUS */ -+ -+static inline int __ssam_register_clients(struct device *parent, struct ssam_controller *ctrl, -+ struct fwnode_handle *node) -+{ -+ return 0; -+} -+ - static inline void ssam_remove_clients(struct device *dev) {} -+ - #endif /* CONFIG_SURFACE_AGGREGATOR_BUS */ - -+/** -+ * ssam_register_clients() - Register all client devices defined under the -+ * given parent device. -+ * @dev: The parent device under which clients should be registered. -+ * @ctrl: The controller with which client should be registered. -+ * -+ * Register all clients that have via firmware nodes been defined as children -+ * of the given (parent) device. The respective child firmware nodes will be -+ * associated with the correspondingly created child devices. -+ * -+ * The given controller will be used to instantiate the new devices. See -+ * ssam_device_add() for details. -+ * -+ * Return: Returns zero on success, nonzero on failure. -+ */ -+static inline int ssam_register_clients(struct device *dev, struct ssam_controller *ctrl) -+{ -+ return __ssam_register_clients(dev, ctrl, dev_fwnode(dev)); -+} -+ -+/** -+ * ssam_device_register_clients() - Register all client devices defined under -+ * the given SSAM parent device. -+ * @sdev: The parent device under which clients should be registered. -+ * -+ * Register all clients that have via firmware nodes been defined as children -+ * of the given (parent) device. The respective child firmware nodes will be -+ * associated with the correspondingly created child devices. -+ * -+ * The controller used by the parent device will be used to instantiate the new -+ * devices. See ssam_device_add() for details. -+ * -+ * Return: Returns zero on success, nonzero on failure. -+ */ -+static inline int ssam_device_register_clients(struct ssam_device *sdev) -+{ -+ return ssam_register_clients(&sdev->dev, sdev->ctrl); -+} -+ - - /* -- Helpers for client-device requests. ----------------------------------- */ - --- -2.37.3 - -From 27f8c2755977e980995a6c1a1fc4f310e7fd845d Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 22:57:59 +0200 -Subject: [PATCH] platform/surface: aggregator: Move subsystem hub drivers to - their own module - -Split out subsystem device hub drivers into their own module. This -allows us to load the hub drivers separately from the registry, which -will help future DT/OF support. - -While doing so, also remove a small bit of code duplication. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624205800.1355621-3-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - MAINTAINERS | 6 + - drivers/platform/surface/Kconfig | 35 +- - drivers/platform/surface/Makefile | 1 + - .../platform/surface/surface_aggregator_hub.c | 371 ++++++++++++++++++ - .../surface/surface_aggregator_registry.c | 371 +----------------- - 5 files changed, 410 insertions(+), 374 deletions(-) - create mode 100644 drivers/platform/surface/surface_aggregator_hub.c - -diff --git a/MAINTAINERS b/MAINTAINERS -index 773eb8387f4a..55e80354a097 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13376,6 +13376,12 @@ F: include/linux/surface_acpi_notify.h - F: include/linux/surface_aggregator/ - F: include/uapi/linux/surface_aggregator/ - -+MICROSOFT SURFACE SYSTEM AGGREGATOR HUB DRIVER -+M: Maximilian Luz <luzmaximilian@gmail.com> -+L: platform-driver-x86@vger.kernel.org -+S: Maintained -+F: drivers/platform/surface/surface_aggregator_hub.c -+ - MICROTEK X6 SCANNER - M: Oliver Neukum <oliver@neukum.org> - S: Maintained -diff --git a/drivers/platform/surface/Kconfig b/drivers/platform/surface/Kconfig -index b152e930cc84..b629e82af97c 100644 ---- a/drivers/platform/surface/Kconfig -+++ b/drivers/platform/surface/Kconfig -@@ -72,18 +72,45 @@ config SURFACE_AGGREGATOR_CDEV - The provided interface is intended for debugging and development only, - and should not be used otherwise. - -+config SURFACE_AGGREGATOR_HUB -+ tristate "Surface System Aggregator Module Subsystem Device Hubs" -+ depends on SURFACE_AGGREGATOR -+ depends on SURFACE_AGGREGATOR_BUS -+ help -+ Device-hub drivers for Surface System Aggregator Module (SSAM) subsystem -+ devices. -+ -+ Provides subsystem hub drivers which manage client devices on various -+ SSAM subsystems. In some subsystems, notably the BAS subsystem managing -+ devices contained in the base of the Surface Book 3 and the KIP subsystem -+ managing type-cover devices in the Surface Pro 8 and Surface Pro X, -+ devices can be (hot-)removed. Hub devices and drivers are required to -+ manage these subdevices. -+ -+ Devices managed via these hubs are: -+ - Battery/AC devices (Surface Book 3). -+ - HID input devices (7th-generation and later models with detachable -+ input devices). -+ -+ Select M (recommended) or Y here if you want support for the above -+ mentioned devices on the corresponding Surface models. Without this -+ module, the respective devices mentioned above will not be instantiated -+ and thus any functionality provided by them will be missing, even when -+ drivers for these devices are present. This module only provides the -+ respective subsystem hubs. Both drivers and device specification (e.g. -+ via the Surface Aggregator Registry) for these devices still need to be -+ selected via other options. -+ - config SURFACE_AGGREGATOR_REGISTRY - tristate "Surface System Aggregator Module Device Registry" - depends on SURFACE_AGGREGATOR - depends on SURFACE_AGGREGATOR_BUS - help -- Device-registry and device-hubs for Surface System Aggregator Module -- (SSAM) devices. -+ Device-registry for Surface System Aggregator Module (SSAM) devices. - - Provides a module and driver which act as a device-registry for SSAM - client devices that cannot be detected automatically, e.g. via ACPI. -- Such devices are instead provided via this registry and attached via -- device hubs, also provided in this module. -+ Such devices are instead provided and managed via this registry. - - Devices provided via this registry are: - - Platform profile (performance-/cooling-mode) device (5th- and later -diff --git a/drivers/platform/surface/Makefile b/drivers/platform/surface/Makefile -index 18b27898543e..53344330939b 100644 ---- a/drivers/platform/surface/Makefile -+++ b/drivers/platform/surface/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_SURFACE_3_POWER_OPREGION) += surface3_power.o - obj-$(CONFIG_SURFACE_ACPI_NOTIFY) += surface_acpi_notify.o - obj-$(CONFIG_SURFACE_AGGREGATOR) += aggregator/ - obj-$(CONFIG_SURFACE_AGGREGATOR_CDEV) += surface_aggregator_cdev.o -+obj-$(CONFIG_SURFACE_AGGREGATOR_HUB) += surface_aggregator_hub.o - obj-$(CONFIG_SURFACE_AGGREGATOR_REGISTRY) += surface_aggregator_registry.o - obj-$(CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH) += surface_aggregator_tabletsw.o - obj-$(CONFIG_SURFACE_DTX) += surface_dtx.o -diff --git a/drivers/platform/surface/surface_aggregator_hub.c b/drivers/platform/surface/surface_aggregator_hub.c -new file mode 100644 -index 000000000000..43061514be38 ---- /dev/null -+++ b/drivers/platform/surface/surface_aggregator_hub.c -@@ -0,0 +1,371 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Driver for Surface System Aggregator Module (SSAM) subsystem device hubs. -+ * -+ * Provides a driver for SSAM subsystems device hubs. This driver performs -+ * instantiation of the devices managed by said hubs and takes care of -+ * (hot-)removal. -+ * -+ * Copyright (C) 2020-2022 Maximilian Luz <luzmaximilian@gmail.com> -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/limits.h> -+#include <linux/module.h> -+#include <linux/types.h> -+#include <linux/workqueue.h> -+ -+#include <linux/surface_aggregator/device.h> -+ -+ -+/* -- SSAM generic subsystem hub driver framework. -------------------------- */ -+ -+enum ssam_hub_state { -+ SSAM_HUB_UNINITIALIZED, /* Only set during initialization. */ -+ SSAM_HUB_CONNECTED, -+ SSAM_HUB_DISCONNECTED, -+}; -+ -+enum ssam_hub_flags { -+ SSAM_HUB_HOT_REMOVED, -+}; -+ -+struct ssam_hub; -+ -+struct ssam_hub_ops { -+ int (*get_state)(struct ssam_hub *hub, enum ssam_hub_state *state); -+}; -+ -+struct ssam_hub { -+ struct ssam_device *sdev; -+ -+ enum ssam_hub_state state; -+ unsigned long flags; -+ -+ struct delayed_work update_work; -+ unsigned long connect_delay; -+ -+ struct ssam_event_notifier notif; -+ struct ssam_hub_ops ops; -+}; -+ -+struct ssam_hub_desc { -+ struct { -+ struct ssam_event_registry reg; -+ struct ssam_event_id id; -+ enum ssam_event_mask mask; -+ } event; -+ -+ struct { -+ u32 (*notify)(struct ssam_event_notifier *nf, const struct ssam_event *event); -+ int (*get_state)(struct ssam_hub *hub, enum ssam_hub_state *state); -+ } ops; -+ -+ unsigned long connect_delay_ms; -+}; -+ -+static void ssam_hub_update_workfn(struct work_struct *work) -+{ -+ struct ssam_hub *hub = container_of(work, struct ssam_hub, update_work.work); -+ enum ssam_hub_state state; -+ int status = 0; -+ -+ status = hub->ops.get_state(hub, &state); -+ if (status) -+ return; -+ -+ /* -+ * There is a small possibility that hub devices were hot-removed and -+ * re-added before we were able to remove them here. In that case, both -+ * the state returned by get_state() and the state of the hub will -+ * equal SSAM_HUB_CONNECTED and we would bail early below, which would -+ * leave child devices without proper (re-)initialization and the -+ * hot-remove flag set. -+ * -+ * Therefore, we check whether devices have been hot-removed via an -+ * additional flag on the hub and, in this case, override the returned -+ * hub state. In case of a missed disconnect (i.e. get_state returned -+ * "connected"), we further need to re-schedule this work (with the -+ * appropriate delay) as the actual connect work submission might have -+ * been merged with this one. -+ * -+ * This then leads to one of two cases: Either we submit an unnecessary -+ * work item (which will get ignored via either the queue or the state -+ * checks) or, in the unlikely case that the work is actually required, -+ * double the normal connect delay. -+ */ -+ if (test_and_clear_bit(SSAM_HUB_HOT_REMOVED, &hub->flags)) { -+ if (state == SSAM_HUB_CONNECTED) -+ schedule_delayed_work(&hub->update_work, hub->connect_delay); -+ -+ state = SSAM_HUB_DISCONNECTED; -+ } -+ -+ if (hub->state == state) -+ return; -+ hub->state = state; -+ -+ if (hub->state == SSAM_HUB_CONNECTED) -+ status = ssam_device_register_clients(hub->sdev); -+ else -+ ssam_remove_clients(&hub->sdev->dev); -+ -+ if (status) -+ dev_err(&hub->sdev->dev, "failed to update hub child devices: %d\n", status); -+} -+ -+static int ssam_hub_mark_hot_removed(struct device *dev, void *_data) -+{ -+ struct ssam_device *sdev = to_ssam_device(dev); -+ -+ if (is_ssam_device(dev)) -+ ssam_device_mark_hot_removed(sdev); -+ -+ return 0; -+} -+ -+static void ssam_hub_update(struct ssam_hub *hub, bool connected) -+{ -+ unsigned long delay; -+ -+ /* Mark devices as hot-removed before we remove any. */ -+ if (!connected) { -+ set_bit(SSAM_HUB_HOT_REMOVED, &hub->flags); -+ device_for_each_child_reverse(&hub->sdev->dev, NULL, ssam_hub_mark_hot_removed); -+ } -+ -+ /* -+ * Delay update when the base/keyboard cover is being connected to give -+ * devices/EC some time to set up. -+ */ -+ delay = connected ? hub->connect_delay : 0; -+ -+ schedule_delayed_work(&hub->update_work, delay); -+} -+ -+static int __maybe_unused ssam_hub_resume(struct device *dev) -+{ -+ struct ssam_hub *hub = dev_get_drvdata(dev); -+ -+ schedule_delayed_work(&hub->update_work, 0); -+ return 0; -+} -+static SIMPLE_DEV_PM_OPS(ssam_hub_pm_ops, NULL, ssam_hub_resume); -+ -+static int ssam_hub_probe(struct ssam_device *sdev) -+{ -+ const struct ssam_hub_desc *desc; -+ struct ssam_hub *hub; -+ int status; -+ -+ desc = ssam_device_get_match_data(sdev); -+ if (!desc) { -+ WARN(1, "no driver match data specified"); -+ return -EINVAL; -+ } -+ -+ hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL); -+ if (!hub) -+ return -ENOMEM; -+ -+ hub->sdev = sdev; -+ hub->state = SSAM_HUB_UNINITIALIZED; -+ -+ hub->notif.base.priority = INT_MAX; /* This notifier should run first. */ -+ hub->notif.base.fn = desc->ops.notify; -+ hub->notif.event.reg = desc->event.reg; -+ hub->notif.event.id = desc->event.id; -+ hub->notif.event.mask = desc->event.mask; -+ hub->notif.event.flags = SSAM_EVENT_SEQUENCED; -+ -+ hub->connect_delay = msecs_to_jiffies(desc->connect_delay_ms); -+ hub->ops.get_state = desc->ops.get_state; -+ -+ INIT_DELAYED_WORK(&hub->update_work, ssam_hub_update_workfn); -+ -+ ssam_device_set_drvdata(sdev, hub); -+ -+ status = ssam_device_notifier_register(sdev, &hub->notif); -+ if (status) -+ return status; -+ -+ schedule_delayed_work(&hub->update_work, 0); -+ return 0; -+} -+ -+static void ssam_hub_remove(struct ssam_device *sdev) -+{ -+ struct ssam_hub *hub = ssam_device_get_drvdata(sdev); -+ -+ ssam_device_notifier_unregister(sdev, &hub->notif); -+ cancel_delayed_work_sync(&hub->update_work); -+ ssam_remove_clients(&sdev->dev); -+} -+ -+ -+/* -- SSAM base-subsystem hub driver. --------------------------------------- */ -+ -+/* -+ * Some devices (especially battery) may need a bit of time to be fully usable -+ * after being (re-)connected. This delay has been determined via -+ * experimentation. -+ */ -+#define SSAM_BASE_UPDATE_CONNECT_DELAY 2500 -+ -+SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_query_opmode, u8, { -+ .target_category = SSAM_SSH_TC_BAS, -+ .target_id = 0x01, -+ .command_id = 0x0d, -+ .instance_id = 0x00, -+}); -+ -+#define SSAM_BAS_OPMODE_TABLET 0x00 -+#define SSAM_EVENT_BAS_CID_CONNECTION 0x0c -+ -+static int ssam_base_hub_query_state(struct ssam_hub *hub, enum ssam_hub_state *state) -+{ -+ u8 opmode; -+ int status; -+ -+ status = ssam_retry(ssam_bas_query_opmode, hub->sdev->ctrl, &opmode); -+ if (status < 0) { -+ dev_err(&hub->sdev->dev, "failed to query base state: %d\n", status); -+ return status; -+ } -+ -+ if (opmode != SSAM_BAS_OPMODE_TABLET) -+ *state = SSAM_HUB_CONNECTED; -+ else -+ *state = SSAM_HUB_DISCONNECTED; -+ -+ return 0; -+} -+ -+static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) -+{ -+ struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif); -+ -+ if (event->command_id != SSAM_EVENT_BAS_CID_CONNECTION) -+ return 0; -+ -+ if (event->length < 1) { -+ dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length); -+ return 0; -+ } -+ -+ ssam_hub_update(hub, event->data[0]); -+ -+ /* -+ * Do not return SSAM_NOTIF_HANDLED: The event should be picked up and -+ * consumed by the detachment system driver. We're just a (more or less) -+ * silent observer. -+ */ -+ return 0; -+} -+ -+static const struct ssam_hub_desc base_hub = { -+ .event = { -+ .reg = SSAM_EVENT_REGISTRY_SAM, -+ .id = { -+ .target_category = SSAM_SSH_TC_BAS, -+ .instance = 0, -+ }, -+ .mask = SSAM_EVENT_MASK_NONE, -+ }, -+ .ops = { -+ .notify = ssam_base_hub_notif, -+ .get_state = ssam_base_hub_query_state, -+ }, -+ .connect_delay_ms = SSAM_BASE_UPDATE_CONNECT_DELAY, -+}; -+ -+ -+/* -- SSAM KIP-subsystem hub driver. ---------------------------------------- */ -+ -+/* -+ * Some devices may need a bit of time to be fully usable after being -+ * (re-)connected. This delay has been determined via experimentation. -+ */ -+#define SSAM_KIP_UPDATE_CONNECT_DELAY 250 -+ -+#define SSAM_EVENT_KIP_CID_CONNECTION 0x2c -+ -+SSAM_DEFINE_SYNC_REQUEST_R(__ssam_kip_query_state, u8, { -+ .target_category = SSAM_SSH_TC_KIP, -+ .target_id = 0x01, -+ .command_id = 0x2c, -+ .instance_id = 0x00, -+}); -+ -+static int ssam_kip_hub_query_state(struct ssam_hub *hub, enum ssam_hub_state *state) -+{ -+ int status; -+ u8 connected; -+ -+ status = ssam_retry(__ssam_kip_query_state, hub->sdev->ctrl, &connected); -+ if (status < 0) { -+ dev_err(&hub->sdev->dev, "failed to query KIP connection state: %d\n", status); -+ return status; -+ } -+ -+ *state = connected ? SSAM_HUB_CONNECTED : SSAM_HUB_DISCONNECTED; -+ return 0; -+} -+ -+static u32 ssam_kip_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) -+{ -+ struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif); -+ -+ if (event->command_id != SSAM_EVENT_KIP_CID_CONNECTION) -+ return 0; /* Return "unhandled". */ -+ -+ if (event->length < 1) { -+ dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length); -+ return 0; -+ } -+ -+ ssam_hub_update(hub, event->data[0]); -+ return SSAM_NOTIF_HANDLED; -+} -+ -+static const struct ssam_hub_desc kip_hub = { -+ .event = { -+ .reg = SSAM_EVENT_REGISTRY_SAM, -+ .id = { -+ .target_category = SSAM_SSH_TC_KIP, -+ .instance = 0, -+ }, -+ .mask = SSAM_EVENT_MASK_TARGET, -+ }, -+ .ops = { -+ .notify = ssam_kip_hub_notif, -+ .get_state = ssam_kip_hub_query_state, -+ }, -+ .connect_delay_ms = SSAM_KIP_UPDATE_CONNECT_DELAY, -+}; -+ -+ -+/* -- Driver registration. -------------------------------------------------- */ -+ -+static const struct ssam_device_id ssam_hub_match[] = { -+ { SSAM_VDEV(HUB, 0x01, SSAM_SSH_TC_KIP, 0x00), (unsigned long)&kip_hub }, -+ { SSAM_VDEV(HUB, 0x02, SSAM_SSH_TC_BAS, 0x00), (unsigned long)&base_hub }, -+ { } -+}; -+MODULE_DEVICE_TABLE(ssam, ssam_hub_match); -+ -+static struct ssam_device_driver ssam_subsystem_hub_driver = { -+ .probe = ssam_hub_probe, -+ .remove = ssam_hub_remove, -+ .match_table = ssam_hub_match, -+ .driver = { -+ .name = "surface_aggregator_subsystem_hub", -+ .probe_type = PROBE_PREFER_ASYNCHRONOUS, -+ .pm = &ssam_hub_pm_ops, -+ }, -+}; -+module_ssam_device_driver(ssam_subsystem_hub_driver); -+ -+MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); -+MODULE_DESCRIPTION("Subsystem device hub driver for Surface System Aggregator Module"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index c680792a037e..0cbb7f3a6b2d 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -11,14 +11,11 @@ - - #include <linux/acpi.h> - #include <linux/kernel.h> --#include <linux/limits.h> - #include <linux/module.h> - #include <linux/platform_device.h> - #include <linux/property.h> - #include <linux/types.h> --#include <linux/workqueue.h> - --#include <linux/surface_aggregator/controller.h> - #include <linux/surface_aggregator/device.h> - - -@@ -286,335 +283,6 @@ static const struct software_node *ssam_node_group_sp8[] = { - }; - - --/* -- SSAM generic subsystem hub driver framework. -------------------------- */ -- --enum ssam_hub_state { -- SSAM_HUB_UNINITIALIZED, /* Only set during initialization. */ -- SSAM_HUB_CONNECTED, -- SSAM_HUB_DISCONNECTED, --}; -- --enum ssam_hub_flags { -- SSAM_HUB_HOT_REMOVED, --}; -- --struct ssam_hub { -- struct ssam_device *sdev; -- -- enum ssam_hub_state state; -- unsigned long flags; -- -- struct delayed_work update_work; -- unsigned long connect_delay; -- -- struct ssam_event_notifier notif; -- -- int (*get_state)(struct ssam_hub *hub, enum ssam_hub_state *state); --}; -- --static void ssam_hub_update_workfn(struct work_struct *work) --{ -- struct ssam_hub *hub = container_of(work, struct ssam_hub, update_work.work); -- enum ssam_hub_state state; -- int status = 0; -- -- status = hub->get_state(hub, &state); -- if (status) -- return; -- -- /* -- * There is a small possibility that hub devices were hot-removed and -- * re-added before we were able to remove them here. In that case, both -- * the state returned by get_state() and the state of the hub will -- * equal SSAM_HUB_CONNECTED and we would bail early below, which would -- * leave child devices without proper (re-)initialization and the -- * hot-remove flag set. -- * -- * Therefore, we check whether devices have been hot-removed via an -- * additional flag on the hub and, in this case, override the returned -- * hub state. In case of a missed disconnect (i.e. get_state returned -- * "connected"), we further need to re-schedule this work (with the -- * appropriate delay) as the actual connect work submission might have -- * been merged with this one. -- * -- * This then leads to one of two cases: Either we submit an unnecessary -- * work item (which will get ignored via either the queue or the state -- * checks) or, in the unlikely case that the work is actually required, -- * double the normal connect delay. -- */ -- if (test_and_clear_bit(SSAM_HUB_HOT_REMOVED, &hub->flags)) { -- if (state == SSAM_HUB_CONNECTED) -- schedule_delayed_work(&hub->update_work, hub->connect_delay); -- -- state = SSAM_HUB_DISCONNECTED; -- } -- -- if (hub->state == state) -- return; -- hub->state = state; -- -- if (hub->state == SSAM_HUB_CONNECTED) -- status = ssam_device_register_clients(hub->sdev); -- else -- ssam_remove_clients(&hub->sdev->dev); -- -- if (status) -- dev_err(&hub->sdev->dev, "failed to update hub child devices: %d\n", status); --} -- --static int ssam_hub_mark_hot_removed(struct device *dev, void *_data) --{ -- struct ssam_device *sdev = to_ssam_device(dev); -- -- if (is_ssam_device(dev)) -- ssam_device_mark_hot_removed(sdev); -- -- return 0; --} -- --static void ssam_hub_update(struct ssam_hub *hub, bool connected) --{ -- unsigned long delay; -- -- /* Mark devices as hot-removed before we remove any. */ -- if (!connected) { -- set_bit(SSAM_HUB_HOT_REMOVED, &hub->flags); -- device_for_each_child_reverse(&hub->sdev->dev, NULL, ssam_hub_mark_hot_removed); -- } -- -- /* -- * Delay update when the base/keyboard cover is being connected to give -- * devices/EC some time to set up. -- */ -- delay = connected ? hub->connect_delay : 0; -- -- schedule_delayed_work(&hub->update_work, delay); --} -- --static int __maybe_unused ssam_hub_resume(struct device *dev) --{ -- struct ssam_hub *hub = dev_get_drvdata(dev); -- -- schedule_delayed_work(&hub->update_work, 0); -- return 0; --} --static SIMPLE_DEV_PM_OPS(ssam_hub_pm_ops, NULL, ssam_hub_resume); -- --static int ssam_hub_setup(struct ssam_device *sdev, struct ssam_hub *hub) --{ -- int status; -- -- hub->sdev = sdev; -- hub->state = SSAM_HUB_UNINITIALIZED; -- -- INIT_DELAYED_WORK(&hub->update_work, ssam_hub_update_workfn); -- -- ssam_device_set_drvdata(sdev, hub); -- -- status = ssam_device_notifier_register(sdev, &hub->notif); -- if (status) -- return status; -- -- schedule_delayed_work(&hub->update_work, 0); -- return 0; --} -- --static void ssam_hub_remove(struct ssam_device *sdev) --{ -- struct ssam_hub *hub = ssam_device_get_drvdata(sdev); -- -- ssam_device_notifier_unregister(sdev, &hub->notif); -- cancel_delayed_work_sync(&hub->update_work); -- ssam_remove_clients(&sdev->dev); --} -- -- --/* -- SSAM base-hub driver. ------------------------------------------------- */ -- --/* -- * Some devices (especially battery) may need a bit of time to be fully usable -- * after being (re-)connected. This delay has been determined via -- * experimentation. -- */ --#define SSAM_BASE_UPDATE_CONNECT_DELAY msecs_to_jiffies(2500) -- --SSAM_DEFINE_SYNC_REQUEST_R(ssam_bas_query_opmode, u8, { -- .target_category = SSAM_SSH_TC_BAS, -- .target_id = 0x01, -- .command_id = 0x0d, -- .instance_id = 0x00, --}); -- --#define SSAM_BAS_OPMODE_TABLET 0x00 --#define SSAM_EVENT_BAS_CID_CONNECTION 0x0c -- --static int ssam_base_hub_query_state(struct ssam_hub *hub, enum ssam_hub_state *state) --{ -- u8 opmode; -- int status; -- -- status = ssam_retry(ssam_bas_query_opmode, hub->sdev->ctrl, &opmode); -- if (status < 0) { -- dev_err(&hub->sdev->dev, "failed to query base state: %d\n", status); -- return status; -- } -- -- if (opmode != SSAM_BAS_OPMODE_TABLET) -- *state = SSAM_HUB_CONNECTED; -- else -- *state = SSAM_HUB_DISCONNECTED; -- -- return 0; --} -- --static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) --{ -- struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif); -- -- if (event->command_id != SSAM_EVENT_BAS_CID_CONNECTION) -- return 0; -- -- if (event->length < 1) { -- dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length); -- return 0; -- } -- -- ssam_hub_update(hub, event->data[0]); -- -- /* -- * Do not return SSAM_NOTIF_HANDLED: The event should be picked up and -- * consumed by the detachment system driver. We're just a (more or less) -- * silent observer. -- */ -- return 0; --} -- --static int ssam_base_hub_probe(struct ssam_device *sdev) --{ -- struct ssam_hub *hub; -- -- hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL); -- if (!hub) -- return -ENOMEM; -- -- hub->notif.base.priority = INT_MAX; /* This notifier should run first. */ -- hub->notif.base.fn = ssam_base_hub_notif; -- hub->notif.event.reg = SSAM_EVENT_REGISTRY_SAM; -- hub->notif.event.id.target_category = SSAM_SSH_TC_BAS, -- hub->notif.event.id.instance = 0, -- hub->notif.event.mask = SSAM_EVENT_MASK_NONE; -- hub->notif.event.flags = SSAM_EVENT_SEQUENCED; -- -- hub->connect_delay = SSAM_BASE_UPDATE_CONNECT_DELAY; -- hub->get_state = ssam_base_hub_query_state; -- -- return ssam_hub_setup(sdev, hub); --} -- --static const struct ssam_device_id ssam_base_hub_match[] = { -- { SSAM_VDEV(HUB, 0x02, SSAM_SSH_TC_BAS, 0x00) }, -- { }, --}; -- --static struct ssam_device_driver ssam_base_hub_driver = { -- .probe = ssam_base_hub_probe, -- .remove = ssam_hub_remove, -- .match_table = ssam_base_hub_match, -- .driver = { -- .name = "surface_aggregator_base_hub", -- .probe_type = PROBE_PREFER_ASYNCHRONOUS, -- .pm = &ssam_hub_pm_ops, -- }, --}; -- -- --/* -- SSAM KIP-subsystem hub driver. ---------------------------------------- */ -- --/* -- * Some devices may need a bit of time to be fully usable after being -- * (re-)connected. This delay has been determined via experimentation. -- */ --#define SSAM_KIP_UPDATE_CONNECT_DELAY msecs_to_jiffies(250) -- --#define SSAM_EVENT_KIP_CID_CONNECTION 0x2c -- --SSAM_DEFINE_SYNC_REQUEST_R(__ssam_kip_get_connection_state, u8, { -- .target_category = SSAM_SSH_TC_KIP, -- .target_id = 0x01, -- .command_id = 0x2c, -- .instance_id = 0x00, --}); -- --static int ssam_kip_get_connection_state(struct ssam_hub *hub, enum ssam_hub_state *state) --{ -- int status; -- u8 connected; -- -- status = ssam_retry(__ssam_kip_get_connection_state, hub->sdev->ctrl, &connected); -- if (status < 0) { -- dev_err(&hub->sdev->dev, "failed to query KIP connection state: %d\n", status); -- return status; -- } -- -- *state = connected ? SSAM_HUB_CONNECTED : SSAM_HUB_DISCONNECTED; -- return 0; --} -- --static u32 ssam_kip_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event) --{ -- struct ssam_hub *hub = container_of(nf, struct ssam_hub, notif); -- -- if (event->command_id != SSAM_EVENT_KIP_CID_CONNECTION) -- return 0; /* Return "unhandled". */ -- -- if (event->length < 1) { -- dev_err(&hub->sdev->dev, "unexpected payload size: %u\n", event->length); -- return 0; -- } -- -- ssam_hub_update(hub, event->data[0]); -- return SSAM_NOTIF_HANDLED; --} -- --static int ssam_kip_hub_probe(struct ssam_device *sdev) --{ -- struct ssam_hub *hub; -- -- hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL); -- if (!hub) -- return -ENOMEM; -- -- hub->notif.base.priority = INT_MAX; /* This notifier should run first. */ -- hub->notif.base.fn = ssam_kip_hub_notif; -- hub->notif.event.reg = SSAM_EVENT_REGISTRY_SAM; -- hub->notif.event.id.target_category = SSAM_SSH_TC_KIP, -- hub->notif.event.id.instance = 0, -- hub->notif.event.mask = SSAM_EVENT_MASK_TARGET; -- hub->notif.event.flags = SSAM_EVENT_SEQUENCED; -- -- hub->connect_delay = SSAM_KIP_UPDATE_CONNECT_DELAY; -- hub->get_state = ssam_kip_get_connection_state; -- -- return ssam_hub_setup(sdev, hub); --} -- --static const struct ssam_device_id ssam_kip_hub_match[] = { -- { SSAM_VDEV(HUB, 0x01, SSAM_SSH_TC_KIP, 0x00) }, -- { }, --}; -- --static struct ssam_device_driver ssam_kip_hub_driver = { -- .probe = ssam_kip_hub_probe, -- .remove = ssam_hub_remove, -- .match_table = ssam_kip_hub_match, -- .driver = { -- .name = "surface_kip_hub", -- .probe_type = PROBE_PREFER_ASYNCHRONOUS, -- .pm = &ssam_hub_pm_ops, -- }, --}; -- -- - /* -- SSAM platform/meta-hub driver. ---------------------------------------- */ - - static const struct acpi_device_id ssam_platform_hub_match[] = { -@@ -727,44 +395,7 @@ static struct platform_driver ssam_platform_hub_driver = { - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - }, - }; -- -- --/* -- Module initialization. ------------------------------------------------ */ -- --static int __init ssam_device_hub_init(void) --{ -- int status; -- -- status = platform_driver_register(&ssam_platform_hub_driver); -- if (status) -- goto err_platform; -- -- status = ssam_device_driver_register(&ssam_base_hub_driver); -- if (status) -- goto err_base; -- -- status = ssam_device_driver_register(&ssam_kip_hub_driver); -- if (status) -- goto err_kip; -- -- return 0; -- --err_kip: -- ssam_device_driver_unregister(&ssam_base_hub_driver); --err_base: -- platform_driver_unregister(&ssam_platform_hub_driver); --err_platform: -- return status; --} --module_init(ssam_device_hub_init); -- --static void __exit ssam_device_hub_exit(void) --{ -- ssam_device_driver_unregister(&ssam_kip_hub_driver); -- ssam_device_driver_unregister(&ssam_base_hub_driver); -- platform_driver_unregister(&ssam_platform_hub_driver); --} --module_exit(ssam_device_hub_exit); -+module_platform_driver(ssam_platform_hub_driver); - - MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>"); - MODULE_DESCRIPTION("Device-registry for Surface System Aggregator Module"); --- -2.37.3 - -From 98864856924810e997eca629da2544485183a9ae Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Fri, 24 Jun 2022 22:58:00 +0200 -Subject: [PATCH] platform/surface: Update copyright year of various drivers - -Update the copyright of various Surface drivers to the current year. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220624205800.1355621-4-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/aggregator/Kconfig | 2 +- - drivers/platform/surface/aggregator/Makefile | 2 +- - drivers/platform/surface/aggregator/bus.c | 2 +- - drivers/platform/surface/aggregator/bus.h | 2 +- - drivers/platform/surface/aggregator/controller.c | 2 +- - drivers/platform/surface/aggregator/controller.h | 2 +- - drivers/platform/surface/aggregator/core.c | 2 +- - drivers/platform/surface/aggregator/ssh_msgb.h | 2 +- - drivers/platform/surface/aggregator/ssh_packet_layer.c | 2 +- - drivers/platform/surface/aggregator/ssh_packet_layer.h | 2 +- - drivers/platform/surface/aggregator/ssh_parser.c | 2 +- - drivers/platform/surface/aggregator/ssh_parser.h | 2 +- - drivers/platform/surface/aggregator/ssh_request_layer.c | 2 +- - drivers/platform/surface/aggregator/ssh_request_layer.h | 2 +- - drivers/platform/surface/aggregator/trace.h | 2 +- - drivers/platform/surface/surface_acpi_notify.c | 2 +- - drivers/platform/surface/surface_aggregator_cdev.c | 2 +- - drivers/platform/surface/surface_aggregator_registry.c | 2 +- - drivers/platform/surface/surface_dtx.c | 2 +- - drivers/platform/surface/surface_gpe.c | 2 +- - drivers/platform/surface/surface_hotplug.c | 2 +- - drivers/platform/surface/surface_platform_profile.c | 2 +- - 22 files changed, 22 insertions(+), 22 deletions(-) - -diff --git a/drivers/platform/surface/aggregator/Kconfig b/drivers/platform/surface/aggregator/Kconfig -index cab020324256..c114f9dd5fe1 100644 ---- a/drivers/platform/surface/aggregator/Kconfig -+++ b/drivers/platform/surface/aggregator/Kconfig -@@ -1,5 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0+ --# Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+# Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - - menuconfig SURFACE_AGGREGATOR - tristate "Microsoft Surface System Aggregator Module Subsystem and Drivers" -diff --git a/drivers/platform/surface/aggregator/Makefile b/drivers/platform/surface/aggregator/Makefile -index c0d550eda5cd..fdf664a217f9 100644 ---- a/drivers/platform/surface/aggregator/Makefile -+++ b/drivers/platform/surface/aggregator/Makefile -@@ -1,5 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0+ --# Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+# Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - - # For include/trace/define_trace.h to include trace.h - CFLAGS_core.o = -I$(src) -diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c -index e0b0381a2834..de539938896e 100644 ---- a/drivers/platform/surface/aggregator/bus.c -+++ b/drivers/platform/surface/aggregator/bus.c -@@ -2,7 +2,7 @@ - /* - * Surface System Aggregator Module bus and device integration. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/device.h> -diff --git a/drivers/platform/surface/aggregator/bus.h b/drivers/platform/surface/aggregator/bus.h -index 6964ee84e79c..5b4dbf21906c 100644 ---- a/drivers/platform/surface/aggregator/bus.h -+++ b/drivers/platform/surface/aggregator/bus.h -@@ -2,7 +2,7 @@ - /* - * Surface System Aggregator Module bus and device integration. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #ifndef _SURFACE_AGGREGATOR_BUS_H -diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c -index 6de834b52b63..43e765199137 100644 ---- a/drivers/platform/surface/aggregator/controller.c -+++ b/drivers/platform/surface/aggregator/controller.c -@@ -2,7 +2,7 @@ - /* - * Main SSAM/SSH controller structure and functionality. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/acpi.h> -diff --git a/drivers/platform/surface/aggregator/controller.h b/drivers/platform/surface/aggregator/controller.h -index a0963c3562ff..f0d987abc51e 100644 ---- a/drivers/platform/surface/aggregator/controller.h -+++ b/drivers/platform/surface/aggregator/controller.h -@@ -2,7 +2,7 @@ - /* - * Main SSAM/SSH controller structure and functionality. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #ifndef _SURFACE_AGGREGATOR_CONTROLLER_H -diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c -index a62c5dfe42d6..1a6373dea109 100644 ---- a/drivers/platform/surface/aggregator/core.c -+++ b/drivers/platform/surface/aggregator/core.c -@@ -7,7 +7,7 @@ - * Handles communication via requests as well as enabling, disabling, and - * relaying of events. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/acpi.h> -diff --git a/drivers/platform/surface/aggregator/ssh_msgb.h b/drivers/platform/surface/aggregator/ssh_msgb.h -index e562958ffdf0..f3ecad92eefd 100644 ---- a/drivers/platform/surface/aggregator/ssh_msgb.h -+++ b/drivers/platform/surface/aggregator/ssh_msgb.h -@@ -2,7 +2,7 @@ - /* - * SSH message builder functions. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #ifndef _SURFACE_AGGREGATOR_SSH_MSGB_H -diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c -index 8a4451c1ffe5..6748fe4ac5d5 100644 ---- a/drivers/platform/surface/aggregator/ssh_packet_layer.c -+++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c -@@ -2,7 +2,7 @@ - /* - * SSH packet transport layer. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <asm/unaligned.h> -diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.h b/drivers/platform/surface/aggregator/ssh_packet_layer.h -index 2eb329f0b91a..64633522f971 100644 ---- a/drivers/platform/surface/aggregator/ssh_packet_layer.h -+++ b/drivers/platform/surface/aggregator/ssh_packet_layer.h -@@ -2,7 +2,7 @@ - /* - * SSH packet transport layer. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #ifndef _SURFACE_AGGREGATOR_SSH_PACKET_LAYER_H -diff --git a/drivers/platform/surface/aggregator/ssh_parser.c b/drivers/platform/surface/aggregator/ssh_parser.c -index b77912f8f13b..a6f668694365 100644 ---- a/drivers/platform/surface/aggregator/ssh_parser.c -+++ b/drivers/platform/surface/aggregator/ssh_parser.c -@@ -2,7 +2,7 @@ - /* - * SSH message parser. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <asm/unaligned.h> -diff --git a/drivers/platform/surface/aggregator/ssh_parser.h b/drivers/platform/surface/aggregator/ssh_parser.h -index 3bd6e180fd16..801d8fa69fb5 100644 ---- a/drivers/platform/surface/aggregator/ssh_parser.h -+++ b/drivers/platform/surface/aggregator/ssh_parser.h -@@ -2,7 +2,7 @@ - /* - * SSH message parser. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #ifndef _SURFACE_AGGREGATOR_SSH_PARSER_H -diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.c b/drivers/platform/surface/aggregator/ssh_request_layer.c -index 790f7f0eee98..f5565570f16c 100644 ---- a/drivers/platform/surface/aggregator/ssh_request_layer.c -+++ b/drivers/platform/surface/aggregator/ssh_request_layer.c -@@ -2,7 +2,7 @@ - /* - * SSH request transport layer. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <asm/unaligned.h> -diff --git a/drivers/platform/surface/aggregator/ssh_request_layer.h b/drivers/platform/surface/aggregator/ssh_request_layer.h -index 9c3cbae2d4bd..4e387a031351 100644 ---- a/drivers/platform/surface/aggregator/ssh_request_layer.h -+++ b/drivers/platform/surface/aggregator/ssh_request_layer.h -@@ -2,7 +2,7 @@ - /* - * SSH request transport layer. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #ifndef _SURFACE_AGGREGATOR_SSH_REQUEST_LAYER_H -diff --git a/drivers/platform/surface/aggregator/trace.h b/drivers/platform/surface/aggregator/trace.h -index cc9e73fbc18e..2a2c17771d01 100644 ---- a/drivers/platform/surface/aggregator/trace.h -+++ b/drivers/platform/surface/aggregator/trace.h -@@ -2,7 +2,7 @@ - /* - * Trace points for SSAM/SSH. - * -- * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2020-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #undef TRACE_SYSTEM -diff --git a/drivers/platform/surface/surface_acpi_notify.c b/drivers/platform/surface/surface_acpi_notify.c -index c0e12f0b9b79..44e317970557 100644 ---- a/drivers/platform/surface/surface_acpi_notify.c -+++ b/drivers/platform/surface/surface_acpi_notify.c -@@ -8,7 +8,7 @@ - * notifications sent from ACPI via the SAN interface by providing them to any - * registered external driver. - * -- * Copyright (C) 2019-2020 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <asm/unaligned.h> -diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c -index 30fb50fde450..492c82e69182 100644 ---- a/drivers/platform/surface/surface_aggregator_cdev.c -+++ b/drivers/platform/surface/surface_aggregator_cdev.c -@@ -3,7 +3,7 @@ - * Provides user-space access to the SSAM EC via the /dev/surface/aggregator - * misc device. Intended for debugging and development. - * -- * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2020-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/fs.h> -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 0cbb7f3a6b2d..d5655f6a4a41 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -6,7 +6,7 @@ - * cannot be auto-detected. Provides device-hubs and performs instantiation - * for these devices. - * -- * Copyright (C) 2020-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2020-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/acpi.h> -diff --git a/drivers/platform/surface/surface_dtx.c b/drivers/platform/surface/surface_dtx.c -index 1203b9a82993..ed36944467f9 100644 ---- a/drivers/platform/surface/surface_dtx.c -+++ b/drivers/platform/surface/surface_dtx.c -@@ -8,7 +8,7 @@ - * acknowledge (to speed things up), abort (e.g. in case the dGPU is still in - * use), or request detachment via user-space. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/fs.h> -diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c -index ec66fde28e75..27365cbe1ee9 100644 ---- a/drivers/platform/surface/surface_gpe.c -+++ b/drivers/platform/surface/surface_gpe.c -@@ -4,7 +4,7 @@ - * properly configuring the respective GPEs. Required for wakeup via lid on - * newer Intel-based Microsoft Surface devices. - * -- * Copyright (C) 2020 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2020-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -diff --git a/drivers/platform/surface/surface_hotplug.c b/drivers/platform/surface/surface_hotplug.c -index cfcc15cfbacb..f004a2495201 100644 ---- a/drivers/platform/surface/surface_hotplug.c -+++ b/drivers/platform/surface/surface_hotplug.c -@@ -10,7 +10,7 @@ - * Event signaling is handled via ACPI, which will generate the appropriate - * device-check notifications to be picked up by the PCIe hot-plug driver. - * -- * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2019-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <linux/acpi.h> -diff --git a/drivers/platform/surface/surface_platform_profile.c b/drivers/platform/surface/surface_platform_profile.c -index 6373d3b5eb7f..fbf2e11fd6ce 100644 ---- a/drivers/platform/surface/surface_platform_profile.c -+++ b/drivers/platform/surface/surface_platform_profile.c -@@ -3,7 +3,7 @@ - * Surface Platform Profile / Performance Mode driver for Surface System - * Aggregator Module (thermal subsystem). - * -- * Copyright (C) 2021 Maximilian Luz <luzmaximilian@gmail.com> -+ * Copyright (C) 2021-2022 Maximilian Luz <luzmaximilian@gmail.com> - */ - - #include <asm/unaligned.h> --- -2.37.3 - -From af14813f2c2c1571196481fa564649e0e92dc503 Mon Sep 17 00:00:00 2001 -From: Lukas Bulwahn <lukas.bulwahn@gmail.com> -Date: Wed, 13 Jul 2022 06:09:16 +0200 -Subject: [PATCH] MAINTAINERS: repair file entry in MICROSOFT SURFACE - AGGREGATOR TABLET-MODE SWITCH - -Commit 9f794056db5b ("platform/surface: Add KIP/POS tablet-mode switch -driver") adds the section MICROSOFT SURFACE AGGREGATOR TABLET-MODE SWITCH -with a file entry, but the file that is added with this commit is actually -named slightly differently. - - file entry name: drivers/platform/surface/surface_aggregator_tablet_switch.c - added file name: drivers/platform/surface/surface_aggregator_tabletsw.c - -Hence, ./scripts/get_maintainer.pl --self-test=patterns complains about a -broken reference. - -Repair this file entry to the actual file name added with the commit above. - -Fixes: 9f794056db5b ("platform/surface: Add KIP/POS tablet-mode switch driver") -Signed-off-by: Lukas Bulwahn <lukas.bulwahn@gmail.com> -Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> -Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220713040916.1767-1-lukas.bulwahn@gmail.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - MAINTAINERS | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 55e80354a097..6772c9d0eccc 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13303,7 +13303,7 @@ MICROSOFT SURFACE AGGREGATOR TABLET-MODE SWITCH - M: Maximilian Luz <luzmaximilian@gmail.com> - L: platform-driver-x86@vger.kernel.org - S: Maintained --F: drivers/platform/surface/surface_aggregator_tablet_switch.c -+F: drivers/platform/surface/surface_aggregator_tabletsw.c - - MICROSOFT SURFACE BATTERY AND AC DRIVERS - M: Maximilian Luz <luzmaximilian@gmail.com> --- -2.37.3 - -From 799b65f7dd3e013e1b5cd57877cc08c0b8298504 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Sun, 17 Jul 2022 14:07:35 +0200 -Subject: [PATCH] platform/surface: tabletsw: Fix __le32 integer access - -The sources.count field is a __le32 inside a packed struct. So use the -proper functions to access it. - -Reported-by: kernel test robot <lkp@intel.com> -Fixes: 9f794056db5b ("platform/surface: Add KIP/POS tablet-mode switch driver") -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220717120735.2052160-1-luzmaximilian@gmail.com -Reviewed-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-sam ---- - drivers/platform/surface/surface_aggregator_tabletsw.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_tabletsw.c b/drivers/platform/surface/surface_aggregator_tabletsw.c -index 596ca6c80681..27d95a6a7851 100644 ---- a/drivers/platform/surface/surface_aggregator_tabletsw.c -+++ b/drivers/platform/surface/surface_aggregator_tabletsw.c -@@ -410,7 +410,7 @@ static int ssam_pos_get_source(struct ssam_tablet_sw *sw, u32 *source_id) - if (status) - return status; - -- if (sources.count == 0) { -+ if (get_unaligned_le32(&sources.count) == 0) { - dev_err(&sw->sdev->dev, "no posture sources found\n"); - return -ENODEV; - } -@@ -422,7 +422,7 @@ static int ssam_pos_get_source(struct ssam_tablet_sw *sw, u32 *source_id) - * is a device that provides multiple sources, at which point we can - * then try to figure out how to handle them. - */ -- WARN_ON(sources.count > 1); -+ WARN_ON(get_unaligned_le32(&sources.count) > 1); - - *source_id = get_unaligned_le32(&sources.id[0]); - return 0; --- -2.37.3 - -From edc6a485b06125a928c62c7d149861ca4d603ccd Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Sat, 25 Jun 2022 20:42:00 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Rename HID device - nodes based on their function - -Rename HID device nodes based on their function. In particular, these -are nodes for firmware updates via the CFU mechanism (component firmware -update), HID based sensors, and a USB-C UCSI client. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Patchset: surface-sam ---- - .../surface/surface_aggregator_registry.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 93ab62eb393d..7d82398f55b1 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -104,14 +104,14 @@ static const struct software_node ssam_node_hid_tid1_touchpad = { - .parent = &ssam_node_root, - }; - --/* HID device instance 6 (TID1, unknown HID device). */ --static const struct software_node ssam_node_hid_tid1_iid6 = { -+/* HID device instance 6 (TID1, HID sensor collection). */ -+static const struct software_node ssam_node_hid_tid1_sensors = { - .name = "ssam:01:15:01:06:00", - .parent = &ssam_node_root, - }; - --/* HID device instance 7 (TID1, unknown HID device). */ --static const struct software_node ssam_node_hid_tid1_iid7 = { -+/* HID device instance 7 (TID1, UCM UCSI HID client). */ -+static const struct software_node ssam_node_hid_tid1_ucm_ucsi = { - .name = "ssam:01:15:01:07:00", - .parent = &ssam_node_root, - }; -@@ -182,8 +182,8 @@ static const struct software_node ssam_node_hid_kip_touchpad = { - .parent = &ssam_node_hub_kip, - }; - --/* HID device instance 5 (KIP hub, unknown HID device). */ --static const struct software_node ssam_node_hid_kip_iid5 = { -+/* HID device instance 5 (KIP hub, type-cover firmware update). */ -+static const struct software_node ssam_node_hid_kip_fwupd = { - .name = "ssam:01:15:02:05:00", - .parent = &ssam_node_hub_kip, - }; -@@ -244,8 +244,8 @@ static const struct software_node *ssam_node_group_sls[] = { - &ssam_node_hid_tid1_keyboard, - &ssam_node_hid_tid1_penstash, - &ssam_node_hid_tid1_touchpad, -- &ssam_node_hid_tid1_iid6, -- &ssam_node_hid_tid1_iid7, -+ &ssam_node_hid_tid1_sensors, -+ &ssam_node_hid_tid1_ucm_ucsi, - &ssam_node_hid_tid1_sysctrl, - NULL, - }; -@@ -278,7 +278,7 @@ static const struct software_node *ssam_node_group_sp8[] = { - &ssam_node_hid_kip_keyboard, - &ssam_node_hid_kip_penstash, - &ssam_node_hid_kip_touchpad, -- &ssam_node_hid_kip_iid5, -+ &ssam_node_hid_kip_fwupd, - NULL, - }; - --- -2.37.3 +2.38.0 -From a92cc0122356f6015bb73773038b61a5e269a0bd Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Sat, 25 Jun 2022 20:52:47 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Rename HID device - nodes based on new findings - -On Windows, the HID devices with target ID 1 are grouped as "Surface Hot -Plug - SAM". Rename their device nodes in the registry to reflect that -and update the comments accordingly. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Patchset: surface-sam ---- - .../surface/surface_aggregator_registry.c | 36 +++++++++---------- - 1 file changed, 18 insertions(+), 18 deletions(-) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 7d82398f55b1..9970f89b1411 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -86,38 +86,38 @@ static const struct software_node ssam_node_bas_dtx = { - .parent = &ssam_node_root, - }; - --/* HID keyboard (TID1). */ --static const struct software_node ssam_node_hid_tid1_keyboard = { -+/* HID keyboard (SAM, TID=1). */ -+static const struct software_node ssam_node_hid_sam_keyboard = { - .name = "ssam:01:15:01:01:00", - .parent = &ssam_node_root, - }; - --/* HID pen stash (TID1; pen taken / stashed away evens). */ --static const struct software_node ssam_node_hid_tid1_penstash = { -+/* HID pen stash (SAM, TID=1; pen taken / stashed away evens). */ -+static const struct software_node ssam_node_hid_sam_penstash = { - .name = "ssam:01:15:01:02:00", - .parent = &ssam_node_root, - }; - --/* HID touchpad (TID1). */ --static const struct software_node ssam_node_hid_tid1_touchpad = { -+/* HID touchpad (SAM, TID=1). */ -+static const struct software_node ssam_node_hid_sam_touchpad = { - .name = "ssam:01:15:01:03:00", - .parent = &ssam_node_root, - }; - --/* HID device instance 6 (TID1, HID sensor collection). */ --static const struct software_node ssam_node_hid_tid1_sensors = { -+/* HID device instance 6 (SAM, TID=1, HID sensor collection). */ -+static const struct software_node ssam_node_hid_sam_sensors = { - .name = "ssam:01:15:01:06:00", - .parent = &ssam_node_root, - }; - --/* HID device instance 7 (TID1, UCM UCSI HID client). */ --static const struct software_node ssam_node_hid_tid1_ucm_ucsi = { -+/* HID device instance 7 (SAM, TID=1, UCM UCSI HID client). */ -+static const struct software_node ssam_node_hid_sam_ucm_ucsi = { - .name = "ssam:01:15:01:07:00", - .parent = &ssam_node_root, - }; - --/* HID system controls (TID1). */ --static const struct software_node ssam_node_hid_tid1_sysctrl = { -+/* HID system controls (SAM, TID=1). */ -+static const struct software_node ssam_node_hid_sam_sysctrl = { - .name = "ssam:01:15:01:08:00", - .parent = &ssam_node_root, - }; -@@ -241,12 +241,12 @@ static const struct software_node *ssam_node_group_sls[] = { - &ssam_node_bat_main, - &ssam_node_tmp_pprof, - &ssam_node_pos_tablet_switch, -- &ssam_node_hid_tid1_keyboard, -- &ssam_node_hid_tid1_penstash, -- &ssam_node_hid_tid1_touchpad, -- &ssam_node_hid_tid1_sensors, -- &ssam_node_hid_tid1_ucm_ucsi, -- &ssam_node_hid_tid1_sysctrl, -+ &ssam_node_hid_sam_keyboard, -+ &ssam_node_hid_sam_penstash, -+ &ssam_node_hid_sam_touchpad, -+ &ssam_node_hid_sam_sensors, -+ &ssam_node_hid_sam_ucm_ucsi, -+ &ssam_node_hid_sam_sysctrl, - NULL, - }; - --- -2.37.3 - -From 2b28caa61d0783215ce24c418e435214f867c0dd Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Sat, 25 Jun 2022 20:54:59 +0200 -Subject: [PATCH] platform/surface: aggregator_registry: Add HID devices for - sensors and UCSI client to SP8 - -Add software nodes for the HID sensor collection and the UCM UCSI HID -client to the Surface Pro 8. In contrast to the type-cover devices, -these devices are directly attached to the SAM controller, without any -hub. - -This enables support for HID-based sensors, including the ones used for -automatic screen rotation, on the Surface Pro 8. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Patchset: surface-sam ---- - drivers/platform/surface/surface_aggregator_registry.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c -index 9970f89b1411..585911020cea 100644 ---- a/drivers/platform/surface/surface_aggregator_registry.c -+++ b/drivers/platform/surface/surface_aggregator_registry.c -@@ -279,6 +279,8 @@ static const struct software_node *ssam_node_group_sp8[] = { - &ssam_node_hid_kip_penstash, - &ssam_node_hid_kip_touchpad, - &ssam_node_hid_kip_fwupd, -+ &ssam_node_hid_sam_sensors, -+ &ssam_node_hid_sam_ucm_ucsi, - NULL, - }; - --- -2.37.3 - -From 749702e2ed1883c23763cc434f2ce1ddcdd0f336 Mon Sep 17 00:00:00 2001 +From aea7c2d43bb6419f5abc89441fa6dddea59b414c Mon Sep 17 00:00:00 2001 From: Maximilian Luz <luzmaximilian@gmail.com> Date: Sat, 25 Jul 2020 17:19:53 +0200 Subject: [PATCH] i2c: acpi: Implement RawBytes read access @@ -7340,9 +2640,9 @@ index 08b561f0709d..d7c397bce0f0 100644 dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n", accessor_type, client->addr); -- -2.37.3 +2.38.0 -From bcb73e7e4c52a3c430e252d090614d18bad7e044 Mon Sep 17 00:00:00 2001 +From 6f7f7ad9af793bcb4b60564b5a5da353b0690960 Mon Sep 17 00:00:00 2001 From: Maximilian Luz <luzmaximilian@gmail.com> Date: Sat, 13 Feb 2021 16:41:18 +0100 Subject: [PATCH] platform/surface: Add driver for Surface Book 1 dGPU switch @@ -7563,9 +2863,9 @@ index 000000000000..8b816ed8f35c +MODULE_DESCRIPTION("Discrete GPU Power-Switch for Surface Book 1"); +MODULE_LICENSE("GPL"); -- -2.37.3 +2.38.0 -From 48e1c1ac0c69aa95a8c9f19307fffb4b77cf2170 Mon Sep 17 00:00:00 2001 +From 5cf259bfcbbe641c70ad6c5eea62ebc1e6e07bd9 Mon Sep 17 00:00:00 2001 From: Sachi King <nakato@nakato.io> Date: Tue, 5 Oct 2021 00:05:09 +1100 Subject: [PATCH] Input: soc_button_array - support AMD variant Surface devices @@ -7640,9 +2940,9 @@ index 480476121c01..36e1bf7b7a01 100644 /* -- -2.37.3 +2.38.0 -From df10e0afc475ed5177cfa692db6dbfea28d7a9fe Mon Sep 17 00:00:00 2001 +From 1bdc0fbcda34412b4a4bf0372d4cf776c7ca43a3 Mon Sep 17 00:00:00 2001 From: Sachi King <nakato@nakato.io> Date: Tue, 5 Oct 2021 00:22:57 +1100 Subject: [PATCH] platform/surface: surfacepro3_button: don't load on amd @@ -7712,9 +3012,9 @@ index 242fb690dcaf..30eea54dbb47 100644 -- -2.37.3 +2.38.0 -From 62a4fddab3c7a44dc5b17633ccc7f125f59ee3f9 Mon Sep 17 00:00:00 2001 +From 1ffe7e9746dba16ca1936198703166d8c27e1649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl> Date: Thu, 5 Nov 2020 13:09:45 +0100 Subject: [PATCH] hid/multitouch: Turn off Type Cover keyboard backlight when @@ -7750,7 +3050,7 @@ Patchset: surface-typecover 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index 2e72922e36f5..15f5f11c4b85 100644 +index 91a4d3fc30e0..458537bf4a8e 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -34,7 +34,10 @@ @@ -7823,7 +3123,7 @@ index 2e72922e36f5..15f5f11c4b85 100644 }; @@ -1706,6 +1726,69 @@ static void mt_expired_timeout(struct timer_list *t) - clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); } +static void get_type_cover_backlight_field(struct hid_device *hdev, @@ -7945,9 +3245,9 @@ index 2e72922e36f5..15f5f11c4b85 100644 { .driver_data = MT_CLS_GOOGLE, HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE, -- -2.37.3 +2.38.0 -From 2b1d157b58d6a192e147dbfc84526e7ffa9ae2c1 Mon Sep 17 00:00:00 2001 +From 7f0b06e3e5b7df1ddcb954906f651f727f10717d Mon Sep 17 00:00:00 2001 From: PJungkamp <p.jungkamp@gmail.com> Date: Fri, 25 Feb 2022 12:04:25 +0100 Subject: [PATCH] hid/multitouch: Add support for surface pro type cover tablet @@ -7976,7 +3276,7 @@ Patchset: surface-typecover 1 file changed, 122 insertions(+), 26 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index 15f5f11c4b85..69202575ce19 100644 +index 458537bf4a8e..3d7d002a662f 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -76,6 +76,7 @@ MODULE_LICENSE("GPL"); @@ -8144,7 +3444,7 @@ index 15f5f11c4b85..69202575ce19 100644 suffix = "UNKNOWN"; break; @@ -1726,30 +1815,6 @@ static void mt_expired_timeout(struct timer_list *t) - clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); } -static void get_type_cover_backlight_field(struct hid_device *hdev, @@ -8245,52 +3545,9 @@ index 15f5f11c4b85..69202575ce19 100644 unregister_pm_notifier(&td->pm_notifier); del_timer_sync(&td->release_timer); -- -2.37.3 - -From 716290db6ffaeb61e78eb40d6b466e05bb983990 Mon Sep 17 00:00:00 2001 -From: Maximilian Luz <luzmaximilian@gmail.com> -Date: Thu, 21 Jul 2022 14:11:20 +0200 -Subject: [PATCH] platform/surface: gpe: Add support for 13" Intel version of - Surface Laptop 4 - -The 13" Intel version of the Surface Laptop 4 uses the same GPE as the -Surface Laptop Studio for wakeups via the lid. Set it up accordingly. - -Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com> -Link: https://lore.kernel.org/r/20220721121120.2002430-1-luzmaximilian@gmail.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Patchset: surface-gpe ---- - drivers/platform/surface/surface_gpe.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/platform/surface/surface_gpe.c b/drivers/platform/surface/surface_gpe.c -index 27365cbe1ee9..c219b840d491 100644 ---- a/drivers/platform/surface/surface_gpe.c -+++ b/drivers/platform/surface/surface_gpe.c -@@ -171,6 +171,18 @@ static const struct dmi_system_id dmi_lid_device_table[] = { - }, - .driver_data = (void *)lid_device_props_l4D, - }, -+ { -+ .ident = "Surface Laptop 4 (Intel 13\")", -+ .matches = { -+ /* -+ * We match for SKU here due to different variants: The -+ * AMD (15") version does not rely on GPEs. -+ */ -+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), -+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Laptop_4_1950:1951"), -+ }, -+ .driver_data = (void *)lid_device_props_l4B, -+ }, - { - .ident = "Surface Laptop Studio", - .matches = { --- -2.37.3 +2.38.0 -From 63aeabc28778964d2ff7f33c81394d82945beae4 Mon Sep 17 00:00:00 2001 +From f7a93cc0fd6be37a77b98c2abc57211d8269730e Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Sun, 10 Oct 2021 20:56:57 +0200 Subject: [PATCH] ACPI: delay enumeration of devices with a _DEP pointing to an @@ -8350,10 +3607,10 @@ Patchset: cameras 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index 762b61f67e6c..2c0f39a7f2a1 100644 +index 42cec8120f18..72d0e599120f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c -@@ -2122,6 +2122,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used, +@@ -2108,6 +2108,9 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used, static void acpi_default_enumeration(struct acpi_device *device) { @@ -8364,9 +3621,9 @@ index 762b61f67e6c..2c0f39a7f2a1 100644 * Do not enumerate devices with enumeration_by_parent flag set as * they will be enumerated by their respective parents. -- -2.37.3 +2.38.0 -From 0a1366c998d0bbd976995ddedb3c1fca8665db6c Mon Sep 17 00:00:00 2001 +From e53ff4336793833ca7475d11409cf61203370f05 Mon Sep 17 00:00:00 2001 From: zouxiaoh <xiaohong.zou@intel.com> Date: Fri, 25 Jun 2021 08:52:59 +0800 Subject: [PATCH] iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs @@ -8392,7 +3649,7 @@ Patchset: cameras 1 file changed, 30 insertions(+) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c -index 825b524e81f3..095d566c058f 100644 +index d8ecca292f93..e3b37a19b6bc 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -37,6 +37,12 @@ @@ -8408,7 +3665,7 @@ index 825b524e81f3..095d566c058f 100644 #define IS_IPTS(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL && \ ((pdev)->device == 0x9d3e)) #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) -@@ -310,12 +316,14 @@ EXPORT_SYMBOL_GPL(intel_iommu_enabled); +@@ -284,12 +290,14 @@ EXPORT_SYMBOL_GPL(intel_iommu_enabled); static int dmar_map_gfx = 1; static int dmar_map_ipts = 1; @@ -8422,8 +3679,8 @@ index 825b524e81f3..095d566c058f 100644 +#define IDENTMAP_IPU 8 #define IDENTMAP_IPTS 16 - int intel_iommu_gfx_mapped; -@@ -2664,6 +2672,9 @@ static int device_def_domain_type(struct device *dev) + const struct iommu_ops intel_iommu_ops; +@@ -2607,6 +2615,9 @@ static int device_def_domain_type(struct device *dev) if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev)) return IOMMU_DOMAIN_IDENTITY; @@ -8433,7 +3690,7 @@ index 825b524e81f3..095d566c058f 100644 if ((iommu_identity_mapping & IDENTMAP_IPTS) && IS_IPTS(pdev)) return IOMMU_DOMAIN_IDENTITY; } -@@ -3102,6 +3113,9 @@ static int __init init_dmars(void) +@@ -2998,6 +3009,9 @@ static int __init init_dmars(void) if (!dmar_map_gfx) iommu_identity_mapping |= IDENTMAP_GFX; @@ -8443,7 +3700,7 @@ index 825b524e81f3..095d566c058f 100644 if (!dmar_map_ipts) iommu_identity_mapping |= IDENTMAP_IPTS; -@@ -4933,6 +4947,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev) +@@ -4798,6 +4812,18 @@ static void quirk_iommu_igfx(struct pci_dev *dev) dmar_map_gfx = 0; } @@ -8462,7 +3719,7 @@ index 825b524e81f3..095d566c058f 100644 static void quirk_iommu_ipts(struct pci_dev *dev) { if (!IS_IPTS(dev)) -@@ -4944,6 +4970,7 @@ static void quirk_iommu_ipts(struct pci_dev *dev) +@@ -4809,6 +4835,7 @@ static void quirk_iommu_ipts(struct pci_dev *dev) pci_info(dev, "Passthrough IOMMU for IPTS\n"); dmar_map_ipts = 0; } @@ -8470,7 +3727,7 @@ index 825b524e81f3..095d566c058f 100644 /* G4x/GM45 integrated gfx dmar support is totally busted. */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx); -@@ -4979,6 +5006,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); +@@ -4844,6 +4871,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx); @@ -8481,9 +3738,9 @@ index 825b524e81f3..095d566c058f 100644 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9D3E, quirk_iommu_ipts); -- -2.37.3 +2.38.0 -From 23350bbaa1baea7694766c9aeeeecacd67d5a877 Mon Sep 17 00:00:00 2001 +From 62a30b7c7a3c825600efe1a70f6c670a655ea5e2 Mon Sep 17 00:00:00 2001 From: Daniel Scally <djrscally@gmail.com> Date: Sun, 10 Oct 2021 20:57:02 +0200 Subject: [PATCH] platform/x86: int3472: Enable I2c daisy chain @@ -8518,9 +3775,9 @@ index 22f61b47f9e5..e1de1ff40bba 100644 return 0; -- -2.37.3 +2.38.0 -From 247beedc634caa1a965f462451641d7f37f07d74 Mon Sep 17 00:00:00 2001 +From 16fff23e17f0a0bde5e484e2aaba0940aff63ce1 Mon Sep 17 00:00:00 2001 From: Daniel Scally <djrscally@gmail.com> Date: Thu, 28 Oct 2021 21:55:16 +0100 Subject: [PATCH] media: i2c: Add driver for DW9719 VCM @@ -8539,10 +3796,10 @@ Patchset: cameras create mode 100644 drivers/media/i2c/dw9719.c diff --git a/MAINTAINERS b/MAINTAINERS -index 6772c9d0eccc..a639e7ff0402 100644 +index 72b9654f764c..cecb621a6581 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -6163,6 +6163,13 @@ T: git git://linuxtv.org/media_tree.git +@@ -6250,6 +6250,13 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt F: drivers/media/i2c/dw9714.c @@ -8557,10 +3814,10 @@ index 6772c9d0eccc..a639e7ff0402 100644 M: Dongchun Zhu <dongchun.zhu@mediatek.com> L: linux-media@vger.kernel.org diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig -index c926e5d43820..5c245f642ae3 100644 +index 7806d4b81716..98d081efeef7 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig -@@ -806,6 +806,17 @@ config VIDEO_DW9714 +@@ -821,6 +821,17 @@ config VIDEO_DW9714 capability. This is designed for linear control of voice coil motors, controlled via I2C serial interface. @@ -8579,10 +3836,10 @@ index c926e5d43820..5c245f642ae3 100644 tristate "DW9768 lens voice coil support" depends on I2C && VIDEO_DEV diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile -index 3e1696963e7f..9dfda069e006 100644 +index 0a2933103dd9..b82a07c76388 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile -@@ -29,6 +29,7 @@ obj-$(CONFIG_VIDEO_CS5345) += cs5345.o +@@ -30,6 +30,7 @@ obj-$(CONFIG_VIDEO_CS5345) += cs5345.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o obj-$(CONFIG_VIDEO_CX25840) += cx25840/ obj-$(CONFIG_VIDEO_DW9714) += dw9714.o @@ -9024,9 +4281,9 @@ index 000000000000..8451c75b696b +MODULE_DESCRIPTION("DW9719 VCM Driver"); +MODULE_LICENSE("GPL"); -- -2.37.3 +2.38.0 -From 131a1b6b516582eeeba78853894a168c0a4604fd Mon Sep 17 00:00:00 2001 +From ed77e610029cf5cdcbed647670d963a8ade49d10 Mon Sep 17 00:00:00 2001 From: Daniel Scally <djrscally@gmail.com> Date: Wed, 4 May 2022 23:21:45 +0100 Subject: [PATCH] media: ipu3-cio2: Move functionality from .complete() to @@ -9045,7 +4302,7 @@ Patchset: cameras 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -index dbdbdb648a0d..d0715144bf3e 100644 +index a3fe547b7fce..5648f29ced7b 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -1383,7 +1383,10 @@ static int cio2_notifier_bound(struct v4l2_async_notifier *notifier, @@ -9139,9 +4396,9 @@ index dbdbdb648a0d..d0715144bf3e 100644 static int cio2_parse_firmware(struct cio2_device *cio2) -- -2.37.3 +2.38.0 -From 82abd409bf7173da2ed6b76d95410f1f60e714fa Mon Sep 17 00:00:00 2001 +From bac377c1e75c9aea4f7fcee09db02c7c0be1e40d Mon Sep 17 00:00:00 2001 From: Daniel Scally <djrscally@gmail.com> Date: Thu, 2 Jun 2022 22:15:56 +0100 Subject: [PATCH] media: ipu3-cio2: Re-add .complete() to ipu3-cio2 @@ -9159,7 +4416,7 @@ Patchset: cameras 1 file changed, 9 insertions(+) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c -index d0715144bf3e..3a25dfc696b2 100644 +index 5648f29ced7b..957a30cd369d 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -1430,9 +1430,18 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier, @@ -9182,9 +4439,9 @@ index d0715144bf3e..3a25dfc696b2 100644 static int cio2_parse_firmware(struct cio2_device *cio2) -- -2.37.3 +2.38.0 -From 1abd24d4d11a1842c20c2d7feed35b39c4061745 Mon Sep 17 00:00:00 2001 +From 2cdd92525b8a27fd8c8edf6cb1e1c5d3cb233b92 Mon Sep 17 00:00:00 2001 From: Maximilian Luz <luzmaximilian@gmail.com> Date: Fri, 15 Jul 2022 23:48:00 +0200 Subject: [PATCH] drivers/media/i2c: Fix DW9719 dependencies @@ -9198,10 +4455,10 @@ Patchset: cameras 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig -index 5c245f642ae3..50ea62e63784 100644 +index 98d081efeef7..c67966cafe10 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig -@@ -808,7 +808,7 @@ config VIDEO_DW9714 +@@ -823,7 +823,7 @@ config VIDEO_DW9714 config VIDEO_DW9719 tristate "DW9719 lens voice coil support" @@ -9211,9 +4468,9 @@ index 5c245f642ae3..50ea62e63784 100644 select VIDEO_V4L2_SUBDEV_API select V4L2_ASYNC -- -2.37.3 +2.38.0 -From 86f47552d0d743f3100b07c6f859033c031db588 Mon Sep 17 00:00:00 2001 +From a3051d35806d33fe6fb31040ff6c0a1f81a31e37 Mon Sep 17 00:00:00 2001 From: Sakari Ailus <sakari.ailus@linux.intel.com> Date: Thu, 25 Aug 2022 21:36:37 +0300 Subject: [PATCH] ipu3-imgu: Fix NULL pointer dereference in active selection @@ -9292,9 +4549,9 @@ index d1c539cefba8..2234bb8d48b3 100644 static int imgu_subdev_set_selection(struct v4l2_subdev *sd, -- -2.37.3 +2.38.0 -From 90d952acdd44a833c8131cd63df69a43453763fe Mon Sep 17 00:00:00 2001 +From 07342c91ee73cfa7e1d25cecd6aa4e0b5961659b Mon Sep 17 00:00:00 2001 From: Maximilian Luz <luzmaximilian@gmail.com> Date: Wed, 7 Sep 2022 15:38:08 +0200 Subject: [PATCH] ipu3-imgu: Fix NULL pointer dereference in @@ -9423,9 +4680,9 @@ index 2234bb8d48b3..490ba0eb249b 100644 } -- -2.37.3 +2.38.0 -From f48f910254bcbc02338128293f8199e832b07fcb Mon Sep 17 00:00:00 2001 +From 7f05ef4c0b13280490b8ec2e57b2c030e4f52be3 Mon Sep 17 00:00:00 2001 From: Sachi King <nakato@nakato.io> Date: Sat, 29 May 2021 17:47:38 +1000 Subject: [PATCH] ACPI: Add quirk for Surface Laptop 4 AMD missing irq 7 @@ -9490,9 +4747,9 @@ index 907cc98b1938..0116d27b29ea 100644 mp_config_acpi_legacy_irqs(); -- -2.37.3 +2.38.0 -From 324a9a147dda942ca3f96b1d10edab524ea47193 Mon Sep 17 00:00:00 2001 +From c9cb2f9530fa98146ae22dc43e0bed4d317c0808 Mon Sep 17 00:00:00 2001 From: Maximilian Luz <luzmaximilian@gmail.com> Date: Thu, 3 Jun 2021 14:04:26 +0200 Subject: [PATCH] ACPI: Add AMD 13" Surface Laptop 4 model to irq 7 override @@ -9532,5 +4789,5 @@ index 0116d27b29ea..af102c6f8e5b 100644 }; -- -2.37.3 +2.38.0 |