Skip to contentSkip to conversation

Add PWM framework and device tree support

PATCH Superseded Thierry Reding 7 participants 48 messages Mar 28, 2012 – Apr 7, 2012

Subsystems (13)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v5 cover Add PWM framework and device tree support

This patch series adds very rudimentary device-tree support for PWM devices. With all of these patches applied (plus one board-specific patch that is not included), I'm able to control the backlight on the device I'm working on using the sysfs interface provided by the pwm-bl driver and the backlight class.

This series is based on Sascha Hauer's series of patches[0] to add a generic PWM framework. The first patch in this series is taken from Sascha's branch, while the second patch enables each PWM chip to provide multiple PWM devices (the Blackfin and PXA drivers have been ported to the framework for reference). Currently a global namespace is still provided to keep backwards-compatibility with the legacy PWM API. In order to achieve this, the number of global PWM devices is limited to 1024. However, patch 2 introduces per-chip indexing of PWM devices in the core and patch 4 adds an API to request a PWM device using a lookup table registered by board setup code. They are supposed to eventually replace pwm_request() and allow to get rid of the global namespace. The device tree support code does not use the global namespace.

Patch 3 adds a debugfs interface.

Patch 5 adds some code to lookup a PWM chip given its device-tree handle. This code will be used later on by the pwm-bl driver to find the PWM device that it should be using. If the no corresponding PWM chip is available yet, the code returns EPROBE_DEFER to have users automatically probed again later when the PWM provider may have become available. Device tree binding documentation is also provided.

Patch 6 was taken from the Chromium tree and is required to provide proper clocking of the Tegra2 PWFM controller. All Chromium-specific tags have been removed from the commit message. Some cleanup of the clock registration for Tegra is done in patch 7 because a subsequent patch will instantiate one PWFM controller device instead of four.

Patch 8 adds a generic PWM framework driver for the Tegra2 PWFM controller. The code is taken from the Chromium tree with some adjustments to integrate it with the PWM framework. Device tree based probing of the driver is implemented in patch 9.

Patches 10 and 11 are ports of the Blackfin PWM and the PXA PWM drivers to the PWM framework. These are only compile-tested as I do not have any hardware to test them on.

Patches 12, 13 and 14 move the i.MX, Samsung and VT8500 drivers over to the framework. These are originally by Sascha Hauer and were updated to take advantage of the multiple PWM devices per chip feature.

Patch 15 implements DT-based probing in the pwm-backlight driver. Note that this code only handles the "pwms" property (by looking up the PWM device via the new PWM DT binding). Switching power to the backlight via GPIOs is not supported yet. The DT binding also deviates from the platform data in that it requires a list of brightness levels to be specified instead of assuming a linearily spaced range from 0 to a given maximum brightness.

Finally, patch 16 makes me the new maintainer of the PWM subsystem.

The whole series is based on the linux-next tree from 20120328. I think I've addressed all of the concerns raised in the first four versions.

Thierry

[0]: http://git.pengutronix.de/?p=imx/linux-2.6.git;a=shortlog;h=refs/heads/pwmlib

Sascha Hauer (4):
pwm: Add PWM framework support
ARM i.MX: Move i.MX pwm driver to pwm framework ARM Samsung: Move s3c pwm driver to pwm framework ARM vt8500: Move vt8500 pwm driver to pwm framework

Simon Que (1):
ARM: tegra: Fix PWM clock programming

Thierry Reding (11):
pwm: Allow chips to support multiple PWMs
pwm: Add debugfs interface
pwm: Add table-based lookup for static mappings
pwm: Add device tree support
ARM: tegra: Provide clock for only one PWM controller
pwm: Add NVIDIA Tegra SoC support
pwm: tegra: Add device tree support
pwm: Move Blackfin PWM driver to PWM framework
pwm: Move PXA PWM driver to PWM framework
pwm-backlight: Add rudimentary device tree support
pwm: Take over maintainership of the PWM subsystem

 .../devicetree/bindings/pwm/nvidia,tegra20-pwm.txt |   18 +
 Documentation/devicetree/bindings/pwm/pwm.txt      |   53 ++
 .../bindings/video/backlight/pwm-backlight         |   30 +
 Documentation/pwm.txt                              |   76 +++
 MAINTAINERS                                        |   12 +
 arch/arm/boot/dts/tegra20.dtsi                     |    6 +
 arch/arm/boot/dts/tegra30.dtsi                     |    6 +
 arch/arm/mach-tegra/board-dt-tegra20.c             |    1 +
 arch/arm/mach-tegra/board-dt-tegra30.c             |    3 +
 arch/arm/mach-tegra/tegra2_clocks.c                |   36 +-
 arch/arm/mach-tegra/tegra30_clocks.c               |    6 +-
 arch/arm/mach-vt8500/Makefile                      |    2 -
 arch/arm/plat-mxc/Kconfig                          |    6 -
 arch/arm/plat-mxc/Makefile                         |    1 -
 arch/arm/plat-pxa/Makefile                         |    1 -
 arch/arm/plat-samsung/Makefile                     |    4 -
 arch/blackfin/Kconfig                              |   10 -
 arch/blackfin/kernel/Makefile                      |    1 -
 arch/blackfin/kernel/pwm.c                         |  100 ---
 drivers/Kconfig                                    |    2 +
 drivers/Makefile                                   |    1 +
 drivers/pwm/Kconfig                                |   67 ++
 drivers/pwm/Makefile                               |    7 +
 drivers/pwm/core.c                                 |  679 ++++++++++++++++++++
 drivers/pwm/pwm-bfin.c                             |  164 +++++
 arch/arm/plat-mxc/pwm.c => drivers/pwm/pwm-imx.c   |  182 ++----
 arch/arm/plat-pxa/pwm.c => drivers/pwm/pwm-pxa.c   |  172 ++---
 .../pwm.c => drivers/pwm/pwm-samsung.c             |  228 +++----
 drivers/pwm/pwm-tegra.c                            |  265 ++++++++
 .../mach-vt8500/pwm.c => drivers/pwm/pwm-vt8500.c  |  169 ++---
 drivers/video/backlight/Kconfig                    |    2 +-
 drivers/video/backlight/pwm_bl.c                   |  145 ++++-
 include/linux/of_pwm.h                             |   34 +
 include/linux/pwm.h                                |  115 ++++
 include/linux/pwm_backlight.h                      |    1 +
 35 files changed, 1967 insertions(+), 638 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm.txt
 create mode 100644 Documentation/devicetree/bindings/video/backlight/pwm-backlight
 create mode 100644 Documentation/pwm.txt
 delete mode 100644 arch/blackfin/kernel/pwm.c
 create mode 100644 drivers/pwm/Kconfig
 create mode 100644 drivers/pwm/Makefile
 create mode 100644 drivers/pwm/core.c
 create mode 100644 drivers/pwm/pwm-bfin.c
 rename arch/arm/plat-mxc/pwm.c => drivers/pwm/pwm-imx.c (58%)
 rename arch/arm/plat-pxa/pwm.c => drivers/pwm/pwm-pxa.c (57%)
 rename arch/arm/plat-samsung/pwm.c => drivers/pwm/pwm-samsung.c (58%)
 create mode 100644 drivers/pwm/pwm-tegra.c
 rename arch/arm/mach-vt8500/pwm.c => drivers/pwm/pwm-vt8500.c (52%)
 create mode 100644 include/linux/of_pwm.h
Signature · 1 line
1.7.9.4
#1 lore raw

PATCH v5 1/16 pwm: Add PWM framework support

From: Sascha Hauer <[email protected]>

This patch adds framework support for PWM (pulse width modulation) devices.

The is a barebone PWM API already in the kernel under include/linux/pwm.h, but it does not allow for multiple drivers as each of them implements the pwm_*() functions.

There are other PWM framework patches around from Bill Gatliff. Unlike his framework this one does not change the existing API for PWMs so that this framework can act as a drop in replacement for the existing API.

Why another framework?

Several people argue that there should not be another framework for PWMs but they should be integrated into one of the existing frameworks like led or hwmon. Unlike these frameworks the PWM framework is agnostic to the purpose of the PWM. In fact, a PWM can drive a LED, but this makes the LED framework a user of a PWM, like already done in leds-pwm.c. The gpio framework also is not suitable for PWMs. Every gpio could be turned into a PWM using timer based toggling, but on the other hand not every PWM hardware device can be turned into a gpio due to the lack of hardware capabilities.

This patch does not try to improve the PWM API yet, this could be done in subsequent patches.

[thierry.reding at avionic-design.de: fixup typos, kerneldoc comments]

---
Changes in v5:
- minor cleanups and typo fixes
- add some kerneldoc comments

 Documentation/pwm.txt |   54 ++++++++++++
 MAINTAINERS           |    6 ++
 drivers/Kconfig       |    2 +
 drivers/Makefile      |    1 +
 drivers/pwm/Kconfig   |   12 +++
 drivers/pwm/Makefile  |    1 +
 drivers/pwm/core.c    |  227 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pwm.h   |   38 +++++++++
 8 files changed, 341 insertions(+)
 create mode 100644 Documentation/pwm.txt
 create mode 100644 drivers/pwm/Kconfig
 create mode 100644 drivers/pwm/Makefile
 create mode 100644 drivers/pwm/core.c
Documentation/pwm.txt new file +54 -0
new file mode 100644
index 0000000..03e39d1
@@ -0,0 +1,54 @@
+Pulse Width Modulation (PWM) interface
+
+This provides an overview about the Linux PWM interface
+
+PWMs are commonly used for controlling LEDs, fans or vibrators in
+cell phones. PWMs with a fixed purpose have no need implementing
+the Linux PWM API (although they could). However, PWMs are often
+found as discrete devices on SoCs which have no fixed purpose. It's
+up to the board designer to connect them to LEDs or fans. To provide
+this kind of flexibility the generic PWM API exists.
+
+Identifying PWMs
+----------------
+
+Users of the legacy PWM API use unique IDs to refer to PWM devices. One
+goal of the new PWM framework is to get rid of this global namespace.
+
+Using PWMs
+----------
+
+A PWM can be requested using pwm_request() and freed after usage with
+pwm_free(). After being requested a PWM has to be configured using
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
+
+To start/stop toggling the PWM output use pwm_enable()/pwm_disable().
+
+Implementing a PWM driver
+-------------------------
+
+Currently there are two ways to implement pwm drivers. Traditionally
+there only has been the barebone API meaning that each driver has
+to implement the pwm_*() functions itself. This means that it's impossible
+to have multiple PWM drivers in the system. For this reason it's mandatory
+for new drivers to use the generic PWM framework.
+A new PWM device can be added using pwmchip_add() and removed again with
+pwmchip_remove(). pwmchip_add() takes a filled in struct pwm_chip as
+argument which provides the ops and the pwm id to the framework.
+
+Locking
+-------
+
+The PWM core list manipulations are protected by a mutex, so pwm_request()
+and pwm_free() may not be called from an atomic context. Currently the
+PWM core does not enforce any locking to pwm_enable(), pwm_disable() and
+pwm_config(), so the calling context is currently driver specific. This
+is an issue derived from the former barebone API and should be fixed soon.
+
+Helpers
+-------
+
+Currently a PWM can only be configured with period_ns and duty_ns. For several
+use cases freq_hz and duty_percent might be better. Instead of calculating
+this in your driver please consider adding appropriate helpers to the framework.
MAINTAINERS +6 -0
index c934395..d68feef 100644
@@ -5429,6 +5429,12 @@ S:	Maintained
 F:	Documentation/video4linux/README.pvrusb2
 F:	drivers/media/video/pvrusb2/
 
