[[PATCH]] drivers: leds/trigger: system cannot enter suspend
Linus Walleij
linus.walleij at linaro.org
Fri Jun 9 04:25:28 PDT 2017
On Mon, Jun 5, 2017 at 9:36 AM, Zhang Bo <bo.zhang at nxp.com> wrote:
> System cannot enter suspend mode because of heartbeat led trigger.
As mentioned this should not be a problem.
> Heartbeat_pm_notifier is called when system prepare to enter suspend
> mode, then call led_trigger_unregister to change the trigger of led device
> to none. It will send uevent message and the wakeup source count changed.
>
> Add suspend/resume ops to the struct led_trigger, implement these two ops
> for ledtrig-heartbeat. Add led_trigger_suspend/led_trigger_resume funcitons
> to iterate through all LED class devices registered on given trigger and
> call their suspend/resume ops and disable/enable sysfs at the same time.
>
> Call led_trigger_suspend{resuem} API in pm_notifier function to
> suspend/resume all led devices listed in given trigger.
>
> Signed-off-by: Zhang Bo <bo.zhang at nxp.com>
The patch is nice because it fixes my sloppy approach of just adding/removing
the trigger made earlier.
It stops unsolicited I2C traffic and other nastines from happening during the
suspend/resume cycle.
I would even add:
Fixes: 5ab92a7cb82c ("leds: handle suspend/resume in heartbeat trigger")
(...)
> +static void heartbeat_trig_resume(struct led_classdev *led_cdev)
> +{
> + struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
> +
> + if (led_cdev->suspended) {
> + setup_timer(&heartbeat_data->timer,
> + led_heartbeat_function, (unsigned long) led_cdev);
> + heartbeat_data->phase = 0;
> + led_heartbeat_function(heartbeat_data->timer.data);
> + led_cdev->suspended = false;
> + }
> +}
> +
> +static void heartbeat_trig_suspend(struct led_classdev *led_cdev)
> +{
> + struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
> +
> + if (led_cdev->activated && !led_cdev->suspended) {
> + del_timer_sync(&heartbeat_data->timer);
> + led_cdev->suspended = true;
> }
Are we sure that the LED is *off* at this point so you don't suspend/resume
with a glowing LED?
Else insert a call to make sure that it's like so, and maybe even
a variable to hold the current state (off/on) across the suspend/resume
cycle.
> @@ -161,25 +186,23 @@ static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)
> .name = "heartbeat",
> .activate = heartbeat_trig_activate,
> .deactivate = heartbeat_trig_deactivate,
> + .suspend = heartbeat_trig_suspend,
> + .resume = heartbeat_trig_resume,
(...)
> + void (*suspend)(struct led_classdev *led_cdev);
> + void (*resume)(struct led_classdev *led_cdev);
These names do not correspons to the actual PM calls
they are utilized for.
Name them
.pm_prepare_suspend()
.pm_post_suspend()
Instead, this indicates better the place when they get called.
Yours,
Linus Walleij
More information about the linux-arm-kernel
mailing list