From: Jim Quinlan <jim2101024@gmail.com> To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne <nsaenz@kernel.org>, Rob Herring <robh@kernel.org>, Mark Brown <broonie@kernel.org>, bcm-kernel-feedback-list@broadcom.com, jim2101024@gmail.com, james.quinlan@broadcom.com Cc: "Florian Fainelli" <f.fainelli@gmail.com>, "Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>, "Krzysztof Wilczyński" <kw@linux.com>, "Bjorn Helgaas" <bhelgaas@google.com>, linux-rpi-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v6 8/9] PCI: brcmstb: Do not turn off regulators if EP can wake up Date: Fri, 29 Oct 2021 16:03:16 -0400 [thread overview] Message-ID: <20211029200319.23475-9-jim2101024@gmail.com> (raw) In-Reply-To: <20211029200319.23475-1-jim2101024@gmail.com> If any downstream device may wake up during S2/S3 suspend, we do not want to turn off its power when suspending. Signed-off-by: Jim Quinlan <jim2101024@gmail.com> --- drivers/pci/controller/pcie-brcmstb.c | 49 ++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 6635e143cfcb..18b9f7c97864 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -192,6 +192,7 @@ static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val); static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val); static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val); +static bool brcm_pcie_link_up(struct brcm_pcie *pcie); static const char * const supplies[] = { "vpcie3v3", @@ -304,8 +305,20 @@ struct brcm_pcie { void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val); struct regulator_bulk_data supplies[ARRAY_SIZE(supplies)]; unsigned int num_supplies; + bool ep_wakeup_capable; }; +static int pci_dev_may_wakeup(struct pci_dev *dev, void *data) +{ + bool *ret = data; + + if (device_may_wakeup(&dev->dev)) { + *ret = true; + dev_dbg(&dev->dev, "disable cancelled for wake-up device\n"); + } + return (int) *ret; +} + static int brcm_regulators_on(struct brcm_pcie *pcie) { struct device *dev = pcie->dev; @@ -313,6 +326,18 @@ static int brcm_regulators_on(struct brcm_pcie *pcie) if (!pcie->num_supplies) return 0; + + if (pcie->ep_wakeup_capable) { + /* + * We are resuming from a suspend. In the previous suspend + * we did not disable the power supplies, so there is no + * need to enable them (and falsely increase their usage + * count). + */ + pcie->ep_wakeup_capable = false; + return 0; + } + ret = regulator_bulk_enable(pcie->num_supplies, pcie->supplies); if (ret) dev_err(dev, "failed to enable EP regulators\n"); @@ -320,13 +345,28 @@ static int brcm_regulators_on(struct brcm_pcie *pcie) return ret; } -static int brcm_regulators_off(struct brcm_pcie *pcie) +static int brcm_regulators_off(struct brcm_pcie *pcie, bool force) { + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); struct device *dev = pcie->dev; int ret; if (!pcie->num_supplies) return 0; + + pcie->ep_wakeup_capable = false; + + if (!force && bridge->bus && brcm_pcie_link_up(pcie)) { + /* + * If at least one device on this bus is enabled as a + * wake-up source, do not turn off regulators. + */ + pci_walk_bus(bridge->bus, pci_dev_may_wakeup, + &pcie->ep_wakeup_capable); + if (pcie->ep_wakeup_capable) + return 0; + } + ret = regulator_bulk_disable(pcie->num_supplies, pcie->supplies); if (ret) dev_err(dev, "failed to disable EP regulators\n"); @@ -1248,7 +1288,7 @@ static int brcm_pcie_suspend(struct device *dev) reset_control_rearm(pcie->rescal); clk_disable_unprepare(pcie->clk); - return brcm_regulators_off(pcie); + return brcm_regulators_off(pcie, false); } static int brcm_pcie_resume(struct device *dev) @@ -1264,6 +1304,7 @@ static int brcm_pcie_resume(struct device *dev) ret = reset_control_reset(pcie->rescal); if (ret) goto err_disable_clk; + ret = brcm_regulators_on(pcie); if (ret) goto err_reset; @@ -1311,7 +1352,7 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie) reset_control_rearm(pcie->rescal); clk_disable_unprepare(pcie->clk); if (pcie->num_supplies) { - brcm_regulators_off(pcie); + brcm_regulators_off(pcie, true); regulator_bulk_free(pcie->num_supplies, pcie->supplies); } } @@ -1382,7 +1423,7 @@ static int brcm_pcie_pci_subdev_prepare(struct pci_bus *bus, int devfn, return 0; err_out1: - brcm_regulators_off(pcie); + brcm_regulators_off(pcie, true); err_out0: regulator_bulk_free(pcie->num_supplies, pcie->supplies); pcie->num_supplies = 0; -- 2.17.1
WARNING: multiple messages have this Message-ID (diff)
From: Jim Quinlan <jim2101024@gmail.com> To: linux-pci@vger.kernel.org, Nicolas Saenz Julienne <nsaenz@kernel.org>, Rob Herring <robh@kernel.org>, Mark Brown <broonie@kernel.org>, bcm-kernel-feedback-list@broadcom.com, jim2101024@gmail.com, james.quinlan@broadcom.com Cc: "Florian Fainelli" <f.fainelli@gmail.com>, "Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>, "Krzysztof Wilczyński" <kw@linux.com>, "Bjorn Helgaas" <bhelgaas@google.com>, linux-rpi-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel@lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v6 8/9] PCI: brcmstb: Do not turn off regulators if EP can wake up Date: Fri, 29 Oct 2021 16:03:16 -0400 [thread overview] Message-ID: <20211029200319.23475-9-jim2101024@gmail.com> (raw) In-Reply-To: <20211029200319.23475-1-jim2101024@gmail.com> If any downstream device may wake up during S2/S3 suspend, we do not want to turn off its power when suspending. Signed-off-by: Jim Quinlan <jim2101024@gmail.com> --- drivers/pci/controller/pcie-brcmstb.c | 49 ++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 6635e143cfcb..18b9f7c97864 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -192,6 +192,7 @@ static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val); static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val); static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val); +static bool brcm_pcie_link_up(struct brcm_pcie *pcie); static const char * const supplies[] = { "vpcie3v3", @@ -304,8 +305,20 @@ struct brcm_pcie { void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val); struct regulator_bulk_data supplies[ARRAY_SIZE(supplies)]; unsigned int num_supplies; + bool ep_wakeup_capable; }; +static int pci_dev_may_wakeup(struct pci_dev *dev, void *data) +{ + bool *ret = data; + + if (device_may_wakeup(&dev->dev)) { + *ret = true; + dev_dbg(&dev->dev, "disable cancelled for wake-up device\n"); + } + return (int) *ret; +} + static int brcm_regulators_on(struct brcm_pcie *pcie) { struct device *dev = pcie->dev; @@ -313,6 +326,18 @@ static int brcm_regulators_on(struct brcm_pcie *pcie) if (!pcie->num_supplies) return 0; + + if (pcie->ep_wakeup_capable) { + /* + * We are resuming from a suspend. In the previous suspend + * we did not disable the power supplies, so there is no + * need to enable them (and falsely increase their usage + * count). + */ + pcie->ep_wakeup_capable = false; + return 0; + } + ret = regulator_bulk_enable(pcie->num_supplies, pcie->supplies); if (ret) dev_err(dev, "failed to enable EP regulators\n"); @@ -320,13 +345,28 @@ static int brcm_regulators_on(struct brcm_pcie *pcie) return ret; } -static int brcm_regulators_off(struct brcm_pcie *pcie) +static int brcm_regulators_off(struct brcm_pcie *pcie, bool force) { + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); struct device *dev = pcie->dev; int ret; if (!pcie->num_supplies) return 0; + + pcie->ep_wakeup_capable = false; + + if (!force && bridge->bus && brcm_pcie_link_up(pcie)) { + /* + * If at least one device on this bus is enabled as a + * wake-up source, do not turn off regulators. + */ + pci_walk_bus(bridge->bus, pci_dev_may_wakeup, + &pcie->ep_wakeup_capable); + if (pcie->ep_wakeup_capable) + return 0; + } + ret = regulator_bulk_disable(pcie->num_supplies, pcie->supplies); if (ret) dev_err(dev, "failed to disable EP regulators\n"); @@ -1248,7 +1288,7 @@ static int brcm_pcie_suspend(struct device *dev) reset_control_rearm(pcie->rescal); clk_disable_unprepare(pcie->clk); - return brcm_regulators_off(pcie); + return brcm_regulators_off(pcie, false); } static int brcm_pcie_resume(struct device *dev) @@ -1264,6 +1304,7 @@ static int brcm_pcie_resume(struct device *dev) ret = reset_control_reset(pcie->rescal); if (ret) goto err_disable_clk; + ret = brcm_regulators_on(pcie); if (ret) goto err_reset; @@ -1311,7 +1352,7 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie) reset_control_rearm(pcie->rescal); clk_disable_unprepare(pcie->clk); if (pcie->num_supplies) { - brcm_regulators_off(pcie); + brcm_regulators_off(pcie, true); regulator_bulk_free(pcie->num_supplies, pcie->supplies); } } @@ -1382,7 +1423,7 @@ static int brcm_pcie_pci_subdev_prepare(struct pci_bus *bus, int devfn, return 0; err_out1: - brcm_regulators_off(pcie); + brcm_regulators_off(pcie, true); err_out0: regulator_bulk_free(pcie->num_supplies, pcie->supplies); pcie->num_supplies = 0; -- 2.17.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-10-29 20:04 UTC|newest] Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-10-29 20:03 [PATCH v6 0/9] PCI: brcmstb: have host-bridge turn on sub-device power Jim Quinlan 2021-10-29 20:03 ` Jim Quinlan 2021-10-29 20:03 ` [PATCH v6 1/9] dt-bindings: PCI: correct brcmstb interrupts, interrupt-map Jim Quinlan 2021-10-29 20:03 ` Jim Quinlan 2021-10-29 21:06 ` Florian Fainelli 2021-10-29 21:06 ` Florian Fainelli 2021-11-02 14:27 ` Rob Herring 2021-11-02 14:27 ` Rob Herring 2021-10-29 20:03 ` [PATCH v6 2/9] dt-bindings: PCI: Add bindings for Brcmstb EP voltage regulators Jim Quinlan 2021-10-29 20:03 ` Jim Quinlan 2021-11-02 15:18 ` Rob Herring 2021-11-02 15:18 ` Rob Herring 2021-10-29 20:03 ` [PATCH v6 3/9] PCI: move pci_device_add() call Jim Quinlan 2021-10-29 20:03 ` [PATCH v6 4/9] PCI: separate device_initialize() from pci_device_add() Jim Quinlan 2021-10-29 20:03 ` [PATCH v6 5/9] PCI: allow for callback to prepare nascent subdev Jim Quinlan 2021-10-29 20:03 ` [PATCH v6 6/9] PCI: brcmstb: split brcm_pcie_setup() into two funcs Jim Quinlan 2021-10-29 20:03 ` Jim Quinlan 2021-10-29 20:03 ` [PATCH v6 7/9] PCI: brcmstb: Add control of subdevice voltage regulators Jim Quinlan 2021-10-29 20:03 ` Jim Quinlan 2021-10-31 19:49 ` kernel test robot 2021-10-31 19:49 ` kernel test robot 2021-11-01 15:24 ` Mark Brown 2021-11-01 15:24 ` Mark Brown 2021-11-02 16:00 ` Rob Herring 2021-11-02 16:00 ` Rob Herring 2021-11-02 22:36 ` Jim Quinlan 2021-11-02 22:36 ` Jim Quinlan 2021-11-04 14:42 ` Rob Herring 2021-11-04 14:42 ` Rob Herring 2021-10-29 20:03 ` Jim Quinlan [this message] 2021-10-29 20:03 ` [PATCH v6 8/9] PCI: brcmstb: Do not turn off regulators if EP can wake up Jim Quinlan 2021-11-01 15:26 ` Mark Brown 2021-11-01 15:26 ` Mark Brown 2021-10-29 20:03 ` [PATCH v6 9/9] PCI: brcmstb: change brcm_phy_stop() to return void Jim Quinlan 2021-10-29 20:03 ` Jim Quinlan
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211029200319.23475-9-jim2101024@gmail.com \ --to=jim2101024@gmail.com \ --cc=bcm-kernel-feedback-list@broadcom.com \ --cc=bhelgaas@google.com \ --cc=broonie@kernel.org \ --cc=f.fainelli@gmail.com \ --cc=james.quinlan@broadcom.com \ --cc=kw@linux.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pci@vger.kernel.org \ --cc=linux-rpi-kernel@lists.infradead.org \ --cc=lorenzo.pieralisi@arm.com \ --cc=nsaenz@kernel.org \ --cc=robh@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.