2021-02-12 11:58:03

by Maximilian Luz

[permalink] [raw]
Subject: [PATCH v3 0/6] platform/surface: Add Surface Aggregator device registry

The Surface System Aggregator Module (SSAM) subsystem provides various
functionalities, which are separated by spreading them across multiple
devices and corresponding drivers. Parts of that functionality / some of
those devices, however, can (as far as we currently know) not be
auto-detected by conventional means. While older (specifically 5th- and
6th-)generation models do advertise most of their functionality via
standard platform devices in ACPI, newer generations do not.

As we are currently also not aware of any feasible way to query said
functionalities dynamically, this poses a problem. There is, however, a
device in ACPI that seems to be used by Windows for identifying
different Surface models: The Windows Surface Integration Device (WSID).
This device seems to have a HID corresponding to the overall set of
functionalities SSAM provides for the associated model.

This series introduces a device registry based on software nodes and
device hubs to solve this problem. The registry is intended to contain
all required non-detectable information.

The platform hub driver is loaded against the WSID device and
instantiates and manages SSAM devices based on the information provided
by the registry for the given WSID HID of the Surface model. All new
devices created by this hub added as child devices to this hub.

In addition, a base hub is introduced to manage devices associated with
the detachable base part of the Surface Book 3, as this requires special
handling (i.e. devices need to be removed when the base is removed).
Again, all devices created by the base hub (i.e. associated with the
base) are added as child devices to this hub.

In total, this will yield the following device structure

WSID
|- SSAM device 1 (physical device)
|- SSAM device 2 (physical device)
|- SSAM device 3 (physical device)
|- ...
\- SSAM base hub (virtual device)
|- SSAM base device 1 (physical device)
|- SSAM base device 2 (physical device)
|- ...

While software nodes seem to be well suited for this approach due to
extensibility, they still need to be hard-coded, so I'm open for ideas
on how this could be improved.

Changes in v2:
- Fix Kconfig dependency

Changes in v3:
- Fix use of lockdep_assert_held()

Maximilian Luz (6):
platform/surface: Set up Surface Aggregator device registry
platform/surface: aggregator_registry: Add base device hub
platform/surface: aggregator_registry: Add battery subsystem devices
platform/surface: aggregator_registry: Add platform profile device
platform/surface: aggregator_registry: Add DTX device
platform/surface: aggregator_registry: Add HID subsystem devices

MAINTAINERS | 1 +
drivers/platform/surface/Kconfig | 27 +
drivers/platform/surface/Makefile | 1 +
.../surface/surface_aggregator_registry.c | 641 ++++++++++++++++++
4 files changed, 670 insertions(+)
create mode 100644 drivers/platform/surface/surface_aggregator_registry.c

--
2.30.1


2021-02-12 11:59:35

by Maximilian Luz

[permalink] [raw]
Subject: [PATCH v3 2/6] platform/surface: aggregator_registry: Add base device hub

The Surface Book 3 has a detachable base part. While the top part
(so-called clipboard) contains the CPU, touchscreen, and primary
battery, the base contains, among other things, a keyboard, touchpad,
and secondary battery.

Those devices do not react well to being accessed when the base part is
detached and should thus be removed and added in sync with the base. To
facilitate this, we introduce a virtual base device hub, which
automatically removes or adds the devices registered under it.

Signed-off-by: Maximilian Luz <[email protected]>
---

Changes in v3:
- Fix use of lockdep_assert_held()

---
.../surface/surface_aggregator_registry.c | 261 +++++++++++++++++-
1 file changed, 260 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
index a051d941ad96..6c23d75a044c 100644
--- a/drivers/platform/surface/surface_aggregator_registry.c
+++ b/drivers/platform/surface/surface_aggregator_registry.c
@@ -11,9 +11,12 @@

#include <linux/acpi.h>
#include <linux/kernel.h>
+#include <linux/limits.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/property.h>
+#include <linux/types.h>

#include <linux/surface_aggregator/controller.h>
#include <linux/surface_aggregator/device.h>
@@ -38,6 +41,12 @@ static const struct software_node ssam_node_root = {
.name = "ssam_platform_hub",
};

