Skip to content

Commit 64dd243

Browse files
qzeddtor
authored andcommitted
platform/x86: surfacepro3_button: Fix device check
Do not use the surfacepro3_button driver on newer Microsoft Surface models, only use it on the Surface Pro 3 and 4. Newer models (5th, 6th and possibly future generations) use the same device as the Surface Pro 4 to represent their volume and power buttons (MSHW0040), but their actual implementation is significantly different. This patch ensures that the surfacepro3_button driver is only used on the Pro 3 and 4 models, allowing a different driver to bind on other models. Signed-off-by: Maximilian Luz <[email protected]> Acked-by: Andy Shevchenko <[email protected]> Acked-by: Chen Yu <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 3b51c44 commit 64dd243

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

drivers/platform/x86/surfacepro3_button.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
#define SURFACE_BUTTON_OBJ_NAME "VGBI"
2121
#define SURFACE_BUTTON_DEVICE_NAME "Surface Pro 3/4 Buttons"
2222

23+
#define MSHW0040_DSM_REVISION 0x01
24+
#define MSHW0040_DSM_GET_OMPR 0x02 // get OEM Platform Revision
25+
static const guid_t MSHW0040_DSM_UUID =
26+
GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
27+
0x49, 0x80, 0x35);
28+
2329
#define SURFACE_BUTTON_NOTIFY_TABLET_MODE 0xc8
2430

2531
#define SURFACE_BUTTON_NOTIFY_PRESS_POWER 0xc6
@@ -142,6 +148,44 @@ static int surface_button_resume(struct device *dev)
142148
}
143149
#endif
144150

151+
/*
152+
* Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device
153+
* ID (MSHW0040) for the power/volume buttons. Make sure this is the right
154+
* device by checking for the _DSM method and OEM Platform Revision.
155+
*
156+
* Returns true if the driver should bind to this device, i.e. the device is
157+
* either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
158+
*/
159+
static bool surface_button_check_MSHW0040(struct acpi_device *dev)
160+
{
161+
acpi_handle handle = dev->handle;
162+
union acpi_object *result;
163+
u64 oem_platform_rev = 0; // valid revisions are nonzero
164+
165+
// get OEM platform revision
166+
result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
167+
MSHW0040_DSM_REVISION,
168+
MSHW0040_DSM_GET_OMPR,
169+
NULL, ACPI_TYPE_INTEGER);
170+
171+
/*
172+
* If evaluating the _DSM fails, the method is not present. This means
173+
* that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we
174+
* should use this driver. We use revision 0 indicating it is
175+
* unavailable.
176+
*/
177+
178+
if (result) {
179+
oem_platform_rev = result->integer.value;
180+
ACPI_FREE(result);
181+
}
182+
183+
dev_dbg(&dev->dev, "OEM Platform Revision %llu\n", oem_platform_rev);
184+
185+
return oem_platform_rev == 0;
186+
}
187+
188+
145189
static int surface_button_add(struct acpi_device *device)
146190
{
147191
struct surface_button *button;
@@ -154,6 +198,9 @@ static int surface_button_add(struct acpi_device *device)
154198
strlen(SURFACE_BUTTON_OBJ_NAME)))
155199
return -ENODEV;
156200

201+
if (!surface_button_check_MSHW0040(device))
202+
return -ENODEV;
203+
157204
button = kzalloc(sizeof(struct surface_button), GFP_KERNEL);
158205
if (!button)
159206
return -ENOMEM;

0 commit comments

Comments
 (0)