* [PATCH] soc: qcom: pmic_glink_altmode: acknowledge notifications on undescribed ports
@ 2026-09-30 11:16 Rahul Pon
0 siblings, 0 replies; only message in thread
From: Rahul Pon @ 2026-09-30 11:16 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio; +Cc: linux-arm-msm, linux-kernel
The driver enables port notifications from the firmware (ALTMODE_PAN_EN)
for every port, but only acknowledges them (ALTMODE_PAN_ACK) from the
worker of a port that has a connector node. A notification for any other
port is logged at debug level and dropped without an acknowledgment.
On an HP OmniBook 5 (Snapdragon X2, Mahua) whose device tree does not
yet describe the USB-C connectors, the firmware kept charging on the
connector that was plugged in, but once a notification had gone
unacknowledged (on unplug), its UCSI connector status reported no
connection on either port through repeated replugs, and no charging
session started again. The firmware also reports more UCSI connectors
than a board may describe to this driver (here a third, USB Standard-A,
port).
Acknowledge notifications for ports without a connector node from a
work item, as pmic_glink_altmode_request() sleeps and the notification
callback must not.
Assisted-by: LLM
Signed-off-by: Rahul Pon <theflyingrahul@gmail.com>
---
drivers/soc/qcom/pmic_glink_altmode.c | 42 +++++++++++++++++++++++++--
1 file changed, 40 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index 13c434f8d0..24ee9ecc42 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -6,6 +6,7 @@
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/cleanup.h>
+#include <linux/devm-helpers.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -138,6 +139,10 @@ struct pmic_glink_altmode {
struct work_struct enable_work;
+ /* Ports without a connector node with a notification to acknowledge */
+ struct work_struct ack_work;
+ unsigned long ack_pending;
+
struct pmic_glink_altmode_port ports[PMIC_GLINK_MAX_PORTS];
};
@@ -393,6 +398,35 @@ static void pmic_glink_altmode_worker(struct work_struct *work)
pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index);
}
+/*
+ * The firmware expects every port notification to be acknowledged, also for
+ * ports that have no connector node and are otherwise ignored here; one left
+ * unacknowledged can keep it from reporting further connections. Acknowledge
+ * those from process context, as pmic_glink_altmode_request() sleeps.
+ */
+static void pmic_glink_altmode_ack_worker(struct work_struct *work)
+{
+ struct pmic_glink_altmode *altmode = container_of(work, struct pmic_glink_altmode,
+ ack_work);
+ unsigned int port;
+
+ for (port = 0; port < BITS_PER_LONG; port++) {
+ if (test_and_clear_bit(port, &altmode->ack_pending))
+ pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, port);
+ }
+}
+
+static void pmic_glink_altmode_ack_undefined(struct pmic_glink_altmode *altmode, u8 port)
+{
+ dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
+
+ if (port >= BITS_PER_LONG)
+ return;
+
+ set_bit(port, &altmode->ack_pending);
+ schedule_work(&altmode->ack_work);
+}
+
static enum typec_orientation pmic_glink_altmode_orientation(unsigned int orientation)
{
if (orientation == 0)
@@ -441,7 +475,7 @@ static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmod
svid = mux == 2 ? USB_TYPEC_DP_SID : 0;
if (port >= ARRAY_SIZE(altmode->ports) || !altmode->ports[port].altmode) {
- dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
+ pmic_glink_altmode_ack_undefined(altmode, port);
return;
}
@@ -480,7 +514,7 @@ static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmod
orientation = notify->orientation;
if (port >= ARRAY_SIZE(altmode->ports) || !altmode->ports[port].altmode) {
- dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
+ pmic_glink_altmode_ack_undefined(altmode, port);
return;
}
@@ -593,6 +627,10 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
init_completion(&altmode->pan_ack);
mutex_init(&altmode->lock);
+ ret = devm_work_autocancel(dev, &altmode->ack_work, pmic_glink_altmode_ack_worker);
+ if (ret)
+ return ret;
+
device_for_each_child_node(dev, fwnode) {
ret = fwnode_property_read_u32(fwnode, "reg", &port);
if (ret < 0) {
base-commit: 551c722f40809618230001baccf219193e22fc5a
--
2.53.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-30 11:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-30 11:16 [PATCH] soc: qcom: pmic_glink_altmode: acknowledge notifications on undescribed ports Rahul Pon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®