All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Al Cooper <alcooperx@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>,
	kishon@ti.com, bcm-kernel-feedback-list@broadcom.com,
	linux-phy@lists.infradead.org
Subject: [PATCH AUTOSEL 5.10 03/23] phy: usb: Leave some clocks running during suspend
Date: Tue, 15 Feb 2022 10:29:37 -0500	[thread overview]
Message-ID: <20220215152957.581303-3-sashal@kernel.org> (raw)
In-Reply-To: <20220215152957.581303-1-sashal@kernel.org>

From: Al Cooper <alcooperx@gmail.com>

[ Upstream commit 42fed57046fc74586d7058bd51a1c10ac9c690cb ]

The PHY client driver does a phy_exit() call on suspend or rmmod and
the PHY driver needs to know the difference because some clocks need
to be kept running for suspend but can be shutdown on unbind/rmmod
(or if there are no PHY clients at all).

The fix is to use a PM notifier so the driver can tell if a PHY
client is calling exit() because of a system suspend or a driver
unbind/rmmod.

Signed-off-by: Al Cooper <alcooperx@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20211201180653.35097-2-alcooperx@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/phy/broadcom/phy-brcm-usb.c | 38 +++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
index 99fbc7e4138be..b901a0d4e2a80 100644
--- a/drivers/phy/broadcom/phy-brcm-usb.c
+++ b/drivers/phy/broadcom/phy-brcm-usb.c
@@ -17,6 +17,7 @@
 #include <linux/soc/brcmstb/brcmstb.h>
 #include <dt-bindings/phy/phy.h>
 #include <linux/mfd/syscon.h>
+#include <linux/suspend.h>
 
 #include "phy-brcm-usb-init.h"
 
@@ -69,12 +70,35 @@ struct brcm_usb_phy_data {
 	int			init_count;
 	int			wake_irq;
 	struct brcm_usb_phy	phys[BRCM_USB_PHY_ID_MAX];
+	struct notifier_block	pm_notifier;
+	bool			pm_active;
 };
 
 static s8 *node_reg_names[BRCM_REGS_MAX] = {
 	"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
 };
 
