devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexandre Courbot <acourbot@nvidia.com>
To: Stephen Warren <swarren@nvidia.com>,
	Thierry Reding <thierry.reding@avionic-design.de>,
	Simon Glass <sjg@chromium.org>,
	Grant Likely <grant.likely@secretlab.ca>,
	Rob Herring <rob.herring@calxeda.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	Arnd Bergmann <arnd@arndb.de>
Cc: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-fbdev@vger.kernel.org, devicetree-discuss@lists.ozlabs.org,
	Alexandre Courbot <acourbot@nvidia.com>
Subject: [RFC][PATCH v3 1/3] runtime interpreted power sequences
Date: Fri, 27 Jul 2012 21:05:48 +0900	[thread overview]
Message-ID: <1343390750-3642-2-git-send-email-acourbot@nvidia.com> (raw)
In-Reply-To: <1343390750-3642-1-git-send-email-acourbot@nvidia.com>

Some device drivers (panel backlights especially) need to follow precise
sequences for powering on and off, involving gpios, regulators, PWMs
with a precise powering order and delays to respect between each steps.
These sequences are board-specific, and do not belong to a particular
driver - therefore they have been performed by board-specific hook
functions to far.

With the advent of the device tree and of ARM kernels that are not
board-tied, we cannot rely on these board-specific hooks anymore but
need a way to implement these sequences in a portable manner. This patch
introduces a simple interpreter that can execute such power sequences
encoded either as platform data or within the device tree.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 Documentation/power/power_seq.txt | 120 +++++++++++++++
 drivers/base/Kconfig              |   4 +
 drivers/base/Makefile             |   1 +
 drivers/base/power_seq.c          | 300 ++++++++++++++++++++++++++++++++++++++
 include/linux/power_seq.h         | 139 ++++++++++++++++++
 5 files changed, 564 insertions(+)
 create mode 100644 Documentation/power/power_seq.txt
 create mode 100644 drivers/base/power_seq.c
 create mode 100644 include/linux/power_seq.h

diff --git a/Documentation/power/power_seq.txt b/Documentation/power/power_seq.txt
new file mode 100644
index 0000000..aa2ceb5
--- /dev/null
+++ b/Documentation/power/power_seq.txt
@@ -0,0 +1,120 @@
+Runtime Interpreted Power Sequences
+-----------------------------------
+
+Problem
+-------
+One very common board-dependent code is the out-of-driver code that is used to
+turn a device on or off. For instance, SoC boards very commonly use a GPIO
+(abstracted to a regulator or not) to control the power supply of a backlight,
+disabling it when the backlight is not used in order to save power. The GPIO
+that should be used, however, as well as the exact power sequence that may
+involve different resources, is board-dependent and thus unknown of the driver.
+
+This has been addressed so far by using hooks in the device's platform data that
+are called whenever the state of the device might reflect a power change. This
+approach, however, introduces board-dependant code into the kernel and is not
+compatible with the device tree.
+
+The Runtime Interpreted Power Sequences (or power sequences for short) aim at
+turning this code into platform data or device tree nodes. Power sequences are
+described using a simple format and run by a simple interpreter whenever needed.
+This allows to remove the callback mechanism and makes the kernel less
+board-dependant.
+
+Sequences Format
+----------------
+Power sequences are a series of sequential steps during which an action is
+performed on a resource. The supported resources so far are:
+- GPIOs
+- Regulators
+- PWMs
+
+Each step designates a resource and the following parameters:
+- Whether the step should enable or disable the resource,
+- Delay to wait before performing the action,
+- Delay to wait after performing the action.
+
+Both new resources and parameters can be introduced, but the goal is of course
+to keep things as simple and compact as possible.
+
+The platform data is a simple array of platform_power_seq_step instances, each
+instance describing a step. The type as well as one of id or gpio members
+(depending on the type) must be specified. The last step must be of type
+POWER_SEQ_STOP. Regulator and PWM resources are identified by name. GPIO are
+identified by number. For example, the following sequence will turn on the
+"power" regulator of the device, wait 10ms, and set GPIO number 110 to 1:
+
+struct platform_power_seq_step power_on_seq[] = {
+	{
+		.type = POWER_SEQ_REGULATOR,
+		.id = "power",
+		.params = {
+			.enable = 1,
+			.post_delay = 10,
+		},
+	},
+	{
+		.type = POWER_SEQ_GPIO,
+		.gpio = 110,
+		.params = {
+			.enable = 1,
+		},
+	},
+	{
+		.type = POWER_SEQ_STOP,
+	},
+};
+
+Usage by Drivers and Resources Management
+-----------------------------------------
+Power sequences make use of resources that must be properly allocated and
+managed. The power_seq_build() function takes care of resolving the resources as
+they are met in the sequence and to allocate them if needed:
+
+power_seq *power_seq_build(struct device *dev, power_seq_resources *ress,
+			   platform_power_seq *pseq);
+
+You will need an instance of power_seq_resources to keep track of the resources
+that are already allocated. On success, the function returns a devm allocated
+resolved sequence that is ready to be passed to power_seq_run(). In case of
+failure, and error code is returned.
+
+A resolved power sequence returned by power_seq_build can be run by
+power_run_run():
+
+int power_seq_run(struct device *dev, power_seq *seq);
+
+It returns 0 if the sequence has successfully been run, or an error code if a
+problem occured.
+
+Finally, some resources that cannot be allocated through devm need to be freed
+manually. Therefore, be sure to call power_seq_free_resources() in your device
+remove function:
+
+void power_seq_free_resources(power_seq_resources *ress);
+
+Device tree
+-----------
+All the same, power sequences can be encoded as device tree nodes. The following
+properties and nodes are equivalent to the platform data defined previously:
+
+		power-supply = <&mydevice_reg>;
+		enable-gpio = <&gpio 6 0>;
+
+		power-on-sequence {
+			regulator@0 {
+				id = "power";
+				enable;
+				post-delay = <10>;
+			};
+			gpio@1 {
+				id = "enable-gpio";
+				enable;
+			};
+		};
+
+Note that first, the phandles of the regulator and gpio used in the sequences
+are defined as properties. Then the sequence references them through the id
+property of every step. The name of sub-properties defines the type of the step.
+Valid names are "regulator", "gpio" and "pwm". Steps must be numbered
+sequentially.
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 08b4c52..65bebfe 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -282,4 +282,8 @@ config CMA_AREAS
 
 endif
 
