From: Tomi Valkeinen <tomi.valkeinen@ti.com>
To: Jacek Anaszewski <j.anaszewski@samsung.com>,
Jingoo Han <jingoohan1@gmail.com>,
Lee Jones <lee.jones@linaro.org>,
linux-leds@vger.kernel.org, linux-fbdev@vger.kernel.org
Cc: Andrew Lunn <andrew@lunn.ch>, Tomi Valkeinen <tomi.valkeinen@ti.com>
Subject: [PATCHv3 1/3] leds: Add of_led_get() and led_put()
Date: Fri, 11 Sep 2015 13:07:35 +0000 [thread overview]
Message-ID: <1441976857-26548-2-git-send-email-tomi.valkeinen@ti.com> (raw)
In-Reply-To: <1441976857-26548-1-git-send-email-tomi.valkeinen@ti.com>
This patch adds basic support for a kernel driver to get a LED device.
This will be used by the led-backlight driver.
Only OF version is implemented for now, and the behavior is similar to
PWM's of_pwm_get() and pwm_put().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/leds/Makefile | 6 +++-
drivers/leds/led-class.c | 13 +++++++-
drivers/leds/led-of.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/leds/leds.h | 1 +
include/linux/leds.h | 10 ++++++
include/linux/of_leds.h | 26 +++++++++++++++
6 files changed, 139 insertions(+), 2 deletions(-)
create mode 100644 drivers/leds/led-of.c
create mode 100644 include/linux/of_leds.h
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a2f513..6fd22e411810 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -1,7 +1,11 @@
# LED Core
obj-$(CONFIG_NEW_LEDS) += led-core.o
-obj-$(CONFIG_LEDS_CLASS) += led-class.o
+
+obj-$(CONFIG_LEDS_CLASS) += led-class-objs.o
+led-class-objs-y := led-class.o
+led-class-objs-$(CONFIG_OF) += led-of.o
+
obj-$(CONFIG_LEDS_CLASS_FLASH) += led-class-flash.o
obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index beabfbc6f7cd..1234f9dc3537 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -22,7 +22,7 @@
#include <linux/timer.h>
#include "leds.h"
-static struct class *leds_class;
+struct class *leds_class;
static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -216,6 +216,17 @@ static int led_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
+/**
+ * led_put() - release a LED device, reserved with led_get()
+ * @led_cdev: LED device
+ */
+void led_put(struct led_classdev *led_cdev)
+{
+ put_device(led_cdev->dev);
+ module_put(led_cdev->dev->parent->driver->owner);
+}
+EXPORT_SYMBOL_GPL(led_put);
+
static int match_name(struct device *dev, const void *data)
{
if (!dev_name(dev))
diff --git a/drivers/leds/led-of.c b/drivers/leds/led-of.c
new file mode 100644
index 000000000000..6e96fee9adf1
--- /dev/null
+++ b/drivers/leds/led-of.c
@@ -0,0 +1,85 @@
+/*
+ * LED Class Core OF support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_leds.h>
+
+#include "leds.h"
+
+/* find OF node for the given led_cdev */
+static struct device_node *find_led_of_node(struct led_classdev *led_cdev)
+{
+ struct device *led_dev = led_cdev->dev;
+ struct device_node *child;
+
+ for_each_child_of_node(led_dev->parent->of_node, child) {
+ int idx;
+
+ idx = of_property_match_string(child, "label", led_cdev->name);
+ if (idx = 0)
+ return child;
+ }
+
+ return NULL;
+}
+
+static int led_match_led_node(struct device *led_dev, const void *data)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(led_dev);
+ const struct device_node *target_node = data;
+ struct device_node *led_node;
+
+ led_node = find_led_of_node(led_cdev);
+ if (!led_node)
+ return 0;
+
+ of_node_put(led_node);
+
+ return led_node = target_node;
+}
+
+/**
+ * of_led_get() - request a LED device via the LED framework
+ * @np: device node to get the LED device from
+ *
+ * Returns the LED device parsed from the phandle specified in the "leds"
+ * property of a device tree node or a negative error-code on failure.
+ *
+ * The caller must use led_put() to release the device after use.
+ */
+struct led_classdev *of_led_get(struct device_node *np)
+{
+ struct device *led_dev;
+ struct led_classdev *led_cdev;
+ struct device_node *led_node;
+
+ led_node = of_parse_phandle(np, "leds", 0);
+ if (!led_node)
+ return ERR_PTR(-ENODEV);
+
+ led_dev = class_find_device(leds_class, NULL, led_node,
+ led_match_led_node);
+
+ of_node_put(led_node);
+
+ if (!led_dev) {
+ pr_err("failed to find led device for node %s, deferring probe\n",
+ of_node_full_name(led_node));
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+ led_cdev = dev_get_drvdata(led_dev);
+
+ if (!try_module_get(led_cdev->dev->parent->driver->owner))
+ return ERR_PTR(-ENODEV);
+
+ return led_cdev;
+}
+EXPORT_SYMBOL_GPL(of_led_get);
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index bc89d7ace2c4..ccc3abb417d4 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -46,6 +46,7 @@ static inline int led_get_brightness(struct led_classdev *led_cdev)
void led_stop_software_blink(struct led_classdev *led_cdev);
+extern struct class *leds_class;
extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
diff --git a/include/linux/leds.h b/include/linux/leds.h
index b122eeafb5dc..fbad4ce78e6e 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -113,6 +113,16 @@ extern void devm_led_classdev_unregister(struct device *parent,
extern void led_classdev_suspend(struct led_classdev *led_cdev);
extern void led_classdev_resume(struct led_classdev *led_cdev);
+#if IS_ENABLED(CONFIG_LEDS_CLASS)
+
+extern void led_put(struct led_classdev *led_cdev);
+
+#else
+
+static inline void led_put(struct led_classdev *led_cdev) { }
+
+#endif /* IS_ENABLED(CONFIG_LEDS_CLASS) */
+
/**
* led_blink_set - set blinking with software fallback
* @led_cdev: the LED to start blinking
diff --git a/include/linux/of_leds.h b/include/linux/of_leds.h
new file mode 100644
index 000000000000..7e8e64bd9811
--- /dev/null
+++ b/include/linux/of_leds.h
@@ -0,0 +1,26 @@
+/*
+ * OF support for leds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __LINUX_LEDS_OF_H_INCLUDED
+#define __LINUX_LEDS_OF_H_INCLUDED
+
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_LEDS_CLASS)
+
+extern struct led_classdev *of_led_get(struct device_node *np);
+
+#else
+
+static inline struct led_classdev *of_led_get(struct device_node *np)
+{
+ return -ENODEV;
+}
+
+#endif
+
+#endif /* __LINUX_LEDS_OF_H_INCLUDED */
--
2.1.4
next prev parent reply other threads:[~2015-09-11 13:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-11 13:07 [PATCHv3 0/3] backlight: led-backlight driver Tomi Valkeinen
2015-09-11 13:07 ` Tomi Valkeinen [this message]
2015-09-11 13:50 ` [PATCHv3 1/3] leds: Add of_led_get() and led_put() Jacek Anaszewski
2015-09-28 8:08 ` Tomi Valkeinen
2015-09-11 13:07 ` [PATCHv3 2/3] backlight: add led-backlight driver Tomi Valkeinen
2015-09-28 8:12 ` Tomi Valkeinen
2015-09-28 10:31 ` Lee Jones
2015-09-11 13:07 ` [PATCHv3 3/3] devicetree: Add led-backlight binding Tomi Valkeinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1441976857-26548-2-git-send-email-tomi.valkeinen@ti.com \
--to=tomi.valkeinen@ti.com \
--cc=andrew@lunn.ch \
--cc=j.anaszewski@samsung.com \
--cc=jingoohan1@gmail.com \
--cc=lee.jones@linaro.org \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).