+PWM core
+M:	Sascha Hauer <[email protected]>
+L:	linux-kernel at vger.kernel.org
+S:	Maintained
+F:	drivers/pwm/
+
 PXA2xx/PXA3xx SUPPORT
 M:	Eric Miao <[email protected]>
 M:	Russell King <[email protected]>
drivers/Kconfig +2 -0
index b3ae9e5..ec094b5 100644
@@ -142,4 +142,6 @@ source "drivers/devfreq/Kconfig"
 
 source "drivers/modem_shm/Kconfig"
 
+source "drivers/pwm/Kconfig"
+
 endmenu
drivers/Makefile +1 -0
index 4855a1a..52fe956 100644
@@ -8,6 +8,7 @@
 # GPIO must come after pinctrl as gpios may need to mux pins etc
 obj-y				+= pinctrl/
 obj-y				+= gpio/
+obj-y				+= pwm/
 obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
drivers/pwm/Kconfig new file +12 -0
new file mode 100644
index 0000000..93c1052
@@ -0,0 +1,12 @@
+menuconfig PWM
+	bool "PWM Support"
+	help
+	  This enables PWM support through the generic PWM framework.
+	  You only need to enable this, if you also want to enable
+	  one or more of the PWM drivers below.
+
+	  If unsure, say N.
+
+if PWM
+
+endif
drivers/pwm/Makefile new file +1 -0
new file mode 100644
index 0000000..3469c3d
@@ -0,0 +1 @@
+obj-$(CONFIG_PWM)		+= core.o
drivers/pwm/core.c new file +227 -0

227 lines not on this page · raw message

include/linux/pwm.h +38 -0
index 7c77575..4bad29c 100644
@@ -28,4 +28,42 @@ int pwm_enable(struct pwm_device *pwm);
  */
 void pwm_disable(struct pwm_device *pwm);
 
+#ifdef CONFIG_PWM
+struct pwm_chip;
+
+/**
+ * struct pwm_ops - PWM controller operations
+ * @request: optional hook for requesting a PWM
+ * @free: optional hook for freeing a PWM
+ * @config: configure duty cycles and period length for this PWM
+ * @enable: enable PWM output toggling
+ * @disable: disable PWM output toggling
+ * @owner: helps prevent removal of modules exporting active PWMs
+ */
+struct pwm_ops {
+	int			(*request)(struct pwm_chip *chip);
+	void			(*free)(struct pwm_chip *chip);
+	int			(*config)(struct pwm_chip *chip, int duty_ns,
+						int period_ns);
+	int			(*enable)(struct pwm_chip *chip);
+	void			(*disable)(struct pwm_chip *chip);
+	struct module		*owner;
+};
+
+/**
+ * struct pwm_chip - abstract a PWM
+ * @label: for diagnostics
+ * @owner: helps prevent removal of modules exporting active PWMs
+ * @ops: The callbacks for this PWM
+ */
+struct pwm_chip {
+	int			pwm_id;
+	const char		*label;
+	struct pwm_ops		*ops;
+};
+
+int pwmchip_add(struct pwm_chip *chip);
+int pwmchip_remove(struct pwm_chip *chip);
+#endif
+
 #endif /* __LINUX_PWM_H */
Signature · 1 line
1.7.9.4
#2 lore raw

PATCH v5 1/16 pwm: Add PWM framework support

Quoted 3 lines · Thierry Reding

From: Sascha Hauer <[email protected]>

This patch adds framework support for PWM (pulse width modulation) devices.

Looking good, hope we can get this in for 3.5!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120329/2b4e4011/attachment.sig>

#3 lore raw

PATCH v5 1/16 pwm: Add PWM framework support

In reply to Thierry Reding

A couple of trivial editorial errors, otherwise,

Quoted 5 lines · Thierry Reding

From: Sascha Hauer <[email protected]>

This patch adds framework support for PWM (pulse width modulation) devices.

The is a barebone PWM API already in the kernel under include/linux/pwm.h,

s/The/There

Quoted 3 lines

but it does not allow for multiple drivers as each of them implements the pwm_*() functions.

...

Quoted 3 lines

+/**
+ * pwm_request() - request a PWM device
+ * @pwm: global PWM device index

s/pwm/pwm_id

Quoted 3 lines

+ * @label: PWM device label
+ */
+struct pwm_device *pwm_request(int pwm_id, const char *label)

...

Quoted 4 lines

+/**
+ * struct pwm_chip - abstract a PWM
+ * @label: for diagnostics
+ * @owner: helps prevent removal of modules exporting active PWMs

The doc needs an update.

Regards,
Shawn

Quoted 16 lines

+ * @ops: The callbacks for this PWM
+ */

include/linux/pwm.h +10 -0
+struct pwm_chip {
+	int			pwm_id;
+	const char		*label;
+	struct pwm_ops		*ops;
+};
+
+int pwmchip_add(struct pwm_chip *chip);
+int pwmchip_remove(struct pwm_chip *chip);
+#endif
+
 #endif /* __LINUX_PWM_H */
Signature · 1 line
1.7.9.4
#4 lore raw

PATCH v5 1/16 pwm: Add PWM framework support

Quoted 27 lines · Shawn Guo

A couple of trivial editorial errors, otherwise,

Quoted 5 lines · Thierry Reding

From: Sascha Hauer <[email protected]>

This patch adds framework support for PWM (pulse width modulation) devices.

The is a barebone PWM API already in the kernel under include/linux/pwm.h,

s/The/There

Quoted 3 lines

but it does not allow for multiple drivers as each of them implements the pwm_*() functions.

...

Quoted 3 lines

+/**
+ * pwm_request() - request a PWM device
+ * @pwm: global PWM device index

s/pwm/pwm_id

Quoted 3 lines

+ * @label: PWM device label
+ */
+struct pwm_device *pwm_request(int pwm_id, const char *label)

Quoted 8 lines

...

Quoted 4 lines

