All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
	Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>,
	Matthias Kaehlcke
	<matthias-RprLehDfhQ3k1uMJSBkQmQ@public.gmane.org>,
	Kurt Van Dijck <kurt.van.dijck-/BeEPy95v10@public.gmane.org>,
	Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>,
	Grant Likely
	<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>,
	Colin Cross <ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org>,
	Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org>,
	Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	Richard Purdie <rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org>,
	Mark Brown
	<broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>,
	Mitch Bradley <wmb-D5eQfiDGL7eakBO8gow8eQ@public.gmane.org>,
	Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>,
	Eric Miao <eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>,
	Ryan Mallon <rmallon-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Shawn Guo <shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Bernhard Walle <walle-pDveNdigDaDu9UdzE1sIFA@public.gmane.org>
Subject: [PATCH v6 05/17] pwm: Add device tree support
Date: Tue, 10 Apr 2012 17:06:28 +0200	[thread overview]
Message-ID: <1334070400-25013-6-git-send-email-thierry.reding@avionic-design.de> (raw)
In-Reply-To: <1334070400-25013-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

This patch adds helpers to support device tree bindings for the generic
PWM API. Device tree binding documentation for PWM controllers is also
provided.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
---
Changes in v6:
- don't override error code in of_pwm_simple_xlate()
- no longer export of_pwm_request(), only pwm_get() should be used
- do a reverse lookup of the index into the "pwms" property by matching
  the con_id parameter to the "pwm-names" property

Changes in v5:
- use IS_ENABLED(CONFIG_OF) along with the compiler's DCE instead of
  empty implementations of of_pwmchip_add() and of_pwmchip_remove() in
  the !OF case
- remove OF_PWM Kconfig symbol and make OF support code conditional on
  the OF symbol only
- use "pwms" and "pwm-names" fixed property names
- remove redundant check in of_pwm_simple_xlate()
- use pwm_request_from_chip() instead of pwm_request_from_device()
- integrate OF support with pwm_get() from new patch 4

Changes in v4:
- add OF-specific code removed from patch 2
- make of_node_to_pwmchip() and of_pwm_simple_xlate() static
- rename of_get_named_pwm() to of_pwm_request(), return a struct
  pwm_device, get rid of the now unused spec parameter and use the
  device_node.name field as the PWM's name
- return a requested struct pwm_device from pwm_chip.of_xlate and
  drop the now unused spec parameter
- move OF support code into drivers/pwm/core.c
- used deferred probing if a PWM chip is not available yet

Changes in v2:
- add device tree binding documentation
- add of_xlate to parse controller-specific PWM-specifier

 Documentation/devicetree/bindings/pwm/pwm.txt |   57 ++++++++++
 drivers/pwm/core.c                            |  151 ++++++++++++++++++++++++-
 include/linux/pwm.h                           |    6 +
 3 files changed, 212 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm.txt

diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt
new file mode 100644
index 0000000..73ec962
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm.txt
@@ -0,0 +1,57 @@
+Specifying PWM information for devices
+======================================
+
+1) PWM user nodes
+-----------------
+
+PWM users should specify a list of PWM devices that they want to use
+with a property containing a 'pwm-list':
+
+	pwm-list ::= <single-pwm> [pwm-list]
+	single-pwm ::= <pwm-phandle> <pwm-specifier>
+	pwm-phandle : phandle to PWM controller node
+	pwm-specifier : array of #pwm-cells specifying the given PWM
+			(controller specific)
+
+PWM properties should be named "pwms". The exact meaning of each pwms
+property must be documented in the device tree binding for each device.
+An optional property "pwm-names" may contain a list of strings to label
+each of the PWM devices listed in the "pwms" property. If no "pwm-names"
+property is given, the name of the user node will be used as fallback.
+
+Drivers for devices that use more than a single PWM device can use the
+"pwm-names" property to map the name of the PWM device requested by the
+pwm_get() call to an index into the list given by the "pwms" property.
+
+The following example could be used to describe a PWM-based backlight
+device:
+
+	pwm: pwm {
+		#pwm-cells = <2>;
+	};
+
+	[...]
+
+	bl: backlight {
+		pwms = <&pwm 0 5000000>;
+		pwm-names = "backlight";
+	};
+
+pwm-specifier typically encodes the chip-relative PWM number and the PWM
+period in nanoseconds. Note that in the example above, specifying the
+"pwm-names" is redundant because the name "backlight" would be used as
+fallback anyway.
+
+2) PWM controller nodes
+-----------------------
+
+PWM controller nodes must specify the number of cells used for the
+specifier using the '#pwm-cells' property.
+
+An example PWM controller might look like this:
+
+	pwm: pwm@7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 402e466..e5ab7cd 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -129,6 +129,45 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
 	return 0;
 }
 
