cancel_work_sync(&led_cdev->set_brightness_work);
led_stop_software_blink(led_cdev);
+ device_remove_groups(led_cdev->dev, led_cdev->trigger->groups);
if (led_cdev->trigger->deactivate)
led_cdev->trigger->deactivate(led_cdev);
- device_remove_groups(led_cdev->dev, led_cdev->trigger->groups);
led_cdev->trigger = NULL;
led_cdev->trigger_data = NULL;
led_cdev->activated = false;
spin_unlock(&trig->leddev_list_lock);
led_cdev->trigger = trig;
+ /*
+ * Some activate() calls use led_trigger_event() to initialize
+ * the brightness of the LED for which the trigger is being set.
+ * Ensure the led_cdev is visible on trig->led_cdevs for this.
+ */
+ synchronize_rcu();
+
+ /*
+ * If "set brightness to 0" is pending in workqueue,
+ * we don't want that to be reordered after ->activate()
+ */
+ flush_work(&led_cdev->set_brightness_work);
+
ret = 0;
if (trig->activate)
ret = trig->activate(led_cdev);
}
EXPORT_SYMBOL_GPL(led_trigger_event);
+void led_mc_trigger_event(struct led_trigger *trig,
+ unsigned int *intensity_value, unsigned int num_colors,
+ enum led_brightness brightness)
+{
+ struct led_classdev *led_cdev;
+
+ if (!trig)
+ return;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) {
+ if (!(led_cdev->flags & LED_MULTI_COLOR))
+ continue;
+
+ led_mc_set_brightness(led_cdev, intensity_value, num_colors, brightness);
+ }
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(led_mc_trigger_event);
+
static void led_trigger_blink_setup(struct led_trigger *trig,
unsigned long delay_on,
unsigned long delay_off,