From: Alexandre Courbot <acourbot@nvidia.com>
To: Thierry Reding <thierry.reding@avionic-design.de>,
Stephen Warren <swarren@wwwdotorg.org>
Cc: linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-tegra@vger.kernel.org, Mark Zhang <markz@nvidia.com>,
gnurou@gmail.com, Alexandre Courbot <acourbot@nvidia.com>
Subject: [PATCH 1/3] pwm-backlight: add subdriver mechanism
Date: Sat, 19 Jan 2013 10:30:18 +0000 [thread overview]
Message-ID: <1358591420-7790-2-git-send-email-acourbot@nvidia.com> (raw)
In-Reply-To: <1358591420-7790-1-git-send-email-acourbot@nvidia.com>
PWM-controlled backlights often need additional power control prior
to activating the PWM, typically switching regulators or GPIOs. This has
been done so far through hooks defined in board files, but this
mechanism cannot be used on platforms that rely on the device tree.
This patch introduces a "subdriver" mechanism to the pwm-backlight
driver that allows such hooks to be defined in optionally-compiled
sub-drivers. Every subdriver has its own device tree properties, which
sets the correct hooks to the pwm-backlight driver.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
drivers/video/backlight/Makefile | 4 +++
drivers/video/backlight/pwm_bl.c | 67 +++++++++++++++++++++++++++++++++++++++-
include/linux/pwm_backlight.h | 15 +++++++++
3 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index e7ce729..df97ab1 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -29,6 +29,10 @@ obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
+# pwm-backlight subdrivers must be listed *before* pwm_bl.o.
+# Link order is important as subdrivers must register themselves
+# before pwm-backlight's probe function can be called.
+obj-$(CONFIG_BACKLIGHT_PWM_TEGRA) += pwm_bl_tegra.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o
obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 069983c..b65a797 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
struct pwm_bl_data {
+ void *subdriver_data;
struct pwm_device *pwm;
struct device *dev;
unsigned int period;
@@ -35,6 +36,54 @@ struct pwm_bl_data {
void (*exit)(struct device *);
};
+static DEFINE_MUTEX(pwm_backlight_subdrivers_mutex);
+static LIST_HEAD(pwm_backlight_subdrivers);
+
+void pwm_backlight_add_subdriver(struct pwm_backlight_subdriver *driver)
+{
+ mutex_lock(&pwm_backlight_subdrivers_mutex);
+ list_add(&driver->list, &pwm_backlight_subdrivers);
+ mutex_unlock(&pwm_backlight_subdrivers_mutex);
+}
+EXPORT_SYMBOL(pwm_backlight_add_subdriver);
+
+void pwm_backlight_remove_subdriver(struct pwm_backlight_subdriver *driver)
+{
+ mutex_lock(&pwm_backlight_subdrivers_mutex);
+ list_del(&driver->list);
+ mutex_unlock(&pwm_backlight_subdrivers_mutex);
+}
+EXPORT_SYMBOL(pwm_backlight_remove_subdriver);
+
+/**
+ * pwm_backlight_set_subdriver_data - set subdriver data
+ * @dev: backlight device which data is to be set
+ * @data: subdriver data
+ *
+ * This function can be called *only* in the init() hook of the subdriver. The
+ * data will be temporarily set as driver data before being retrieved by
+ * the probe() function and moved to its final place.
+ */
+void pwm_backlight_set_subdriver_data(struct device *dev, void *data)
+{
+ dev_set_drvdata(dev, data);
+}
+EXPORT_SYMBOL(pwm_backlight_set_subdriver_data);
+
+/**
+ * pwm_backlight_get_subdriver_data - retrieve subdriver data
+ * @dev: backlight device to get subdriver data of
+ *
+ * This function can be called in any subdriver hook, excepted init().
+ */
+void *pwm_backlight_get_subdriver_data(struct device *dev)
+{
+ struct backlight_device *bl = dev_get_drvdata(dev);
+ struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
+ return pb->subdriver_data;
+}
+EXPORT_SYMBOL(pwm_backlight_get_subdriver_data);
+
static int pwm_backlight_update_status(struct backlight_device *bl)
{
struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev);
@@ -98,6 +147,7 @@ static const struct backlight_ops pwm_backlight_ops = {
static int pwm_backlight_parse_dt(struct device *dev,
struct platform_pwm_backlight_data *data)
{
+ struct pwm_backlight_subdriver *subdriver;
struct device_node *node = dev->of_node;
struct property *prop;
int length;
@@ -150,6 +200,17 @@ static int pwm_backlight_parse_dt(struct device *dev,
* backlight power. Support for specifying these needs to be
* added.
*/
+ mutex_lock(&pwm_backlight_subdrivers_mutex);
+ list_for_each_entry(subdriver, &pwm_backlight_subdrivers, list)
+ if (of_device_is_compatible(node, subdriver->name)) {
+ data->init = subdriver->init;
+ data->exit = subdriver->exit;
+ data->notify = subdriver->notify;
+ data->notify_after = subdriver->notify_after;
+ data->check_fb = subdriver->check_fb;
+ break;
+ }
+ mutex_unlock(&pwm_backlight_subdrivers_mutex);
return 0;
}
@@ -201,6 +262,9 @@ static int pwm_backlight_probe(struct platform_device *pdev)
goto err_alloc;
}
+ /* if the init function set subdriver data, move it to correct place */
+ pb->subdriver_data = dev_get_drvdata(&pdev->dev);
+
if (data->levels) {
max = data->levels[data->max_brightness];
pb->levels = data->levels;
@@ -249,10 +313,11 @@ static int pwm_backlight_probe(struct platform_device *pdev)
goto err_alloc;
}
+ platform_set_drvdata(pdev, bl);
+
bl->props.brightness = data->dft_brightness;
backlight_update_status(bl);
- platform_set_drvdata(pdev, bl);
return 0;
err_alloc:
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h
index 56f4a86..6abe1ef 100644
--- a/include/linux/pwm_backlight.h
+++ b/include/linux/pwm_backlight.h
@@ -20,4 +20,19 @@ struct platform_pwm_backlight_data {
int (*check_fb)(struct device *dev, struct fb_info *info);
};
+struct pwm_backlight_subdriver {
+ struct list_head list;
+ const char *name;
+ int (*init)(struct device *dev);
+ int (*notify)(struct device *dev, int brightness);
+ void (*notify_after)(struct device *dev, int brightness);
+ void (*exit)(struct device *dev);
+ int (*check_fb)(struct device *dev, struct fb_info *info);
+};
+
+void pwm_backlight_add_subdriver(struct pwm_backlight_subdriver *driver);
+void pwm_backlight_remove_subdriver(struct pwm_backlight_subdriver *driver);
+
+void pwm_backlight_set_subdriver_data(struct device *dev, void *data);
+void *pwm_backlight_get_subdriver_data(struct device *dev);
#endif
--
1.8.1.1
next prev parent reply other threads:[~2013-01-19 10:30 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-19 10:30 [PATCH 0/3] pwm-backlight: add subdrivers & Tegra support Alexandre Courbot
2013-01-19 10:30 ` Alexandre Courbot [this message]
2013-01-19 10:30 ` [PATCH 2/3] tegra: pwm-backlight: add tegra pwm-bl driver Alexandre Courbot
[not found] ` <1358591420-7790-3-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-01-21 7:35 ` Mark Zhang
2013-01-21 8:24 ` Alex Courbot
2013-01-21 8:35 ` Mark Zhang
[not found] ` <50FCEFDE.8000705-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-01-21 8:52 ` Marc Dietrich
2013-01-21 8:55 ` Mark Zhang
2013-01-21 17:46 ` Stephen Warren
[not found] ` <50FD7EF9.1010205-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-01-22 3:24 ` Alex Courbot
2013-01-22 7:06 ` Thierry Reding
2013-01-23 9:45 ` Alex Courbot
2013-01-24 6:10 ` Alex Courbot
2013-01-22 16:30 ` Stephen Warren
2013-01-23 10:27 ` Leela Krishna Amudala
[not found] ` <CAL1wa8d2BS3RxdsdUyCqF20ZKe46jUZcfUKitnpP9Lgb9aB5hw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-01-23 10:29 ` Alex Courbot
[not found] ` <1358591420-7790-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-01-19 10:30 ` [PATCH 3/3] tegra: ventana: of: add host1x device to DT Alexandre Courbot
2013-01-20 3:38 ` [PATCH 0/3] pwm-backlight: add subdrivers & Tegra support Mark Zhang
2013-01-20 5:26 ` Alexandre Courbot
2013-01-20 5:51 ` Mark Zhang
2013-01-21 2:09 ` Mark Zhang
[not found] ` <50FCA346.2070608-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-01-21 2:59 ` Mark Zhang
2013-01-21 7:49 ` Thierry Reding
[not found] ` <20130121074928.GE15508-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2013-01-21 8:18 ` Alex Courbot
2013-01-22 7:17 ` Thierry Reding
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=1358591420-7790-2-git-send-email-acourbot@nvidia.com \
--to=acourbot@nvidia.com \
--cc=gnurou@gmail.com \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=markz@nvidia.com \
--cc=swarren@wwwdotorg.org \
--cc=thierry.reding@avionic-design.de \
/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).