+/* 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",
+ .parent = &ssam_node_root,
+};
+
/* Devices for Surface Book 2. */
static const struct software_node *ssam_node_group_sb2[] = {
&ssam_node_root,
@@ -47,6 +56,7 @@ static const struct software_node *ssam_node_group_sb2[] = {
/* Devices for Surface Book 3. */
static const struct software_node *ssam_node_group_sb3[] = {
&ssam_node_root,
+ &ssam_node_hub_base,
NULL,
};

@@ -177,6 +187,230 @@ static int ssam_hub_add_devices(struct device *parent, struct ssam_controller *c
}


+/* -- SSAM base-hub driver. ------------------------------------------------- */
+
+enum ssam_base_hub_state {
+ SSAM_BASE_HUB_UNINITIALIZED,
+ SSAM_BASE_HUB_CONNECTED,
+ SSAM_BASE_HUB_DISCONNECTED,
+};
+
+struct ssam_base_hub {
+ struct ssam_device *sdev;
+
+ struct mutex lock; /* Guards state update checks and transitions. */
+ enum ssam_base_hub_state state;
+
+ struct ssam_event_notifier notif;
+};
+
+static 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_base_hub *hub, enum ssam_base_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_BASE_HUB_CONNECTED;
+ else
+ *state = SSAM_BASE_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;
+
+ mutex_lock(&hub->lock);
+ connected = hub->state == SSAM_BASE_HUB_CONNECTED;
+ mutex_unlock(&hub->lock);
+
+ 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,
+};
+
+const struct attribute_group ssam_base_hub_group = {
+ .attrs = ssam_base_hub_attrs,
+};
+
+static int __ssam_base_hub_update(struct ssam_base_hub *hub, enum ssam_base_hub_state new)
+{
+ struct fwnode_handle *node = dev_fwnode(&hub->sdev->dev);
+ int status = 0;
+
+ lockdep_assert_held(&hub->lock);
+
+ if (hub->state == new)
+ return 0;
+ hub->state = new;
+
+ if (hub->state == SSAM_BASE_HUB_CONNECTED)
+ status = ssam_hub_add_devices(&hub->sdev->dev, hub->sdev->ctrl, node);
+ else
+ ssam_hub_remove_devices(&hub->sdev->dev);
+
+ if (status)
+ dev_err(&hub->sdev->dev, "failed to update base-hub devices: %d\n", status);
+
+ return status;
+}
+
+static int ssam_base_hub_update(struct ssam_base_hub *hub)
+{
+ enum ssam_base_hub_state state;
+ int status;
+
+ mutex_lock(&hub->lock);
+
+ status = ssam_base_hub_query_state(hub, &state);
+ if (!status)
+ status = __ssam_base_hub_update(hub, state);
+
+ mutex_unlock(&hub->lock);
+ return status;
+}
+
+static u32 ssam_base_hub_notif(struct ssam_event_notifier *nf, const struct ssam_event *event)
+{
+ struct ssam_base_hub *hub;
+ struct ssam_device *sdev;
+ enum ssam_base_hub_state new;
+
+ hub = container_of(nf, struct ssam_base_hub, notif);
+ sdev = hub->sdev;
+
+ if (event->command_id != SSAM_EVENT_BAS_CID_CONNECTION)
+ return 0;
+
+ if (event->length < 1) {
+ dev_err(&sdev->dev, "unexpected payload size: %u\n",
+ event->length);
+ return 0;
+ }
+
+ if (event->data[0])
+ new = SSAM_BASE_HUB_CONNECTED;
+ else
+ new = SSAM_BASE_HUB_DISCONNECTED;
+
+ mutex_lock(&hub->lock);
+ __ssam_base_hub_update(hub, new);
+ mutex_unlock(&hub->lock);
+
+ /*
+ * 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 __maybe_unused ssam_base_hub_resume(struct device *dev)
+{
+ return ssam_base_hub_update(dev_get_drvdata(dev));
+}
+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;
+
+ hub = devm_kzalloc(&sdev->dev, sizeof(*hub), GFP_KERNEL);
+ if (!hub)
+ return -ENOMEM;
+
+ mutex_init(&hub->lock);
+
+ 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;
+ 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;
+
+ ssam_device_set_drvdata(sdev, hub);
+
+ status = ssam_notifier_register(sdev->ctrl, &hub->notif);
+ if (status)
+ goto err_register;
+
+ status = ssam_base_hub_update(hub);
+ if (status)
+ goto err_update;
+
+ status = sysfs_create_group(&sdev->dev.kobj, &ssam_base_hub_group);
+ if (status)
+ goto err_update;
+
+ return 0;
+
+err_update:
+ ssam_notifier_unregister(sdev->ctrl, &hub->notif);
+ ssam_hub_remove_devices(&sdev->dev);
+err_register:
+ mutex_destroy(&hub->lock);
+ 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_notifier_unregister(sdev->ctrl, &hub->notif);
+ ssam_hub_remove_devices(&sdev->dev);
+
+ mutex_destroy(&hub->lock);
+}
+
+static const struct ssam_device_id ssam_base_hub_match[] = {
+ { SSAM_VDEV(HUB, 0x02, SSAM_ANY_IID, 0x00) },
+ { },
+};
+
+static struct ssam_device_driver ssam_base_hub_driver = {
+ .probe = ssam_base_hub_probe,
+ .remove = ssam_base_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,
+ },
+};
+
+
/* -- SSAM platform/meta-hub driver. ---------------------------------------- */

static const struct acpi_device_id ssam_platform_hub_match[] = {
@@ -277,7 +511,32 @@ static struct platform_driver ssam_platform_hub_driver = {
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
};
-module_platform_driver(ssam_platform_hub_driver);
+
+
+/* -- Module initialization. ------------------------------------------------ */
+
+static int __init ssam_device_hub_init(void)
+{
+ int status;
+
+ status = platform_driver_register(&ssam_platform_hub_driver);
+ if (status)
+ return status;
+
+ status = ssam_device_driver_register(&ssam_base_hub_driver);
+ if (status)
+ platform_driver_unregister(&ssam_platform_hub_driver);
+
+ return status;
+}
+module_init(ssam_device_hub_init);
+
+static void __exit ssam_device_hub_exit(void)
+{
+ ssam_device_driver_unregister(&ssam_base_hub_driver);
+ platform_driver_unregister(&ssam_platform_hub_driver);
+}
+module_exit(ssam_device_hub_exit);

MODULE_AUTHOR("Maximilian Luz <[email protected]>");
MODULE_DESCRIPTION("Device-registry for Surface System Aggregator Module");
--
2.30.1

2021-02-12 12:01:40

by Maximilian Luz

[permalink] [raw]
Subject: [PATCH v3 5/6] platform/surface: aggregator_registry: Add DTX device

Add the detachment system (DTX) SSAM device for the Surface Book 3. This
device is accessible under the base (TC=0x11) subsystem.

Signed-off-by: Maximilian Luz <[email protected]>
---
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 33904613dd4b..dc044d06828b 100644
--- a/drivers/platform/surface/surface_aggregator_registry.c
+++ b/drivers/platform/surface/surface_aggregator_registry.c
@@ -71,6 +71,12 @@ static const struct software_node ssam_node_tmp_pprof = {
.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",
+ .parent = &ssam_node_root,
+};
+
/* Devices for Surface Book 2. */
static const struct software_node *ssam_node_group_sb2[] = {
&ssam_node_root,
@@ -86,6 +92,7 @@ static const struct software_node *ssam_node_group_sb3[] = {
&ssam_node_bat_main,
&ssam_node_bat_sb3base,
&ssam_node_tmp_pprof,
+ &ssam_node_bas_dtx,
NULL,
};

--
2.30.1

2021-02-12 12:01:50

by Maximilian Luz

[permalink] [raw]
Subject: [PATCH v3 3/6] platform/surface: aggregator_registry: Add battery subsystem devices

Add battery subsystem (TC=0x02) devices (battery and AC) to the SSAM
device registry. These devices need to be registered for 7th-generation
Surface models. On 5th- and 6th-generation models, these devices are
handled via the standard ACPI battery/AC interface, which in turn
accesses the same SSAM interface via the Surface ACPI Notify (SAN)
driver.

Signed-off-by: Maximilian Luz <[email protected]>
---
.../surface/surface_aggregator_registry.c | 27 +++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
index 6c23d75a044c..cde279692842 100644
--- a/drivers/platform/surface/surface_aggregator_registry.c
+++ b/drivers/platform/surface/surface_aggregator_registry.c
@@ -47,6 +47,24 @@ static const struct software_node ssam_node_hub_base = {
.parent = &ssam_node_root,
};

+/* AC adapter. */
+static const struct software_node ssam_node_bat_ac = {
+ .name = "ssam:01:02:01:01:01",
+ .parent = &ssam_node_root,
+};
+
+/* Primary battery. */
+static const struct software_node ssam_node_bat_main = {
+ .name = "ssam:01:02:01:01:00",
+ .parent = &ssam_node_root,
+};
+
+/* Secondary battery (Surface Book 3). */
+static const struct software_node ssam_node_bat_sb3base = {
+ .name = "ssam:01:02:02:01:00",
+ .parent = &ssam_node_hub_base,
+};
+
/* Devices for Surface Book 2. */
static const struct software_node *ssam_node_group_sb2[] = {
&ssam_node_root,
@@ -57,6 +75,9 @@ static const struct software_node *ssam_node_group_sb2[] = {
static const struct software_node *ssam_node_group_sb3[] = {
&ssam_node_root,
&ssam_node_hub_base,
+ &ssam_node_bat_ac,
+ &ssam_node_bat_main,
+ &ssam_node_bat_sb3base,
NULL,
};

@@ -75,12 +96,16 @@ static const struct software_node *ssam_node_group_sl2[] = {
/* Devices for Surface Laptop 3. */
static const struct software_node *ssam_node_group_sl3[] = {
&ssam_node_root,
+ &ssam_node_bat_ac,
+ &ssam_node_bat_main,
NULL,
};

/* Devices for Surface Laptop Go. */
static const struct software_node *ssam_node_group_slg1[] = {
&ssam_node_root,
+ &ssam_node_bat_ac,
+ &ssam_node_bat_main,
NULL,
};

@@ -99,6 +124,8 @@ static const struct software_node *ssam_node_group_sp6[] = {
/* Devices for Surface Pro 7. */
static const struct software_node *ssam_node_group_sp7[] = {
&ssam_node_root,
+ &ssam_node_bat_ac,
+ &ssam_node_bat_main,
NULL,
};

--
2.30.1

2021-02-12 12:01:54

by Maximilian Luz

[permalink] [raw]
Subject: [PATCH v3 4/6] platform/surface: aggregator_registry: Add platform profile device

Add the SSAM platform profile device to the SSAM device registry. This
device is accessible under the thermal subsystem (TC=0x03) and needs to
be registered for all Surface models.

Signed-off-by: Maximilian Luz <[email protected]>
---
.../surface/surface_aggregator_registry.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
index cde279692842..33904613dd4b 100644
--- a/drivers/platform/surface/surface_aggregator_registry.c
+++ b/drivers/platform/surface/surface_aggregator_registry.c
@@ -65,9 +65,16 @@ static const struct software_node ssam_node_bat_sb3base = {
.parent = &ssam_node_hub_base,
};

+/* Platform profile / performance-mode device. */
+static const struct software_node ssam_node_tmp_pprof = {
+ .name = "ssam:01:03:01:00:01",
+ .parent = &ssam_node_root,
+};
+
/* Devices for Surface Book 2. */
static const struct software_node *ssam_node_group_sb2[] = {
&ssam_node_root,
+ &ssam_node_tmp_pprof,
NULL,
};

@@ -78,18 +85,21 @@ static const struct software_node *ssam_node_group_sb3[] = {
&ssam_node_bat_ac,
&ssam_node_bat_main,
&ssam_node_bat_sb3base,
+ &ssam_node_tmp_pprof,
NULL,
};

/* Devices for Surface Laptop 1. */
static const struct software_node *ssam_node_group_sl1[] = {
&ssam_node_root,
+ &ssam_node_tmp_pprof,
NULL,
};

/* Devices for Surface Laptop 2. */
static const struct software_node *ssam_node_group_sl2[] = {
&ssam_node_root,
+ &ssam_node_tmp_pprof,
NULL,
};

@@ -98,6 +108,7 @@ static const struct software_node *ssam_node_group_sl3[] = {
&ssam_node_root,
&ssam_node_bat_ac,
&ssam_node_bat_main,
+ &ssam_node_tmp_pprof,
NULL,
};

@@ -106,18 +117,21 @@ static const struct software_node *ssam_node_group_slg1[] = {
&ssam_node_root,
&ssam_node_bat_ac,
&ssam_node_bat_main,
+ &ssam_node_tmp_pprof,
NULL,
};

/* Devices for Surface Pro 5. */
static const struct software_node *ssam_node_group_sp5[] = {
&ssam_node_root,
+ &ssam_node_tmp_pprof,
NULL,
};

/* Devices for Surface Pro 6. */
static const struct software_node *ssam_node_group_sp6[] = {
&ssam_node_root,
+ &ssam_node_tmp_pprof,
NULL,
};

@@ -126,6 +140,7 @@ static const struct software_node *ssam_node_group_sp7[] = {
&ssam_node_root,
&ssam_node_bat_ac,
&ssam_node_bat_main,
+ &ssam_node_tmp_pprof,
NULL,
};

--
2.30.1

2021-02-12 12:02:09

by Maximilian Luz

[permalink] [raw]
Subject: [PATCH v3 6/6] platform/surface: aggregator_registry: Add HID subsystem devices

Add HID subsystem (TC=0x15) devices. These devices need to be registered
for 7th-generation Surface models. On previous generations, these
devices are either provided as platform devices via ACPI (Surface Laptop
1 and 2) or implemented as standard USB device.

Signed-off-by: Maximilian Luz <[email protected]>
---
.../surface/surface_aggregator_registry.c | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)

diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
index dc044d06828b..caee90d135c5 100644
--- a/drivers/platform/surface/surface_aggregator_registry.c
+++ b/drivers/platform/surface/surface_aggregator_registry.c
@@ -77,6 +77,48 @@ static const struct software_node ssam_node_bas_dtx = {
.parent = &ssam_node_root,
};

+/* HID keyboard. */
+static const struct software_node ssam_node_hid_main_keyboard = {
+ .name = "ssam:01:15:02:01:00",
+ .parent = &ssam_node_root,
+};
+
+/* HID touchpad. */
+static const struct software_node ssam_node_hid_main_touchpad = {
+ .name = "ssam:01:15:02:03:00",
+ .parent = &ssam_node_root,
+};
+
+/* HID device instance 5 (unknown HID device). */
+static const struct software_node ssam_node_hid_main_iid5 = {
+ .name = "ssam:01:15:02:05:00",
+ .parent = &ssam_node_root,
+};
+
+/* HID keyboard (base hub). */
+static const struct software_node ssam_node_hid_base_keyboard = {
+ .name = "ssam:01:15:02:01:00",
+ .parent = &ssam_node_hub_base,
+};
+
+/* HID touchpad (base hub). */
+static const struct software_node ssam_node_hid_base_touchpad = {
+ .name = "ssam:01:15:02:03:00",
+ .parent = &ssam_node_hub_base,
+};
+
+/* HID device instance 5 (unknown HID device, base hub). */
+static const struct software_node ssam_node_hid_base_iid5 = {
+ .name = "ssam:01:15:02:05:00",
+ .parent = &ssam_node_hub_base,
+};
+
+/* HID device instance 6 (unknown HID device, base hub). */
+static const struct software_node ssam_node_hid_base_iid6 = {
+ .name = "ssam:01:15:02:06:00",
+ .parent = &ssam_node_hub_base,
+};
+
/* Devices for Surface Book 2. */
static const struct software_node *ssam_node_group_sb2[] = {
&ssam_node_root,
@@ -93,6 +135,10 @@ static const struct software_node *ssam_node_group_sb3[] = {
&ssam_node_bat_sb3base,
&ssam_node_tmp_pprof,
&ssam_node_bas_dtx,
+ &ssam_node_hid_base_keyboard,
+ &ssam_node_hid_base_touchpad,
+ &ssam_node_hid_base_iid5,
+ &ssam_node_hid_base_iid6,
NULL,
};

@@ -116,6 +162,9 @@ static const struct software_node *ssam_node_group_sl3[] = {
&ssam_node_bat_ac,
&ssam_node_bat_main,
&ssam_node_tmp_pprof,
+ &ssam_node_hid_main_keyboard,
+ &ssam_node_hid_main_touchpad,
+ &ssam_node_hid_main_iid5,
NULL,
};

--
2.30.1

2021-03-05 00:10:50

by Hans de Goede

[permalink] [raw]
Subject: Re: [PATCH v3 0/6] platform/surface: Add Surface Aggregator device registry

Hi,

On 2/12/21 12:54 PM, Maximilian Luz wrote:
> The Surface System Aggregator Module (SSAM) subsystem provides various
> functionalities, which are separated by spreading them across multiple
> devices and corresponding drivers. Parts of that functionality / some of
> those devices, however, can (as far as we currently know) not be
> auto-detected by conventional means. While older (specifically 5th- and
> 6th-)generation models do advertise most of their functionality via
> standard platform devices in ACPI, newer generations do not.
>
> As we are currently also not aware of any feasible way to query said
> functionalities dynamically, this poses a problem. There is, however, a
> device in ACPI that seems to be used by Windows for identifying
> different Surface models: The Windows Surface Integration Device (WSID).
> This device seems to have a HID corresponding to the overall set of
> functionalities SSAM provides for the associated model.
>
> This series introduces a device registry based on software nodes and
> device hubs to solve this problem. The registry is intended to contain
> all required non-detectable information.
>
> The platform hub driver is loaded against the WSID device and
> instantiates and manages SSAM devices based on the information provided
> by the registry for the given WSID HID of the Surface model. All new
> devices created by this hub added as child devices to this hub.
>
> In addition, a base hub is introduced to manage devices associated with
> the detachable base part of the Surface Book 3, as this requires special
> handling (i.e. devices need to be removed when the base is removed).
> Again, all devices created by the base hub (i.e. associated with the
> base) are added as child devices to this hub.
>
> In total, this will yield the following device structure
>
> WSID
> |- SSAM device 1 (physical device)
> |- SSAM device 2 (physical device)
> |- SSAM device 3 (physical device)
> |- ...
> \- SSAM base hub (virtual device)
> |- SSAM base device 1 (physical device)
> |- SSAM base device 2 (physical device)
> |- ...
>
> While software nodes seem to be well suited for this approach due to
> extensibility, they still need to be hard-coded, so I'm open for ideas
> on how this could be improved.

Thank you for your patch-series, I've applied the series to my
review-hans branch:
https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans

Note it will show up in my review-hans branch once I've pushed my
local branch there, which might take a while.

Once I've run some tests on this branch the patches there will be
added to the platform-drivers-x86/for-next branch and eventually
will be included in the pdx86 pull-request to Linus for the next
merge-window.

Regards,

Hans



>
> Changes in v2:
> - Fix Kconfig dependency
>
> Changes in v3:
> - Fix use of lockdep_assert_held()
>
> Maximilian Luz (6):
> platform/surface: Set up Surface Aggregator device registry
> platform/surface: aggregator_registry: Add base device hub
> platform/surface: aggregator_registry: Add battery subsystem devices
> platform/surface: aggregator_registry: Add platform profile device
> platform/surface: aggregator_registry: Add DTX device
> platform/surface: aggregator_registry: Add HID subsystem devices
>
> MAINTAINERS | 1 +
> drivers/platform/surface/Kconfig | 27 +
> drivers/platform/surface/Makefile | 1 +
> .../surface/surface_aggregator_registry.c | 641 ++++++++++++++++++
> 4 files changed, 670 insertions(+)
> create mode 100644 drivers/platform/surface/surface_aggregator_registry.c
>