Skip to contentSkip to conversation

leds: leds-gpio: Fix multiple instances registration when 'label' property is absent

PATCH Applied Fabio Estevam 4 participants 12 messages Dec 3, 2014 – Dec 4, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 leds: leds-gpio: Fix multiple instances registration when 'label' property is absent

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

---
Changes since v1:
- Consider ACPI case as suggested by Grant

 drivers/leds/leds-gpio.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/leds/leds-gpio.c +11 -1
index fd53968..8a8ba11 100644
@@ -170,6 +170,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
 	struct fwnode_handle *child;
 	struct gpio_leds_priv *priv;
 	int count, ret;
+	struct device_node *np;
 
 	count = device_get_child_node_count(dev);
 	if (!count)
@@ -189,7 +190,16 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
 			goto err;
 		}
 
-		fwnode_property_read_string(child, "label", &led.name);
+		np = of_node(child);
+
+		if (fwnode_property_present(child, "label")) {
+			fwnode_property_read_string(child, "label", &led.name);
+		} else {
+			if (IS_ENABLED(CONFIG_OF) && !led.name && np)
+				led.name = np->name;
+			if (!led.name)
+				return ERR_PTR(-EINVAL);
+		}
 		fwnode_property_read_string(child, "linux,default-trigger",
 					    &led.default_trigger);
 
Signature · 1 line
1.9.1
#1 lore raw
Quoted 42 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

---
Changes since v1:
- Consider ACPI case as suggested by Grant

 drivers/leds/leds-gpio.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/leds/leds-gpio.c +2 -1
index fd53968..8a8ba11 100644
@@ -170,6 +170,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
        struct fwnode_handle *child;
        struct gpio_leds_priv *priv;
        int count, ret;
+       struct device_node *np;
 
        count = device_get_child_node_count(dev);
        if (!count)
@@ -189,7 +190,16 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
                        goto err;
                }
 
-               fwnode_property_read_string(child, "label", &led.name);
+               np = of_node(child);

drivers/leds/leds-gpio.c static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) · line 203