+static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc,
+					      const struct of_phandle_args *args)
+{
+	struct pwm_device *pwm;
+
+	if (pc->of_pwm_n_cells < 2)
+		return ERR_PTR(-EINVAL);
+
+	if (args->args[0] >= pc->npwm)
+		return ERR_PTR(-EINVAL);
+
+	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
+	if (IS_ERR(pwm))
+		return pwm;
+
+	pwm_set_period(pwm, args->args[1]);
+
+	return pwm;
+}
+
+void of_pwmchip_add(struct pwm_chip *chip)
+{
+	if (!chip->dev || !chip->dev->of_node)
+		return;
+
+	if (!chip->of_xlate) {
+		chip->of_xlate = of_pwm_simple_xlate;
+		chip->of_pwm_n_cells = 2;
+	}
+
+	of_node_get(chip->dev->of_node);
+}
+
+void of_pwmchip_remove(struct pwm_chip *chip)
+{
+	if (chip->dev && chip->dev->of_node)
+		of_node_put(chip->dev->of_node);
+}
+
 /**
  * pwm_set_chip_data() - set private chip data for a PWM
  * @pwm: PWM device
@@ -197,6 +236,9 @@ int pwmchip_add(struct pwm_chip *chip)
 	INIT_LIST_HEAD(&chip->list);
 	list_add(&chip->list, &pwm_chips);
 
+	if (IS_ENABLED(CONFIG_OF))
+		of_pwmchip_add(chip);
+
 out:
 	mutex_unlock(&pwm_lock);
 	return ret;
@@ -227,6 +269,10 @@ int pwmchip_remove(struct pwm_chip *chip)
 	}
 
 	list_del_init(&chip->list);
+
+	if (IS_ENABLED(CONFIG_OF))
+		of_pwmchip_remove(chip);
+
 	free_pwms(chip);
 
 out:
@@ -352,6 +398,102 @@ void pwm_disable(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_disable);
 
+#ifdef CONFIG_OF
+static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
+{
+	struct pwm_chip *chip;
+
+	mutex_lock(&pwm_lock);
+
+	list_for_each_entry(chip, &pwm_chips, list)
+		if (chip->dev && chip->dev->of_node == np) {
+			mutex_unlock(&pwm_lock);
+			return chip;
+		}
+
+	mutex_unlock(&pwm_lock);
+
+	return ERR_PTR(-EPROBE_DEFER);
+}
+
+/**
+ * of_pwm_request() - request a PWM via the PWM framework
+ * @np: device node to get the PWM from
+ * @con_id: consumer name
+ *
+ * Returns the PWM device parsed from the phandle and index specified in the
+ * "pwms" property of a device tree node or a negative error-code on failure.
+ * Values parsed from the device tree are stored in the returned PWM device
+ * object.
+ *
+ * If con_id is NULL, the first PWM device listed in the "pwms" property will
+ * be requested. Otherwise the "pwm-names" property is used to do a reverse
+ * lookup of the PWM index. This also means that the "pwm-names" property
+ * becomes mandatory for devices that look up the PWM device via the con_id
+ * parameter.
+ */
+static struct pwm_device *of_pwm_request(struct device_node *np,
+					 const char *con_id)
+{
+	struct pwm_device *pwm = NULL;
+	struct of_phandle_args args;
+	struct pwm_chip *pc;
+	int index = 0;
+	int err;
+
+	if (con_id) {
+		index = of_property_match_string(np, "pwm-names", con_id);
+		if (index < 0)
+			return ERR_PTR(index);
+	}
+
+	err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index,
+					 &args);
+	if (err) {
+		pr_debug("%s(): can't parse \"pwms\" property\n", __func__);
+		return ERR_PTR(err);
+	}
+
+	pc = of_node_to_pwmchip(args.np);
+	if (IS_ERR(pc)) {
+		pr_debug("%s(): PWM chip not found\n", __func__);
+		pwm = ERR_CAST(pc);
+		goto put;
+	}
+
+	if (args.args_count != pc->of_pwm_n_cells) {
+		pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
+			 args.np->full_name);
+		pwm = ERR_PTR(-EINVAL);
+		goto put;
+	}
+
+	pwm = pc->of_xlate(pc, &args);
+	if (IS_ERR(pwm))
+		goto put;
+
+	/*
+	 * If a consumer name was not given, try to look it up from the
+	 * "pwm-names" property if it exists. Otherwise use the name of
+	 * the user device node.
+	 */
+	if (!con_id) {
+		err = of_property_read_string_index(np, "pwm-names", index,
+						    &con_id);
+		if (err < 0)
+			con_id = np->name;
+	}
+
+	pwm->label = con_id;
+
+put:
+	of_node_put(args.np);
+
+	return pwm;
+}
+EXPORT_SYMBOL(of_pwm_request);
+#endif
+
 /**
  * pwm_add_table() - register PWM device consumers
  * @table: array of consumers to register
@@ -374,8 +516,9 @@ void __init pwm_add_table(struct pwm_lookup *table, size_t num)
  * @dev: device for PWM consumer
  * @con_id: consumer name
  *
- * Look up a PWM chip and a relative index via a table supplied by board setup
- * code (see pwm_add_table()).
+ * Lookup is first attempted using DT. If the device was not instantiated from
+ * a device tree, a PWM chip and a relative index is looked up via a table
+ * supplied by board setup code (see pwm_add_table()).
  *
  * Once a PWM chip has been found the specified PWM device will be requested
  * and is ready to be used.
@@ -390,6 +533,10 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
 	unsigned int index;
 	unsigned int match;
 
+	/* look up via DT first */
+	if (dev && dev->of_node)
+		return of_pwm_request(dev->of_node, con_id);
+
 	/*
 	 * We look up the provider in the static table typically provided by
 	 * board setup code. We first try to lookup the consumer device by
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 2947a4f..21d076c 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -1,6 +1,8 @@
 #ifndef __LINUX_PWM_H
 #define __LINUX_PWM_H
 
+#include <linux/of.h>
+
 struct pwm_device;
 struct seq_file;
 
@@ -105,6 +107,10 @@ struct pwm_chip {
 	unsigned int		npwm;
 
 	struct pwm_device	*pwms;
+
+	struct pwm_device *	(*of_xlate)(struct pwm_chip *pc,
+					    const struct of_phandle_args *args);
+	unsigned int		of_pwm_n_cells;
 };
 
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
-- 
1.7.9.6

WARNING: multiple messages have this Message-ID (diff)
From: thierry.reding@avionic-design.de (Thierry Reding)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6 05/17] pwm: Add device tree support
Date: Tue, 10 Apr 2012 17:06:28 +0200	[thread overview]
Message-ID: <1334070400-25013-6-git-send-email-thierry.reding@avionic-design.de> (raw)
In-Reply-To: <1334070400-25013-1-git-send-email-thierry.reding@avionic-design.de>

This patch adds helpers to support device tree bindings for the generic
PWM API. Device tree binding documentation for PWM controllers is also
provided.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
---
Changes in v6:
- don't override error code in of_pwm_simple_xlate()
- no longer export of_pwm_request(), only pwm_get() should be used
- do a reverse lookup of the index into the "pwms" property by matching
  the con_id parameter to the "pwm-names" property

Changes in v5:
- use IS_ENABLED(CONFIG_OF) along with the compiler's DCE instead of
  empty implementations of of_pwmchip_add() and of_pwmchip_remove() in
  the !OF case
- remove OF_PWM Kconfig symbol and make OF support code conditional on
  the OF symbol only
- use "pwms" and "pwm-names" fixed property names
- remove redundant check in of_pwm_simple_xlate()
- use pwm_request_from_chip() instead of pwm_request_from_device()
- integrate OF support with pwm_get() from new patch 4

Changes in v4:
- add OF-specific code removed from patch 2
- make of_node_to_pwmchip() and of_pwm_simple_xlate() static
- rename of_get_named_pwm() to of_pwm_request(), return a struct
  pwm_device, get rid of the now unused spec parameter and use the
  device_node.name field as the PWM's name
- return a requested struct pwm_device from pwm_chip.of_xlate and
  drop the now unused spec parameter
- move OF support code into drivers/pwm/core.c
- used deferred probing if a PWM chip is not available yet

Changes in v2:
- add device tree binding documentation
- add of_xlate to parse controller-specific PWM-specifier

 Documentation/devicetree/bindings/pwm/pwm.txt |   57 ++++++++++
 drivers/pwm/core.c                            |  151 ++++++++++++++++++++++++-
 include/linux/pwm.h                           |    6 +
 3 files changed, 212 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm.txt

diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt
new file mode 100644
index 0000000..73ec962
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm.txt
@@ -0,0 +1,57 @@
+Specifying PWM information for devices
+======================================
+
+1) PWM user nodes
+-----------------
+
+PWM users should specify a list of PWM devices that they want to use
+with a property containing a 'pwm-list':
+
+	pwm-list ::= <single-pwm> [pwm-list]
+	single-pwm ::= <pwm-phandle> <pwm-specifier>
+	pwm-phandle : phandle to PWM controller node
+	pwm-specifier : array of #pwm-cells specifying the given PWM
+			(controller specific)
+
+PWM properties should be named "pwms". The exact meaning of each pwms
+property must be documented in the device tree binding for each device.
+An optional property "pwm-names" may contain a list of strings to label
+each of the PWM devices listed in the "pwms" property. If no "pwm-names"
+property is given, the name of the user node will be used as fallback.
+
+Drivers for devices that use more than a single PWM device can use the
+"pwm-names" property to map the name of the PWM device requested by the
+pwm_get() call to an index into the list given by the "pwms" property.
+
+The following example could be used to describe a PWM-based backlight
+device:
+
+	pwm: pwm {
+		#pwm-cells = <2>;
+	};
+
+	[...]
+
+	bl: backlight {
+		pwms = <&pwm 0 5000000>;
+		pwm-names = "backlight";
+	};
+
+pwm-specifier typically encodes the chip-relative PWM number and the PWM
+period in nanoseconds. Note that in the example above, specifying the
+"pwm-names" is redundant because the name "backlight" would be used as
+fallback anyway.
+
+2) PWM controller nodes
+-----------------------
+
+PWM controller nodes must specify the number of cells used for the
+specifier using the '#pwm-cells' property.
+
+An example PWM controller might look like this:
+
+	pwm: pwm at 7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 402e466..e5ab7cd 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -129,6 +129,45 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
 	return 0;
 }
 
+static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc,
+					      const struct of_phandle_args *args)
+{
+	struct pwm_device *pwm;
+
+	if (pc->of_pwm_n_cells < 2)
+		return ERR_PTR(-EINVAL);
+
+	if (args->args[0] >= pc->npwm)
+		return ERR_PTR(-EINVAL);
+
+	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
+	if (IS_ERR(pwm))
+		return pwm;
+
+	pwm_set_period(pwm, args->args[1]);
+
+	return pwm;
+}
+
+void of_pwmchip_add(struct pwm_chip *chip)
+{
+	if (!chip->dev || !chip->dev->of_node)
+		return;
+
+	if (!chip->of_xlate) {
+		chip->of_xlate = of_pwm_simple_xlate;
+		chip->of_pwm_n_cells = 2;
+	}
+
+	of_node_get(chip->dev->of_node);
+}
+
+void of_pwmchip_remove(struct pwm_chip *chip)
+{
+	if (chip->dev && chip->dev->of_node)
+		of_node_put(chip->dev->of_node);
+}
+
 /**
  * pwm_set_chip_data() - set private chip data for a PWM
  * @pwm: PWM device
@@ -197,6 +236,9 @@ int pwmchip_add(struct pwm_chip *chip)
 	INIT_LIST_HEAD(&chip->list);
 	list_add(&chip->list, &pwm_chips);
 
+	if (IS_ENABLED(CONFIG_OF))
+		of_pwmchip_add(chip);
+
 out:
 	mutex_unlock(&pwm_lock);
 	return ret;
@@ -227,6 +269,10 @@ int pwmchip_remove(struct pwm_chip *chip)
 	}
 
 	list_del_init(&chip->list);
+
+	if (IS_ENABLED(CONFIG_OF))
+		of_pwmchip_remove(chip);
+
 	free_pwms(chip);
 
 out:
@@ -352,6 +398,102 @@ void pwm_disable(struct pwm_device *pwm)
 }
 EXPORT_SYMBOL_GPL(pwm_disable);
 
+#ifdef CONFIG_OF
+static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
+{
+	struct pwm_chip *chip;
+
+	mutex_lock(&pwm_lock);
+
+	list_for_each_entry(chip, &pwm_chips, list)
+		if (chip->dev && chip->dev->of_node == np) {
+			mutex_unlock(&pwm_lock);
+			return chip;
+		}
+
+	mutex_unlock(&pwm_lock);
+
+	return ERR_PTR(-EPROBE_DEFER);
+}
+
+/**
+ * of_pwm_request() - request a PWM via the PWM framework
+ * @np: device node to get the PWM from
+ * @con_id: consumer name
+ *
+ * Returns the PWM device parsed from the phandle and index specified in the
+ * "pwms" property of a device tree node or a negative error-code on failure.
+ * Values parsed from the device tree are stored in the returned PWM device
+ * object.
+ *
+ * If con_id is NULL, the first PWM device listed in the "pwms" property will
+ * be requested. Otherwise the "pwm-names" property is used to do a reverse
+ * lookup of the PWM index. This also means that the "pwm-names" property
+ * becomes mandatory for devices that look up the PWM device via the con_id
+ * parameter.
+ */
+static struct pwm_device *of_pwm_request(struct device_node *np,
+					 const char *con_id)
+{
+	struct pwm_device *pwm = NULL;
+	struct of_phandle_args args;
+	struct pwm_chip *pc;
+	int index = 0;
+	int err;
+
+	if (con_id) {
+		index = of_property_match_string(np, "pwm-names", con_id);
+		if (index < 0)
+			return ERR_PTR(index);
+	}
+
+	err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index,
+					 &args);
+	if (err) {
+		pr_debug("%s(): can't parse \"pwms\" property\n", __func__);
+		return ERR_PTR(err);
+	}
+
+	pc = of_node_to_pwmchip(args.np);
+	if (IS_ERR(pc)) {
+		pr_debug("%s(): PWM chip not found\n", __func__);
+		pwm = ERR_CAST(pc);
+		goto put;
+	}
+
+	if (args.args_count != pc->of_pwm_n_cells) {
+		pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
+			 args.np->full_name);
+		pwm = ERR_PTR(-EINVAL);
+		goto put;
+	}
+
+	pwm = pc->of_xlate(pc, &args);
+	if (IS_ERR(pwm))
+		goto put;
+
+	/*
+	 * If a consumer name was not given, try to look it up from the
+	 * "pwm-names" property if it exists. Otherwise use the name of
+	 * the user device node.
+	 */
+	if (!con_id) {
+		err = of_property_read_string_index(np, "pwm-names", index,
+						    &con_id);
+		if (err < 0)
+			con_id = np->name;
+	}
+
+	pwm->label = con_id;
+
+put:
+	of_node_put(args.np);
+
+	return pwm;
+}
+EXPORT_SYMBOL(of_pwm_request);
+#endif
+
 /**
  * pwm_add_table() - register PWM device consumers
  * @table: array of consumers to register
@@ -374,8 +516,9 @@ void __init pwm_add_table(struct pwm_lookup *table, size_t num)
  * @dev: device for PWM consumer
  * @con_id: consumer name
  *
- * Look up a PWM chip and a relative index via a table supplied by board setup
- * code (see pwm_add_table()).
+ * Lookup is first attempted using DT. If the device was not instantiated from
+ * a device tree, a PWM chip and a relative index is looked up via a table
+ * supplied by board setup code (see pwm_add_table()).
  *
  * Once a PWM chip has been found the specified PWM device will be requested
  * and is ready to be used.
@@ -390,6 +533,10 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
 	unsigned int index;
 	unsigned int match;
 
+	/* look up via DT first */
+	if (dev && dev->of_node)
+		return of_pwm_request(dev->of_node, con_id);
+
 	/*
 	 * We look up the provider in the static table typically provided by
 	 * board setup code. We first try to lookup the consumer device by
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 2947a4f..21d076c 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -1,6 +1,8 @@
 #ifndef __LINUX_PWM_H
 #define __LINUX_PWM_H
 
+#include <linux/of.h>
+
 struct pwm_device;
 struct seq_file;
 
@@ -105,6 +107,10 @@ struct pwm_chip {
 	unsigned int		npwm;
 
 	struct pwm_device	*pwms;
+
+	struct pwm_device *	(*of_xlate)(struct pwm_chip *pc,
+					    const struct of_phandle_args *args);
+	unsigned int		of_pwm_n_cells;
 };
 
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
-- 
1.7.9.6

  parent reply	other threads:[~2012-04-10 15:06 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-10 15:06 [PATCH v6 00/17] Add PWM framework and device tree support Thierry Reding
2012-04-10 15:06 ` Thierry Reding
     [not found] ` <1334070400-25013-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-10 15:06   ` [PATCH v6 01/17] pwm: Add PWM framework support Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 02/17] pwm: Allow chips to support multiple PWMs Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 03/17] pwm: Add debugfs interface Thierry Reding
2012-04-10 15:06     ` Thierry Reding
     [not found]     ` <1334070400-25013-4-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 12:33       ` Shawn Guo
2012-04-11 12:33         ` Shawn Guo
     [not found]         ` <20120411123352.GA2445-rvtDTF3kK1ictlrPMvKcciBecyulp+rMXqFh9Ls21Oc@public.gmane.org>
2012-04-11 12:38           ` Thierry Reding
2012-04-11 12:38             ` Thierry Reding
2012-04-11 15:11           ` Mark Brown
2012-04-11 15:11             ` Mark Brown
2012-04-10 15:06   ` [PATCH v6 04/17] pwm: Add table-based lookup for static mappings Thierry Reding
2012-04-10 15:06     ` Thierry Reding
     [not found]     ` <1334070400-25013-5-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 12:38       ` Shawn Guo
2012-04-11 12:38         ` Shawn Guo
     [not found]         ` <20120411123815.GB2445-rvtDTF3kK1ictlrPMvKcciBecyulp+rMXqFh9Ls21Oc@public.gmane.org>
2012-04-11 12:51           ` Thierry Reding
2012-04-11 12:51             ` Thierry Reding
2012-04-13  9:47       ` Mark Brown
2012-04-13  9:47         ` Mark Brown
2012-04-10 15:06   ` Thierry Reding [this message]
2012-04-10 15:06     ` [PATCH v6 05/17] pwm: Add device tree support Thierry Reding
     [not found]     ` <1334070400-25013-6-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 13:02       ` Shawn Guo
2012-04-11 13:02         ` Shawn Guo
     [not found]         ` <20120411130208.GC2445-rvtDTF3kK1ictlrPMvKcciBecyulp+rMXqFh9Ls21Oc@public.gmane.org>
2012-04-11 13:14           ` Thierry Reding
2012-04-11 13:14             ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 06/17] ARM: tegra: Fix PWM clock programming Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 07/17] ARM: tegra: Provide clock for only one PWM controller Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 08/17] pwm: Add NVIDIA Tegra SoC support Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 09/17] pwm: tegra: Add device tree support Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 10/17] pwm: Move Blackfin PWM driver to PWM framework Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 11/17] pwm: Move PXA " Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 12/17] ARM i.MX: Move i.MX pwm driver to pwm framework Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 13/17] ARM Samsung: Move s3c " Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 14/17] ARM vt8500: Move vt8500 " Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 15/17] pwm: add pwm-mxs support Thierry Reding
2012-04-10 15:06     ` Thierry Reding
2012-04-10 15:06   ` [PATCH v6 16/17] pwm-backlight: Add rudimentary device tree support Thierry Reding
2012-04-10 15:06     ` Thierry Reding
     [not found]     ` <1334070400-25013-17-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 13:28       ` Shawn Guo
2012-04-11 13:28         ` Shawn Guo
2012-04-13  9:48       ` Mark Brown
2012-04-13  9:48         ` Mark Brown
2012-04-10 15:06   ` [PATCH v6 17/17] pwm: Take over maintainership of the PWM subsystem Thierry Reding
2012-04-10 15:06     ` Thierry Reding
     [not found]     ` <1334070400-25013-18-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-10 19:51       ` Arnd Bergmann
2012-04-10 19:51         ` Arnd Bergmann
     [not found]         ` <201204101951.44198.arnd-r2nGTMty4D4@public.gmane.org>
2012-04-12  7:22           ` Thierry Reding
2012-04-12  7:22             ` Thierry Reding
     [not found]             ` <20120412072206.GB18252-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-12 11:34               ` Arnd Bergmann
2012-04-12 11:34                 ` Arnd Bergmann
     [not found]                 ` <201204121134.24892.arnd-r2nGTMty4D4@public.gmane.org>
2012-04-12 12:27                   ` Thierry Reding
2012-04-12 12:27                     ` Thierry Reding
     [not found]                     ` <20120412122740.GB5353-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-16  5:50                       ` Thierry Reding
2012-04-16  5:50                         ` Thierry Reding
     [not found]                         ` <20120416055012.GA3037-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-16 15:02                           ` Arnd Bergmann
2012-04-16 15:02                             ` Arnd Bergmann
2012-04-10 20:58       ` Sascha Hauer
2012-04-10 20:58         ` Sascha Hauer
2012-06-14 12:47   ` [PATCH v6 00/17] Add PWM framework and device tree support Hebbar, Gururaja
2012-06-14 12:47     ` Hebbar, Gururaja
     [not found]     ` <1BAFE6F6C881BF42822005164F1491C33EA21A9F-Er742YJ7I/eIQmiDNMet8wC/G2K4zDHf@public.gmane.org>
2012-06-14 12:53       ` Thierry Reding
2012-06-14 12:53         ` Thierry Reding
2012-06-14 13:36         ` Hebbar, Gururaja
2012-06-14 13:36           ` Hebbar, Gururaja
2012-04-29 15:40 ` Eric Bénard
2012-04-29 15:40   ` Eric Bénard

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=1334070400-25013-6-git-send-email-thierry.reding@avionic-design.de \
    --to=thierry.reding-rm9k5ik7kjkj5m59nbduvrnah6klmebb@public.gmane.org \
    --cc=arnd-r2nGTMty4D4@public.gmane.org \
    --cc=broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org \
    --cc=ccross-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org \
    --cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
    --cc=eric.y.miao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
    --cc=kurt.van.dijck-/BeEPy95v10@public.gmane.org \
    --cc=lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=matthias-RprLehDfhQ3k1uMJSBkQmQ@public.gmane.org \
    --cc=olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org \
    --cc=rmallon-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org \
    --cc=rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org \
    --cc=s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
    --cc=shawn.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
    --cc=vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org \
    --cc=walle-pDveNdigDaDu9UdzE1sIFA@public.gmane.org \
    --cc=wmb-D5eQfiDGL7eakBO8gow8eQ@public.gmane.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.