leds: class: Improve LED and LED flash class registration API
authorJacek Anaszewski <jacek.anaszewski@gmail.com>
Sun, 9 Jun 2019 18:19:03 +0000 (20:19 +0200)
committerJacek Anaszewski <jacek.anaszewski@gmail.com>
Thu, 25 Jul 2019 18:07:50 +0000 (20:07 +0200)
Replace of_led_classdev_register() with led_classdev_register_ext(), which
accepts easily extendable struct led_init_data, instead of the fixed
struct device_node argument. The latter can be now passed in an fwnode
property of the struct led_init_data.

The modification is driven by the need for passing additional arguments
required for the forthcoming generic mechanism for composing LED names.
Currently the LED name is conveyed in the "name" char pointer property of
the struct led_classdev. This is redundant since LED class device name
is accessible throughout the whole LED class device life time via
associated struct device's kobj->name property.

The change will not break any existing clients since the patch alters
also existing led_classdev{_flash}_register() macro wrappers, that pass
NULL in place of init_data, which leads to using legacy name
initialization path basing on the struct led_classdev's "name" property.

Three existing users of devm_of_led_classdev_registers() are modified
to use devm_led_classdev_register(), which will not impact their
operation since they in fact didn't need to pass struct device_node on
registration from the beginning.

Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Cc: Baolin Wang <baolin.wang@linaro.org>
Cc: Dan Murphy <dmurphy@ti.com>
Cc: Daniel Mack <daniel@zonque.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Oleh Kravchenko <oleg@kaa.org.ua>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Simon Shields <simon@lineageos.org>
Acked-by: Pavel Machek <pavel@ucw.cz>
drivers/leds/led-class-flash.c
drivers/leds/led-class.c
drivers/leds/leds-cr0014114.c
drivers/leds/leds-gpio.c
drivers/leds/leds-max77650.c
drivers/leds/leds-pwm.c
include/linux/led-class-flash.h
include/linux/leds.h

index 94980c654d8934621043e132f591d747fad95d5c..60c3de5c6b9f9bb4d7e83f2da3f2629a33cd281f 100644 (file)
@@ -282,8 +282,9 @@ static void led_flash_init_sysfs_groups(struct led_classdev_flash *fled_cdev)
        led_cdev->groups = flash_groups;
 }
 
