[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1668430562-27114-1-git-send-email-ivo.g.dimitrov.75@gmail.com>
Date: Mon, 14 Nov 2022 14:56:02 +0200
From: Ivaylo Dimitrov <ivo.g.dimitrov.75@...il.com>
To: sre@...nel.org, orsonzhai@...il.com, baolin.wang@...ux.alibaba.com,
zhang.lyra@...il.com, gregkh@...uxfoundation.org,
felipe.balbi@...ux.intel.com
Cc: linux-pm@...r.kernel.org, linux-kernel@...r.kernel.org,
patches@...nsource.cirrus.com, linux-usb@...r.kernel.org,
tony@...mide.com, Ivaylo Dimitrov <ivo.g.dimitrov.75@...il.com>
Subject: [PATCH] usb: phy: add dedicated notifier for charger events
usb_phy::notifier is already used by various PHY drivers (including
phy_generic) to report VBUS status changes and its usage conflicts with
charger current limit changes reporting.
Fix that by introducing a second notifier that is dedicated to usb charger
notifications. Add usb_charger_XXX_notifier functions. Fix charger drivers
that currently (ab)use usb_XXX_notifier() to use the new API.
Fixes: a9081a008f84 ("usb: phy: Add USB charger support")
Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@...il.com>
---
drivers/power/supply/sc2731_charger.c | 4 ++--
drivers/power/supply/wm831x_power.c | 7 ++++---
drivers/usb/phy/phy.c | 7 +++++--
include/linux/usb/phy.h | 14 ++++++++++++++
4 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/power/supply/sc2731_charger.c b/drivers/power/supply/sc2731_charger.c
index 9ac17cf..e3fa0e2 100644
--- a/drivers/power/supply/sc2731_charger.c
+++ b/drivers/power/supply/sc2731_charger.c
@@ -500,7 +500,7 @@ static int sc2731_charger_probe(struct platform_device *pdev)
}
info->usb_notify.notifier_call = sc2731_charger_usb_change;
- ret = usb_register_notifier(info->usb_phy, &info->usb_notify);
+ ret = usb_charger_register_notifier(info->usb_phy, &info->usb_notify);
if (ret) {
dev_err(&pdev->dev, "failed to register notifier: %d\n", ret);
return ret;
@@ -515,7 +515,7 @@ static int sc2731_charger_remove(struct platform_device *pdev)
{
struct sc2731_charger_info *info = platform_get_drvdata(pdev);
- usb_unregister_notifier(info->usb_phy, &info->usb_notify);
+ usb_charger_unregister_notifier(info->usb_phy, &info->usb_notify);
return 0;
}
diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c
index 82e3106..0744167 100644
--- a/drivers/power/supply/wm831x_power.c
+++ b/drivers/power/supply/wm831x_power.c
@@ -650,7 +650,8 @@ static int wm831x_power_probe(struct platform_device *pdev)
switch (ret) {
case 0:
power->usb_notify.notifier_call = wm831x_usb_limit_change;
- ret = usb_register_notifier(power->usb_phy, &power->usb_notify);
+ ret = usb_charger_register_notifier(power->usb_phy,
+ &power->usb_notify);
if (ret) {
dev_err(&pdev->dev, "Failed to register notifier: %d\n",
ret);
@@ -701,8 +702,8 @@ static int wm831x_power_remove(struct platform_device *pdev)
int irq, i;
if (wm831x_power->usb_phy) {
- usb_unregister_notifier(wm831x_power->usb_phy,
- &wm831x_power->usb_notify);
+ usb_charger_unregister_notifier(wm831x_power->usb_phy,
+ &wm831x_power->usb_notify);
}
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 1b24492..6b8bf05 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -129,12 +129,13 @@ static void usb_phy_notify_charger_work(struct work_struct *work)
case USB_CHARGER_PRESENT:
usb_phy_get_charger_current(usb_phy, &min, &max);
- atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy);
+ atomic_notifier_call_chain(&usb_phy->chg_notifier, max,
+ usb_phy);
break;
case USB_CHARGER_ABSENT:
usb_phy_set_default_current(usb_phy);
- atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy);
+ atomic_notifier_call_chain(&usb_phy->chg_notifier, 0, usb_phy);
break;
default:
dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n",
@@ -678,6 +679,7 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
return ret;
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
+ ATOMIC_INIT_NOTIFIER_HEAD(&x->chg_notifier);
spin_lock_irqsave(&phy_lock, flags);
@@ -730,6 +732,7 @@ int usb_add_phy_dev(struct usb_phy *x)
x->dev->type = &usb_phy_dev_type;
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
+ ATOMIC_INIT_NOTIFIER_HEAD(&x->chg_notifier);
spin_lock_irqsave(&phy_lock, flags);
list_add_tail(&x->head, &phy_list);
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index e4de6bc..23db554 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -111,6 +111,7 @@ struct usb_phy {
enum usb_charger_state chg_state;
struct usb_charger_current chg_cur;
struct work_struct chg_work;
+ struct atomic_notifier_head chg_notifier;
/* for notification of usb_phy_events */
struct atomic_notifier_head notifier;
@@ -347,6 +348,19 @@ static inline void usb_phy_set_charger_state(struct usb_phy *usb_phy,
atomic_notifier_chain_unregister(&x->notifier, nb);
}
+/* notifiers */
+static inline int
+usb_charger_register_notifier(struct usb_phy *x, struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&x->chg_notifier, nb);
+}
+
+static inline void
+usb_charger_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)
+{
+ atomic_notifier_chain_unregister(&x->chg_notifier, nb);
+}
+
static inline const char *usb_phy_type_string(enum usb_phy_type type)
{
switch (type) {
--
1.9.1
Powered by blists - more mailing lists