Merge branch 'net-phy-qca808x-fix-the-active-high-led-polarity-mode'

Donggeun Yoo says:

====================
net: phy: qca808x: fix the active-high LED polarity mode

A QCA8081 with an 'active-high' LED node does not work today, in two
separate ways, so this is now two patches: qca808x_led_polarity_set()
rejects the mode outright, and once it stops doing that
qca808x_config_init() still will not put the bit back after the reset
phy_init_hw() runs.

Tested in QEMU against a synthetic MDIO bus that answers as a QCA8081 and
emulates MMD7 0x901a, with the reset clearing BIT(6) as f203c8c77c
describes. One kernel, one harness, three arms, x86_64, 7.3.0-rc2+:

  DT node            base      1/2 only   1/2 + 2/2
  active-high        -EINVAL   inverted   correct
  active-low         correct   correct    correct
  no polarity node   correct   correct    correct
  high-impedance     -EINVAL   -EINVAL    -EINVAL

Still no QCA808x hardware here; the harness emulates the one register,
so a confirmation on a real board would be welcome.
====================

Link: https://patch.msgid.link/20260915223138.321307-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-09-17 17:02:38 -07:00
commit 29f4b46371

View File

@ -87,6 +87,9 @@
#define QCA8081_PHY_ID 0x004dd101
/* led_polarity_mode otherwise holds a PHY_LED_ACTIVE_* value */
#define QCA808X_PHY_LED_UNSET -1
MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi");
MODULE_LICENSE("GPL");
@ -187,8 +190,7 @@ static int qca808x_probe(struct phy_device *phydev)
if (!priv)
return -ENOMEM;
/* Init LED polarity mode to -1 */
priv->led_polarity_mode = -1;
priv->led_polarity_mode = QCA808X_PHY_LED_UNSET;
phydev->priv = priv;
@ -200,8 +202,8 @@ static int qca808x_config_init(struct phy_device *phydev)
struct qca808x_priv *priv = phydev->priv;
int ret;
/* Default to LED Active High if active-low not in DT */
if (priv->led_polarity_mode == -1) {
/* Set LED Active High unless active-low was requested in DT */
if (priv->led_polarity_mode != PHY_LED_ACTIVE_LOW) {
ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN,
QCA808X_MMD7_LED_POLARITY_CTRL,
QCA808X_LED_ACTIVE_HIGH);
@ -603,6 +605,9 @@ static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
case PHY_LED_ACTIVE_LOW:
active_low = true;
break;
case PHY_LED_ACTIVE_HIGH:
active_low = false;
break;
default:
return -EINVAL;
}
@ -612,7 +617,7 @@ static int qca808x_led_polarity_set(struct phy_device *phydev, int index,
* To detect this, check if last requested polarity mode
* match the new one.
*/
if (priv->led_polarity_mode >= 0 &&
if (priv->led_polarity_mode != QCA808X_PHY_LED_UNSET &&
priv->led_polarity_mode != active_low) {
phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n");
return -EINVAL;