From patchwork Sat Mar 9 15:19:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 10845973 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0BB8713B5 for ; Sat, 9 Mar 2019 15:21:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E34842BBE3 for ; Sat, 9 Mar 2019 15:21:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D166A2C938; Sat, 9 Mar 2019 15:21:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 890252BBE3 for ; Sat, 9 Mar 2019 15:21:29 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 8641A825; Sat, 9 Mar 2019 16:20:36 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 8641A825 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1552144886; bh=p+i9lq16VqDdxge4pLaSD4xofN0zLv4RyELvVjoZhe4=; h=From:To:Date:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From; b=WhSWYYuRKnlOKYN3FADj2tdta8psfsoj1c75VDyyWpjfJq2Zqd1wjjg+0qJrid1Uy /yT1laCR3YmM2J3j+AoWQPRlyVgsr4NXbuFSIkt2xMJbK/6n5c1T11XpGRNIBJOzfx Pr8fIIAEo6S3CXy1y3YSSDs+LsLZ8ZoPW4+0oy0E= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 090DDF896CE; Sat, 9 Mar 2019 16:20:36 +0100 (CET) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4F40AF896EC; Sat, 9 Mar 2019 16:20:34 +0100 (CET) Received: from youngberry.canonical.com (youngberry.canonical.com [91.189.89.112]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 8C6A7F80724 for ; Sat, 9 Mar 2019 16:20:30 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 8C6A7F80724 Received: from [112.44.203.232] (helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1h2dlz-0003sY-V0; Sat, 09 Mar 2019 15:20:29 +0000 From: Hui Wang To: alsa-devel@alsa-project.org, tiwai@suse.de Date: Sat, 9 Mar 2019 23:19:47 +0800 Message-Id: <20190309151947.24663-1-hui.wang@canonical.com> X-Mailer: git-send-email 2.17.1 Subject: [alsa-devel] [PATCH] ALSA: hda - call runtime_resume after S3 and S4 for each codec X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" X-Virus-Scanned: ClamAV using ClamSMTP Recently we found the audio jack detection doesn't work after suspend on many machines with Realtek codec. Sometimes the audio selection dialogue didn't show up after users plugged headhphone/headset into the headset jack, sometimes after uses plugged headphone/headset, then click the sound icon on the upper-right corner of gnome-desktop, it also showed the speaker rather than the headphone. The root cause is that before suspend, the codec already call the runtime_suspend since this codec is not used by any apps, then in resume, it will not call runtime_resume for this codec. But for some realtek codec (so far, alc236, alc255 and alc891) with the specific BIOS, if it doesn't run runtime_resume after suspend, all codec functions including jack detection stop working anymore. This problem existed for a long time, but it was not exposed, that is because if users is playing sound or recording sound, and at the same time they run suspend, the runtime_suspend will be called in pm_suspend and runtime_resume will be called in pm_resume; if audio codec is not used by any apps and users run suspend, the runtime_resume will not be called in pm_resume, then codec stops working, but if users play sound or open sound-setting to check audio device, this will trigger calling to runtime_resume ( via snd_hda_power_up), then the codec starts working again before users notice this problem. Since we don't know how many codec and BIOS combinations have this problem, to fix it, let the driver call runtime_resume for all codecs in pm_resume, maybe for some codecs, this is not needed, but it is harmless. After a codec is runtime resumed, if it is not used by any apps, it will be runtime suspended soon and furthermore we don't run suspend frequently, this change will not add much power consumption. Signed-off-by: Hui Wang --- include/sound/hda_codec.h | 3 +++ sound/pci/hda/hda_codec.c | 26 +++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h index cc7c8d42d4fd..a4e26d1d18bc 100644 --- a/include/sound/hda_codec.h +++ b/include/sound/hda_codec.h @@ -262,6 +262,9 @@ struct hda_codec { unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */ unsigned int force_pin_prefix:1; /* Add location prefix */ unsigned int link_down_at_suspend:1; /* link down at runtime suspend */ +#ifdef CONFIG_PM_SLEEP + unsigned int already_rt_suspend:1; /* already runtime suspend before sleep */ +#endif #ifdef CONFIG_PM unsigned long power_on_acct; unsigned long power_off_acct; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 5f2005098a60..7c2bbe25adde 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2939,34 +2939,54 @@ static int hda_codec_runtime_resume(struct device *dev) #endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP +static int hda_codec_force_resume(struct device *dev) +{ + struct hda_codec *codec = dev_to_hda_codec(dev); + + if (codec->already_rt_suspend) { + int ret; + + pm_runtime_get_noresume(dev); + ret = pm_runtime_force_resume(dev); + pm_runtime_put(dev); + return ret; + } else + return pm_runtime_force_resume(dev); +} static int hda_codec_pm_suspend(struct device *dev) { + struct hda_codec *codec = dev_to_hda_codec(dev); + dev->power.power_state = PMSG_SUSPEND; + codec->already_rt_suspend = pm_runtime_suspended(dev); return pm_runtime_force_suspend(dev); } static int hda_codec_pm_resume(struct device *dev) { dev->power.power_state = PMSG_RESUME; - return pm_runtime_force_resume(dev); + return hda_codec_force_resume(dev); } static int hda_codec_pm_freeze(struct device *dev) { + struct hda_codec *codec = dev_to_hda_codec(dev); + dev->power.power_state = PMSG_FREEZE; + codec->already_rt_suspend = pm_runtime_suspended(dev); return pm_runtime_force_suspend(dev); } static int hda_codec_pm_thaw(struct device *dev) { dev->power.power_state = PMSG_THAW; - return pm_runtime_force_resume(dev); + return hda_codec_force_resume(dev); } static int hda_codec_pm_restore(struct device *dev) { dev->power.power_state = PMSG_RESTORE; - return pm_runtime_force_resume(dev); + return hda_codec_force_resume(dev); } #endif /* CONFIG_PM_SLEEP */