aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2011-12-14 05:10:32 -0500
committerThierry Reding <thierry.reding@avionic-design.de>2012-06-15 06:56:57 -0400
commit7299ab70e68e20e70cb45fe4ab4b6029fe964acd (patch)
treeb396b29f6170deb3769c0b884ccf0fd64211f6ee
parente05e5070f0ec2557d2d2ff3655ba03f29e297151 (diff)
pwm: Add device tree support
This patch adds helpers to support device tree bindings for the generic PWM API. Device tree binding documentation for PWM controllers is also provided. Acked-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm.txt57
-rw-r--r--drivers/pwm/core.c148
-rw-r--r--include/linux/pwm.h6
3 files changed, 209 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt
new file mode 100644
index 000000000000..73ec962bfe8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm.txt
@@ -0,0 +1,57 @@
1Specifying PWM information for devices
2======================================
3
41) PWM user nodes
5-----------------
6
7PWM users should specify a list of PWM devices that they want to use
8with a property containing a 'pwm-list':
9
10 pwm-list ::= <single-pwm> [pwm-list]
11 single-pwm ::= <pwm-phandle> <pwm-specifier>
12 pwm-phandle : phandle to PWM controller node
13 pwm-specifier : array of #pwm-cells specifying the given PWM
14 (controller specific)
15
16PWM properties should be named "pwms". The exact meaning of each pwms
17property must be documented in the device tree binding for each device.
18An optional property "pwm-names" may contain a list of strings to label
19each of the PWM devices listed in the "pwms" property. If no "pwm-names"
20property is given, the name of the user node will be used as fallback.
21
22Drivers for devices that use more than a single PWM device can use the
23"pwm-names" property to map the name of the PWM device requested by the
24pwm_get() call to an index into the list given by the "pwms" property.
25
26The following example could be used to describe a PWM-based backlight
27device:
28
29 pwm: pwm {
30 #pwm-cells = <2>;
31 };
32
33 [...]
34
35 bl: backlight {
36 pwms = <&pwm 0 5000000>;
37 pwm-names = "backlight";
38 };
39
40pwm-specifier typically encodes the chip-relative PWM number and the PWM
41period in nanoseconds. Note that in the example above, specifying the
42"pwm-names" is redundant because the name "backlight" would be used as
43fallback anyway.
44
452) PWM controller nodes
46-----------------------
47
48PWM controller nodes must specify the number of cells used for the
49specifier using the '#pwm-cells' property.
50
51An example PWM controller might look like this:
52
53 pwm: pwm@7000a000 {
54 compatible = "nvidia,tegra20-pwm";
55 reg = <0x7000a000 0x100>;
56 #pwm-cells = <2>;
57 };
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index a2af599e61ae..dbab53005da8 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)
129 return 0; 129 return 0;
130} 130}
131 131
132static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc,
133 const struct of_phandle_args *args)
134{
135 struct pwm_device *pwm;
136
137 if (pc->of_pwm_n_cells < 2)
138 return ERR_PTR(-EINVAL);
139
140 if (args->args[0] >= pc->npwm)
141 return ERR_PTR(-EINVAL);
142
143 pwm = pwm_request_from_chip(pc, args->args[0], NULL);
144 if (IS_ERR(pwm))
145 return pwm;
146
147 pwm_set_period(pwm, args->args[1]);
148
149 return pwm;
150}
151
152void of_pwmchip_add(struct pwm_chip *chip)
153{
154 if (!chip->dev || !chip->dev->of_node)
155 return;
156
157 if (!chip->of_xlate) {
158 chip->of_xlate = of_pwm_simple_xlate;
159 chip->of_pwm_n_cells = 2;
160 }
161
162 of_node_get(chip->dev->of_node);
163}
164
165void of_pwmchip_remove(struct pwm_chip *chip)
166{
167 if (chip->dev && chip->dev->of_node)
168 of_node_put(chip->dev->of_node);
169}
170
132/** 171/**
133 * pwm_set_chip_data() - set private chip data for a PWM 172 * pwm_set_chip_data() - set private chip data for a PWM
134 * @pwm: PWM device 173 * @pwm: PWM device
@@ -201,6 +240,9 @@ int pwmchip_add(struct pwm_chip *chip)
201 240
202 ret = 0; 241 ret = 0;
203 242
243 if (IS_ENABLED(CONFIG_OF))
244 of_pwmchip_add(chip);
245
204out: 246out:
205 mutex_unlock(&pwm_lock); 247 mutex_unlock(&pwm_lock);
206 return ret; 248 return ret;
@@ -231,6 +273,10 @@ int pwmchip_remove(struct pwm_chip *chip)
231 } 273 }
232 274
233 list_del_init(&chip->list); 275 list_del_init(&chip->list);
276
277 if (IS_ENABLED(CONFIG_OF))
278 of_pwmchip_remove(chip);
279
234 free_pwms(chip); 280 free_pwms(chip);
235 281
236out: 282out:
@@ -356,6 +402,99 @@ void pwm_disable(struct pwm_device *pwm)
356} 402}
357EXPORT_SYMBOL_GPL(pwm_disable); 403EXPORT_SYMBOL_GPL(pwm_disable);
358 404
405static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
406{
407 struct pwm_chip *chip;
408
409 mutex_lock(&pwm_lock);
410
411 list_for_each_entry(chip, &pwm_chips, list)
412 if (chip->dev && chip->dev->of_node == np) {
413 mutex_unlock(&pwm_lock);
414 return chip;
415 }
416
417 mutex_unlock(&pwm_lock);
418
419 return ERR_PTR(-EPROBE_DEFER);
420}
421
422/**
423 * of_pwm_request() - request a PWM via the PWM framework
424 * @np: device node to get the PWM from
425 * @con_id: consumer name
426 *
427 * Returns the PWM device parsed from the phandle and index specified in the
428 * "pwms" property of a device tree node or a negative error-code on failure.
429 * Values parsed from the device tree are stored in the returned PWM device
430 * object.
431 *
432 * If con_id is NULL, the first PWM device listed in the "pwms" property will
433 * be requested. Otherwise the "pwm-names" property is used to do a reverse
434 * lookup of the PWM index. This also means that the "pwm-names" property
435 * becomes mandatory for devices that look up the PWM device via the con_id
436 * parameter.
437 */
438static struct pwm_device *of_pwm_request(struct device_node *np,
439 const char *con_id)
440{
441 struct pwm_device *pwm = NULL;
442 struct of_phandle_args args;
443 struct pwm_chip *pc;
444 int index = 0;
445 int err;
446
447 if (con_id) {
448 index = of_property_match_string(np, "pwm-names", con_id);
449 if (index < 0)
450 return ERR_PTR(index);
451 }
452
453 err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index,
454 &args);
455 if (err) {
456 pr_debug("%s(): can't parse \"pwms\" property\n", __func__);
457 return ERR_PTR(err);
458 }
459
460 pc = of_node_to_pwmchip(args.np);
461 if (IS_ERR(pc)) {
462 pr_debug("%s(): PWM chip not found\n", __func__);
463 pwm = ERR_CAST(pc);
464 goto put;
465 }
466
467 if (args.args_count != pc->of_pwm_n_cells) {
468 pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name,
469 args.np->full_name);
470 pwm = ERR_PTR(-EINVAL);
471 goto put;
472 }
473
474 pwm = pc->of_xlate(pc, &args);
475 if (IS_ERR(pwm))
476 goto put;
477
478 /*
479 * If a consumer name was not given, try to look it up from the
480 * "pwm-names" property if it exists. Otherwise use the name of
481 * the user device node.
482 */
483 if (!con_id) {
484 err = of_property_read_string_index(np, "pwm-names", index,
485 &con_id);
486 if (err < 0)
487 con_id = np->name;
488 }
489
490 pwm->label = con_id;
491
492put:
493 of_node_put(args.np);
494
495 return pwm;
496}
497
359/** 498/**
360 * pwm_add_table() - register PWM device consumers 499 * pwm_add_table() - register PWM device consumers
361 * @table: array of consumers to register 500 * @table: array of consumers to register
@@ -378,8 +517,9 @@ void __init pwm_add_table(struct pwm_lookup *table, size_t num)
378 * @dev: device for PWM consumer 517 * @dev: device for PWM consumer
379 * @con_id: consumer name 518 * @con_id: consumer name
380 * 519 *
381 * Look up a PWM chip and a relative index via a table supplied by board setup 520 * Lookup is first attempted using DT. If the device was not instantiated from
382 * code (see pwm_add_table()). 521 * a device tree, a PWM chip and a relative index is looked up via a table
522 * supplied by board setup code (see pwm_add_table()).
383 * 523 *
384 * Once a PWM chip has been found the specified PWM device will be requested 524 * Once a PWM chip has been found the specified PWM device will be requested
385 * and is ready to be used. 525 * and is ready to be used.
@@ -394,6 +534,10 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
394 unsigned int index; 534 unsigned int index;
395 unsigned int match; 535 unsigned int match;
396 536
537 /* look up via DT first */
538 if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
539 return of_pwm_request(dev->of_node, con_id);
540
397 /* 541 /*
398 * We look up the provider in the static table typically provided by 542 * We look up the provider in the static table typically provided by
399 * board setup code. We first try to lookup the consumer device by 543 * 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 2947a4fea6ad..21d076c5089e 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -1,6 +1,8 @@
1#ifndef __LINUX_PWM_H 1#ifndef __LINUX_PWM_H
2#define __LINUX_PWM_H 2#define __LINUX_PWM_H
3 3
4#include <linux/of.h>
5
4struct pwm_device; 6struct pwm_device;
5struct seq_file; 7struct seq_file;
6 8
@@ -105,6 +107,10 @@ struct pwm_chip {
105 unsigned int npwm; 107 unsigned int npwm;
106 108
107 struct pwm_device *pwms; 109 struct pwm_device *pwms;
110
111 struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
112 const struct of_phandle_args *args);
113 unsigned int of_pwm_n_cells;
108}; 114};
109 115
110int pwm_set_chip_data(struct pwm_device *pwm, void *data); 116int pwm_set_chip_data(struct pwm_device *pwm, void *data);