+static int brcm_pm_notifier(struct notifier_block *notifier,
+			    unsigned long pm_event,
+			    void *unused)
+{
+	struct brcm_usb_phy_data *priv =
+		container_of(notifier, struct brcm_usb_phy_data, pm_notifier);
+
+	switch (pm_event) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		priv->pm_active = true;
+		break;
+	case PM_POST_RESTORE:
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		priv->pm_active = false;
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
 static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
 {
 	struct phy *gphy = dev_id;
@@ -90,6 +114,9 @@ static int brcm_usb_phy_init(struct phy *gphy)
 	struct brcm_usb_phy_data *priv =
 		container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
 
+	if (priv->pm_active)
+		return 0;
+
 	/*
 	 * Use a lock to make sure a second caller waits until
 	 * the base phy is inited before using it.
@@ -119,6 +146,9 @@ static int brcm_usb_phy_exit(struct phy *gphy)
 	struct brcm_usb_phy_data *priv =
 		container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
 
+	if (priv->pm_active)
+		return 0;
+
 	dev_dbg(&gphy->dev, "EXIT\n");
 	if (phy->id == BRCM_USB_PHY_2_0)
 		brcm_usb_uninit_eohci(&priv->ini);
@@ -484,6 +514,9 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
+	priv->pm_notifier.notifier_call = brcm_pm_notifier;
+	register_pm_notifier(&priv->pm_notifier);
+
 	mutex_init(&priv->mutex);
 
 	/* make sure invert settings are correct */
@@ -524,7 +557,10 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
 
 static int brcm_usb_phy_remove(struct platform_device *pdev)
 {
+	struct brcm_usb_phy_data *priv = dev_get_drvdata(&pdev->dev);
+
 	sysfs_remove_group(&pdev->dev.kobj, &brcm_usb_phy_group);
+	unregister_pm_notifier(&priv->pm_notifier);
 
 	return 0;
 }
@@ -535,6 +571,7 @@ static int brcm_usb_phy_suspend(struct device *dev)
 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
 
 	if (priv->init_count) {
+		dev_dbg(dev, "SUSPEND\n");
 		priv->ini.wake_enabled = device_may_wakeup(dev);
 		if (priv->phys[BRCM_USB_PHY_3_0].inited)
 			brcm_usb_uninit_xhci(&priv->ini);
@@ -574,6 +611,7 @@ static int brcm_usb_phy_resume(struct device *dev)
 	 * Uninitialize anything that wasn't previously initialized.
 	 */
 	if (priv->init_count) {
+		dev_dbg(dev, "RESUME\n");
 		if (priv->wake_irq >= 0)
 			disable_irq_wake(priv->wake_irq);
 		brcm_usb_init_common(&priv->ini);
-- 
2.34.1


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

WARNING: multiple messages have this Message-ID (diff)
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Al Cooper <alcooperx@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>,
	kishon@ti.com, bcm-kernel-feedback-list@broadcom.com,
	linux-phy@lists.infradead.org
Subject: [PATCH AUTOSEL 5.10 03/23] phy: usb: Leave some clocks running during suspend
Date: Tue, 15 Feb 2022 10:29:37 -0500	[thread overview]
Message-ID: <20220215152957.581303-3-sashal@kernel.org> (raw)
In-Reply-To: <20220215152957.581303-1-sashal@kernel.org>

From: Al Cooper <alcooperx@gmail.com>

[ Upstream commit 42fed57046fc74586d7058bd51a1c10ac9c690cb ]

The PHY client driver does a phy_exit() call on suspend or rmmod and
the PHY driver needs to know the difference because some clocks need
to be kept running for suspend but can be shutdown on unbind/rmmod
(or if there are no PHY clients at all).

The fix is to use a PM notifier so the driver can tell if a PHY
client is calling exit() because of a system suspend or a driver
unbind/rmmod.

Signed-off-by: Al Cooper <alcooperx@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20211201180653.35097-2-alcooperx@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/phy/broadcom/phy-brcm-usb.c | 38 +++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
index 99fbc7e4138be..b901a0d4e2a80 100644
--- a/drivers/phy/broadcom/phy-brcm-usb.c
+++ b/drivers/phy/broadcom/phy-brcm-usb.c
@@ -17,6 +17,7 @@
 #include <linux/soc/brcmstb/brcmstb.h>
 #include <dt-bindings/phy/phy.h>
 #include <linux/mfd/syscon.h>
+#include <linux/suspend.h>
 
 #include "phy-brcm-usb-init.h"
 
@@ -69,12 +70,35 @@ struct brcm_usb_phy_data {
 	int			init_count;
 	int			wake_irq;
 	struct brcm_usb_phy	phys[BRCM_USB_PHY_ID_MAX];
+	struct notifier_block	pm_notifier;
+	bool			pm_active;
 };
 
 static s8 *node_reg_names[BRCM_REGS_MAX] = {
 	"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
 };
 
+static int brcm_pm_notifier(struct notifier_block *notifier,
+			    unsigned long pm_event,
+			    void *unused)
+{
+	struct brcm_usb_phy_data *priv =
+		container_of(notifier, struct brcm_usb_phy_data, pm_notifier);
+
+	switch (pm_event) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		priv->pm_active = true;
+		break;
+	case PM_POST_RESTORE:
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		priv->pm_active = false;
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
 static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
 {
 	struct phy *gphy = dev_id;
@@ -90,6 +114,9 @@ static int brcm_usb_phy_init(struct phy *gphy)
 	struct brcm_usb_phy_data *priv =
 		container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
 
+	if (priv->pm_active)
+		return 0;
+
 	/*
 	 * Use a lock to make sure a second caller waits until
 	 * the base phy is inited before using it.
@@ -119,6 +146,9 @@ static int brcm_usb_phy_exit(struct phy *gphy)
 	struct brcm_usb_phy_data *priv =
 		container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
 
+	if (priv->pm_active)
+		return 0;
+
 	dev_dbg(&gphy->dev, "EXIT\n");
 	if (phy->id == BRCM_USB_PHY_2_0)
 		brcm_usb_uninit_eohci(&priv->ini);
@@ -484,6 +514,9 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
+	priv->pm_notifier.notifier_call = brcm_pm_notifier;
+	register_pm_notifier(&priv->pm_notifier);
+
 	mutex_init(&priv->mutex);
 
 	/* make sure invert settings are correct */
@@ -524,7 +557,10 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
 
 static int brcm_usb_phy_remove(struct platform_device *pdev)
 {
+	struct brcm_usb_phy_data *priv = dev_get_drvdata(&pdev->dev);
+
 	sysfs_remove_group(&pdev->dev.kobj, &brcm_usb_phy_group);
+	unregister_pm_notifier(&priv->pm_notifier);
 
 	return 0;
 }
@@ -535,6 +571,7 @@ static int brcm_usb_phy_suspend(struct device *dev)
 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
 
 	if (priv->init_count) {
+		dev_dbg(dev, "SUSPEND\n");
 		priv->ini.wake_enabled = device_may_wakeup(dev);
 		if (priv->phys[BRCM_USB_PHY_3_0].inited)
 			brcm_usb_uninit_xhci(&priv->ini);
@@ -574,6 +611,7 @@ static int brcm_usb_phy_resume(struct device *dev)
 	 * Uninitialize anything that wasn't previously initialized.
 	 */
 	if (priv->init_count) {
+		dev_dbg(dev, "RESUME\n");
 		if (priv->wake_irq >= 0)
 			disable_irq_wake(priv->wake_irq);
 		brcm_usb_init_common(&priv->ini);
-- 
2.34.1


  parent reply	other threads:[~2022-02-15 15:48 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-15 15:29 [PATCH AUTOSEL 5.10 01/23] ARM: OMAP2+: hwmod: Add of_node_put() before break Sasha Levin
2022-02-15 15:29 ` Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 02/23] ARM: OMAP2+: adjust the location of put_device() call in omapdss_init_of Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29 ` Sasha Levin [this message]
2022-02-15 15:29   ` [PATCH AUTOSEL 5.10 03/23] phy: usb: Leave some clocks running during suspend Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 04/23] usb: usb251xb: add boost-up property support Sasha Levin
2022-02-20 10:12   ` Pavel Machek
2022-02-28 12:23     ` Richard Leitner
2022-03-02  9:24       ` Tommaso Merciai
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 05/23] irqchip/sifive-plic: Add missing thead, c900-plic match string Sasha Levin
2022-02-15 15:29   ` [PATCH AUTOSEL 5.10 05/23] irqchip/sifive-plic: Add missing thead,c900-plic " Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 06/23] netfilter: conntrack: don't refresh sctp entries in closed state Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 07/23] arm64: dts: meson-gx: add ATF BL32 reserved-memory region Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 08/23] arm64: dts: meson-g12: " Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 09/23] arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610 Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 10/23] pidfd: fix test failure due to stack overflow on some arches Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 11/23] selftests: fixup build warnings in pidfd / clone3 tests Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 12/23] kconfig: let 'shell' return enough output for deep path names Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 13/23] scsi: lpfc: Remove NVMe support if kernel has NVME_FC disabled Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 14/23] scsi: lpfc: Reduce log messages seen after firmware download Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 15/23] ata: libata-core: Disable TRIM on M88V29 Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 16/23] soc: aspeed: lpc-ctrl: Block error printing on probe defer cases Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 17/23] xprtrdma: fix pointer derefs in error cases of rpcrdma_ep_create Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 18/23] drm/rockchip: dw_hdmi: Do not leave clock enabled in error case Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29   ` Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 19/23] tracing: Fix tp_printk option related with tp_printk_stop_on_boot Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 20/23] NFSD: Fix offset type in I/O trace points Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 21/23] net: usb: qmi_wwan: Add support for Dell DW5829e Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 22/23] net: macb: Align the dma and coherent dma masks Sasha Levin
2022-02-15 15:29 ` [PATCH AUTOSEL 5.10 23/23] kconfig: fix failing to generate auto.conf Sasha Levin

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=20220215152957.581303-3-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=alcooperx@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=f.fainelli@gmail.com \
    --cc=kishon@ti.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=stable@vger.kernel.org \
    --cc=vkoul@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: link
Be 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.