From patchwork Thu May 12 14:06:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 9081541 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4EFDC9F372 for ; Thu, 12 May 2016 14:06:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 66E032022D for ; Thu, 12 May 2016 14:06:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 47C1D20204 for ; Thu, 12 May 2016 14:06:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752154AbcELOGj (ORCPT ); Thu, 12 May 2016 10:06:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52153 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751901AbcELOGi (ORCPT ); Thu, 12 May 2016 10:06:38 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0169891FC8; Thu, 12 May 2016 14:06:37 +0000 (UTC) Received: from plouf.banquise.eu.com (ovpn-116-134.ams2.redhat.com [10.36.116.134]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4CE6YeM011095; Thu, 12 May 2016 10:06:35 -0400 From: Benjamin Tissoires To: "Rafael J. Wysocki" , Len Brown Cc: Mika Westerberg , Bastien Nocera , linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] ACPI / scan: force creation of platform device for the Surface tablets Date: Thu, 12 May 2016 16:06:32 +0200 Message-Id: <1463061992-11443-1-git-send-email-benjamin.tissoires@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 12 May 2016 14:06:37 +0000 (UTC) Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As mentioned in drivers/platform/x86/surfacepro3_button.c, the various Microsoft Surface tablets do not follow the ACPI SOC buttons specification. They present an I2C device like this: Device (WBUT) { Method (_HID, 0, NotSerialized) // _HID: Hardware ID { Return ("PNP0C40") } Name (_CID, "PNP0C40" /* Standard Button Controller */) // _CID: Compatible ID Method (_STA, 0, NotSerialized) // _STA: Status { Return (0x0F) } Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method { [stripped] } } Device (TEV2) { Name (_HID, "MSHW0028") // _HID: Hardware ID Name (_DEP, Package (0x06) // _DEP: Dependencies { GPO0, GPO2, GPO1, ^PCI0.I2C2, ^PCI0.I2C7, ^PCI0.I2C7.PMIC }) Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { Name (RBUF, ResourceTemplate () { GpioInt (Edge, ActiveBoth, SharedAndWake, PullDefault, 0x09C4, "\\_SB.GPO2", 0x00, ResourceConsumer, , ) { // Pin list 0x0008 } GpioInt (Edge, ActiveBoth, SharedAndWake, PullDefault, 0x09C4, "\\_SB.GPO2", 0x00, ResourceConsumer, , ) { // Pin list 0x000A } GpioInt (Edge, ActiveBoth, Shared, PullDefault, 0x09C4, "\\_SB.GPO0", 0x00, ResourceConsumer, , ) { // Pin list 0x005D } GpioInt (Edge, ActiveBoth, Shared, PullDefault, 0x09C4, "\\_SB.GPO1", 0x00, ResourceConsumer, , ) { // Pin list 0x0008 } I2cSerialBus (0x002D, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.PCI0.I2C2", 0x00, ResourceConsumer, , ) [stripped] }) [stripped] If ((OBID <= 0x0C)) { Return (RBUF) /* \_SB_.TEV2._CRS.RBUF */ } Return (PBUF) /* \_SB_.TEV2._CRS.PBUF */ } Method (_STA, 0, NotSerialized) // _STA: Status { Return (0x0F) } Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method { [stripped] } } The actual HW button is named MSHW0028 on the MS Surface (Pro) 3 and is meant to be bound on the I2C bus 7. The problem is that the bus doesn't see any device on the address 0x002D. The Surface Pro devices have working ACPI events and thus we can use surfacepro3_button which is a pure acpi driver. The Surface 3 however does not generate any ACPI events and the buttons are not working through surfacepro3_button (even when we add the name TEV2 in this module). The solution consists in forcing the creation of an platform device which we can handle in soc_button_array as any proper SOC GPIO buttons should be. Signed-off-by: Benjamin Tissoires --- Hi, this is IMO the best way to handle this situation (besides fixing the DSDT itself). The other solutions I thought were: - add a specific acpi driver that will unbind the current I2C acpi handle and will create the platform_driver - add a specific acpi driver that merges surfacepro3_button and soc_button_array but has a lot of code duplication I am open to any other solution if we could have this list of ids in a different place but I could not see any other. Cheers, Benjamin drivers/acpi/scan.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5f28cf7..6fe9296 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -46,6 +46,12 @@ DEFINE_MUTEX(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); static DEFINE_MUTEX(acpi_hp_context_lock); +static const struct acpi_device_id i2c_whitelisted_id_list[] = { + {"MSHW0028", 0}, /* Surface (Pro) 3 buttons */ + {"MSHW0040", 0}, /* Surface Pro 4 buttons */ + {"", 0}, +}; + struct acpi_dep_data { struct list_head node; acpi_handle master; @@ -1676,13 +1682,21 @@ static void acpi_default_enumeration(struct acpi_device *device) bool is_spi_i2c_slave = false; /* - * Do not enemerate SPI/I2C slaves as they will be enuerated by their + * Do not enemerate SPI/I2C slaves as they will be enumerated by their * respective parents. */ INIT_LIST_HEAD(&resource_list); acpi_dev_get_resources(device, &resource_list, acpi_check_spi_i2c_slave, &is_spi_i2c_slave); acpi_dev_free_resource_list(&resource_list); + + /* + * these devices are declared as I2C but should actually be + * enumerated as platform devices. + */ + if (!acpi_match_device_ids(device, i2c_whitelisted_id_list)) + is_spi_i2c_slave = false; + if (!is_spi_i2c_slave) acpi_create_platform_device(device); }