+/**
+ * struct pwm_chip - abstract a PWM
+ * @label: for diagnostics
+ * @owner: helps prevent removal of modules exporting active PWMs

The doc needs an update.

Thanks,
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120404/590c1526/attachment-0001.sig>

#5 lore raw

PATCH v5 2/16 pwm: Allow chips to support multiple PWMs

In reply to Thierry Reding

Many PWM controllers provide access to more than a single PWM output and may even share some resource among them. Allowing a PWM chip to provide multiple PWM devices enables better sharing of those resources. As a side-effect this change allows easy integration with the device tree where a given PWM can be looked up based on the PWM chip's phandle and a corresponding index.

This commit modifies the PWM core to support multiple PWMs per struct pwm_chip. It achieves this in a similar way to how gpiolib works, by allowing PWM ranges to be requested dynamically (pwm_chip.base == -1) or starting at a given offset (pwm_chip.base >= 0). A chip specifies how many PWMs it controls using the npwm member. Each of the functions in the pwm_ops structure gets an additional argument that specified the PWM number (it can be converted to a per-chip index by subtracting the chip's base).

The total maximum number of PWM devices is currently fixed to 1024 while the data is actually stored in a radix tree, thus saving resources if not all of them are used.

---
Changes in v5:
- add sanity checks to pwmchip_add()
- make pwm_chip.pwm_ops constant
- remove unused pwm_request_from_device() function
- check for valid chip in pwm_request_from_chip()
- add sanity checks to pwm_config(), pwm_enable() and pwm_disable()
- update Documentation/pwm.txt
- use deferred driver probing if pwm_request() cannot find a PWM

Changes in v4:
- remove OF-specific code to preserve bisectability
- add pwm_request_from_device() and pwm_request_from_chip() functions
- refactor PWM requesting code
- store period in struct pwm_device and get rid of the unused struct pwm_spec

Changes in v3:
- get rid of pwm_desc structure and keep only struct pwm_device
- keep a list of pwm_chip structures for fast and easy lookup
- pass struct pwm_device directly to pwm_ops
- add debugfs file

Changes in v2:
- add 'struct device *dev' field to pwm_chip, drop label field
- use radix tree for PWM descriptors
- add pwm_set_chip_data() and pwm_get_chip_data() functions to allow storing and retrieving chip-specific per-PWM data

 Documentation/pwm.txt |    9 +-
 drivers/pwm/core.c    |  263 ++++++++++++++++++++++++++++++++++---------------
 include/linux/pwm.h   |   71 ++++++++++---
 3 files changed, 250 insertions(+), 93 deletions(-)
Documentation/pwm.txt +6 -3
index 03e39d1..48f598a 100644
@@ -33,9 +33,12 @@ there only has been the barebone API meaning that each driver has
 to implement the pwm_*() functions itself. This means that it's impossible
 to have multiple PWM drivers in the system. For this reason it's mandatory
 for new drivers to use the generic PWM framework.
-A new PWM device can be added using pwmchip_add() and removed again with
-pwmchip_remove(). pwmchip_add() takes a filled in struct pwm_chip as
-argument which provides the ops and the pwm id to the framework.
+
+A new PWM controller/chip can be added using pwmchip_add() and removed
+again with pwmchip_remove(). pwmchip_add() takes a filled in struct
+pwm_chip as argument which provides a description of the PWM chip, the
+number of PWM devices provider by the chip and the chip-specific
+implementation of the supported PWM operations to the framework.
 
 Locking
 -------
drivers/pwm/core.c +186 -77

371 lines not on this page · raw message

include/linux/pwm.h +58 -13

93 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#6 lore raw

PATCH v5 2/16 pwm: Allow chips to support multiple PWMs

Quoted 6 lines · Thierry Reding

Many PWM controllers provide access to more than a single PWM output and may even share some resource among them. Allowing a PWM chip to provide multiple PWM devices enables better sharing of those resources. As a side-effect this change allows easy integration with the device tree where a given PWM can be looked up based on the PWM chip's phandle and a corresponding index.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120329/03d467ed/attachment.sig>

#7 lore raw

PATCH v5 2/16 pwm: Allow chips to support multiple PWMs

In reply to Thierry Reding
Quoted 16 lines · Thierry Reding

Many PWM controllers provide access to more than a single PWM output and may even share some resource among them. Allowing a PWM chip to provide multiple PWM devices enables better sharing of those resources. As a side-effect this change allows easy integration with the device tree where a given PWM can be looked up based on the PWM chip's phandle and a corresponding index.

This commit modifies the PWM core to support multiple PWMs per struct pwm_chip. It achieves this in a similar way to how gpiolib works, by allowing PWM ranges to be requested dynamically (pwm_chip.base == -1) or starting at a given offset (pwm_chip.base >= 0). A chip specifies how many PWMs it controls using the npwm member. Each of the functions in the pwm_ops structure gets an additional argument that specified the PWM number (it can be converted to a per-chip index by subtracting the chip's base).

Quoted 5 lines

The total maximum number of PWM devices is currently fixed to 1024 while the data is actually stored in a radix tree, thus saving resources if not all of them are used.

Signature · 2 lines
Regards,
Shawn
#8 lore raw

PATCH v5 3/16 pwm: Add debugfs interface

In reply to Thierry Reding

This commit adds a debugfs interface that can be used to list the current internal state of the PWM devices registered with the PWM framework.

---
Changes in v5:
- new patch splitting off debugfs interface implementation
- use seq_file's iterator interface for debugfs support
- add missing forward declaration of struct seq_file

 drivers/pwm/core.c  |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pwm.h |    6 ++++
 2 files changed, 96 insertions(+)
drivers/pwm/core.c +90 -0
index 46dcbe1..12a643d 100644
@@ -27,6 +27,8 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #define MAX_PWMS 1024
 
@@ -334,3 +336,91 @@ void pwm_disable(struct pwm_device *pwm)
 		pwm->chip->ops->disable(pwm->chip, pwm);
 }
 EXPORT_SYMBOL_GPL(pwm_disable);
+
+#ifdef CONFIG_DEBUG_FS
+static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
+{
+	unsigned int i;
+
+	for (i = 0; i < chip->npwm; i++) {
+		struct pwm_device *pwm = &chip->pwms[i];
+
+		seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label);
+
+		if (test_bit(PWMF_REQUESTED, &pwm->flags))
+			seq_printf(s, " requested");
+
+		if (test_bit(PWMF_ENABLED, &pwm->flags))
+			seq_printf(s, " enabled");
+
+		seq_printf(s, "\n");
+	}
+}
+
+static void *pwm_seq_start(struct seq_file *s, loff_t *pos)
+{
+	mutex_lock(&pwm_lock);
+	s->private = "";
+
+	return seq_list_start(&pwm_chips, *pos);
+}
+
+static void *pwm_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	s->private = "\n";
+
+	return seq_list_next(v, &pwm_chips, pos);
+}
+
+static void pwm_seq_stop(struct seq_file *s, void *v)
+{
+	mutex_unlock(&pwm_lock);
+}
+
+static int pwm_seq_show(struct seq_file *s, void *v)
+{
+	struct pwm_chip *chip = list_entry(v, struct pwm_chip, list);
+
+	seq_printf(s, "%s%s/%s, %d PWM device%s\n", (char *)s->private,
+		   chip->dev->bus ? chip->dev->bus->name : "no-bus",
+		   dev_name(chip->dev), chip->npwm,
+		   (chip->npwm != 1) ? "s" : "");
+
+	if (chip->ops->dbg_show)
+		chip->ops->dbg_show(chip, s);
+	else
+		pwm_dbg_show(chip, s);
+
+	return 0;
+}
+
+static const struct seq_operations pwm_seq_ops = {
+	.start = pwm_seq_start,
+	.next = pwm_seq_next,
+	.stop = pwm_seq_stop,
+	.show = pwm_seq_show,
+};
+
+static int pwm_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &pwm_seq_ops);
+}
+
+static const struct file_operations pwm_debugfs_ops = {
+	.owner = THIS_MODULE,
+	.open = pwm_seq_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+static int __init pwm_debugfs_init(void)
+{
+	debugfs_create_file("pwm", S_IFREG | S_IRUGO, NULL, NULL,
+			    &pwm_debugfs_ops);
+
+	return 0;
+}
+
+subsys_initcall(pwm_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
include/linux/pwm.h +6 -0
index 5710391..047cd53 100644
@@ -2,6 +2,7 @@
 #define __LINUX_PWM_H
 
 struct pwm_device;
+struct seq_file;
 
 /*
  * pwm_request - request a PWM device
@@ -65,6 +66,7 @@ static inline unsigned int pwm_get_period(struct pwm_device *pwm)
  * @config: configure duty cycles and period length for this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
+ * @dbg_show: optional routine to show contents in debugfs
  * @owner: helps prevent removal of modules exporting active PWMs
  */
 struct pwm_ops {
@@ -79,6 +81,10 @@ struct pwm_ops {
 					  struct pwm_device *pwm);
 	void			(*disable)(struct pwm_chip *chip,
 					   struct pwm_device *pwm);
+#ifdef CONFIG_DEBUG_FS
+	void			(*dbg_show)(struct pwm_chip *chip,
+					    struct seq_file *s);
+#endif
 	struct module		*owner;
 };
 
Signature · 1 line
1.7.9.4
#9 lore raw

PATCH v5 3/16 pwm: Add debugfs interface

Quoted 3 lines · Thierry Reding

This commit adds a debugfs interface that can be used to list the current internal state of the PWM devices registered with the PWM framework.

I'm not sure I don't find the style with a file per chip more managable,
but I think that's mostly a thing for GPIOs since you get so many of
them in most systems that the file gets large which isn't such an issue
with pwms, you tend to get much fewer of them. It's certainly a matter
of taste anyway.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120329/016d21b4/attachment.sig>

#11 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

In reply to Thierry Reding

In order to get rid of the global namespace for PWM devices, this commit provides an alternative method, similar to that of the regulator or clock frameworks, for registering a static mapping for PWM devices. This works by providing a table with a provider/consumer map in the board setup code.

With the new pwm_get() and pwm_put() functions available, usage of pwm_request() and pwm_free() becomes deprecated.

---
Changes in v5:
- new patch with table-based lookup for statically registered devices
- update Documentation/pwm.txt

 Documentation/pwm.txt |   27 +++++++--
 drivers/pwm/core.c    |  152 ++++++++++++++++++++++++++++++++++++++++++++-----
 include/linux/pwm.h   |   20 +++++++
 3 files changed, 180 insertions(+), 19 deletions(-)
Documentation/pwm.txt +23 -4
index 48f598a..bb3d2f9 100644
@@ -12,14 +12,33 @@ this kind of flexibility the generic PWM API exists.
 Identifying PWMs
 ----------------
 
-Users of the legacy PWM API use unique IDs to refer to PWM devices. One
-goal of the new PWM framework is to get rid of this global namespace.
+Users of the legacy PWM API use unique IDs to refer to PWM devices.
+
+Instead of referring to a PWM device via its unique ID, board setup code
+should instead register a static mapping that can be used to match PWM
+consumers to providers, as given in the following example:
+
+	static struct pwm_lookup board_pwm_lookup[] = {
+		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight"),
+	};
+
+	static void __init board_init(void)
+	{
+		...
+		pwm_add_table(board_pwm_lookup, ARRAY_SIZE(board_pwm_lookup));
+		...
+	}
 
 Using PWMs
 ----------
 
-A PWM can be requested using pwm_request() and freed after usage with
-pwm_free(). After being requested a PWM has to be configured using
+Legacy users can request a PWM device using pwm_request() and free it
+after usage with pwm_free().
+
+New users should use the pwm_get() function and pass to it the consumer
+device or a consumer name. pwm_put() is used to free the PWM device.
+
+After being requested a PWM has to be configured using:
 
 int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
 
drivers/pwm/core.c +137 -15

185 lines not on this page · raw message

include/linux/pwm.h +20 -0
index 047cd53..a32d2b7 100644
@@ -115,6 +115,26 @@ int pwmchip_remove(struct pwm_chip *chip);
 struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
 					 unsigned int index,
 					 const char *label);
+
+struct pwm_device *pwm_get(struct device *dev, const char *consumer);
+void pwm_put(struct pwm_device *pwm);
+
+struct pwm_lookup {
+	struct list_head list;
+	const char *provider;
+	unsigned int index;
+	const char *consumer;
+};
+
+#define PWM_LOOKUP(_provider, _index, _consumer)	\
+	{						\
+		.provider = _provider,			\
+		.index = _index,			\
+		.consumer = _consumer,			\
+	}
+
+void pwm_add_table(struct pwm_lookup *table, size_t num);
+
 #endif
 
 #endif /* __LINUX_PWM_H */
Signature · 1 line
1.7.9.4
#12 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Documentation/pwm.txt this kind of flexibility the generic PWM API exists. · line 23

Quoted 3 lines · Thierry Reding
Documentation/pwm.txt +3 -0
+	static struct pwm_lookup board_pwm_lookup[] = {
+		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight"),
+	};

The clock and regulator APIs namespace the consumers by struct device - might this not be sensible here? pwm_get() does already take the device as an argument. It'd feel safer, and for example there's plenty of phones out there with two backlit displays...

Quoted 4 lines

+ * pwm_get() - look up and request a PWM device
+ * @dev: device for PWM consumer
+ * @provider: name of provider PWM chip
+ * @index: per-chip index of PWM to request

The documentation is out of sync with the signature.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120329/afdf521d/attachment.sig>

#13 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Quoted 10 lines · Mark Brown

Documentation/pwm.txt this kind of flexibility the generic PWM API exists. · line 23

Quoted 3 lines · Thierry Reding
Documentation/pwm.txt +3 -0
+	static struct pwm_lookup board_pwm_lookup[] = {
+		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight"),
+	};

