From b530456be77160b13efe8dececb6c826538bd4a2 Mon Sep 17 00:00:00 2001 From: Piotr Kubik Date: Mon, 19 Oct 2026 18:24:52 +0200 Subject: [PATCH] net: pse-pd: si3474: keep detection enabled on the other PIs DETECT_CLASS_ENABLE holds the detection and classification bits of all four channels of a quad. si3474_pi_enable() wrote the register with the bits of its own PI only, so it cleared them for the other PI of the quad. In AUTO mode that PI keeps its admin state and a PD that already has power keeps it, but the port runs no new detection: a PD plugged in later, or one waiting for detection when the other PI is enabled, gets no power. Read the register and set the PI bits, as the PORT_MODE update above already does. Discovered by an AI code review agent. Confirmed on an SDG-9000 board (MediaTek MT7988A, two Si3474 in AUTO pin mode) with Linux 6.18: with both PIs of one quad disabled, enabling PI A and then PI B left DETECT_CLASS_ENABLE with the bits of PI B only, and a PD on PI A never got power. No kernel change was needed to reproduce it. Tested on the same board with the same sequence in both orders: DETECT_CLASS_ENABLE keeps the bits of both PIs, and the PD gets power. No kernel selftest covers PSE hardware. Fixes: a2317231df4b ("net: pse-pd: Add Si3474 PSE controller driver") Signed-off-by: Piotr Kubik Reviewed-by: Kory Maincent Link: https://patch.msgid.link/20261019162453.1244120-2-piotr@kubik.pl Signed-off-by: Jakub Kicinski --- drivers/net/pse-pd/si3474.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/pse-pd/si3474.c b/drivers/net/pse-pd/si3474.c index efb0af041599..a66a982e5ec4 100644 --- a/drivers/net/pse-pd/si3474.c +++ b/drivers/net/pse-pd/si3474.c @@ -312,8 +312,13 @@ static int si3474_pi_enable(struct pse_controller_dev *pcdev, int id) /* DETECT_CLASS_ENABLE must be set when using AUTO mode, * otherwise PI does not power up - datasheet section 2.10.2 */ - val = CHAN_BIT(chan0) | CHAN_UPPER_BIT(chan0) | - CHAN_BIT(chan1) | CHAN_UPPER_BIT(chan1); + ret = i2c_smbus_read_byte_data(client, DETECT_CLASS_ENABLE_REG); + if (ret < 0) + return ret; + + val = (u8)ret; + val |= CHAN_BIT(chan0) | CHAN_UPPER_BIT(chan0) | + CHAN_BIT(chan1) | CHAN_UPPER_BIT(chan1); ret = i2c_smbus_write_byte_data(client, DETECT_CLASS_ENABLE_REG, val); if (ret)