Received: by 10.213.65.68 with SMTP id h4csp258822imn; Fri, 16 Mar 2018 02:05:50 -0700 (PDT) X-Google-Smtp-Source: AG47ELuJQMuEjaDlYFiT9ctrKy80KyztBnyZa9po0zSAZcxI7ANBOIH6agHGh8G9fhYm8UQ4hZiM X-Received: by 2002:a17:902:c6b:: with SMTP id 98-v6mr1244797pls.267.1521191150481; Fri, 16 Mar 2018 02:05:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521191150; cv=none; d=google.com; s=arc-20160816; b=QasGKOeIh89ytDrRVnToxPoz30YmJSkBrlarckJtqym1aqN/SzgQ0Hopi48yA50s7I +7m/bia+4cHuqF24VMtqWJZSjz507oaNEFb4nnD4taEIPMQB5AT2Aify7+0b/bCF83I5 ifT2sdv//yhl2FEnZcn86CZ5+GjttX1hyUT9JY2vT0fSRMlwyIAeOiM4fNem8xMzJ2Rc nGmARepeNUDG16z13+2k5MefoxwSG8bHrgIs2pUfj4LlpYseeiTdqw8YLNUIqVYDU8en 3RKjfF0DELzNyBJo0ldlol0TsrTE/lMtBFhlOdeRhdhMVv+C2GdwZX+e01c63LO8Ch0a kerw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:arc-authentication-results; bh=uDOcnEYoRofqNJwXovY237d2i1fIoURfTDWLKovcDAU=; b=DwaSxJlK8lfLjXuARKvXZ+UJlQMf0LLT0s2A9RvZsB9bwLnr18fNa9JzOKRs0K6zQ3 5HjdB4FiRVu/tRaMjQcdv6f9ghmhBsSpZzZ7AHLueY3o9zB3KAR7vOOGr6JmhGEeW2x2 RpHb2uHidl5+wOfnHn7ywSvgBFBLL6pGIHIBLIBIv9PNf6YK8ckHvNRqwEYZfyVj65LF ZcGIuDp9u7vqZHvYO02j42AeA0q4s/ZJK8yY+dsE3y2J9kAKhdyU+TIsksFNj8bS2ECk ZPj+hniTJ7r9AJ1fLo0Xb1vnyoKNzTQIijGwO3L68Lf/2JQP7xXgcpUUvx+tKf1SyW+M Unbw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t22-v6si6118423plj.233.2018.03.16.02.05.36; Fri, 16 Mar 2018 02:05:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752819AbeCPJDW (ORCPT + 99 others); Fri, 16 Mar 2018 05:03:22 -0400 Received: from mga14.intel.com ([192.55.52.115]:15076 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750877AbeCPJDU (ORCPT ); Fri, 16 Mar 2018 05:03:20 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Mar 2018 02:03:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,315,1517904000"; d="scan'208";a="38492708" Received: from mattu-haswell.fi.intel.com (HELO [10.237.72.164]) ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 16 Mar 2018 02:03:17 -0700 Subject: Re: Intel GemniLake xHCI connected devices can never wake up the system from suspend To: Daniel Drake Cc: chiu@endlessm.com, mathias.nyman@intel.com, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux@endlessm.com, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, "Rafael J. Wysocki" References: <20180316082320.12636-1-drake@endlessm.com> From: Mathias Nyman Message-ID: <71f9b3cb-a66b-937a-8cfc-7b9127f6f5b9@linux.intel.com> Date: Fri, 16 Mar 2018 11:06:42 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <20180316082320.12636-1-drake@endlessm.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Adding Rafael directly to CC In short, if _S3D and _S3W are missing in DSDT then a PCI device stays in D0 during suspend in Linux, but goes to D3 in Windows. USB wake doesn't work in Geminilake because of this. Should this be changed? reasoning below. On 16.03.2018 10:23, Daniel Drake wrote: >> I've studied the ACPI spec trying to understand better, but I'm >> struggling with the question: >> What is the maximum number (lowest power) permitted device power state >> for a device that is configured as able to wake the system from S3, >> **that does not implement the _S3W method**? > > Actually the ACPI spec has an answer for the case when _S3D is present. > The lack of clarity is only over the situation when both _S3D and _S3W > are missing - like on the platforms being worked on here. > > The _S3D docs say: >> If the device can wake the system from the S3 system sleeping state (see >> _PRW) then the device must support wake in the D-state returned by this >> object. However, OSPM cannot assume wake from the S3 system sleeping state >> is supported in any deeper D-state unless specified by a corresponding >> _S3W object > > Looking at the design of the existing Linux code, it seems like this > "max = min" assignment that is causing us trouble originates directly > from an attempt to implement that logic: if we didn't get a response from > _S3W, then we must clamp ourselves to the data we got from _S3D. > > If I modify the Linux code to be a little more specific in that logic > (only applying when we actually got something from _S3D) then the > problematic behaviour is avoided and USB wakeups work. > > I feel that this change makes the Linux implementation more directly > mirror the wording in the ACPI spec and it's associated lack of clarity > for when both methods are missing. Thoughts? > > --- > drivers/acpi/device_pm.c | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c > index a4c8ad98560d..44f12c5c75ee 100644 > --- a/drivers/acpi/device_pm.c > +++ b/drivers/acpi/device_pm.c > @@ -543,6 +543,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, > unsigned long long ret; > int d_min, d_max; > bool wakeup = false; > + acpi_status sxd_status; > acpi_status status; > > /* > @@ -565,8 +566,8 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, > * provided if AE_NOT_FOUND is returned. > */ > ret = d_min; > - status = acpi_evaluate_integer(handle, method, NULL, &ret); > - if ((ACPI_FAILURE(status) && status != AE_NOT_FOUND) > + sxd_status = acpi_evaluate_integer(handle, method, NULL, &ret); > + if ((ACPI_FAILURE(sxd_status) && sxd_status != AE_NOT_FOUND) > || ret > ACPI_STATE_D3_COLD) > return -ENODATA; > > @@ -599,7 +600,11 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, > method[3] = 'W'; > status = acpi_evaluate_integer(handle, method, NULL, &ret); > if (status == AE_NOT_FOUND) { > - if (target_state > ACPI_STATE_S0) > + /* No _SxW. In this case, the ACPI spec says that we > + * must not go into any power state deeper than the > + * value returned from _SxD. > + */ > + if (sxd_status == AE_OK && target_state > ACPI_STATE_S0) > d_max = d_min; > } else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) { > /* Fall back to D3cold if ret is not a valid state. */ >