+config POWER_SEQ
+	bool
+	default n
+
 endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 5aa2d70..4c498c1 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
 ifeq ($(CONFIG_SYSFS),y)
 obj-$(CONFIG_MODULES)	+= module.o
 endif
+obj-$(CONFIG_POWER_SEQ)	+= power_seq.o
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
 obj-$(CONFIG_REGMAP)	+= regmap/
 obj-$(CONFIG_SOC_BUS) += soc.o
diff --git a/drivers/base/power_seq.c b/drivers/base/power_seq.c
new file mode 100644
index 0000000..6ccefa1
--- /dev/null
+++ b/drivers/base/power_seq.c
@@ -0,0 +1,300 @@
+/*
+ * power_seq.c - A simple power sequence interpreter for platform devices
+ *               and device tree.
+ *
+ * Author: Alexandre Courbot <acourbot@nvidia.com>
+ *
+ * Copyright (c) 2012 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <linux/power_seq.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#endif
+
+static int power_seq_step_run(struct power_seq_step *step)
+{
+	int err = 0;
+
+	if (step->params.pre_delay)
+		mdelay(step->params.pre_delay);
+
+	switch (step->resource->type) {
+#ifdef CONFIG_REGULATOR
+	case POWER_SEQ_REGULATOR:
+		if (step->params.enable)
+			err = regulator_enable(step->resource->regulator);
+		else
+			err = regulator_disable(step->resource->regulator);
+		break;
+#endif
+#ifdef CONFIG_PWM
+	case POWER_SEQ_PWM:
+		if (step->params.enable)
+			err = pwm_enable(step->resource->pwm);
+		else
+			pwm_disable(step->resource->pwm);
+		break;
+#endif
+#ifdef CONFIG_GPIOLIB
+	case POWER_SEQ_GPIO:
+		gpio_set_value_cansleep(step->resource->gpio,
+					step->params.enable);
+		break;
+#endif
+	/*
+	 * should never happen unless the sequence includes a step which
+	 * type does not have support compiled in
+	 */
+	default:
+		return -EINVAL;
+	}
+
+	if (err < 0)
+		return err;
+
+	if (step->params.post_delay)
+		mdelay(step->params.post_delay);
+
+	return 0;
+}
+
+int power_seq_run(struct device *dev, power_seq *seq)
+{
+	int err;
+
+	if (!seq) return 0;
+
+	while (seq->resource) {
+		if ((err = power_seq_step_run(seq++))) {
+			dev_err(dev, "error %d while running power sequence!\n",
+				err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(power_seq_run);
+
+#ifdef CONFIG_OF
+static int of_parse_power_seq_step(struct device *dev, struct device_node *node,
+				   struct platform_power_seq_step *step)
+{
+	if (of_property_read_string(node, "id", &step->id)) {
+		dev_err(dev, "missing id property!\n");
+		return -EINVAL;
+	}
+
+	if (!strcmp(node->name, "regulator")) {
+		step->type = POWER_SEQ_REGULATOR;
+#ifdef CONFIG_OF_GPIO
+	} else if (!strcmp(node->name, "gpio")) {
+		int gpio;
+
+		step->type = POWER_SEQ_GPIO;
+		gpio = of_get_named_gpio(dev->of_node, step->id, 0);
+		if (gpio < 0) {
+			dev_err(dev, "cannot resolve gpio \"%s\"\n", step->id);
+			return gpio;
+		}
+		step->gpio = gpio;
+#endif /* CONFIG_OF_GPIO */
+	} else if (!strcmp(node->name, "pwm")) {
+		step->type = POWER_SEQ_PWM;
+	} else {
+		dev_err(dev, "invalid power seq step type!\n");
+		return -EINVAL;
+	}
+
+	if (of_find_property(node, "enable", NULL)) {
+		step->params.enable = 1;
+	} else if (!of_find_property(node, "disable", NULL)) {
+		dev_err(dev, "missing enable or disable property!\n");
+		return -EINVAL;
+	}
+
+	of_property_read_u32(node, "pre-delay", &step->params.pre_delay);
+	of_property_read_u32(node, "post-delay", &step->params.post_delay);
+
+	return 0;
+}
+
+platform_power_seq *of_parse_power_seq(struct device *dev,
+				       struct device_node *node)
+{
+	struct device_node *child = NULL;
+	platform_power_seq *ret;
+	int cpt = 0;
+	int err;
+
+	if (!node) return NULL;
+
+	while ((child = of_get_next_child(node, child)))
+		cpt++;
+
+	/* allocate one more step to signal end of sequence */
+	ret = devm_kzalloc(dev, sizeof(*ret) * (cpt + 1), GFP_KERNEL);
+	if (!ret)
+		return ERR_PTR(-ENOMEM);
+
+	cpt = 0;
+	while ((child = of_get_next_child(node, child))) {
+		if ((err = of_parse_power_seq_step(dev, child, &ret[cpt++])))
+			return ERR_PTR(err);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(of_parse_power_seq);
+#endif /* CONFIG_OF */
+
+static
+struct power_seq_resource * power_seq_find_resource(power_seq_resources *ress,
+					struct platform_power_seq_step *res)
+{
+	struct power_seq_resource *step;
+
+	list_for_each_entry(step, ress, list) {
+		if (step->type != res->type) continue;
+		switch (res->type) {
+		case POWER_SEQ_GPIO:
+			if (step->gpio == res->gpio)
+				return step;
+			break;
+		default:
+			if (!strcmp(step->id, res->id))
+				return step;
+			break;
+		}
+	}
+
+	return NULL;
+}
+
+static int power_seq_allocate_resource(struct device *dev,
+				       struct power_seq_resource *res)
+{
+	int err;
+
+	switch (res->type) {
+#ifdef CONFIG_REGULATOR
+	case POWER_SEQ_REGULATOR:
+		res->regulator = devm_regulator_get(dev, res->id);
+		if (IS_ERR(res->regulator)) {
+			dev_err(dev, "cannot get regulator \"%s\"\n", res->id);
+			return PTR_ERR(res->regulator);
+		}
+		break;
+#endif
+#ifdef CONFIG_PWM
+	case POWER_SEQ_PWM:
+		res->pwm = pwm_get(dev, res->id);
+		if (IS_ERR(res->pwm)) {
+			dev_err(dev, "cannot get pwm \"%s\"\n", res->id);
+			return PTR_ERR(res->pwm);
+		}
+		break;
+#endif
+#ifdef CONFIG_GPIOLIB
+	case POWER_SEQ_GPIO:
+		err = devm_gpio_request_one(dev, res->gpio, GPIOF_OUT_INIT_HIGH,
+					    "backlight_gpio");
+		if (err) {
+			dev_err(dev, "cannot get gpio %d\n", res->gpio);
+			return err;
+		}
+		break;
+#endif
+	default:
+		dev_err(dev, "invalid resource type %d\n", res->type);
+		return -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+power_seq *power_seq_build(struct device *dev, power_seq_resources *ress,
+			   platform_power_seq *pseq)
+{
+	struct power_seq_step *seq = NULL, *ret;
+	struct power_seq_resource *res;
+	int cpt, err;
+
+	/* first pass to count the number of steps to allocate */
+	for (cpt = 0; pseq[cpt].type != POWER_SEQ_STOP; cpt++);
+
+	if (!cpt)
+		return seq;
+
+	/* 1 more for the STOP step */
+	ret = seq = devm_kzalloc(dev, sizeof(*seq) * (cpt + 1), GFP_KERNEL);
+	if (!seq)
+		return ERR_PTR(-ENOMEM);
+
+	for (; pseq->type != POWER_SEQ_STOP; pseq++, seq++) {
+		/* create resource node if not referenced already */
+		if (!(res = power_seq_find_resource(ress, pseq))) {
+			res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+			if (!res)
+				return ERR_PTR(-ENOMEM);
+			res->type = pseq->type;
+
+			if (res->type == POWER_SEQ_GPIO)
+				res->gpio = pseq->gpio;
+			else
+				res->id = pseq->id;
+
+			if ((err = power_seq_allocate_resource(dev, res)) < 0)
+				return ERR_PTR(err);
+
+			list_add(&res->list, ress);
+		}
+		seq->resource = res;
+		memcpy(&seq->params, &pseq->params, sizeof(seq->params));
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(power_seq_build);
+
+void power_seq_free_resources(power_seq_resources *ress) {
+	struct power_seq_resource *res;
+
+#ifdef CONFIG_PWM
+	list_for_each_entry(res, ress, list) {
+		if (res->type == POWER_SEQ_PWM)
+			pwm_put(res->pwm);
+	}
+#endif
+}
+EXPORT_SYMBOL_GPL(power_seq_free_resources);
+
+MODULE_AUTHOR("Alexandre Courbot <acourbot@nvidia.com>");
+MODULE_DESCRIPTION("Runtime Interpreted Power Sequences");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/power_seq.h b/include/linux/power_seq.h
new file mode 100644
index 0000000..da0593a
--- /dev/null
+++ b/include/linux/power_seq.h
@@ -0,0 +1,139 @@
+/*
+ * power_seq.h
+ *
+ * Simple interpreter for defining power sequences as platform data or device
+ * tree properties. Initially designed for use with backlight drivers.
+ *
+ * Power sequences are designed to replace the callbacks typically used in
+ * board-specific files that implement board-specific power sequences of devices
+ * such as backlights. A power sequence is an array of resources (which can a
+ * regulator, a GPIO, a PWM, ...) with an action to perform on it (enable or
+ * disable) and optional pre and post step delays. By having them interpreted
+ * instead of arbitrarily executed, it is possible to describe these in the
+ * device tree and thus remove board-specific code from the kernel.
+ *
+ * Author: Alexandre Courbot <acourbot@nvidia.com>
+ *
+ * Copyright (c) 2012 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef __LINUX_POWER_SEQ_H
+#define __LINUX_POWER_SEQ_H
+
+#include <linux/types.h>
+
+struct device;
+struct regulator;
+struct pwm_device;
+struct device_node;
+
+/**
+ * The different kinds of resources that can be controlled during the sequences.
+ */
+typedef enum {
+	POWER_SEQ_STOP = 0,
+	POWER_SEQ_REGULATOR,
+	POWER_SEQ_PWM,
+	POWER_SEQ_GPIO,
+	POWER_SEQ_MAX,
+} power_res_type;
+
+struct power_seq_resource {
+	power_res_type type;
+	/* name to resolve for resources with a name (regulator, pwm) */
+	const char *id;
+	/* resolved resource */
+	union {
+		struct regulator *regulator;
+		struct pwm_device *pwm;
+		int gpio;
+	};
+	/* used to maintain the list of resources used by the driver */
+	struct list_head list;
+};
+typedef struct list_head power_seq_resources;
+
+struct power_step_params {
+	/* enable the resource if 1, disable if 0 */
+	bool enable;
+	/* delay (in ms) to wait before executing the step */
+	int  pre_delay;
+	/* delay (in ms) to wait after executing the step */
+	int post_delay;
+};
+
+/**
+ * Platform definition of power sequences. A sequence is an array of these,
+ * terminated by a STOP instance.
+ */
+struct platform_power_seq_step {
+	power_res_type type;
+	union {
+		/* Used by REGULATOR and PWM types to name the resource */
+		const char *id;
+		/* Used by GPIO */
+		int gpio;
+	};
+	struct power_step_params params;
+};
+typedef struct platform_power_seq_step platform_power_seq;
+
+/**
+ * Power sequence steps resolved against their resource. Built by
+ * power_seq_build and used to run the sequence.
+ */
+struct power_seq_step {
+	struct power_seq_resource *resource;
+	struct power_step_params params;
+};
+typedef struct power_seq_step power_seq;
+
+#ifdef CONFIG_OF
+/**
+ * Build a platform data sequence from a device tree node. Memory for the
+ * sequence is allocated using devm_kzalloc on dev.
+ */
+platform_power_seq *of_parse_power_seq(struct device *dev,
+				       struct device_node *node);
+#else
+platform_power_seq *of_parse_power_seq(struct device *dev,
+				       struct device_node *node)
+{
+	return NULL;
+}
+#endif
+
+/**
+ * Build a runnable power sequence from platform data, and add the resources
+ * it uses into ress. Memory for the sequence is allocated using devm_kzalloc
+ * on dev.
+ */
+power_seq *power_seq_build(struct device *dev, power_seq_resources *ress,
+			   platform_power_seq *pseq);
+
+/**
+ * Free all the resources previously allocated by power_seq_allocate_resources.
+ */
+void power_seq_free_resources(power_seq_resources *ress);
+
+/**
+ * Run the given power sequence. Returns 0 on success, error code in case of
+ * failure.
+ */
+int power_seq_run(struct device *dev, power_seq *seq);
+
+#endif
-- 
1.7.11.3

  reply	other threads:[~2012-07-27 12:05 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-27 12:05 [RFC][PATCH v3 0/3] Power sequences with PWM and DT support Alexandre Courbot
2012-07-27 12:05 ` Alexandre Courbot [this message]
     [not found]   ` <1343390750-3642-2-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-27 18:19     ` [RFC][PATCH v3 1/3] runtime interpreted power sequences Greg Kroah-Hartman
     [not found]       ` <20120727181923.GB23564-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2012-07-30  1:51         ` Alex Courbot
2012-07-30  2:40           ` Gethering power management/policy hw drivers under drivers/power/? (Re: [RFC][PATCH v3 1/3] runtime interpreted power sequences) Anton Vorontsov
2012-07-30 20:59             ` Rafael J. Wysocki
     [not found]               ` <201207302259.39396.rjw-KKrjLPT3xs0@public.gmane.org>
2012-08-01  0:51                 ` Anton Vorontsov
2012-08-06  8:45             ` Pihet-XID, Jean
2012-07-27 18:20     ` [RFC][PATCH v3 1/3] runtime interpreted power sequences Greg Kroah-Hartman
2012-07-30 11:00     ` Simon Glass
2012-07-31  8:37       ` Alex Courbot
     [not found]         ` <50179933.9090501-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-31  9:13           ` Thierry Reding
     [not found]             ` <20120731091324.GA15557-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-07-31 10:11               ` Alex Courbot
     [not found]                 ` <5017AF5D.2010204-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-31 10:46                   ` Thierry Reding
2012-07-31 14:23         ` Mark Brown
2012-07-30 11:33     ` Thierry Reding
2012-07-31  9:51       ` Alex Courbot
     [not found]         ` <5017AA87.2040503-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-31 10:19           ` Thierry Reding
     [not found]             ` <20120731101931.GB16155-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-08-01  2:50               ` Alex Courbot
     [not found]                 ` <5018997B.7010808-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-01  7:17                   ` Thierry Reding
2012-07-31 14:11         ` Mark Brown
2012-07-30 15:44     ` Rob Herring
     [not found]       ` <5016ABDD.5010809-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-07-30 15:47         ` Mark Brown
     [not found]           ` <20120730154706.GL4468-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-07-31  9:16             ` Thierry Reding
2012-07-30 22:26         ` Stephen Warren
     [not found]           ` <50170A14.6000201-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-07-31 10:15             ` Alex Courbot
2012-07-30 22:45     ` Stephen Warren
2012-07-31 10:32       ` Alex Courbot
     [not found]         ` <5017B434.2010706-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-31 10:56           ` Thierry Reding
     [not found]             ` <20120731105640.GD16155-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-07-31 12:22               ` Mitch Bradley
     [not found]                 ` <5017CDF9.2060304-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>
2012-07-31 12:38                   ` Thierry Reding
     [not found]                     ` <20120731123811.GA25855-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-07-31 12:55                       ` Mitch Bradley
2012-08-01  1:47                         ` Alex Courbot
     [not found]                           ` <50188ABB.2060304-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-01  2:15                             ` Mitch Bradley
2012-08-01  1:42                   ` Alex Courbot
2012-07-31 14:13               ` Mark Brown
2012-07-31 14:22                 ` Thierry Reding
2012-07-31 14:26                   ` Mark Brown
     [not found]                     ` <20120731142607.GV4468-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-07-31 14:32                       ` Thierry Reding
     [not found]                         ` <20120731143235.GA21126-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-07-31 15:39                           ` Mark Brown
2012-07-31 16:19                             ` Greg Kroah-Hartman
     [not found]                               ` <20120731161954.GB4941-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
2012-07-31 16:22                                 ` Mark Brown
     [not found]                                   ` <20120731162230.GE11892-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-07-31 16:42                                     ` Greg Kroah-Hartman
2012-07-31 16:50                                       ` Mark Brown
2012-08-01  7:41                             ` Thierry Reding
     [not found]                               ` <20120801074113.GF29673-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-08-01 13:26                                 ` Mark Brown
     [not found]                                   ` <20120801132651.GU11892-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-08-01 13:38                                     ` Thierry Reding
     [not found]                                       ` <20120801133814.GA19771-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-08-01 13:55                                         ` Mark Brown
     [not found]                                           ` <20120801135531.GW11892-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-08-01 14:01                                             ` Thierry Reding
2012-07-31 16:34         ` Stephen Warren
2012-08-02  8:00       ` Alex Courbot
     [not found]         ` <501A338D.7080105-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-02  8:21           ` Thierry Reding
     [not found]             ` <20120802082157.GA14866-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-08-02  8:27               ` Alex Courbot
2012-08-02  8:45                 ` Thierry Reding
2012-08-02  9:20                   ` Alex Courbot
2012-08-02 18:11             ` Mark Brown
     [not found]               ` <20120802181111.GM4537-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-08-03  1:15                 ` Alex Courbot
     [not found]                   ` <501B2642.4080805-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-04 14:12                     ` Mark Brown
2012-08-06  2:27                       ` Alex Courbot
     [not found]                         ` <501F2BAA.8000808-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-08-06 16:16                           ` Stephen Warren
2012-08-07  5:10                             ` Alex Courbot
     [not found] ` <1343390750-3642-1-git-send-email-acourbot-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-07-27 12:05   ` [RFC][PATCH v3 2/3] pwm_backlight: use " Alexandre Courbot
2012-07-27 12:05   ` [RFC][PATCH v3 3/3] tegra: add pwm backlight device tree nodes Alexandre Courbot

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=1343390750-3642-2-git-send-email-acourbot@nvidia.com \
    --to=acourbot@nvidia.com \
    --cc=arnd@arndb.de \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=grant.likely@secretlab.ca \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=rob.herring@calxeda.com \
    --cc=sjg@chromium.org \
    --cc=swarren@nvidia.com \
    --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).