The clock and regulator APIs namespace the consumers by struct device - might this not be sensible here? pwm_get() does already take the device as an argument. It'd feel safer, and for example there's plenty of phones out there with two backlit displays...

That's actually how this is supposed to work. "pwm-backlight" in the above case is matched against the name of the struct device that you pass in to pwm_get(). The only difference, at least as far as I can tell, to the clock and regulator APIs is that a second name is not listed explicitly in the lookup table.

So compared with the clock and regulator APIs it doesn't make too much sense to pass both the struct device and the name to pwm_get() because it will match the device name against the consumer name in the lookup table first and only use the passed name if no match was found.

In case you have two backlight devices I would expect the following to work:

	static struct pwm_lookup board_pwm_lookup[] = {
		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight.0"),
		PWM_LOOKUP("tegra-pwm", 1, "pwm-backlight.1"),
	};
Quoted 7 lines
Quoted 5 lines

+ * pwm_get() - look up and request a PWM device
+ * @dev: device for PWM consumer
+ * @provider: name of provider PWM chip
+ * @index: per-chip index of PWM to request

The documentation is out of sync with the signature.

Indeed. Thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120330/edbfb298/attachment.sig>

#14 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Quoted 7 lines · Thierry Reding
Quoted 4 lines · Mark Brown

The clock and regulator APIs namespace the consumers by struct device - might this not be sensible here? pwm_get() does already take the device as an argument. It'd feel safer, and for example there's plenty of phones out there with two backlit displays...

Quoted 5 lines

That's actually how this is supposed to work. "pwm-backlight" in the above case is matched against the name of the struct device that you pass in to pwm_get(). The only difference, at least as far as I can tell, to the clock and regulator APIs is that a second name is not listed explicitly in the lookup table.

Both clock and regulator APIs map (source) -> (dev, name). This only has a mapping (source) -> (dev).

Quoted 4 lines

So compared with the clock and regulator APIs it doesn't make too much sense to pass both the struct device and the name to pwm_get() because it will match the device name against the consumer name in the lookup table first and only use the passed name if no match was found.

This is different to what the clock and regulator APIs do - they look up the name in the context of the struct device. This is because...

Quoted 6 lines

In case you have two backlight devices I would expect the following to work:

	static struct pwm_lookup board_pwm_lookup[] = {
		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight.0"),
		PWM_LOOKUP("tegra-pwm", 1, "pwm-backlight.1"),
	};

...if a single device uses more than one PWM then the above scheme won't
work - unless I'm missing something?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120330/eceb80cf/attachment.sig>

#15 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Quoted 27 lines · Mark Brown
Quoted 7 lines · Thierry Reding
Quoted 4 lines · Mark Brown

The clock and regulator APIs namespace the consumers by struct device - might this not be sensible here? pwm_get() does already take the device as an argument. It'd feel safer, and for example there's plenty of phones out there with two backlit displays...

Quoted 5 lines

That's actually how this is supposed to work. "pwm-backlight" in the above case is matched against the name of the struct device that you pass in to pwm_get(). The only difference, at least as far as I can tell, to the clock and regulator APIs is that a second name is not listed explicitly in the lookup table.

Both clock and regulator APIs map (source) -> (dev, name). This only has a mapping (source) -> (dev).

Quoted 4 lines

So compared with the clock and regulator APIs it doesn't make too much sense to pass both the struct device and the name to pwm_get() because it will match the device name against the consumer name in the lookup table first and only use the passed name if no match was found.

This is different to what the clock and regulator APIs do - they look up the name in the context of the struct device. This is because...

Quoted 1 line

In case you have two backlight devices I would expect the following to work:

Quoted 7 lines
Quoted 4 lines
	static struct pwm_lookup board_pwm_lookup[] = {
		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight.0"),
		PWM_LOOKUP("tegra-pwm", 1, "pwm-backlight.1"),
	};

...if a single device uses more than one PWM then the above scheme won't work - unless I'm missing something?

Right, now it makes more sense. So basically if I have a single device using two PWM devices, then I'll need to have something like this:

	static struct pwm_lookup board_pwm_lookup[] = {
		PWM_LOOKUP("tegra-pwm", 0, "pwm-foo.0", "bar"),
		PWM_LOOKUP("tegra-pwm", 1, "pwm-foo.0", "baz"),
	};

And then of course I'll need to have a second field by which the PWM device can be identified. Good, I'll fix that up for the next round.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120330/c9e19b10/attachment.sig>

#16 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Quoted 39 lines · Thierry Reding
Quoted 27 lines · Mark Brown
Quoted 7 lines · Thierry Reding
Quoted 4 lines · Mark Brown

The clock and regulator APIs namespace the consumers by struct device - might this not be sensible here? pwm_get() does already take the device as an argument. It'd feel safer, and for example there's plenty of phones out there with two backlit displays...

Quoted 5 lines

That's actually how this is supposed to work. "pwm-backlight" in the above case is matched against the name of the struct device that you pass in to pwm_get(). The only difference, at least as far as I can tell, to the clock and regulator APIs is that a second name is not listed explicitly in the lookup table.

Both clock and regulator APIs map (source) -> (dev, name). This only has a mapping (source) -> (dev).

Quoted 4 lines

So compared with the clock and regulator APIs it doesn't make too much sense to pass both the struct device and the name to pwm_get() because it will match the device name against the consumer name in the lookup table first and only use the passed name if no match was found.

This is different to what the clock and regulator APIs do - they look up the name in the context of the struct device. This is because...

Quoted 1 line

In case you have two backlight devices I would expect the following to work:

Quoted 7 lines
Quoted 4 lines
	static struct pwm_lookup board_pwm_lookup[] = {
		PWM_LOOKUP("tegra-pwm", 0, "pwm-backlight.0"),
		PWM_LOOKUP("tegra-pwm", 1, "pwm-backlight.1"),
	};

...if a single device uses more than one PWM then the above scheme won't work - unless I'm missing something?

Right, now it makes more sense. So basically if I have a single device using two PWM devices, then I'll need to have something like this:

Quoted 7 lines
	static struct pwm_lookup board_pwm_lookup[] = {
		PWM_LOOKUP("tegra-pwm", 0, "pwm-foo.0", "bar"),
		PWM_LOOKUP("tegra-pwm", 1, "pwm-foo.0", "baz"),
	};

And then of course I'll need to have a second field by which the PWM device can be identified. Good, I'll fix that up for the next round.

I've been thinking about this some more, and I can see this becoming a little problem with the DT bindings because the unified pwm_get() always requests the first PWM specified in the "pwms" property.

The best solution that I could come up with is to not pass the index into the of_pwm_request() function but rather forward the consumer name as passed into pwm_get(). The of_pwm_request() could use the "pwm-names" property to do a reverse lookup of the index and request that. One good thing about that would be that I no longer need to export the of_pwm_request() function. The "bad" thing is that it'll make the "pwm-names" property mandatory if more than a single PWM is requested.

Does that sound reasonable?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120331/c7eebdaf/attachment.sig>

#17 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

On Sat, Mar 31, 2012 at 04:30:21PM +0200, Thierry Reding wrote:
...

Quoted 5 lines

The best solution that I could come up with is to not pass the index into the of_pwm_request() function but rather forward the consumer name as passed into pwm_get(). The of_pwm_request() could use the "pwm-names" property to do a reverse lookup of the index and request that. One good thing about that would be that I no longer need to export the of_pwm_request() function.

I never understand why of_pwm_request() needs to be exported anyway. pwm_get() should be the only interface to pwm new/DT users, IMO.

Quoted 4 lines

The "bad"
thing is that it'll make the "pwm-names" property mandatory if more than a single PWM is requested.

You do not have to make it mandatory, but anyone requesting any pwm other than the first on in "pwms" list should fail.

Quoted 2 lines

Does that sound reasonable?

The above is exactly what clock DT does, so it sounds reasonable to me.

And I would expect the next version can just turn the second parameter of pwm_get() into the one that will be used to identify the pwm device rather than adding one more parameter. Then we have pwm API well aligned with clk and regulator.

Signature · 2 lines
Regards,
Shawn
#18 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Quoted 1 line · Shawn Guo

On Sat, Mar 31, 2012 at 04:30:21PM +0200, Thierry Reding wrote:

...

Quoted 7 lines
Quoted 4 lines

The "bad"
thing is that it'll make the "pwm-names" property mandatory if more than a single PWM is requested.

You do not have to make it mandatory, but anyone requesting any pwm other than the first on in "pwms" list should fail.

I should have put it this way. If a client device does not have "pwm-names" property in its node, it should fail when requesting pwm with a name. And if no name is given, the first pwm device in the "pwms" list could just be returned.

Signature · 2 lines
Regards,
Shawn
#19 lore raw

PATCH v5 4/16 pwm: Add table-based lookup for static mappings

Quoted 7 lines · Shawn Guo
Quoted 1 line · Shawn Guo

On Sat, Mar 31, 2012 at 04:30:21PM +0200, Thierry Reding wrote:

...

Quoted 4 lines
Quoted 4 lines

The "bad"
thing is that it'll make the "pwm-names" property mandatory if more than a single PWM is requested.

Quoted 7 lines
Quoted 3 lines

You do not have to make it mandatory, but anyone requesting any pwm other than the first on in "pwms" list should fail.

I should have put it this way. If a client device does not have "pwm-names" property in its node, it should fail when requesting pwm with a name. And if no name is given, the first pwm device in the "pwms" list could just be returned.

Yes, that's how I understood it. =)

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120402/b14048f2/attachment.sig>

#20 lore raw

PATCH v5 5/16 pwm: Add device tree support

In reply to Thierry Reding

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

---
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 |   53 ++++++++++
 drivers/pwm/core.c                            |  135 ++++++++++++++++++++++++-
 include/linux/of_pwm.h                        |   34 +++++++
 include/linux/pwm.h                           |    6 ++
 4 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm.txt
 create mode 100644 include/linux/of_pwm.h
Documentation/devicetree/bindings/pwm/pwm.txt new file +53 -0
new file mode 100644
index 0000000..bf2addc
@@ -0,0 +1,53 @@
+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.
+
+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>;
+	};
drivers/pwm/core.c +133 -2

177 lines not on this page · raw message