-int led_classdev_flash_register(struct device *parent,
-                               struct led_classdev_flash *fled_cdev)
+int led_classdev_flash_register_ext(struct device *parent,
+                                   struct led_classdev_flash *fled_cdev,
+                                   struct led_init_data *init_data)
 {
        struct led_classdev *led_cdev;
        const struct led_flash_ops *ops;
@@ -309,13 +310,13 @@ int led_classdev_flash_register(struct device *parent,
        }
 
        /* Register led class device */
-       ret = led_classdev_register(parent, led_cdev);
+       ret = led_classdev_register_ext(parent, led_cdev, init_data);
        if (ret < 0)
                return ret;
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(led_classdev_flash_register);
+EXPORT_SYMBOL_GPL(led_classdev_flash_register_ext);
 
 void led_classdev_flash_unregister(struct led_classdev_flash *fled_cdev)
 {
index 4793e77808e2c72dffb621600d7ab3e399fc8c7f..242122f493333695becb790818f45d315da38ff7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/leds.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
@@ -242,14 +243,16 @@ static int led_classdev_next_name(const char *init_name, char *name,
 }
 
 /**
- * of_led_classdev_register - register a new object of led_classdev class.
+ * led_classdev_register_ext - register a new object of led_classdev class
+ *                            with init data.
  *
  * @parent: parent of LED device
  * @led_cdev: the led_classdev structure for this device.
- * @np: DT node describing this LED
+ * @init_data: LED class device initialization data
  */
-int of_led_classdev_register(struct device *parent, struct device_node *np,
-                           struct led_classdev *led_cdev)
+int led_classdev_register_ext(struct device *parent,
+                             struct led_classdev *led_cdev,
+                             struct led_init_data *init_data)
 {
        char name[LED_MAX_NAME_SIZE];
        int ret;
@@ -266,7 +269,8 @@ int of_led_classdev_register(struct device *parent, struct device_node *np,
                mutex_unlock(&led_cdev->led_access);
                return PTR_ERR(led_cdev->dev);
        }
-       led_cdev->dev->of_node = np;
+       if (init_data && init_data->fwnode)
+               led_cdev->dev->of_node = to_of_node(init_data->fwnode);
 
        if (ret)
                dev_warn(parent, "Led %s renamed to %s due to name collision",
@@ -311,7 +315,7 @@ int of_led_classdev_register(struct device *parent, struct device_node *np,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(of_led_classdev_register);
+EXPORT_SYMBOL_GPL(led_classdev_register_ext);
 
 /**
  * led_classdev_unregister - unregisters a object of led_properties class.
@@ -356,14 +360,15 @@ static void devm_led_classdev_release(struct device *dev, void *res)
 }
 
 /**
- * devm_of_led_classdev_register - resource managed led_classdev_register()
+ * devm_led_classdev_register_ext - resource managed led_classdev_register_ext()
  *
  * @parent: parent of LED device
  * @led_cdev: the led_classdev structure for this device.
+ * @init_data: LED class device initialization data
  */
-int devm_of_led_classdev_register(struct device *parent,
-                                 struct device_node *np,
-                                 struct led_classdev *led_cdev)
+int devm_led_classdev_register_ext(struct device *parent,
+                                  struct led_classdev *led_cdev,
+                                  struct led_init_data *init_data)
 {
        struct led_classdev **dr;
        int rc;
@@ -372,7 +377,7 @@ int devm_of_led_classdev_register(struct device *parent,
        if (!dr)
                return -ENOMEM;
 
-       rc = of_led_classdev_register(parent, np, led_cdev);
+       rc = led_classdev_register_ext(parent, led_cdev, init_data);
        if (rc) {
                devres_free(dr);
                return rc;
@@ -383,7 +388,7 @@ int devm_of_led_classdev_register(struct device *parent,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(devm_of_led_classdev_register);
+EXPORT_SYMBOL_GPL(devm_led_classdev_register_ext);
 
 static int devm_led_classdev_match(struct device *dev, void *res, void *data)
 {
index 0e4262462cb9d34ca1a6a767b1ad813cd537bcb2..1c82152764d2e2157451ea37adcb8827ce9c5258 100644 (file)
@@ -207,8 +207,7 @@ static int cr0014114_probe_dt(struct cr0014114 *priv)
                led->ldev.max_brightness          = CR_MAX_BRIGHTNESS;
                led->ldev.brightness_set_blocking = cr0014114_set_sync;
 
-               ret = devm_of_led_classdev_register(priv->dev, np,
-                                                   &led->ldev);
+               ret = devm_led_classdev_register(priv->dev, &led->ldev);
                if (ret) {
                        dev_err(priv->dev,
                                "failed to register LED device %s, err %d",
index bdc98ddca1dc07d631c95d2ae1dd7186299cf8d8..8f463c912db8559988ff034c4ac030aaa298f2d4 100644 (file)
@@ -108,7 +108,7 @@ static int create_gpio_led(const struct gpio_led *template,
        if (ret < 0)
                return ret;
 
-       return devm_of_led_classdev_register(parent, np, &led_dat->cdev);
+       return devm_led_classdev_register(parent, &led_dat->cdev);
 }
 
 struct gpio_leds_priv {
index 04738324b3e6259c68afac2c6fd675b52b7d9eef..5a14f9775b0eff21c5a3dc7afabb33d7de2886ce 100644 (file)
@@ -118,7 +118,7 @@ static int max77650_led_probe(struct platform_device *pdev)
                of_property_read_string(child, "linux,default-trigger",
                                        &led->cdev.default_trigger);
 
-               rv = devm_of_led_classdev_register(dev, child, &led->cdev);
+               rv = devm_led_classdev_register(dev, &led->cdev);
                if (rv)
                        goto err_node_put;
 
index 48d068f80f114037a6461707a44a3804971e8094..d0e1f2710351139a91513378a29b3196e69e3fb8 100644 (file)
@@ -111,8 +111,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
        if (!led_data->period && (led->pwm_period_ns > 0))
                led_data->period = led->pwm_period_ns;
 
-       ret = devm_of_led_classdev_register(dev, to_of_node(fwnode),
-                                           &led_data->cdev);
+       ret = devm_led_classdev_register(dev, &led_data->cdev);
        if (ret == 0) {
                priv->num_leds++;
                led_pwm_set(&led_data->cdev, led_data->cdev.brightness);
index f52713f0a2697c0173bc86a9c98257f9d836f1fe..1e824963af17409de8bb066e57e4ca779345c22b 100644 (file)
@@ -86,15 +86,20 @@ static inline struct led_classdev_flash *lcdev_to_flcdev(
 }
 
 /**
- * led_classdev_flash_register - register a new object of led_classdev class
- *                              with support for flash LEDs
- * @parent: the flash LED to register
+ * led_classdev_flash_register_ext - register a new object of LED class with
+ *                                  init data and with support for flash LEDs
+ * @parent: LED flash controller device this flash LED is driven by
  * @fled_cdev: the led_classdev_flash structure for this device
+ * @init_data: the LED class flash device initialization data
  *
  * Returns: 0 on success or negative error value on failure
  */
-extern int led_classdev_flash_register(struct device *parent,
-                               struct led_classdev_flash *fled_cdev);
+extern int led_classdev_flash_register_ext(struct device *parent,
+                                       struct led_classdev_flash *fled_cdev,
+                                       struct led_init_data *init_data);
+
+#define led_classdev_flash_register(parent, fled_cdev)         \
+       led_classdev_flash_register_ext(parent, fled_cdev, NULL)
 
 /**
  * led_classdev_flash_unregister - unregisters an object of led_classdev class
index 9b2bf574a17a87aec95176df2216a974aebca65c..2bbe8a38fe3999d30c53f95dff9fdb3dcff408a8 100644 (file)
@@ -30,6 +30,11 @@ enum led_brightness {
        LED_FULL        = 255,
 };
 
+struct led_init_data {
+       /* device fwnode handle */
+       struct fwnode_handle *fwnode;
+};
+
 struct led_classdev {
        const char              *name;
        enum led_brightness      brightness;
@@ -125,16 +130,25 @@ struct led_classdev {
        struct mutex            led_access;
 };
 
-extern int of_led_classdev_register(struct device *parent,
-                                   struct device_node *np,
-                                   struct led_classdev *led_cdev);
-#define led_classdev_register(parent, led_cdev)                                \
-       of_led_classdev_register(parent, NULL, led_cdev)
-extern int devm_of_led_classdev_register(struct device *parent,
-                                        struct device_node *np,
-                                        struct led_classdev *led_cdev);
-#define devm_led_classdev_register(parent, led_cdev)                   \
-       devm_of_led_classdev_register(parent, NULL, led_cdev)
+/**
+ * led_classdev_register_ext - register a new object of LED class with
+ *                            init data
+ * @parent: LED controller device this LED is driven by
+ * @led_cdev: the led_classdev structure for this device
+ * @init_data: the LED class device initialization data
+ *
+ * Returns: 0 on success or negative error value on failure
+ */
+extern int led_classdev_register_ext(struct device *parent,
+                                    struct led_classdev *led_cdev,
+                                    struct led_init_data *init_data);
+#define led_classdev_register(parent, led_cdev)                        \
+       led_classdev_register_ext(parent, led_cdev, NULL)
+extern int devm_led_classdev_register_ext(struct device *parent,
+                                         struct led_classdev *led_cdev,
+                                         struct led_init_data *init_data);
+#define devm_led_classdev_register(parent, led_cdev)           \
+       devm_led_classdev_register_ext(parent, led_cdev, NULL)
 extern void led_classdev_unregister(struct led_classdev *led_cdev);
 extern void devm_led_classdev_unregister(struct device *parent,
                                         struct led_classdev *led_cdev);