Merge tag 'sound-fix-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[firefly-linux-kernel-4.4.55.git] / drivers / leds / leds-pwm.c
index b31d8e99c41992c77610fe5ca1694211035ea592..7d0aaed1e23a881ab28997b09df13e372d538c36 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/fb.h>
@@ -66,9 +65,11 @@ static void led_pwm_set(struct led_classdev *led_cdev,
        struct led_pwm_data *led_dat =
                container_of(led_cdev, struct led_pwm_data, cdev);
        unsigned int max = led_dat->cdev.max_brightness;
-       unsigned int period =  led_dat->period;
+       unsigned long long duty =  led_dat->period;
 
-       led_dat->duty = brightness * period / max;
+       duty *= brightness;
+       do_div(duty, max);
+       led_dat->duty = duty;
 
        if (led_dat->can_sleep)
                schedule_work(&led_dat->work);
@@ -82,14 +83,22 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds)
                      (sizeof(struct led_pwm_data) * num_leds);
 }
 
+static void led_pwm_cleanup(struct led_pwm_priv *priv)
+{
+       while (priv->num_leds--) {
+               led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
+               if (priv->leds[priv->num_leds].can_sleep)
+                       cancel_work_sync(&priv->leds[priv->num_leds].work);
+       }
+}
+
 static int led_pwm_create_of(struct platform_device *pdev,
                             struct led_pwm_priv *priv)
 {
-       struct device_node *node = pdev->dev.of_node;
        struct device_node *child;
        int ret;
 
-       for_each_child_of_node(node, child) {
+       for_each_child_of_node(pdev->dev.of_node, child) {
                struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
 
                led_dat->cdev.name = of_get_property(child, "label",
@@ -130,8 +139,7 @@ static int led_pwm_create_of(struct platform_device *pdev,
 
        return 0;
 err:
-       while (priv->num_leds--)
-               led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
+       led_pwm_cleanup(priv);
 
        return ret;
 }
@@ -199,8 +207,8 @@ static int led_pwm_probe(struct platform_device *pdev)
        return 0;
 
 err:
-       while (i--)
-               led_classdev_unregister(&priv->leds[i].cdev);
+       priv->num_leds = i;
+       led_pwm_cleanup(priv);
 
        return ret;
 }
@@ -208,13 +216,8 @@ err:
 static int led_pwm_remove(struct platform_device *pdev)
 {
        struct led_pwm_priv *priv = platform_get_drvdata(pdev);
-       int i;
 
-       for (i = 0; i < priv->num_leds; i++) {
-               led_classdev_unregister(&priv->leds[i].cdev);
-               if (priv->leds[i].can_sleep)
-                       cancel_work_sync(&priv->leds[i].work);
-       }
+       led_pwm_cleanup(priv);
 
        return 0;
 }