diff --git a/drivers/leds/rgb/leds-group-multicolor.c b/drivers/leds/rgb/leds-group-multicolor.c index 39f58be32af5..2cf9c3f2c65d 100644 --- a/drivers/leds/rgb/leds-group-multicolor.c +++ b/drivers/leds/rgb/leds-group-multicolor.c @@ -70,6 +70,7 @@ static int leds_gmc_probe(struct platform_device *pdev) struct leds_multicolor *priv; unsigned int max_brightness = 0; int i, ret, count = 0; + bool allow_subled_writes = false; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -121,28 +122,39 @@ static int leds_gmc_probe(struct platform_device *pdev) priv->mc_cdev.num_colors = count; init_data.fwnode = dev_fwnode(dev); + allow_subled_writes = fwnode_property_present(init_data.fwnode, "mc-allow-subled-writes"); ret = devm_led_classdev_multicolor_register_ext(dev, &priv->mc_cdev, &init_data); if (ret) return dev_err_probe(dev, ret, "failed to register multicolor LED for %s.\n", cdev->name); - ret = leds_gmc_set(cdev, cdev->brightness); - if (ret) - return dev_err_probe(dev, ret, "failed to set LED value for %s.", cdev->name); + /* Honor DT default-state using LED core helper */ + { + int def = led_init_default_state_get(dev_fwnode(dev)); + + if (def != LEDS_DEFSTATE_KEEP) { + ret = leds_gmc_set(cdev, cdev->brightness); + if (ret) + return dev_err_probe(dev, ret, "failed to set LED value for %s.", cdev->name); + } + } for (i = 0; i < count; i++) { struct led_classdev *led_cdev = priv->monochromatics[i]; - /* - * Make the individual LED sysfs interface read-only to prevent the user - * to change the brightness of the individual LEDs of the group. - */ - mutex_lock(&led_cdev->led_access); - led_sysfs_disable(led_cdev); - mutex_unlock(&led_cdev->led_access); + /* Optionally keep sub-LED sysfs writable for legacy userspace */ + if (!allow_subled_writes) { + /* + * Make the individual LED sysfs interface read-only to prevent the user + * to change the brightness of the individual LEDs of the group. + */ + mutex_lock(&led_cdev->led_access); + led_sysfs_disable(led_cdev); + mutex_unlock(&led_cdev->led_access); - /* Restore the write access to the LED sysfs when the group is destroyed */ - devm_add_action_or_reset(dev, restore_sysfs_write_access, led_cdev); + /* Restore the write access to the LED sysfs when the group is destroyed */ + devm_add_action_or_reset(dev, restore_sysfs_write_access, led_cdev); + } } return 0;