leds: pwm: convert to atomic PWM API
authorUwe Kleine-König <uwe@kleine-koenig.org>
Fri, 24 Jan 2020 16:54:08 +0000 (17:54 +0100)
committerPavel Machek <pavel@ucw.cz>
Wed, 26 Feb 2020 20:49:39 +0000 (21:49 +0100)
pwm_config(), pwm_enable() and pwm_disable() should get removed in the
long run. So update the driver to use the atomic API that is here to
stay.

A few side effects:

 - led_pwm_set() now returns an error when setting the PWM fails.
 - During .probe() the PWM isn't disabled implicitly by pwm_apply_args()
   any more.

Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
Tested-by: Jeff LaBundy <jeff@labundy.com>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
drivers/leds/leds-pwm.c

index b72fd89..9111cde 100644 (file)
@@ -22,9 +22,8 @@
 struct led_pwm_data {
        struct led_classdev     cdev;
        struct pwm_device       *pwm;
+       struct pwm_state        pwmstate;
        unsigned int            active_low;
-       unsigned int            period;
-       int                     duty;
 };
 
 struct led_pwm_priv {
@@ -32,44 +31,29 @@ struct led_pwm_priv {
        struct led_pwm_data leds[0];
 };
 
-static void __led_pwm_set(struct led_pwm_data *led_dat)
-{
-       int new_duty = led_dat->duty;
-
-       pwm_config(led_dat->pwm, new_duty, led_dat->period);
-
-       if (new_duty == 0)
-               pwm_disable(led_dat->pwm);
-       else
-               pwm_enable(led_dat->pwm);
-}
-
 static int led_pwm_set(struct led_classdev *led_cdev,
                       enum led_brightness brightness)
 {
        struct led_pwm_data *led_dat =
                container_of(led_cdev, struct led_pwm_data, cdev);
        unsigned int max = led_dat->cdev.max_brightness;
-       unsigned long long duty =  led_dat->period;
+       unsigned long long duty = led_dat->pwmstate.period;
 
        duty *= brightness;
        do_div(duty, max);
 
        if (led_dat->active_low)
-               duty = led_dat->period - duty;
-
-       led_dat->duty = duty;
-
-       __led_pwm_set(led_dat);
+               duty = led_dat->pwmstate.period - duty;
 
-       return 0;
+       led_dat->pwmstate.duty_cycle = duty;
+       led_dat->pwmstate.enabled = duty > 0;
+       return pwm_apply_state(led_dat->pwm, &led_dat->pwmstate);
 }
 
 static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
                       struct led_pwm *led, struct fwnode_handle *fwnode)
 {
        struct led_pwm_data *led_data = &priv->leds[priv->num_leds];
-       struct pwm_args pargs;
        int ret;
 
        led_data->active_low = led->active_low;
@@ -93,17 +77,10 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
 
        led_data->cdev.brightness_set_blocking = led_pwm_set;
 
-       /*
-        * FIXME: pwm_apply_args() should be removed when switching to the
-        * atomic PWM API.
-        */
-       pwm_apply_args(led_data->pwm);
-
-       pwm_get_args(led_data->pwm, &pargs);
+       pwm_init_state(led_data->pwm, &led_data->pwmstate);
 
-       led_data->period = pargs.period;
-       if (!led_data->period)
-               led_data->period = led->pwm_period_ns;
+       if (!led_data->pwmstate.period)
+               led_data->pwmstate.period = led->pwm_period_ns;
 
        ret = devm_led_classdev_register(dev, &led_data->cdev);
        if (ret == 0) {