include/linux/of_pwm.h new file +34 -0
new file mode 100644
index 0000000..8c4ed9f
@@ -0,0 +1,34 @@
+/*
+ * OF helpers for the PWM API
+ *
+ * Copyright (c) 2011-2012 Avionic Design GmbH
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __LINUX_OF_PWM_H
+#define __LINUX_OF_PWM_H
+
+#include <linux/err.h>
+#include <linux/pwm.h>
+
+struct device_node;
+
+#ifdef CONFIG_OF
+
+struct pwm_device *of_pwm_request(struct device_node *np, int index);
+
+#else
+
+static inline struct pwm_device *of_pwm_request(struct device_node *np,
+						int index)
+{
+	return ERR_PTR(-ENOSYS);
+}
+
+#endif /* CONFIG_OF */
+
+#endif /* __LINUX_OF_PWM_H */
include/linux/pwm.h +6 -0
index a32d2b7..e19c92a 100644
@@ -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);
Signature · 1 line
1.7.9.4
#22 lore raw

PATCH v5 5/16 pwm: Add device tree support

In reply to Thierry Reding
Quoted 5 lines · Thierry Reding
Documentation/devicetree/bindings/pwm/pwm.txt new file +5 -0
+	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)

Documentation/devicetree/bindings/pwm/pwm.txt

Quoted 10 lines
Documentation/devicetree/bindings/pwm/pwm.txt new file +8 -0
 
+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.
 
+	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
+	if (IS_ERR(pwm))
+		return ERR_PTR(-ENODEV);

It feels wrong to override the error code like this rather than passing
the error we got back to the caller. Is there any great reason for
doing so?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120329/68e27476/attachment.sig>

#23 lore raw

PATCH v5 5/16 pwm: Add device tree support

Quoted 8 lines · Mark Brown

drivers/pwm/core.c static int pwm_device_request(struct pwm_device *pwm, const char *label) · line 146

Quoted 3 lines · Thierry Reding
drivers/pwm/core.c +3 -0
+	pwm = pwm_request_from_chip(pc, args->args[0], NULL);
+	if (IS_ERR(pwm))
+		return ERR_PTR(-ENODEV);

It feels wrong to override the error code like this rather than passing the error we got back to the caller. Is there any great reason for doing so?

Yes, this certainly looks wrong. I must have forgotten to fix this up when of_pwm_simple_xlate() was converted to return a struct pwm_device instead of an int. Previous to that pwm_request_from_chip() would return NULL and -ENODEV seemed like the proper error code for that situation.

I'll change this to just return pwm.

Thanks,
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120330/162206ae/attachment.sig>

#24 lore raw

PATCH v5 6/16 ARM: tegra: Fix PWM clock programming

In reply to Thierry Reding

From: Simon Que <[email protected]>

PWM clock source registers in Tegra 2 have different clock source selection bit fields than other registers. PWM clock source bits in CLK_SOURCE_PWM_0 register are located at bit field bit[30:28] while others are at bit field bit[31:30] in their respective clock source register.

This patch updates the clock programming to correctly reflect that, by adding a flag to indicate the alternate bit field format and checking for it when selecting a clock source (parent clock).

---
Changes in v4:
- reuse PWM flag from Tegra 30 clock programming
- mask out bit 31 explicitly

 arch/arm/mach-tegra/tegra2_clocks.c |   32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)
arch/arm/mach-tegra/tegra2_clocks.c +28 -4
index 592a4ee..64735bd 100644
@@ -69,6 +69,8 @@
 
 #define PERIPH_CLK_SOURCE_MASK		(3<<30)
 #define PERIPH_CLK_SOURCE_SHIFT		30
+#define PERIPH_CLK_SOURCE_PWM_MASK	(7<<28)
+#define PERIPH_CLK_SOURCE_PWM_SHIFT	28
 #define PERIPH_CLK_SOURCE_ENABLE	(1<<28)
 #define PERIPH_CLK_SOURCE_DIVU71_MASK	0xFF
 #define PERIPH_CLK_SOURCE_DIVU16_MASK	0xFFFF
@@ -908,9 +910,20 @@ static void tegra2_periph_clk_init(struct clk *c)
 	u32 val = clk_readl(c->reg);
 	const struct clk_mux_sel *mux = NULL;
 	const struct clk_mux_sel *sel;
