[openwrt/openwrt] realtek: rtl931x: Cleanup LED set initialization

LEDE Commits lede-commits at lists.infradead.org
Mon Oct 6 15:15:52 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/254c9ac40bdb93f8b015e42039ca597bc9bde57f

commit 254c9ac40bdb93f8b015e42039ca597bc9bde57f
Author: Harshal Gohel <hg at simonwunderlich.de>
AuthorDate: Tue Jul 15 19:53:07 2025 +0200

    realtek: rtl931x: Cleanup LED set initialization
    
    The LED sets must be configured before per-port LEDs are actually assigned.
    At the same time, the LED set configuration was basically unreadable and
    the RTL930x from commit 2cfb1ecf1035 ("rtl930x: Rework per port LED
    configuration") does a better job. Instead of moving the old implementation
    around, just adopt the one from RTL930x.
    
    Signed-off-by: Harshal Gohel <hg at simonwunderlich.de>
    Signed-off-by: Sven Eckelmann <se at simonwunderlich.de>
    Link: https://github.com/openwrt/openwrt/pull/20300
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h   |  9 ++++
 .../files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c   | 56 +++++++++++++++-------
 2 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
index 66b761fdd5..9102442231 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl838x.h
@@ -584,6 +584,15 @@ typedef enum {
 
 #define RTL931X_LED_GLB_ACTIVE_LOW BIT(21)
 
+#define RTL931X_LED_SETX_0_CTRL(x) (RTL931X_LED_SET0_0_CTRL - (x * 8))
+#define RTL931X_LED_SETX_1_CTRL(x) (RTL931X_LED_SETX_0_CTRL(x) - 4)
+
+/* get register for given set and led in the set */
+#define RTL931X_LED_SETX_LEDY(x,y) (RTL931X_LED_SETX_0_CTRL(x) - 4 * (y / 2))
+
+/* get shift for given led in any set */
+#define RTL931X_LED_SET_LEDX_SHIFT(x) (16 * (x % 2))
+
 #define MAX_VLANS 4096
 #define MAX_LAGS 16
 #define MAX_PRIOS 8
diff --git a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
index 8ac9bcc177..ca2a5ff5d8 100644
--- a/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
+++ b/target/linux/realtek/files-6.12/drivers/net/dsa/rtl83xx/rtl931x.c
@@ -1494,6 +1494,45 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv)
 		return;
 	}
 
+	for (int set = 0; set < 4; set++) {
+		char set_name[16] = {0};
+		u32 set_config[4];
+		int leds_in_this_set = 0;
+
+		/* Reset LED set configuration */
+		sw_w32(0, RTL931X_LED_SETX_0_CTRL(set));
+		sw_w32(0, RTL931X_LED_SETX_1_CTRL(set));
+
+		/* Each LED set has (up to) 4 LEDs, and each LED is configured
+		 * with 16 bits. So each 32 bit register holds configuration for
+		 * 2 LEDs. Therefore, each set requires 2 registers for
+		 * configuring all 4 LEDs.
+		 */
+		snprintf(set_name, sizeof(set_name), "led_set%d", set);
+		leds_in_this_set = of_property_count_u32_elems(node, set_name);
+
+		if (leds_in_this_set <= 0 || leds_in_this_set > ARRAY_SIZE(set_config)) {
+			if (leds_in_this_set != -EINVAL) {
+				dev_err(dev, "%s invalid, skipping this set, leds_in_this_set=%d, should be (0, %d]\n",
+					set_name, leds_in_this_set, ARRAY_SIZE(set_config));
+			}
+
+			continue;
+		}
+
+		dev_info(dev, "%s has %d LEDs configured\n", set_name, leds_in_this_set);
+
+		if (of_property_read_u32_array(node, set_name, set_config, leds_in_this_set))
+			break;
+
+		/* Write configuration for selected LEDs */
+		for (int i = 0, led = leds_in_this_set - 1; led >= 0; led--, i++) {
+			sw_w32_mask(0xffff << RTL931X_LED_SET_LEDX_SHIFT(led),
+				    (0xffff & set_config[i]) << RTL931X_LED_SET_LEDX_SHIFT(led),
+				    RTL931X_LED_SETX_LEDY(set, led));
+		}
+	}
+
 	for (int i = 0; i < priv->cpu_port; i++) {
 		int pos = (i << 1) % 32;
 		u32 set;
@@ -1518,23 +1557,6 @@ static void rtldsa_931x_led_init(struct rtl838x_switch_priv *priv)
 		sw_w32_mask(0, set << pos, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i));
 	}
 
-	for (int i = 0; i < 4; i++) {
-		const __be32 *led_set;
-		char set_name[9];
-		u32 setlen;
-		u32 v;
-
-		sprintf(set_name, "led_set%d", i);
-		dev_dbg(dev, ">%s<\n", set_name);
-		led_set = of_get_property(node, set_name, &setlen);
-		if (!led_set || setlen != 16)
-			break;
-		v = be32_to_cpup(led_set) << 16 | be32_to_cpup(led_set + 1);
-		sw_w32(v, RTL931X_LED_SET0_0_CTRL - 4 - i * 8);
-		v = be32_to_cpup(led_set + 2) << 16 | be32_to_cpup(led_set + 3);
-		sw_w32(v, RTL931X_LED_SET0_0_CTRL - i * 8);
-	}
-
 	/* Set LED mode to serial (0x1) */
 	sw_w32_mask(0x3, 0x1, RTL931X_LED_GLB_CTRL);
 




More information about the lede-commits mailing list