Quoted 10 lines
drivers/leds/leds-gpio.c +9 -0
+
+               if (fwnode_property_present(child, "label")) {
+                       fwnode_property_read_string(child, "label", &led.name);
+               } else {
+                       if (IS_ENABLED(CONFIG_OF) && !led.name && np)
+                               led.name = np->name;
+                       if (!led.name)
+                               return ERR_PTR(-EINVAL);
+               }
                fwnode_property_read_string(child, "linux,default-trigger",

Or maybe we should not expose the CONFIG_OF versus CONFIG_ACPI ifdefery to the driver and do something like this instead:

drivers/base/property.c +0 -0
index c458458..bdeee26 100644
@@ -399,6 +399,27 @@ struct fwnode_handle

*device_get_next_child_node(struct device *dev,
}
EXPORT_SYMBOL_GPL(device_get_next_child_node);

+const char *device_get_node_name(struct device *dev, struct fwnode_handle *child)
+{
+
+ if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+ struct device_node *node = of_node(child);
+
+ if (node)
+ return node->name;
+ }
+
+ if (IS_ENABLED(CONFIG_ACPI)) {
+ struct acpi_device *node = acpi_node(child);
+
+ if (node)
+ return acpi_dev_name(node);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(device_get_node_name);
+
/**
* fwnode_handle_put - Drop reference to a device node
* @fwnode: Pointer to the device node to drop the reference to.

drivers/leds/leds-gpio.c +0 -0
index fd53968..c1c472b 100644
include/linux/property.h +1 -0
index a6a3d98..9bec811 100644
@@ -72,6 +72,8 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
 struct fwnode_handle *device_get_next_child_node(struct device *dev,
                          struct fwnode_handle *child);
 
+const char *device_get_node_name(struct device *dev, struct

fwnode_handle *child);
+
#define device_for_each_child_node(dev, child) \
for (child = device_get_next_child_node(dev, NULL); child; \
child = device_get_next_child_node(dev, child))

, and then on leds-gpio.c we can simply do:

drivers/leds/leds-gpio.c +0 -0
@@ -189,7 +189,10 @@ static struct gpio_leds_priv

*gpio_leds_create(struct platform_device *pdev)

             goto err;
         }

- fwnode_property_read_string(child, "label", &led.name);
+ if (fwnode_property_present(child, "label"))
+ fwnode_property_read_string(child, "label", &led.name);
+ else

+            led.name = device_get_node_name(dev, child);
         fwnode_property_read_string(child, "linux,default-trigger",
                         &led.default_trigger);

I am not familiar with ACPI so I don't know if the 'return acpi_dev_name(node)' is the appropriate way to retrieve the equivalent of a dt node name.

Please advise.

#2 lore raw
Quoted 41 lines · Fabio Estevam
Quoted 40 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

---
Changes since v1:
- Consider ACPI case as suggested by Grant

 drivers/leds/leds-gpio.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/leds/leds-gpio.c +1 -0
index fd53968..8a8ba11 100644
@@ -170,6 +170,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
        struct fwnode_handle *child;
        struct gpio_leds_priv *priv;
        int count, ret;
+       struct device_node *np;
 
        count = device_get_child_node_count(dev);
        if (!count)
@@ -189,7 +190,16 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
                        goto err;
                }
 
Quoted 16 lines

drivers/leds/leds-gpio.c static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) · line 203

Quoted 12 lines
drivers/leds/leds-gpio.c +10 -1
-               fwnode_property_read_string(child, "label", &led.name);
+               np = of_node(child);
+
+               if (fwnode_property_present(child, "label")) {
+                       fwnode_property_read_string(child, "label", &led.name);
+               } else {
+                       if (IS_ENABLED(CONFIG_OF) && !led.name && np)
+                               led.name = np->name;
+                       if (!led.name)
+                               return ERR_PTR(-EINVAL);
+               }
                fwnode_property_read_string(child, "linux,default-trigger",

Or maybe we should not expose the CONFIG_OF versus CONFIG_ACPI ifdefery to the driver and do something like this instead:

V2 is better than V1 to me. I'd like to see some comments from Grant and leds-gpio.c part looks good to me.

Quoted 74 lines
drivers/base/property.c +21 -0
index c458458..bdeee26 100644
@@ -399,6 +399,27 @@ struct fwnode_handle
 *device_get_next_child_node(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
+const char *device_get_node_name(struct device *dev, struct
 fwnode_handle *child)
+{
+
+    if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+        struct device_node *node = of_node(child);
+
+        if (node)
+            return node->name;
+    }
+
+    if (IS_ENABLED(CONFIG_ACPI)) {
+        struct acpi_device *node = acpi_node(child);
+
+        if (node)
+            return acpi_dev_name(node);
+    }
+
+    return NULL;
+}
+EXPORT_SYMBOL_GPL(device_get_node_name);
+
 /**

* fwnode_handle_put - Drop reference to a device node
* @fwnode: Pointer to the device node to drop the reference to.

drivers/leds/leds-gpio.c +0 -0
index fd53968..c1c472b 100644
include/linux/property.h +2 -0
index a6a3d98..9bec811 100644
@@ -72,6 +72,8 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
 struct fwnode_handle *device_get_next_child_node(struct device *dev,
                          struct fwnode_handle *child);
 
+const char *device_get_node_name(struct device *dev, struct
 fwnode_handle *child);
+
 #define device_for_each_child_node(dev, child) \
     for (child = device_get_next_child_node(dev, NULL); child; \

child = device_get_next_child_node(dev, child))

, and then on leds-gpio.c we can simply do:

drivers/leds/leds-gpio.c +4 -1
@@ -189,7 +189,10 @@ static struct gpio_leds_priv
 *gpio_leds_create(struct platform_device *pdev)
             goto err;
         }
 
-        fwnode_property_read_string(child, "label", &led.name);
+        if (fwnode_property_present(child, "label"))
+            fwnode_property_read_string(child, "label", &led.name);
+        else
+            led.name = device_get_node_name(dev, child);
         fwnode_property_read_string(child, "linux,default-trigger",
                         &led.default_trigger);

I am not familiar with ACPI so I don't know if the 'return acpi_dev_name(node)' is the appropriate way to retrieve the equivalent of a dt node name.

Please advise.

#3 lore raw
In reply to Fabio Estevam
Quoted 78 lines · Fabio Estevam
Quoted 42 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

---
Changes since v1:
- Consider ACPI case as suggested by Grant

 drivers/leds/leds-gpio.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/leds/leds-gpio.c +2 -1
index fd53968..8a8ba11 100644
@@ -170,6 +170,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
        struct fwnode_handle *child;
        struct gpio_leds_priv *priv;
        int count, ret;
+       struct device_node *np;
 
        count = device_get_child_node_count(dev);
        if (!count)
@@ -189,7 +190,16 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
                        goto err;
                }
 
-               fwnode_property_read_string(child, "label", &led.name);
+               np = of_node(child);

drivers/leds/leds-gpio.c static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) · line 203

Quoted 10 lines
drivers/leds/leds-gpio.c +9 -0
+
+               if (fwnode_property_present(child, "label")) {
+                       fwnode_property_read_string(child, "label", &led.name);
+               } else {
+                       if (IS_ENABLED(CONFIG_OF) && !led.name && np)
+                               led.name = np->name;
+                       if (!led.name)
+                               return ERR_PTR(-EINVAL);
+               }
                fwnode_property_read_string(child, "linux,default-trigger",

Or maybe we should not expose the CONFIG_OF versus CONFIG_ACPI ifdefery to the driver and do something like this instead:

drivers/base/property.c +11 -0
index c458458..bdeee26 100644
@@ -399,6 +399,27 @@ struct fwnode_handle
 *device_get_next_child_node(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(device_get_next_child_node);
 
+const char *device_get_node_name(struct device *dev, struct
 fwnode_handle *child)
+{
+
+    if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
+        struct device_node *node = of_node(child);
+
+        if (node)
+            return node->name;
+    }
+
+    if (IS_ENABLED(CONFIG_ACPI)) {

drivers/base/property.c struct fwnode_handle · line 424

Quoted 10 lines
drivers/base/property.c +10 -0
+        struct acpi_device *node = acpi_node(child);
+
+        if (node)
+            return acpi_dev_name(node);
+    }
+
+    return NULL;
+}
+EXPORT_SYMBOL_GPL(device_get_node_name);
+

Instead of a device_get_* variant, for getting the node, I would create a fwnode_get_name() helper as it would be usable in a larger variety of situations. Besides, you've already got the 'child' value to pass into it.

Quoted 38 lines
drivers/base/property.c +0 -0
 /**

* fwnode_handle_put - Drop reference to a device node
* @fwnode: Pointer to the device node to drop the reference to.

drivers/leds/leds-gpio.c +0 -0
index fd53968..c1c472b 100644
include/linux/property.h +2 -0
index a6a3d98..9bec811 100644
@@ -72,6 +72,8 @@ int fwnode_property_read_string(struct fwnode_handle *fwnode,
 struct fwnode_handle *device_get_next_child_node(struct device *dev,
                          struct fwnode_handle *child);
 
+const char *device_get_node_name(struct device *dev, struct
 fwnode_handle *child);
+
 #define device_for_each_child_node(dev, child) \
     for (child = device_get_next_child_node(dev, NULL); child; \

child = device_get_next_child_node(dev, child))

, and then on leds-gpio.c we can simply do:

drivers/leds/leds-gpio.c +4 -1
@@ -189,7 +189,10 @@ static struct gpio_leds_priv
 *gpio_leds_create(struct platform_device *pdev)
             goto err;
         }
 
-        fwnode_property_read_string(child, "label", &led.name);
+        if (fwnode_property_present(child, "label"))
+            fwnode_property_read_string(child, "label", &led.name);
+        else
+            led.name = device_get_node_name(dev, child);
         fwnode_property_read_string(child, "linux,default-trigger",
                         &led.default_trigger);
Quoted 3 lines

I am not familiar with ACPI so I don't know if the 'return acpi_dev_name(node)' is the appropriate way to retrieve the equivalent of a dt node name.

I cannot give good guidance here. I'll leave it to the ACPI folks.

g.

Acked-by on v2 1/1
#4 lore raw
In reply to Fabio Estevam
Quoted 12 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

Quoted 5 lines

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

(Assuming that creating a fwnode_get_name() function turns out to be a non-starter.)

g.

Quoted 40 lines

---
Changes since v1:
- Consider ACPI case as suggested by Grant

 drivers/leds/leds-gpio.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/leds/leds-gpio.c +11 -2
index fd53968..8a8ba11 100644
@@ -170,6 +170,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
        struct fwnode_handle *child;
        struct gpio_leds_priv *priv;
        int count, ret;
+       struct device_node *np;
 
        count = device_get_child_node_count(dev);
        if (!count)
@@ -189,7 +190,16 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
                        goto err;
                }
 
-               fwnode_property_read_string(child, "label", &led.name);
+               np = of_node(child);
+
+               if (fwnode_property_present(child, "label")) {
+                       fwnode_property_read_string(child, "label", &led.name);
+               } else {
+                       if (IS_ENABLED(CONFIG_OF) && !led.name && np)
+                               led.name = np->name;
+                       if (!led.name)
+                               return ERR_PTR(-EINVAL);
+               }
                fwnode_property_read_string(child, "linux,default-trigger",
                                            &led.default_trigger);
 
--

1.9.1

#5 lore raw
Quoted 16 lines · Grant Likely
Quoted 15 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

Quoted 7 lines
Quoted 2 lines

(Assuming that creating a fwnode_get_name() function turns out to be a non-starter.)

Thanks, Grant.

Maybe we should go with this v2 patch initially to fix the regression and then we could consider introducing fwnode_get_name() in a future patch.

#6 lore raw
Quoted 22 lines · Fabio Estevam
Quoted 21 lines · Grant Likely
Quoted 12 lines · Fabio Estevam

From: Fabio Estevam <[email protected]>

Since commit a43f2cbbb009f96 ("leds: leds-gpio: Make use of device property API") it is no longer possible to register multiple gpio leds without passing the 'label' property.

According to Documentation/devicetree/bindings/leds/common.txt:

"Optional properties for child nodes:
- label : The label for this LED. If omitted, the label is taken from the node name (excluding the unit address)."

Quoted 5 lines

So retrieve the node name when the 'label' property is absent to keep the old behaviour and fix this regression.

Quoted 8 lines
Quoted 2 lines

(Assuming that creating a fwnode_get_name() function turns out to be a non-starter.)

Thanks, Grant.

Maybe we should go with this v2 patch initially to fix the regression and then we could consider introducing fwnode_get_name() in a future patch.

I think V1 just touches leds-gpio.c and might be easier to merge as a good fix. And then you can provide a patch to introduce fwnode_get_name().

Or you update your V2 patch to use fwnode_get_name() and try to merge it as a fix.

-Bryan

#7 lore raw

Hi Bryan,

Quoted 7 lines · Bryan Wu
Quoted 3 lines

Maybe we should go with this v2 patch initially to fix the regression and then we could consider introducing fwnode_get_name() in a future patch.

I think V1 just touches leds-gpio.c and might be easier to merge as a good fix. And then you can provide a patch to introduce fwnode_get_name().

Yes, I agree.

Just to make sure we are on the same page: there were two formal patches that I submitted:

- v1: which did not take ACPI into account as pointed out by Grant
- v2: The original one of this thread that does take ACPI into account

Both of them only touch leds-gpio.c.

The one that touches drivers/base/property.c was just a suggestion that I sent as a reply to v2. It was not a formal submission. I also don't know if such suggestion would work for ACPI, as ACPI is something I am not familiar with.

It seems to me that you are calling my [PATCH v2] as v1 and the suggested approach that touches drivers/base/property.c as v2, so that's the confusion ;-). Sorry about that.

Please let me know.

#8 lore raw
Quoted 27 lines · Fabio Estevam

Hi Bryan,

Quoted 7 lines · Bryan Wu
Quoted 3 lines

Maybe we should go with this v2 patch initially to fix the regression and then we could consider introducing fwnode_get_name() in a future patch.

I think V1 just touches leds-gpio.c and might be easier to merge as a good fix. And then you can provide a patch to introduce fwnode_get_name().

Yes, I agree.

Just to make sure we are on the same page: there were two formal patches that I submitted:

- v1: which did not take ACPI into account as pointed out by Grant
- v2: The original one of this thread that does take ACPI into account

Both of them only touch leds-gpio.c.

The one that touches drivers/base/property.c was just a suggestion that I sent as a reply to v2. It was not a formal submission. I also don't know if such suggestion would work for ACPI, as ACPI is something I am not familiar with.

Quoted 5 lines

It seems to me that you are calling my [PATCH v2] as v1 and the suggested approach that touches drivers/base/property.c as v2, so that's the confusion ;-). Sorry about that.

Please let me know.

I got it. Actually we are talking about the same patch in the email [PATCH v2]. So I agree to merge this fix firstly and then introduce a new fwnode_get_name().

If it's OK, I will merge this patch with Grant's Ack.

Thanks,
-Bryan

#9 lore raw
Quoted 4 lines · Bryan Wu

I got it. Actually we are talking about the same patch in the email [PATCH v2]. So I agree to merge this fix firstly and then introduce a new fwnode_get_name().

If it's OK, I will merge this patch with Grant's Ack.

Excellent, thanks!

Acked-by
#10 lore raw
Quoted 8 lines · Fabio Estevam
Quoted 4 lines · Bryan Wu

I got it. Actually we are talking about the same patch in the email [PATCH v2]. So I agree to merge this fix firstly and then introduce a new fwnode_get_name().

If it's OK, I will merge this patch with Grant's Ack.

Excellent, thanks!

Oh, I just found PATCH "leds: leds-gpio: Make use of device property API" is not in my tree. So probably Rafael should take it with my Ack as well:

-Bryan

#11 lore raw
Quoted 6 lines · Bryan Wu
Quoted 5 lines · Fabio Estevam
Quoted 3 lines · Bryan Wu

I got it. Actually we are talking about the same patch in the email [PATCH v2]. So I agree to merge this fix firstly and then introduce a new fwnode_get_name().

Quoted 7 lines
Quoted 2 lines
Quoted 1 line

If it's OK, I will merge this patch with Grant's Ack.

Excellent, thanks!

Oh, I just found PATCH "leds: leds-gpio: Make use of device property API" is not in my tree. So probably Rafael should take it with my Ack as well:

Applied, thanks!