+	u32 shift;
+	u32 mask;
+
+	if (c->flags & MUX_PWM) {
+		shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
+		mask = PERIPH_CLK_SOURCE_PWM_MASK;
+	} else {
+		shift = PERIPH_CLK_SOURCE_SHIFT;
+		mask = PERIPH_CLK_SOURCE_MASK;
+	}
+
 	if (c->flags & MUX) {
 		for (sel = c->inputs; sel->input != NULL; sel++) {
-			if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
+			if ((val & mask) >> shift == sel->value)
 				mux = sel;
 		}
 		BUG_ON(!mux);
@@ -1023,12 +1036,23 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
 {
 	u32 val;
 	const struct clk_mux_sel *sel;
+	u32 mask, shift;
+
 	pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+	if (c->flags & MUX_PWM) {
+		shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
+		mask = PERIPH_CLK_SOURCE_PWM_MASK;
+	} else {
+		shift = PERIPH_CLK_SOURCE_SHIFT;
+		mask = PERIPH_CLK_SOURCE_MASK;
+	}
+
 	for (sel = c->inputs; sel->input != NULL; sel++) {
 		if (sel->input == p) {
 			val = clk_readl(c->reg);
-			val &= ~PERIPH_CLK_SOURCE_MASK;
-			val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
+			val &= ~mask;
+			val |= (sel->value) << shift;
 
 			if (c->refcnt)
 				clk_enable(p);
@@ -2146,7 +2170,7 @@ static struct clk tegra_list_clks[] = {
 	PERIPH_CLK("i2s2",	"tegra-i2s.1",		NULL,	18,	0x104,	26000000,  mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("spdif_out",	"spdif_out",		NULL,	10,	0x108,	100000000, mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("spdif_in",	"spdif_in",		NULL,	10,	0x10c,	100000000, mux_pllp_pllc_pllm,		MUX | DIV_U71),
-	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_audio_clkm_clk32,	MUX | DIV_U71),
+	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_audio_clkm_clk32,	MUX | DIV_U71 | MUX_PWM),
 	PERIPH_CLK("spi",	"spi",			NULL,	43,	0x114,	40000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("xio",	"xio",			NULL,	45,	0x120,	150000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("twc",	"twc",			NULL,	16,	0x12c,	150000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
Signature · 1 line
1.7.9.4
#25 lore raw

PATCH v5 7/16 ARM: tegra: Provide clock for only one PWM controller

In reply to Thierry Reding

A subsequent patch will add a generic PWM API driver for the Tegra PWFM controller, supporting all four PWM devices with a single PWM chip. The device will be named tegra-pwm and only one clock needs to be provided.

---
Changes in v5:
- rename the device name to "tegra-pwm" in the clock lookup table
- get rid of all CLK_DUPLICATE entries which are no longer needed

 arch/arm/mach-tegra/tegra2_clocks.c  |    6 +-----
 arch/arm/mach-tegra/tegra30_clocks.c |    6 +-----
 2 files changed, 2 insertions(+), 10 deletions(-)
arch/arm/mach-tegra/tegra2_clocks.c +1 -5
index 64735bd..c95a878 100644
@@ -2170,7 +2170,7 @@ static struct clk tegra_list_clks[] = {
 	PERIPH_CLK("i2s2",	"tegra-i2s.1",		NULL,	18,	0x104,	26000000,  mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("spdif_out",	"spdif_out",		NULL,	10,	0x108,	100000000, mux_pllaout0_audio2x_pllp_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("spdif_in",	"spdif_in",		NULL,	10,	0x10c,	100000000, mux_pllp_pllc_pllm,		MUX | DIV_U71),
-	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_audio_clkm_clk32,	MUX | DIV_U71 | MUX_PWM),
+	PERIPH_CLK("pwm",	"tegra-pwm",		NULL,	17,	0x110,	432000000, mux_pllp_pllc_audio_clkm_clk32,	MUX | DIV_U71 | MUX_PWM),
 	PERIPH_CLK("spi",	"spi",			NULL,	43,	0x114,	40000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("xio",	"xio",			NULL,	45,	0x120,	150000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("twc",	"twc",			NULL,	16,	0x12c,	150000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
@@ -2269,10 +2269,6 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
 	CLK_DUPLICATE("usbd", "tegra-otg", NULL),
 	CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
 	CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
-	CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
-	CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
-	CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
-	CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
 	CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"),
 	CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
 	CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
arch/arm/mach-tegra/tegra30_clocks.c +1 -5
index 6d08b53..18afd0c 100644
@@ -2886,7 +2886,7 @@ struct clk tegra_list_clks[] = {
 	PERIPH_CLK("i2s4",	"tegra30-i2s.4",	NULL,	102,	0x3c0,	26000000,  mux_pllaout0_audio4_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
 	PERIPH_CLK("spdif_out",	"tegra30-spdif",	"spdif_out",	10,	0x108,	100000000, mux_pllaout0_audio_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
 	PERIPH_CLK("spdif_in",	"tegra30-spdif",	"spdif_in",	10,	0x10c,	100000000, mux_pllp_pllc_pllm,		MUX | DIV_U71 | PERIPH_ON_APB),
-	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_clk32_clkm,	MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("pwm",	"tegra-pwm",		NULL,	17,	0x110,	432000000, mux_pllp_pllc_clk32_clkm,	MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
 	PERIPH_CLK("d_audio",	"tegra30-ahub",		"d_audio", 106,	0x3d0,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("dam0",	"tegra30-dam.0",	NULL,   108,	0x3d8,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
 	PERIPH_CLK("dam1",	"tegra30-dam.1",	NULL,   109,	0x3dc,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
@@ -2990,10 +2990,6 @@ struct clk_duplicate tegra_clk_duplicates[] = {
 	CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
 	CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
 	CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
-	CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
-	CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
-	CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
-	CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
 	CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
 	CLK_DUPLICATE("bsev", "nvavp", "bsev"),
 	CLK_DUPLICATE("vde", "tegra-aes", "vde"),
Signature · 1 line
1.7.9.4
#26 lore raw

PATCH v5 8/16 pwm: Add NVIDIA Tegra SoC support

In reply to Thierry Reding

This commit adds a generic PWM framework driver for the PWFM controller found on NVIDIA Tegra SoCs. The driver is based on code from the Chromium kernel tree and was originally written by Gary King (NVIDIA) and later modified by Simon Que (Chromium).

---
Changes in v5:
- use devm_request_and_ioremap()
- use clk_prepare_enable() and clk_disable_unprepare()
- call pwmchip_remove() after disabling PWM devices
- remove tegra_pwm_chip.enable[] field and use the PWM flags instead
- use pwm_readl()/pwm_writel() for register accesses and split out clock management to where it's needed
- add MODULE_ALIAS to enable automatic module loading

Changes in v4:
- merge patch from ChromiumOS kernel to fix a rounding issue
- move DT code to patch 7

Changes in v3:
- use pwm_device.hwpwm instead of recomputing it
- update pwm_ops for changes in patch 2

Changes in v2:
- set pwm_chip.dev field
- rename clk_enb to enable
- introduce NUM_PWM macro instead of hard-coding the number of PWM devices
- update comment in tegra_pwm_config
- fix coding-style for multi-line comments
- use module_platform_driver
- change license to GPL

 drivers/pwm/Kconfig     |   10 ++
 drivers/pwm/Makefile    |    1 +
 drivers/pwm/pwm-tegra.c |  254 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/pwm/pwm-tegra.c
drivers/pwm/Kconfig +10 -0
index 93c1052..bda6f23 100644
@@ -9,4 +9,14 @@ menuconfig PWM
 
 if PWM
 
+config PWM_TEGRA
+	tristate "NVIDIA Tegra PWM support"
+	depends on ARCH_TEGRA
+	help
+	  Generic PWM framework driver for the PWFM controller found on NVIDIA
+	  Tegra SoCs.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-tegra.
+
 endif
drivers/pwm/Makefile +1 -0
index 3469c3d..12300f5 100644
@@ -1 +1,2 @@
 obj-$(CONFIG_PWM)		+= core.o
+obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
drivers/pwm/pwm-tegra.c new file +254 -0

254 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#27 lore raw

PATCH v5 8/16 pwm: Add NVIDIA Tegra SoC support

Quoted 6 lines · Thierry Reding

This commit adds a generic PWM framework driver for the PWFM controller found on NVIDIA Tegra SoCs. The driver is based on code from the Chromium kernel tree and was originally written by Gary King (NVIDIA) and later modified by Simon Que (Chromium).

#28 lore raw

PATCH v5 8/16 pwm: Add NVIDIA Tegra SoC support

In reply to Thierry Reding

On Wed, Mar 28, 2012 at 04:33:50PM +0200, Thierry Reding wrote:
...

Quoted 1 line

+static struct pwm_ops tegra_pwm_ops = {

const

Quoted 20 lines
drivers/pwm/pwm-tegra.c new file +20 -0
+	.config = tegra_pwm_config,
+	.enable = tegra_pwm_enable,
+	.disable = tegra_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static int tegra_pwm_probe(struct platform_device *pdev)
+{
+	struct tegra_pwm_chip *pwm;
+	struct resource *r;
+	int ret;
+
+	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	pwm->dev = &pdev->dev;
+

drivers/pwm/pwm-tegra.c line 192

Quoted 10 lines
drivers/pwm/pwm-tegra.c new file +10 -0
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		dev_err(&pdev->dev, "no memory resources defined\n");
+		return -ENODEV;
+	}
+
+	pwm->mmio_base = devm_request_and_ioremap(&pdev->dev, r);
+	if (!pwm->mmio_base) {
+		dev_err(&pdev->dev, "failed to ioremap() region\n");
+		return -ENODEV;

The kernel doc of devm_request_and_ioremap() suggests -EADDRNOTAVAIL.

Quoted 2 lines
(quoted diff) +2 -0
+	}
+
Signature · 2 lines
Regards,
Shawn
#29 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

In reply to Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

---
Changes in v5:
- rename tegra-pwm.txt to nvidia,tegra20-pwm.txt

Changes in v4:
- add DT binding documentation
- allow nvidia,tegra20-pwm as fallback for nvidia,tegra30-pwm
- export OF device table (for module auto-loading)

Changes in v3:
- add missing include for mach/iomap.h

 .../devicetree/bindings/pwm/nvidia,tegra20-pwm.txt |   18 ++++++++++++++++++
 arch/arm/boot/dts/tegra20.dtsi                     |    6 ++++++
 arch/arm/boot/dts/tegra30.dtsi                     |    6 ++++++
 arch/arm/mach-tegra/board-dt-tegra20.c             |    1 +
 arch/arm/mach-tegra/board-dt-tegra30.c             |    3 +++
 drivers/pwm/pwm-tegra.c                            |   11 +++++++++++
 6 files changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt new file +18 -0
new file mode 100644
index 0000000..bbbeedb
@@ -0,0 +1,18 @@
+Tegra SoC PWFM controller
+
+Required properties:
+- compatible: should be one of:
+  - "nvidia,tegra20-pwm"
+  - "nvidia,tegra30-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: On Tegra the number of cells used to specify a PWM is 2. The
+  first cell specifies the per-chip index of the PWM to use and the second
+  cell is the duty cycle in nanoseconds.
+
+Example:
+
+	pwm: pwm at 7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
arch/arm/boot/dts/tegra20.dtsi +6 -0
index 108e894..55b28fd 100644
@@ -154,6 +154,12 @@
 		interrupts = < 0 91 0x04 >;
 	};
 
+	pwm: pwm at 7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
+
 	emc at 7000f400 {
 		#address-cells = <1>;
 		#size-cells = <0>;
arch/arm/boot/dts/tegra30.dtsi +6 -0
index 62a7b39..3fa5211 100644
@@ -154,6 +154,12 @@
 		interrupts = < 0 91 0x04 >;
 	};
 
+	pwm: pwm at 7000a000 {
+		compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
+
 	sdhci at 78000000 {
 		compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
 		reg = <0x78000000 0x200>;
arch/arm/mach-tegra/board-dt-tegra20.c +1 -0
index e20b419..2180954 100644
@@ -73,6 +73,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
 		       &tegra_ehci2_device.dev.platform_data),
 	OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2",
 		       &tegra_ehci3_device.dev.platform_data),
+	OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
 	{}
 };
 
arch/arm/mach-tegra/board-dt-tegra30.c +3 -0
index 5f7c03e..5e1180f 100644
@@ -33,6 +33,8 @@
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
 
+#include <mach/iomap.h>
+
 #include "board.h"
 #include "clock.h"
 
@@ -51,6 +53,7 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
 	{}
 };
 
drivers/pwm/pwm-tegra.c +11 -0
index 2219be1..981f28a 100644
@@ -239,9 +239,20 @@ static int __devexit tegra_pwm_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
+#endif
+
 static struct platform_driver tegra_pwm_driver = {
 	.driver = {
 		.name = "tegra-pwm",
+		.of_match_table = of_match_ptr(tegra_pwm_of_match),
 	},
 	.probe = tegra_pwm_probe,
 	.remove = __devexit_p(tegra_pwm_remove),
Signature · 1 line
1.7.9.4
#30 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

#31 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 10 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

Quoted 8 lines

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120402/066b6c5d/attachment.sig>

#32 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 20 lines · Thierry Reding
Quoted 10 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

Quoted 8 lines

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

#33 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 21 lines · Stephen Warren
Quoted 20 lines · Thierry Reding
Quoted 18 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 6 lines
Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

It certainly is counter-intuitive. Maybe Grant or Rob can comment?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120403/ecd4b896/attachment.sig>

#34 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 22 lines · Thierry Reding
Quoted 21 lines · Stephen Warren
Quoted 20 lines · Thierry Reding
Quoted 18 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

It certainly is counter-intuitive. Maybe Grant or Rob can comment?

I think the rule should be the match list is most specific to least specific and/or mutually exclusive like compatible strings. Most examples with multiple entries in the kernel seem to fall into the mutually exclusive case.

For this case, I think would just drop tegra30-pwm altogether and only add it to the driver when you need to distinguish between the 2. The dts should have both though for Tegra3.

Rob

#35 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

In reply to Thierry Reding
Quoted 22 lines · Thierry Reding
Quoted 21 lines · Stephen Warren
Quoted 20 lines · Thierry Reding
Quoted 18 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

It certainly is counter-intuitive. Maybe Grant or Rob can comment?

Yes, it is a bug. The order of of_device_id should be entirely irrelevant, and the order in the DT compatible property should determine which match entry is returned.

g.

#36 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 30 lines · Grant Likely
Quoted 29 lines · Thierry Reding
Quoted 27 lines · Stephen Warren
Quoted 20 lines · Thierry Reding
Quoted 10 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

Quoted 8 lines

drivers/pwm/pwm-tegra.c static int __devexit tegra_pwm_remove(struct platform_device *pdev) · line 245

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

Quoted 5 lines
Quoted 1 line

It certainly is counter-intuitive. Maybe Grant or Rob can comment?

Yes, it is a bug. The order of of_device_id should be entirely irrelevant, and the order in the DT compatible property should determine which match entry is returned.

I've had a look at the code and it looks like a fix will not be entirely trivial. I think moving out the compatible check out of the while loop in of_match_node() and separately iterate over all strings in the compatible property would be the easiest. That will also prioritize the compatible match over matches by name and type but I think that's exactly what we want. From a quick look it certainly seems like the large majority of drivers match by compatible anyway.

Do you want me to prepare a patch or can you take care of it?

Stephen: Can I assume that you're fine with this Tegra PWM patch if such a change to the matching function is committed?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120404/3379f66c/attachment-0001.sig>

#37 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 45 lines · Thierry Reding
Quoted 30 lines · Grant Likely
Quoted 29 lines · Thierry Reding
Quoted 27 lines · Stephen Warren
Quoted 20 lines · Thierry Reding
Quoted 10 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

Quoted 8 lines

drivers/pwm/pwm-tegra.c

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

Quoted 5 lines
Quoted 1 line

It certainly is counter-intuitive. Maybe Grant or Rob can comment?

Yes, it is a bug. The order of of_device_id should be entirely irrelevant, and the order in the DT compatible property should determine which match entry is returned.

I've had a look at the code and it looks like a fix will not be entirely trivial. I think moving out the compatible check out of the while loop in of_match_node() and separately iterate over all strings in the compatible property would be the easiest. That will also prioritize the compatible match over matches by name and type but I think that's exactly what we want. From a quick look it certainly seems like the large majority of drivers match by compatible anyway.

Quoted 4 lines

Do you want me to prepare a patch or can you take care of it?

Stephen: Can I assume that you're fine with this Tegra PWM patch if such a change to the matching function is committed?

Yes.

#38 lore raw

PATCH v5 9/16 pwm: tegra: Add device tree support

Quoted 46 lines · Stephen Warren
Quoted 45 lines · Thierry Reding
Quoted 30 lines · Grant Likely
Quoted 29 lines · Thierry Reding
Quoted 27 lines · Stephen Warren
Quoted 20 lines · Thierry Reding
Quoted 10 lines · Stephen Warren
Quoted 8 lines · Thierry Reding

Add auxdata to instantiate the PWFM controller from a device tree, include the corresponding nodes in the dtsi files for Tegra 20 and Tegra 30 and add binding documentation.

drivers/pwm/pwm-tegra.c +0 -0

...

Quoted 8 lines

drivers/pwm/pwm-tegra.c

Quoted 4 lines
drivers/pwm/pwm-tegra.c +4 -0
+#ifdef CONFIG_OF
+static struct of_device_id tegra_pwm_of_match[] = {
+	{ .compatible = "nvidia,tegra20-pwm" },
+	{ .compatible = "nvidia,tegra30-pwm" },

Could you swap those two lines, so that tegra30-pwm matches first. It makes no difference at present, but might in the future if the driver actually has to differentiate the two SoCs.

Quoted 2 lines

I thought the matching order was determined by the compatible property in the device tree, not the OF match table of the driver.

At least logically, yes. However, of_match_device() appears to iterate over each match table entry, checking whether it matches any string in the compatible flag. Perhaps this could be considered a bug?

Quoted 5 lines
Quoted 1 line

It certainly is counter-intuitive. Maybe Grant or Rob can comment?

Yes, it is a bug. The order of of_device_id should be entirely irrelevant, and the order in the DT compatible property should determine which match entry is returned.

I've had a look at the code and it looks like a fix will not be entirely trivial. I think moving out the compatible check out of the while loop in of_match_node() and separately iterate over all strings in the compatible property would be the easiest. That will also prioritize the compatible match over matches by name and type but I think that's exactly what we want. From a quick look it certainly seems like the large majority of drivers match by compatible anyway.

Quoted 1 line
Quoted 1 line

Do you want me to prepare a patch or can you take care of it?

yes please.

g.

#39 lore raw

PATCH v5 10/16 pwm: Move Blackfin PWM driver to PWM framework

In reply to Thierry Reding

This commit moves the Blackfin PWM driver to the drivers/pwm sub- directory and converts it to register with the new PWM framework.

---
 arch/blackfin/Kconfig         |   10 ---
 arch/blackfin/kernel/Makefile |    1 -
 arch/blackfin/kernel/pwm.c    |  100 -------------------------
 drivers/pwm/Kconfig           |    9 +++
 drivers/pwm/Makefile          |    1 +
 drivers/pwm/pwm-bfin.c        |  164 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 174 insertions(+), 111 deletions(-)
 delete mode 100644 arch/blackfin/kernel/pwm.c
 create mode 100644 drivers/pwm/pwm-bfin.c
arch/blackfin/Kconfig +0 -10
index c1269a1..e08f39b 100644
@@ -950,16 +950,6 @@ config BFIN_GPTIMERS
 	  To compile this driver as a module, choose M here: the module
 	  will be called gptimers.
 
-config HAVE_PWM
-	tristate "Enable PWM API support"
-	depends on BFIN_GPTIMERS
-	help
-	  Enable support for the Pulse Width Modulation framework (as
-	  found in linux/pwm.h).
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called pwm.
-
 choice
 	prompt "Uncached DMA region"
 	default DMA_UNCACHED_1M
arch/blackfin/kernel/Makefile +0 -1
index 9a0d6d7..00fef32 100644
@@ -21,7 +21,6 @@ obj-$(CONFIG_FUNCTION_TRACER)        += ftrace-entry.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)  += ftrace.o
 CFLAGS_REMOVE_ftrace.o = -pg
 
-obj-$(CONFIG_HAVE_PWM)               += pwm.o
 obj-$(CONFIG_IPIPE)                  += ipipe.o
 obj-$(CONFIG_BFIN_GPTIMERS)          += gptimers.o
 obj-$(CONFIG_CPLB_INFO)              += cplbinfo.o
arch/blackfin/kernel/pwm.c deleted +0 -100

100 lines not on this page · raw message

drivers/pwm/Kconfig +9 -0
index bda6f23..eb54042 100644
@@ -9,6 +9,15 @@ menuconfig PWM
 
 if PWM
 
+config PWM_BFIN
+	tristate "Blackfin PWM support"
+	depends on BFIN_GPTIMERS
+	help
+	  Generic PWM framework driver for Blackfin.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-bfin.
+
 config PWM_TEGRA
 	tristate "NVIDIA Tegra PWM support"
 	depends on ARCH_TEGRA
drivers/pwm/Makefile +1 -0
index 12300f5..251b8d2 100644
@@ -1,2 +1,3 @@
 obj-$(CONFIG_PWM)		+= core.o
+obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
drivers/pwm/pwm-bfin.c new file +164 -0

164 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#40 lore raw

PATCH v5 11/16 pwm: Move PXA PWM driver to PWM framework

In reply to Thierry Reding

This commit moves the PXA PWM driver to the drivers/pwm subdirectory and converts it to use the new PWM framework.

---
Changes in v5:
- replace __raw_readl()/__raw_writel() by readl()/writel()
- use clk_prepare_enable() and clk_disable_unprepare()

Changes in v3:
- update PWM ops for changes in patch 2

 arch/arm/plat-pxa/Makefile                       |    1 -
 drivers/pwm/Kconfig                              |    9 ++
 drivers/pwm/Makefile                             |    1 +
 arch/arm/plat-pxa/pwm.c => drivers/pwm/pwm-pxa.c |  172 ++++++++--------------
 4 files changed, 68 insertions(+), 115 deletions(-)
 rename arch/arm/plat-pxa/pwm.c => drivers/pwm/pwm-pxa.c (57%)
arch/arm/plat-pxa/Makefile +0 -1
index f302d04..af8e484 100644
@@ -8,5 +8,4 @@ obj-$(CONFIG_PXA3xx)		+= mfp.o
 obj-$(CONFIG_PXA95x)		+= mfp.o
 obj-$(CONFIG_ARCH_MMP)		+= mfp.o
 
-obj-$(CONFIG_HAVE_PWM)		+= pwm.o
 obj-$(CONFIG_PXA_SSP)		+= ssp.o
drivers/pwm/Kconfig +9 -0
index eb54042..0ef4f30 100644
@@ -18,6 +18,15 @@ config PWM_BFIN
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-bfin.
 
+config PWM_PXA
+	tristate "PXA PWM support"
+	depends on ARCH_PXA
+	help
+	  Generic PWM framework driver for PXA.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-pxa.
+
 config PWM_TEGRA
 	tristate "NVIDIA Tegra PWM support"
 	depends on ARCH_TEGRA
drivers/pwm/Makefile +1 -0
index 251b8d2..e859c51 100644
@@ -1,3 +1,4 @@
 obj-$(CONFIG_PWM)		+= core.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
+obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
drivers/pwm/pwm-pxa.c renamed from arch/arm/plat-pxa/pwm.c +58 -114

253 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#41 lore raw

PATCH v5 12/16 ARM i.MX: Move i.MX pwm driver to pwm framework

In reply to Thierry Reding

From: Sascha Hauer <[email protected]>

Move the driver to drivers/pwm/ and convert it to use the framework.

---
Changes in v5:
- adopt patch by Sascha Hauer to move i.MX driver to PWM framework
- rename to imx_pwm internally

 arch/arm/plat-mxc/Kconfig                        |    6 -
 arch/arm/plat-mxc/Makefile                       |    1 -
 drivers/pwm/Kconfig                              |    9 ++
 drivers/pwm/Makefile                             |    1 +
 arch/arm/plat-mxc/pwm.c => drivers/pwm/pwm-imx.c |  182 +++++++++-------------
 5 files changed, 81 insertions(+), 118 deletions(-)
 rename arch/arm/plat-mxc/pwm.c => drivers/pwm/pwm-imx.c (58%)
arch/arm/plat-mxc/Kconfig +0 -6
index c722f9c..baf9064 100644
@@ -47,12 +47,6 @@ config MXC_TZIC
 config MXC_AVIC
 	bool
 
-config MXC_PWM
-	tristate "Enable PWM driver"
-	select HAVE_PWM
-	help
-	  Enable support for the i.MX PWM controller(s).
-
 config MXC_DEBUG_BOARD
 	bool "Enable MXC debug board(for 3-stack)"
 	help
arch/arm/plat-mxc/Makefile +0 -1
index e81290c..46ba8de 100644
@@ -11,7 +11,6 @@ obj-$(CONFIG_MXC_AVIC) += avic.o
 obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
 obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
-obj-$(CONFIG_MXC_PWM)  += pwm.o
 obj-$(CONFIG_MXC_ULPI) += ulpi.o
 obj-$(CONFIG_MXC_USE_EPIT) += epit.o
 obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
drivers/pwm/Kconfig +9 -0
index 0ef4f30..a9a9715 100644
@@ -18,6 +18,15 @@ config PWM_BFIN
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-bfin.
 
+config PWM_IMX
+	tristate "i.MX pwm support"
+	depends on ARCH_MXC
+	help
+	  Generic PWM framework driver for i.MX.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-imx.
+
 config PWM_PXA
 	tristate "PXA PWM support"
 	depends on ARCH_PXA
drivers/pwm/Makefile +1 -0
index e859c51..3dd1b83 100644
@@ -1,4 +1,5 @@
 obj-$(CONFIG_PWM)		+= core.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
+obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
drivers/pwm/pwm-imx.c renamed from arch/arm/plat-mxc/pwm.c +71 -111

301 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#42 lore raw

PATCH v5 13/16 ARM Samsung: Move s3c pwm driver to pwm framework

In reply to Thierry Reding

From: Sascha Hauer <[email protected]>

Move the driver to drivers/pwm/ and convert it to use the framework.

---
Changes in v5:
- adopt patch by Sascha Hauer to move s3c driver to PWM framework
- This driver could use some cleanups and rework to actually take advantage of the multiple PWM devices per PWM chip feature. Currently, information about the controlling timers is passed via platform resources but is not used. Perhaps the corresponding information can be passed in a better way via platform data?

 arch/arm/plat-samsung/Makefile                     |    4 -
 drivers/pwm/Kconfig                                |    9 +
 drivers/pwm/Makefile                               |    1 +
 .../pwm.c => drivers/pwm/pwm-samsung.c             |  228 ++++++++------------
 4 files changed, 97 insertions(+), 145 deletions(-)
 rename arch/arm/plat-samsung/pwm.c => drivers/pwm/pwm-samsung.c (58%)
arch/arm/plat-samsung/Makefile +0 -4
index 6012366..f09a7cf 100644
@@ -50,7 +50,3 @@ obj-$(CONFIG_SAMSUNG_WAKEMASK)	+= wakeup-mask.o
 # PD support
 
 obj-$(CONFIG_SAMSUNG_PD)	+= pd.o
-
-# PWM support
-
-obj-$(CONFIG_HAVE_PWM)		+= pwm.o
drivers/pwm/Kconfig +9 -0
index a9a9715..0d9aa92 100644
@@ -36,6 +36,15 @@ config PWM_PXA
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-pxa.
 
+config PWM_SAMSUNG
+	tristate "Samsung pwm support"
+	depends on PLAT_SAMSUNG
+	help
+	  Generic PWM framework driver for Samsung.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-samsung.
+
 config PWM_TEGRA
 	tristate "NVIDIA Tegra PWM support"
 	depends on ARCH_TEGRA
drivers/pwm/Makefile +1 -0
index 3dd1b83..a1d87b1 100644
@@ -2,4 +2,5 @@ obj-$(CONFIG_PWM)		+= core.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
 obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
+obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
drivers/pwm/pwm-samsung.c renamed from arch/arm/plat-samsung/pwm.c +87 -141

413 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#43 lore raw

PATCH v5 14/16 ARM vt8500: Move vt8500 pwm driver to pwm framework

In reply to Thierry Reding

From: Sascha Hauer <[email protected]>

Move the driver to drivers/pwm/ and convert it to use the framework.

---
Changes in v5:
- adopt patch by Sascha Hauer to move vt8500 driver to PWM framework

 arch/arm/mach-vt8500/Makefile                      |    2 -
 drivers/pwm/Kconfig                                |    9 ++
 drivers/pwm/Makefile                               |    1 +
 .../mach-vt8500/pwm.c => drivers/pwm/pwm-vt8500.c  |  169 +++++++-------------
 4 files changed, 66 insertions(+), 115 deletions(-)
 rename arch/arm/mach-vt8500/pwm.c => drivers/pwm/pwm-vt8500.c (52%)
arch/arm/mach-vt8500/Makefile +0 -2
index 81aedb7..8df9e4a 100644
@@ -5,5 +5,3 @@ obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
 
 obj-$(CONFIG_MACH_BV07) += bv07.o
 obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
-
-obj-$(CONFIG_HAVE_PWM) += pwm.o
drivers/pwm/Kconfig +9 -0
index 0d9aa92..a93feff 100644
@@ -55,4 +55,13 @@ config PWM_TEGRA
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-tegra.
 
+config PWM_VT8500
+	tristate "vt8500 pwm support"
+	depends on ARCH_VT8500
+	help
+	  Generic PWM framework driver for vt8500.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-vt8500.
+
 endif
drivers/pwm/Makefile +1 -0
index a1d87b1..b7c0fcf 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
+obj-$(CONFIG_PWM_VT8500)	+= pwm-vt8500.o
drivers/pwm/pwm-vt8500.c renamed from arch/arm/mach-vt8500/pwm.c +56 -113

246 lines not on this page · raw message

Signature · 1 line
1.7.9.4
#44 lore raw

PATCH v5 15/16 pwm-backlight: Add rudimentary device tree support

In reply to Thierry Reding

This commit adds very basic support for device tree probing. Currently, only a PWM and a list of distinct brightness levels can be specified. Enabling or disabling backlight power via GPIOs is not yet supported.

---
Changes in v5:
- use "pwms" fixed property name
- document brightness-levels and default-brightness-level properties
- check default-brightness-level against brightness-levels
- use new PWM API (pwm_get() and pwm_put()), legacy API (pwm_request()) as fallback

Changes in v4:
- store a PWM requested with of_pwm_request() in the platform data

Changes in v3:
- use a list of distinct brightness levels instead of a linear range as discussed with Stephen Warren and Mitch Bradley

Changes in v2:
- avoid oops by keeping a reference to the platform-specific exit() callback

TODO:
- add fixed-regulator support for backlight enable/disable

 .../bindings/video/backlight/pwm-backlight         |   30 ++++
 drivers/video/backlight/Kconfig                    |    2 +-
 drivers/video/backlight/pwm_bl.c                   |  145 +++++++++++++++++---
 include/linux/pwm_backlight.h                      |    1 +
 4 files changed, 157 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/backlight/pwm-backlight
Documentation/devicetree/bindings/video/backlight/pwm-backlight new file +30 -0
new file mode 100644
index 0000000..bc2d08d
@@ -0,0 +1,30 @@
+pwm-backlight bindings
+
+Required properties:
+  - compatible: "pwm-backlight"
+  - pwms: OF device-tree PWM specification (see PWM binding[0])
+  - num-brightness-levels: number of distinct brightness levels
+  - brightness-levels: Array of distinct brightness levels. Typically these
+      are in the range from 0 to 255, but any range starting at 0 will do.
+      The actual brightness level (PWM duty cycle) will be interpolated
+      from these values. 0 means a 0% duty cycle (darkest/off), while the
+      last value in the array represents a 100% duty cycle (brightest).
+  - default-brightness-level: the default brightness level (index into the
+      array defined by the "brightness-levels" property)
+
+Optional properties:
+  - pwm-names: a list of names for the PWM devices specified in the
+               "pwms" property (see PWM binding[0])
+
+[0]: Documentation/devicetree/bindings/pwm/pwm.txt
+
+Example:
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 5000000>;
+
+		num-brightness-levels = <8>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+	};
drivers/video/backlight/Kconfig +1 -1
index 7ed9991..cd77e79 100644
@@ -233,7 +233,7 @@ config BACKLIGHT_CARILLO_RANCH
 
 config BACKLIGHT_PWM
 	tristate "Generic PWM based Backlight Driver"
-	depends on HAVE_PWM
+	depends on PWM
 	help
 	  If you have a LCD backlight adjustable by PWM, say Y to enable
 	  this driver.
drivers/video/backlight/pwm_bl.c +125 -20

214 lines not on this page · raw message

include/linux/pwm_backlight.h +1 -0
index 63d2df4..56f4a86 100644
@@ -12,6 +12,7 @@ struct platform_pwm_backlight_data {
 	unsigned int dft_brightness;
 	unsigned int lth_brightness;
 	unsigned int pwm_period_ns;
+	unsigned int *levels;
 	int (*init)(struct device *dev);
 	int (*notify)(struct device *dev, int brightness);
 	void (*notify_after)(struct device *dev, int brightness);
Signature · 1 line
1.7.9.4
#45 lore raw

PATCH v5 15/16 pwm-backlight: Add rudimentary device tree support

Documentation/devicetree/bindings/video/backlight/pwm-backlight line 6

Quoted 11 lines · Thierry Reding

This commit adds very basic support for device tree probing. Currently, only a PWM and a list of distinct brightness levels can be specified. Enabling or disabling backlight power via GPIOs is not yet supported.

Documentation/devicetree/bindings/video/backlight/pwm-backlight +4 -0
+Required properties:
+  - compatible: "pwm-backlight"
+  - pwms: OF device-tree PWM specification (see PWM binding[0])
+  - num-brightness-levels: number of distinct brightness levels

Do we need the "num-brightness-levels" property at all; it's just the length of the brightness-levels property.

Documentation/devicetree/bindings/video/backlight/pwm-backlight line 11

Quoted 5 lines
Documentation/devicetree/bindings/video/backlight/pwm-backlight +5 -0
+  - brightness-levels: Array of distinct brightness levels. Typically these
+      are in the range from 0 to 255, but any range starting at 0 will do.
+      The actual brightness level (PWM duty cycle) will be interpolated
+      from these values. 0 means a 0% duty cycle (darkest/off), while the
+      last value in the array represents a 100% duty cycle (brightest).

...> +Example:

Quoted 9 lines
Documentation/devicetree/bindings/video/backlight/pwm-backlight +9 -0
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 5000000>;
+
+		num-brightness-levels = <8>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+	};
#46 lore raw

PATCH v5 15/16 pwm-backlight: Add rudimentary device tree support

Quoted 7 lines · Stephen Warren
Quoted 5 lines · Thierry Reding

This commit adds very basic support for device tree probing. Currently, only a PWM and a list of distinct brightness levels can be specified. Enabling or disabling backlight power via GPIOs is not yet supported.

Quoted 8 lines

Documentation/devicetree/bindings/video/backlight/pwm-backlight line 6

Quoted 5 lines
Documentation/devicetree/bindings/video/backlight/pwm-backlight +4 -0
+Required properties:
+  - compatible: "pwm-backlight"
+  - pwms: OF device-tree PWM specification (see PWM binding[0])
+  - num-brightness-levels: number of distinct brightness levels

Do we need the "num-brightness-levels" property at all; it's just the length of the brightness-levels property.

No, we don't really need it. As you say, it can be derived from the property length.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120404/6c150550/attachment-0001.sig>

#47 lore raw

PATCH v5 16/16 pwm: Take over maintainership of the PWM subsystem

In reply to Thierry Reding

I'm taking over the maintainership of the PWM subsystem. This commit also adds the URLs to the gitorious project and repository as well as any missing files related to the PWM subsystem.

---
Note: I guess this patch in particular could use some Acked-by, maybe from Arnd and Sascha so that people will know this happens with their blessing.

 MAINTAINERS |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
MAINTAINERS +8 -2
index d68feef..769055a 100644
@@ -5429,10 +5429,16 @@ S:	Maintained
 F:	Documentation/video4linux/README.pvrusb2
 F:	drivers/media/video/pvrusb2/
 
-PWM core
-M:	Sascha Hauer <[email protected]>
+PWM SUBSYSTEM
+M:	Thierry Reding <[email protected]>
 L:	linux-kernel at vger.kernel.org
 S:	Maintained
+W:	http://gitorious.org/linux-pwm
+T:	git git://gitorious.org/linux-pwm/linux-pwm.git
+F:	Documentation/pwm.txt
+F:	Documentation/devicetree/bindings/pwm/
+F:	include/linux/pwm.h
+F:	include/linux/of_pwm.h
 F:	drivers/pwm/
 
 PXA2xx/PXA3xx SUPPORT
Signature · 1 line
1.7.9.4