From patchwork Tue Jun 25 16:22:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 2777941 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5C786C0AB1 for ; Tue, 25 Jun 2013 16:20:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2E52720347 for ; Tue, 25 Jun 2013 16:20:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 641BA20335 for ; Tue, 25 Jun 2013 16:20:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752464Ab3FYQT3 (ORCPT ); Tue, 25 Jun 2013 12:19:29 -0400 Received: from mga11.intel.com ([192.55.52.93]:16532 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752455Ab3FYQT2 (ORCPT ); Tue, 25 Jun 2013 12:19:28 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 25 Jun 2013 09:20:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.87,938,1363158000"; d="scan'208";a="355551849" Received: from blue.fi.intel.com ([10.237.72.156]) by fmsmga001.fm.intel.com with ESMTP; 25 Jun 2013 09:20:08 -0700 Received: by blue.fi.intel.com (Postfix, from userid 1004) id 0C32CE0094; Tue, 25 Jun 2013 19:22:11 +0300 (EEST) From: Mika Westerberg To: Greg Kroah-Hartman , Bjorn Helgaas , "Rafael J. Wysocki" Cc: Jesse Barnes , Yinghai Lu , john.ronciak@intel.com, miles.j.penner@intel.com, bruce.w.allan@intel.com, "Kirill A. Shutemov" , Heikki Krogerus , Mika Westerberg , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, x86@kernel.org Subject: [PATCH 5/6] PCI: acpiphp: look _RMV method a bit deeper in the hierarhcy Date: Tue, 25 Jun 2013 19:22:09 +0300 Message-Id: <1372177330-28013-6-git-send-email-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1372177330-28013-1-git-send-email-mika.westerberg@linux.intel.com> References: <1372177330-28013-1-git-send-email-mika.westerberg@linux.intel.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-8.2 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 The acpiphp driver finds out whether the device is hotpluggable by checking whether it has _RMV method behind it (and if it returns 1). However, at least Acer Aspire S5 with Thunderbolt host router has this method placed behind device called EPUP (endpoint upstream port?) and not directly behind the root port as can be seen from the ASL code below: Device (RP05) { ... Device (HRUP) { Name (_ADR, Zero) Name (_PRW, Package (0x02) { 0x09, 0x04 }) Device (HRDN) { Name (_ADR, 0x00040000) Name (_PRW, Package (0x02) { 0x09, 0x04 }) Device (EPUP) { Name (_ADR, Zero) Method (_RMV, 0, NotSerialized) { Return (One) } } } } If we want to support such machines we must look for the _RMV method a bit deeper in the hierarchy. Fix this by changing pcihp_is_ejectable() to check few more devices down from the root port. Signed-off-by: Kirill A. Shutemov Signed-off-by: Mika Westerberg --- drivers/pci/hotplug/acpi_pcihp.c | 53 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 2a47e82..2760954 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -408,21 +408,64 @@ got_one: } EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); +static acpi_status pcihp_evaluate_rmv(acpi_handle handle, u32 lvl, + void *context, void **return_not_used) +{ + unsigned long long *removable = context; + unsigned long long value; + acpi_status status; + + status = acpi_evaluate_integer(handle, "_RMV", NULL, &value); + if (ACPI_SUCCESS(status) && value) { + *removable = value; + return AE_CTRL_TERMINATE; + } + return AE_OK; +} + +/* + * pcihp_is_removable - check if this device is removable + * @handle: ACPI handle of the device + * @depth: how deep in the hierarchy we look for the _RMV + * + * Look for _RMV method behind the device. @depth specifies how deep in the + * hierarchy we search. + * + * Returns %true if the device is removable, %false otherwise. + */ +static bool pcihp_is_removable(acpi_handle handle, size_t depth) +{ + unsigned long long removable = 0; + acpi_status status; + + status = pcihp_evaluate_rmv(handle, 0, &removable, NULL); + if ((status == AE_CTRL_TERMINATE) && removable) + return true; + + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, depth, pcihp_evaluate_rmv, + NULL, &removable, NULL); + return !!removable; +} + +/* + * Some BIOSes, like the one in Acer Aspire S5 places the _RMV method a bit + * deeper in the hierarhcy. So check at least 3 levels behind this device. + */ +#define PCIHP_RMV_MAX_DEPTH 3 + static int pcihp_is_ejectable(acpi_handle handle) { acpi_status status; acpi_handle tmp; - unsigned long long removable; + status = acpi_get_handle(handle, "_ADR", &tmp); if (ACPI_FAILURE(status)) return 0; status = acpi_get_handle(handle, "_EJ0", &tmp); if (ACPI_SUCCESS(status)) return 1; - status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable); - if (ACPI_SUCCESS(status) && removable) - return 1; - return 0; + + return pcihp_is_removable(handle, PCIHP_RMV_MAX_DEPTH); } /**