From patchwork Tue Nov 1 02:47:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 620780 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26B8DFA3744 for ; Tue, 1 Nov 2022 02:47:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229902AbiKACrx (ORCPT ); Mon, 31 Oct 2022 22:47:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229824AbiKACrw (ORCPT ); Mon, 31 Oct 2022 22:47:52 -0400 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BABA41789F for ; Mon, 31 Oct 2022 19:47:51 -0700 (PDT) Received: by mail-pf1-x42d.google.com with SMTP id b29so12282686pfp.13 for ; Mon, 31 Oct 2022 19:47:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XGwO4GhQFCnfEGWVPRq8FBqqasnQ0/oWKbkrBe1VfIA=; b=mTkPZRYDYhw7QQ4scrrL39McOrmqG4T2zdd9b1wJc1nA4b4vOHpdpe2kQIBil7+LLD 2ZRTIHbgqZo1u2pX5NK3RY9NdieoqMYh3AxjH+xsnP+X5JoUdv7ApEWQdqDJz4DNzFa+ RX0mx/sFa46oPS5LrNP+0FUWDUjDgei/9C7J4jMn6S8MnRfvipYU+Do7DzYSDJU4SdY2 l5//Wj1X/eibK1Pg3kEj/kryDik3M4ZOjdyIqIskK+IE2rgOMevVRB2ZyFv/OhlZE97L h19CJ8DsgqfSkhUIRSTuFucLbA+2+L3ZTWUZVjx9v6I4QDLMEuHXB59VWI4Ep6PsaiXi fQoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XGwO4GhQFCnfEGWVPRq8FBqqasnQ0/oWKbkrBe1VfIA=; b=5fRCANCWuqdlbSofw5cnQi4/woHEuyxhQ2/DHy/G3S92qdd6Pis2hRlBzQSjCWx+Ot 3n3eVJcqfyN9fMSHwU7+H0v5DqgfCK1MyICx/QlXx/VhZx0HW8NYsO9cZonwxZoDFkNQ VC34p1dWTYKzigEHT4brrb/UNthabejodJrTKW8vFUW1LvknZEGr4R0Jnzr3+qVxtTaG GtmGu4xQohVvJqmQaq9puxwXBdZY/up4LlEVdP8n9y9aZEAqvt1AvCIcPOnFKJUV7nBv WSupIwBcKOk4Sia6X9JHMc8PqLabRD1F/+avpMkJ6SYuFotHYYIXW9M+T9VENRtuSEFO +wmQ== X-Gm-Message-State: ACrzQf3tenz5Lmd4jSVf8WzLFYwgmKnTbNL7awk+Hx1Q2h98pyxu8ME8 VqS8sR530RhHMSwrD9ZnQvLHyg== X-Google-Smtp-Source: AMsMyM4bSE21Et48MZZyhTXTYW43mn8i8pnopd2pfokIMPIlsGH1+7KrDx+RdzUA6tPxeJw2/pX3pw== X-Received: by 2002:a62:4c6:0:b0:55f:c739:51e0 with SMTP id 189-20020a6204c6000000b0055fc73951e0mr17184994pfe.49.1667270871297; Mon, 31 Oct 2022 19:47:51 -0700 (PDT) Received: from localhost.localdomain (80.251.214.228.16clouds.com. [80.251.214.228]) by smtp.gmail.com with ESMTPSA id y4-20020a170902ed4400b001714c36a6e7sm5079570plb.284.2022.10.31.19.47.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Oct 2022 19:47:50 -0700 (PDT) From: Shawn Guo To: "Rafael J . Wysocki" Cc: Kevin Hilman , Ulf Hansson , Len Brown , Pavel Machek , Greg Kroah-Hartman , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Shawn Guo Subject: [PATCH v2 1/3] PM: domains: Pass generic PM noirq hooks to genpd_finish_suspend() Date: Tue, 1 Nov 2022 10:47:34 +0800 Message-Id: <20221101024736.1509207-2-shawn.guo@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221101024736.1509207-1-shawn.guo@linaro.org> References: <20221101024736.1509207-1-shawn.guo@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org While argument `poweroff` works fine for genpd_finish_suspend() to handle distinction between suspend and poweroff, it won't scale if we want to use it for freeze as well. Pass generic PM noirq hooks as arguments instead, so that the function can possibly cover freeze case too. Signed-off-by: Shawn Guo --- drivers/base/power/domain.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6471b559230e..54f6b0dd35fb 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1189,12 +1189,15 @@ static int genpd_prepare(struct device *dev) * genpd_finish_suspend - Completion of suspend or hibernation of device in an * I/O pm domain. * @dev: Device to suspend. - * @poweroff: Specifies if this is a poweroff_noirq or suspend_noirq callback. + * @suspend_noirq: Generic suspend_noirq callback. + * @resume_noirq: Generic resume_noirq callback. * * Stop the device and remove power from the domain if all devices in it have * been stopped. */ -static int genpd_finish_suspend(struct device *dev, bool poweroff) +static int genpd_finish_suspend(struct device *dev, + int (*suspend_noirq)(struct device *dev), + int (*resume_noirq)(struct device *dev)) { struct generic_pm_domain *genpd; int ret = 0; @@ -1203,10 +1206,7 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff) if (IS_ERR(genpd)) return -EINVAL; - if (poweroff) - ret = pm_generic_poweroff_noirq(dev); - else - ret = pm_generic_suspend_noirq(dev); + ret = suspend_noirq(dev); if (ret) return ret; @@ -1217,10 +1217,7 @@ static int genpd_finish_suspend(struct device *dev, bool poweroff) !pm_runtime_status_suspended(dev)) { ret = genpd_stop_dev(genpd, dev); if (ret) { - if (poweroff) - pm_generic_restore_noirq(dev); - else - pm_generic_resume_noirq(dev); + resume_noirq(dev); return ret; } } @@ -1244,7 +1241,9 @@ static int genpd_suspend_noirq(struct device *dev) { dev_dbg(dev, "%s()\n", __func__); - return genpd_finish_suspend(dev, false); + return genpd_finish_suspend(dev, + pm_generic_suspend_noirq, + pm_generic_resume_noirq); } /** @@ -1353,7 +1352,9 @@ static int genpd_poweroff_noirq(struct device *dev) { dev_dbg(dev, "%s()\n", __func__); - return genpd_finish_suspend(dev, true); + return genpd_finish_suspend(dev, + pm_generic_poweroff_noirq, + pm_generic_restore_noirq); } /** From patchwork Tue Nov 1 02:47:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 620779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E754FA3741 for ; Tue, 1 Nov 2022 02:48:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229915AbiKACsD (ORCPT ); Mon, 31 Oct 2022 22:48:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229853AbiKACsB (ORCPT ); Mon, 31 Oct 2022 22:48:01 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF87E17A9A for ; Mon, 31 Oct 2022 19:47:58 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id g62so12306752pfb.10 for ; Mon, 31 Oct 2022 19:47:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YzzxAfsdgRp0sBb+mu0K+QG/OOHcPzTsEjXihYPQFME=; b=nFJQRNfBcSfuRnyWTPD2PqIVAOVoYK8UwR3GpVyEu2Kt7VviKDzvwPmdC4oda5tXZ2 bkA+kGHYv3NlC4q4ZHPDUbPSbh6JNnrUCT1mB2s6tZ9C8gFT7fd/oKUen8GU1TFH76ay VJzUmhUvN+OlpOq9PZ8uAuBZLra85nD1jHX5WwHREw4xSjw2bhs800mOw96m7m9xPfXH eC3AgwSdpr/3F65Q0U1FyNBpn5U/7gZLQr1zvjdB0JiEsOP4uDAL0Lgpt/yWfLt2M/BK jHrfqt42dh6i9vJ16+5GY+4I3AmKfe6glSRwh5Hs8sYpdNigMIdicFc2B75xzPHEcUxI fd/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YzzxAfsdgRp0sBb+mu0K+QG/OOHcPzTsEjXihYPQFME=; b=sBf/jHR3q+CXSC63JIhyYWCsY5h2Ev6HPl/BVbfUGd/DFqkJBiM/ATki1saY/w/BVC o9Ne9pwzn/u1kfpJtNz3kA81kQFOwTsqNK427EKfqN4h0JQcw+YaFM3b1e5ivfvKeu6j SZmxNMEZkiHJ32N6ig501o/KSxHFWDDAyyAvS+yPLp1yqQ9HAkct/1rZ/9kqQhXfmCAg lz8ewy0QQLO7qKRKImQRkKihDQLOhg/tDBiYOZflfVBnlnys+vSd5jsGlNI/o6WfWfJ7 KvM5ypwA98ilrrW94QGl/6uYfSukFLfnYSjBseUQaiIOulflvn1MmQgQE5wUHEdPTFsl zg+w== X-Gm-Message-State: ACrzQf3lHzf58yUSqvl6vWuq3OVn91EV6A1+nSDWmWeprca+eKJ2puf2 gGecMHkvOYDwK3VRZbA4ChI2lg== X-Google-Smtp-Source: AMsMyM4PXSRjkxnm+W5B8LwIYiLLmAdpnyzwAapzw27ah/2HWSIAR8kn1/hbuw7umU7fh8lP4gcwxg== X-Received: by 2002:a63:100a:0:b0:46f:b030:877d with SMTP id f10-20020a63100a000000b0046fb030877dmr8939251pgl.333.1667270878330; Mon, 31 Oct 2022 19:47:58 -0700 (PDT) Received: from localhost.localdomain (80.251.214.228.16clouds.com. [80.251.214.228]) by smtp.gmail.com with ESMTPSA id y4-20020a170902ed4400b001714c36a6e7sm5079570plb.284.2022.10.31.19.47.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Oct 2022 19:47:57 -0700 (PDT) From: Shawn Guo To: "Rafael J . Wysocki" Cc: Kevin Hilman , Ulf Hansson , Len Brown , Pavel Machek , Greg Kroah-Hartman , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Shawn Guo Subject: [PATCH v2 3/3] PM: domains: Power off[on] domain in hibernate .freeze[thaw]_noirq hook Date: Tue, 1 Nov 2022 10:47:36 +0800 Message-Id: <20221101024736.1509207-4-shawn.guo@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221101024736.1509207-1-shawn.guo@linaro.org> References: <20221101024736.1509207-1-shawn.guo@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org On platforms which use SHUTDOWN as hibernation mode, the genpd noirq hooks will be called like below. genpd_freeze_noirq() genpd_restore_noirq() ↓ ↑ Create snapshot image Restore system ↓ ↑ genpd_thaw_noirq() Read snapshot image ↓ ↑ Write snapshot image Kernel boot ↓ ↑ power_down() Power on device As of today suspend hooks genpd_suspend[resume]_noirq() manages domain on/off state, but hibernate hooks genpd_freeze[thaw]_noirq() doesn't. This results in a different behavior of domain power state between suspend and hibernate freeze, i.e. domain is powered off for the former while on for the later. It causes a problem on platforms like i.MX where the domain needs to be powered on/off by calling clock and regulator interface. When the platform restores from hibernation, the domain is off in hardware and genpd_restore_noirq() tries to power it on, but will never succeed because software state of domain (clock and regulator) is left on from the last hibernate freeze, so kernel thinks that clock and regulator are enabled while they are actually not turned on in hardware. The consequence would be that devices in the power domain will access registers without clock or power, and cause hardware lockup. Power off[on] domain in hibernate .freeze[thaw]_noirq hook for reasons: - Align the behavior between suspend and hibernate freeze. - Have power state of domains stay in sync between hardware and software for hibernate freeze, and thus fix the lockup issue seen on i.MX platform. Signed-off-by: Shawn Guo --- drivers/base/power/domain.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index b81baeb38d81..28c9e04e3488 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1323,24 +1323,11 @@ static int genpd_resume_noirq(struct device *dev) */ static int genpd_freeze_noirq(struct device *dev) { - const struct generic_pm_domain *genpd; - int ret = 0; - dev_dbg(dev, "%s()\n", __func__); - genpd = dev_to_genpd(dev); - if (IS_ERR(genpd)) - return -EINVAL; - - ret = pm_generic_freeze_noirq(dev); - if (ret) - return ret; - - if (genpd->dev_ops.stop && genpd->dev_ops.start && - !pm_runtime_status_suspended(dev)) - ret = genpd_stop_dev(genpd, dev); - - return ret; + return genpd_finish_suspend(dev, + pm_generic_freeze_noirq, + pm_generic_thaw_noirq); } /** @@ -1352,23 +1339,9 @@ static int genpd_freeze_noirq(struct device *dev) */ static int genpd_thaw_noirq(struct device *dev) { - const struct generic_pm_domain *genpd; - int ret = 0; - dev_dbg(dev, "%s()\n", __func__); - genpd = dev_to_genpd(dev); - if (IS_ERR(genpd)) - return -EINVAL; - - if (genpd->dev_ops.stop && genpd->dev_ops.start && - !pm_runtime_status_suspended(dev)) { - ret = genpd_start_dev(genpd, dev); - if (ret) - return ret; - } - - return pm_generic_thaw_noirq(dev); + return genpd_finish_resume(dev, pm_generic_thaw_noirq); } /**