diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c index 83191cd591..cf9c2dc3c1 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.c +++ b/target/linux/generic/files/drivers/net/phy/ar8327.c @@ -392,8 +392,11 @@ static int ar8327_led_register(struct ar8327_led *aled) { int ret; + struct led_init_data init_data = { + .fwnode = aled->fwnode + }; - ret = led_classdev_register(NULL, &aled->cdev); + ret = led_classdev_register_ext(NULL, &aled->cdev, &init_data); if (ret < 0) return ret; @@ -447,6 +450,7 @@ ar8327_led_create(struct ar8xxx_priv *priv, aled->led_num = led_info->led_num; aled->active_low = led_info->active_low; aled->mode = led_info->mode; + aled->fwnode = led_info->fwnode; if (aled->mode == AR8327_LED_MODE_HW) aled->enable_hw_mode = true; @@ -616,6 +620,7 @@ ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np) const __be32 *paddr; int len; int i; + struct device_node *leds, *child; paddr = of_get_property(np, "qca,ar8327-initvals", &len); if (!paddr || len < (2 * sizeof(*paddr))) @@ -643,6 +648,39 @@ ar8327_hw_config_of(struct ar8xxx_priv *priv, struct device_node *np) } } + leds = of_get_child_by_name(np, "leds"); + if (!leds) + return 0; + + data->leds = kvcalloc(of_get_child_count(leds), sizeof(void *), + GFP_KERNEL); + if (!data->leds) + return -ENOMEM; + + for_each_available_child_of_node(leds, child) { + u32 reg = 0, mode = 0; + struct ar8327_led_info info; + int ret; + + ret = of_property_read_u32(child, "reg", ®); + if (ret) { + pr_err("ar8327: LED %s is missing reg node\n", child->name); + continue; + } + + of_property_read_u32(child, "qca,led-mode", &mode); + + info = (struct ar8327_led_info) { + .name = of_get_property(child, "label", NULL) ? : child->name, + .fwnode = of_fwnode_handle(child), + .active_low = of_property_read_bool(child, "active-low"), + .led_num = (enum ar8327_led_num) reg, + .mode = (enum ar8327_led_mode) mode + }; + ar8327_led_create(priv, &info); + } + + of_node_put(leds); return 0; } #else diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.h b/target/linux/generic/files/drivers/net/phy/ar8327.h index 088b288618..53a82d1f76 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8327.h +++ b/target/linux/generic/files/drivers/net/phy/ar8327.h @@ -317,6 +317,7 @@ struct ar8327_led { struct work_struct led_work; bool enable_hw_mode; enum ar8327_led_pattern pattern; + struct fwnode_handle *fwnode; }; struct ar8327_data { diff --git a/target/linux/generic/files/include/linux/ar8216_platform.h b/target/linux/generic/files/include/linux/ar8216_platform.h index 24bc442a26..fff05ffb5c 100644 --- a/target/linux/generic/files/include/linux/ar8216_platform.h +++ b/target/linux/generic/files/include/linux/ar8216_platform.h @@ -106,6 +106,7 @@ struct ar8327_led_info { bool active_low; enum ar8327_led_num led_num; enum ar8327_led_mode mode; + struct fwnode_handle *fwnode; }; #define AR8327_LED_INFO(_led, _mode, _name) { \