From 9da01759636f519967c0922ae12bd9fff739db9a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Jul 2013 15:05:39 -0700 Subject: [PATCH 01/11] pwm: convert class code to use dev_groups The dev_attrs field of struct class is going away soon, dev_groups should be used instead. This converts the PWM class code to use the correct field. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Thierry Reding --- drivers/pwm/sysfs.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c index 8ca5de316d3b..8c20332d4825 100644 --- a/drivers/pwm/sysfs.c +++ b/drivers/pwm/sysfs.c @@ -268,6 +268,7 @@ static ssize_t pwm_export_store(struct device *parent, return ret ? : len; } +static DEVICE_ATTR(export, 0200, NULL, pwm_export_store); static ssize_t pwm_unexport_store(struct device *parent, struct device_attribute *attr, @@ -288,27 +289,29 @@ static ssize_t pwm_unexport_store(struct device *parent, return ret ? : len; } +static DEVICE_ATTR(unexport, 0200, NULL, pwm_unexport_store); -static ssize_t pwm_npwm_show(struct device *parent, - struct device_attribute *attr, - char *buf) +static ssize_t npwm_show(struct device *parent, struct device_attribute *attr, + char *buf) { const struct pwm_chip *chip = dev_get_drvdata(parent); return sprintf(buf, "%u\n", chip->npwm); } +static DEVICE_ATTR_RO(npwm); -static struct device_attribute pwm_chip_attrs[] = { - __ATTR(export, 0200, NULL, pwm_export_store), - __ATTR(unexport, 0200, NULL, pwm_unexport_store), - __ATTR(npwm, 0444, pwm_npwm_show, NULL), - __ATTR_NULL, +static struct attribute *pwm_chip_attrs[] = { + &dev_attr_export.attr, + &dev_attr_unexport.attr, + &dev_attr_npwm.attr, + NULL, }; +ATTRIBUTE_GROUPS(pwm_chip); static struct class pwm_class = { .name = "pwm", .owner = THIS_MODULE, - .dev_attrs = pwm_chip_attrs, + .dev_groups = pwm_chip_groups, }; static int pwmchip_sysfs_match(struct device *parent, const void *data) From cfb9e4c40e87dffdce96d3a95c33d01f441b2470 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 9 Jul 2013 23:25:37 -0300 Subject: [PATCH 02/11] pwm: mxs: Check the return value from stmp_reset_block() stmp_reset_block() may fail, so let's check its return value and propagate it in the case of error. Signed-off-by: Fabio Estevam Signed-off-by: Thierry Reding --- drivers/pwm/pwm-mxs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-mxs.c b/drivers/pwm/pwm-mxs.c index 2c77b81da7c4..c2c5a4fd1b96 100644 --- a/drivers/pwm/pwm-mxs.c +++ b/drivers/pwm/pwm-mxs.c @@ -161,9 +161,15 @@ static int mxs_pwm_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mxs); - stmp_reset_block(mxs->base); + ret = stmp_reset_block(mxs->base); + if (ret) + goto pwm_remove; return 0; + +pwm_remove: + pwmchip_remove(&mxs->chip); + return ret; } static int mxs_pwm_remove(struct platform_device *pdev) From 9344dade4f9438c26f7eb517caeceee4d52a3a68 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Jul 2013 00:54:21 +0200 Subject: [PATCH 03/11] pwm: Add PWM polarity flag macro for DT Define a PWM_POLARITY_INVERTED macro in include/dt-bindings/pwm/pwm.h to be used by device tree sources. Signed-off-by: Laurent Pinchart Reviewed-by: Stephen Warren Signed-off-by: Thierry Reding --- Documentation/devicetree/bindings/pwm/pwm.txt | 7 ++++--- include/dt-bindings/pwm/pwm.h | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 include/dt-bindings/pwm/pwm.h diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt index 06e67247859a..8556263b8502 100644 --- a/Documentation/devicetree/bindings/pwm/pwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm.txt @@ -43,13 +43,14 @@ because the name "backlight" would be used as fallback anyway. pwm-specifier typically encodes the chip-relative PWM number and the PWM period in nanoseconds. -Optionally, the pwm-specifier can encode a number of flags in a third cell: -- bit 0: PWM signal polarity (0: normal polarity, 1: inverse polarity) +Optionally, the pwm-specifier can encode a number of flags (defined in +) in a third cell: +- PWM_POLARITY_INVERTED: invert the PWM signal polarity Example with optional PWM specifier for inverse polarity bl: backlight { - pwms = <&pwm 0 5000000 1>; + pwms = <&pwm 0 5000000 PWM_POLARITY_INVERTED>; pwm-names = "backlight"; }; diff --git a/include/dt-bindings/pwm/pwm.h b/include/dt-bindings/pwm/pwm.h new file mode 100644 index 000000000000..96f49e82253e --- /dev/null +++ b/include/dt-bindings/pwm/pwm.h @@ -0,0 +1,14 @@ +/* + * This header provides constants for most PWM bindings. + * + * Most PWM bindings can include a flags cell as part of the PWM specifier. + * In most cases, the format of the flags cell uses the standard values + * defined in this header. + */ + +#ifndef _DT_BINDINGS_PWM_PWM_H +#define _DT_BINDINGS_PWM_PWM_H + +#define PWM_POLARITY_INVERTED (1 << 0) + +#endif From 208be7698fe39d54242348aef375fd86180c4506 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Jul 2013 00:54:22 +0200 Subject: [PATCH 04/11] pwm: Use the DT macro directly when parsing PWM DT flags Don't redefine a PWM_SPEC_POLARITY macro with a value identical to PWM_POLARITY_INVERTED, use the PWM DT macro directly. Signed-off-by: Laurent Pinchart Reviewed-by: Stephen Warren Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index dfbfbc521768..2ca95042a0b9 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -30,10 +30,9 @@ #include #include -#define MAX_PWMS 1024 +#include -/* flags in the third cell of the DT PWM specifier */ -#define PWM_SPEC_POLARITY (1 << 0) +#define MAX_PWMS 1024 static DEFINE_MUTEX(pwm_lookup_lock); static LIST_HEAD(pwm_lookup_list); @@ -149,7 +148,7 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args) pwm_set_period(pwm, args->args[1]); - if (args->args[2] & PWM_SPEC_POLARITY) + if (args->args[2] & PWM_POLARITY_INVERTED) pwm_set_polarity(pwm, PWM_POLARITY_INVERSED); else pwm_set_polarity(pwm, PWM_POLARITY_NORMAL); From ebeec0af5b29635b847f5a7a17de1900193d0257 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Jul 2013 00:54:23 +0200 Subject: [PATCH 05/11] pwm: Update DT bindings to reference pwm.txt for cells documentation The PWM client cells format is documented in the generic pwm.txt documentation and duplicated in all PWM driver bindings. Remove duplicate information and reference pwm.txt instead. Signed-off-by: Laurent Pinchart Reviewed-by: Stephen Warren Signed-off-by: Thierry Reding --- .../devicetree/bindings/pwm/atmel-tcb-pwm.txt | 8 +++----- Documentation/devicetree/bindings/pwm/imx-pwm.txt | 4 ++-- Documentation/devicetree/bindings/pwm/mxs-pwm.txt | 4 ++-- .../devicetree/bindings/pwm/nvidia,tegra20-pwm.txt | 5 ++--- .../devicetree/bindings/pwm/nxp,pca9685-pwm.txt | 4 ++-- Documentation/devicetree/bindings/pwm/pwm-samsung.txt | 10 +++------- Documentation/devicetree/bindings/pwm/pwm-tiecap.txt | 8 +++----- Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt | 8 +++----- Documentation/devicetree/bindings/pwm/spear-pwm.txt | 5 ++--- Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt | 4 ++-- .../devicetree/bindings/pwm/ti,twl-pwmled.txt | 4 ++-- Documentation/devicetree/bindings/pwm/vt8500-pwm.txt | 8 +++----- 12 files changed, 29 insertions(+), 43 deletions(-) diff --git a/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt b/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt index de0eaed86651..8031148bcf85 100644 --- a/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt @@ -2,11 +2,9 @@ Atmel TCB PWM controller Required properties: - compatible: should be "atmel,tcb-pwm" -- #pwm-cells: Should be 3. The first cell specifies the per-chip index - of the PWM to use, the second cell is the period in nanoseconds and - bit 0 in the third cell is used to encode the polarity of PWM output. - Set bit 0 of the third cell in PWM specifier to 1 for inverse polarity & - set to 0 for normal polarity. +- #pwm-cells: should be 3. See pwm.txt in this directory for a description of + the cells format. The only third cell flag supported by this binding is + PWM_POLARITY_INVERTED. - tc-block: The Timer Counter block to use as a PWM chip. Example: diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt index 8522bfbccfd7..b50d7a6d9d7f 100644 --- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt @@ -3,8 +3,8 @@ Freescale i.MX PWM controller Required properties: - compatible: should be "fsl,-pwm" - reg: physical base address and length of the controller's registers -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. +- #pwm-cells: should be 2. See pwm.txt in this directory for a description of + the cells format. - interrupts: The interrupt for the pwm controller Example: diff --git a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt index 9e3f8f1d46a2..96cdde5f6208 100644 --- a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt @@ -3,8 +3,8 @@ Freescale MXS PWM controller Required properties: - compatible: should be "fsl,imx23-pwm" - reg: physical base address and length of the controller's registers -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. +- #pwm-cells: should be 2. See pwm.txt in this directory for a description of + the cells format. - fsl,pwm-number: the number of PWM devices Example: diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt index 01438ecd6628..c3fc57af8772 100644 --- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt @@ -5,9 +5,8 @@ Required properties: - "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 period in nanoseconds. +- #pwm-cells: should be 2. See pwm.txt in this directory for a description of + the cells format. Example: diff --git a/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt b/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt index 1e3dfe7a4894..f84ec9d291ea 100644 --- a/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/nxp,pca9685-pwm.txt @@ -3,8 +3,8 @@ NXP PCA9685 16-channel 12-bit PWM LED controller Required properties: - compatible: "nxp,pca9685-pwm" - - #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. + - #pwm-cells: Should be 2. See pwm.txt in this directory for a description of + the cells format. The index 16 is the ALLCALL channel, that sets all PWM channels at the same time. diff --git a/Documentation/devicetree/bindings/pwm/pwm-samsung.txt b/Documentation/devicetree/bindings/pwm/pwm-samsung.txt index ac67c687a327..4caa1a78863e 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-samsung.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-samsung.txt @@ -19,13 +19,9 @@ Required properties: - reg: base address and size of register area - interrupts: list of timer interrupts (one interrupt per timer, starting at timer 0) -- #pwm-cells: number of cells used for PWM specifier - must be 3 - the specifier format is as follows: - - phandle to PWM controller node - - index of PWM channel (from 0 to 4) - - PWM signal period in nanoseconds - - bitmask of optional PWM flags: - 0x1 - invert PWM signal +- #pwm-cells: should be 3. See pwm.txt in this directory for a description of + the cells format. The only third cell flag supported by this binding is + PWM_POLARITY_INVERTED. Optional properties: - samsung,pwm-outputs: list of PWM channels used as PWM outputs on particular diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index 681afad73778..fb81179dce37 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -4,11 +4,9 @@ Required properties: - compatible: Must be "ti,-ecap". for am33xx - compatible = "ti,am33xx-ecap"; for da850 - compatible = "ti,da850-ecap", "ti,am33xx-ecap"; -- #pwm-cells: Should be 3. Number of cells being used to specify PWM property. - First cell specifies the per-chip index of the PWM to use, the second - cell is the period in nanoseconds and bit 0 in the third cell is used to - encode the polarity of PWM output. Set bit 0 of the third in PWM specifier - to 1 for inverse polarity & set to 0 for normal polarity. +- #pwm-cells: should be 3. See pwm.txt in this directory for a description of + the cells format. The PWM channel index ranges from 0 to 4. The only third + cell flag supported by this binding is PWM_POLARITY_INVERTED. - reg: physical base address and size of the registers map. Optional properties: diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt index 337c6fc65d3f..9c100b2c5b23 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt @@ -4,11 +4,9 @@ Required properties: - compatible: Must be "ti,-ehrpwm". for am33xx - compatible = "ti,am33xx-ehrpwm"; for da850 - compatible = "ti,da850-ehrpwm", "ti,am33xx-ehrpwm"; -- #pwm-cells: Should be 3. Number of cells being used to specify PWM property. - First cell specifies the per-chip index of the PWM to use, the second - cell is the period in nanoseconds and bit 0 in the third cell is used to - encode the polarity of PWM output. Set bit 0 of the third in PWM specifier - to 1 for inverse polarity & set to 0 for normal polarity. +- #pwm-cells: should be 3. See pwm.txt in this directory for a description of + the cells format. The only third cell flag supported by this binding is + PWM_POLARITY_INVERTED. - reg: physical base address and size of the registers map. Optional properties: diff --git a/Documentation/devicetree/bindings/pwm/spear-pwm.txt b/Documentation/devicetree/bindings/pwm/spear-pwm.txt index 3ac779d83386..b486de2c3fe3 100644 --- a/Documentation/devicetree/bindings/pwm/spear-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/spear-pwm.txt @@ -5,9 +5,8 @@ Required properties: - "st,spear320-pwm" - "st,spear1340-pwm" - reg: physical base address and length of the controller's registers -- #pwm-cells: number of cells used to specify PWM which is fixed to 2 on - SPEAr. The first cell specifies the per-chip index of the PWM to use and - the second cell is the period in nanoseconds. +- #pwm-cells: should be 2. See pwm.txt in this directory for a description of + the cells format. Example: diff --git a/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt b/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt index 2943ee5fce00..4e32bee11201 100644 --- a/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt @@ -6,8 +6,8 @@ On TWL6030 series: PWM0 and PWM1 Required properties: - compatible: "ti,twl4030-pwm" or "ti,twl6030-pwm" -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. +- #pwm-cells: should be 2. See pwm.txt in this directory for a description of + the cells format. Example: diff --git a/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt b/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt index cb64f3acc10f..9f4b46090782 100644 --- a/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt +++ b/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt @@ -6,8 +6,8 @@ On TWL6030 series: LED PWM (mainly used as charging indicator LED) Required properties: - compatible: "ti,twl4030-pwmled" or "ti,twl6030-pwmled" -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. +- #pwm-cells: should be 2. See pwm.txt in this directory for a description of + the cells format. Example: diff --git a/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt index d21d82d29855..a76390e6df2e 100644 --- a/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt @@ -3,11 +3,9 @@ VIA/Wondermedia VT8500/WM8xxx series SoC PWM controller Required properties: - compatible: should be "via,vt8500-pwm" - reg: physical base address and length of the controller's registers -- #pwm-cells: Should be 3. Number of cells being used to specify PWM property. - First cell specifies the per-chip index of the PWM to use, the second - cell is the period in nanoseconds and bit 0 in the third cell is used to - encode the polarity of PWM output. Set bit 0 of the third in PWM specifier - to 1 for inverse polarity & set to 0 for normal polarity. +- #pwm-cells: should be 3. See pwm.txt in this directory for a description of + the cells format. The only third cell flag supported by this binding is + PWM_POLARITY_INVERTED. - clocks: phandle to the PWM source clock Example: From eb9bdef111b82389f9b7943bc29fb72c3a0fa5b0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Jul 2013 00:54:24 +0200 Subject: [PATCH 06/11] ARM: dts: Use the PWM polarity flags Replace the numerical polarity flags with the PWM_POLARITY_INVERTED symbolic constant. Signed-off-by: Laurent Pinchart Reviewed-by: Stephen Warren Signed-off-by: Thierry Reding --- arch/arm/boot/dts/am335x-evmsk.dts | 3 ++- arch/arm/boot/dts/wm8850-w70v2.dts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 0c8ad173d2b0..62124c71105a 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "am33xx.dtsi" +#include / { model = "TI AM335x EVM-SK"; @@ -298,7 +299,7 @@ backlight { compatible = "pwm-backlight"; - pwms = <&ecap2 0 50000 1>; + pwms = <&ecap2 0 50000 PWM_POLARITY_INVERTED>; brightness-levels = <0 58 61 66 75 90 125 170 255>; default-brightness-level = <8>; }; diff --git a/arch/arm/boot/dts/wm8850-w70v2.dts b/arch/arm/boot/dts/wm8850-w70v2.dts index 90e913fb64be..7a563d2523b0 100644 --- a/arch/arm/boot/dts/wm8850-w70v2.dts +++ b/arch/arm/boot/dts/wm8850-w70v2.dts @@ -11,13 +11,14 @@ /dts-v1/; /include/ "wm8850.dtsi" +#include / { model = "Wondermedia WM8850-W70v2 Tablet"; backlight { compatible = "pwm-backlight"; - pwms = <&pwm 0 50000 1>; /* duty inverted */ + pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; brightness-levels = <0 40 60 80 100 130 190 255>; default-brightness-level = <5>; From 382457e562bbb1ea7d94923e58fcbac9e981ff18 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 26 Jul 2013 00:27:41 +0200 Subject: [PATCH 07/11] pwm: renesas-tpu: Add DT support Specify DT bindings for the TPU PWM controller and add OF support to the driver. Signed-off-by: Laurent Pinchart Acked-by: Stephen Warren Signed-off-by: Thierry Reding --- .../bindings/pwm/renesas,tpu-pwm.txt | 28 +++++++++++++ drivers/pwm/pwm-renesas-tpu.c | 41 +++++++++++++++---- 2 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt diff --git a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt new file mode 100644 index 000000000000..b067e84a94b5 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt @@ -0,0 +1,28 @@ +* Renesas R-Car Timer Pulse Unit PWM Controller + +Required Properties: + + - compatible: should be one of the following. + - "renesas,tpu-r8a73a4": for R8A77A4 (R-Mobile APE6) compatible PWM controller. + - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller. + - "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller. + - "renesas,tpu-sh7372": for SH7372 (SH-Mobile AP4) compatible PWM controller. + - "renesas,tpu": for generic R-Car TPU PWM controller. + + - reg: Base address and length of each memory resource used by the PWM + controller hardware module. + + - #pwm-cells: should be 3. See pwm.txt in this directory for a description of + the cells format. The only third cell flag supported by this binding is + PWM_POLARITY_INVERTED. + +Please refer to pwm.txt in this directory for details of the common PWM bindings +used by client devices. + +Example: R8A7740 (R-Car A1) TPU controller node + + tpu: pwm@e6600000 { + compatible = "renesas,tpu-r8a7740", "renesas,tpu"; + reg = <0xe6600000 0x100>; + #pwm-cells = <3>; + }; diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 2600892782c1..3eeffff69280 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -86,7 +87,7 @@ struct tpu_pwm_device { struct tpu_device { struct platform_device *pdev; - struct tpu_pwm_platform_data *pdata; + enum pwm_polarity polarities[TPU_CHANNEL_MAX]; struct pwm_chip chip; spinlock_t lock; @@ -228,8 +229,7 @@ static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *_pwm) pwm->tpu = tpu; pwm->channel = _pwm->hwpwm; - pwm->polarity = tpu->pdata ? tpu->pdata->channels[pwm->channel].polarity - : PWM_POLARITY_NORMAL; + pwm->polarity = tpu->polarities[pwm->channel]; pwm->prescaler = 0; pwm->period = 0; pwm->duty = 0; @@ -388,6 +388,16 @@ static const struct pwm_ops tpu_pwm_ops = { * Probe and remove */ +static void tpu_parse_pdata(struct tpu_device *tpu) +{ + struct tpu_pwm_platform_data *pdata = tpu->pdev->dev.platform_data; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(tpu->polarities); ++i) + tpu->polarities[i] = pdata ? pdata->channels[i].polarity + : PWM_POLARITY_NORMAL; +} + static int tpu_probe(struct platform_device *pdev) { struct tpu_device *tpu; @@ -400,7 +410,11 @@ static int tpu_probe(struct platform_device *pdev) return -ENOMEM; } - tpu->pdata = pdev->dev.platform_data; + spin_lock_init(&tpu->lock); + tpu->pdev = pdev; + + /* Initialize device configuration from platform data. */ + tpu_parse_pdata(tpu); /* Map memory, get clock and pin control. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -422,11 +436,10 @@ static int tpu_probe(struct platform_device *pdev) /* Initialize and register the device. */ platform_set_drvdata(pdev, tpu); - spin_lock_init(&tpu->lock); - tpu->pdev = pdev; - tpu->chip.dev = &pdev->dev; tpu->chip.ops = &tpu_pwm_ops; + tpu->chip.of_xlate = of_pwm_xlate_with_flags; + tpu->chip.of_pwm_n_cells = 3; tpu->chip.base = -1; tpu->chip.npwm = TPU_CHANNEL_MAX; @@ -457,12 +470,26 @@ static int tpu_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id tpu_of_table[] = { + { .compatible = "renesas,tpu-r8a73a4", }, + { .compatible = "renesas,tpu-r8a7740", }, + { .compatible = "renesas,tpu-r8a7790", }, + { .compatible = "renesas,tpu-sh7372", }, + { .compatible = "renesas,tpu", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, tpu_of_table); +#endif + static struct platform_driver tpu_driver = { .probe = tpu_probe, .remove = tpu_remove, .driver = { .name = "renesas-tpu-pwm", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tpu_of_table), } }; From 88d5a2e6ffaa32e2a09a994872ca10aca07a36e9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 14 Aug 2013 11:11:25 +0200 Subject: [PATCH 08/11] pwm: simplify use of devm_ioremap_resource Remove unneeded error handling on the result of a call to platform_get_resource when the value is passed to devm_ioremap_resource. Move the call to platform_get_resource adjacent to the call to devm_ioremap_resource to make the connection between them more clear. A simplified version of the semantic patch that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression pdev,res,n,e,e1; expression ret != 0; identifier l; @@ - res = platform_get_resource(pdev, IORESOURCE_MEM, n); ... when != res - if (res == NULL) { ... \(goto l;\|return ret;\) } ... when != res + res = platform_get_resource(pdev, IORESOURCE_MEM, n); e = devm_ioremap_resource(e1, res); // Signed-off-by: Julia Lawall Acked-by: Viresh Kumar Signed-off-by: Thierry Reding --- drivers/pwm/pwm-lpc32xx.c | 3 --- drivers/pwm/pwm-renesas-tpu.c | 5 ----- drivers/pwm/pwm-spear.c | 7 +------ 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/pwm/pwm-lpc32xx.c b/drivers/pwm/pwm-lpc32xx.c index efb6c7bf8750..efac99e03d57 100644 --- a/drivers/pwm/pwm-lpc32xx.c +++ b/drivers/pwm/pwm-lpc32xx.c @@ -124,9 +124,6 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - lpc32xx->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(lpc32xx->base)) return PTR_ERR(lpc32xx->base); diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 3eeffff69280..aff6ba9b49e7 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -418,11 +418,6 @@ static int tpu_probe(struct platform_device *pdev) /* Map memory, get clock and pin control. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "failed to get I/O memory\n"); - return -ENXIO; - } - tpu->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(tpu->base)) return PTR_ERR(tpu->base); diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index a54d21401431..8ad26b8bf418 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c @@ -178,18 +178,13 @@ static int spear_pwm_probe(struct platform_device *pdev) int ret; u32 val; - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - dev_err(&pdev->dev, "no memory resources defined\n"); - return -ENODEV; - } - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); if (!pc) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; } + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(pc->mmio_base)) return PTR_ERR(pc->mmio_base); From 3943a650f62d0a88788db30c92df584660f3999d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 2 Aug 2013 15:11:18 +0900 Subject: [PATCH 09/11] pwm: tiecap: add CONFIG_PM_SLEEP to ecap_pwm_{save,restore}_context() ecap_pwm_save_context() and ecap_pwm_restore_context() are only used when CONFIG_PM_SLEEP is selected. drivers/pwm/pwm-tiecap.c:293:13: warning: 'ecap_pwm_save_context' defined but not used [-Wunused-function] drivers/pwm/pwm-tiecap.c:302:13: warning: 'ecap_pwm_restore_context' defined but not used [-Wunused-function] Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tiecap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 72ca42dfa733..c2e2e5852362 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -290,6 +290,7 @@ static int ecap_pwm_remove(struct platform_device *pdev) return pwmchip_remove(&pc->chip); } +#ifdef CONFIG_PM_SLEEP static void ecap_pwm_save_context(struct ecap_pwm_chip *pc) { pm_runtime_get_sync(pc->chip.dev); @@ -306,7 +307,6 @@ static void ecap_pwm_restore_context(struct ecap_pwm_chip *pc) writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2); } -#ifdef CONFIG_PM_SLEEP static int ecap_pwm_suspend(struct device *dev) { struct ecap_pwm_chip *pc = dev_get_drvdata(dev); From ac872bc9ed4452dccfbcebe7d273350103464998 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 2 Aug 2013 15:22:03 +0900 Subject: [PATCH 10/11] pwm: tiehrpwm: add missing __iomem annotation Fix the following sparse warnings: drivers/pwm/pwm-tiehrpwm.c:144:16: warning: incorrect type in argument 1 (different address spaces) drivers/pwm/pwm-tiehrpwm.c:144:16: expected void const volatile [noderef] *addr drivers/pwm/pwm-tiehrpwm.c:144:16: got void * drivers/pwm/pwm-tiehrpwm.c:149:9: warning: incorrect type in argument 2 (different address spaces) drivers/pwm/pwm-tiehrpwm.c:149:9: expected void volatile [noderef] *addr drivers/pwm/pwm-tiehrpwm.c:149:9: got void * drivers/pwm/pwm-tiehrpwm.c:157:18: warning: incorrect type in argument 1 (different address spaces) drivers/pwm/pwm-tiehrpwm.c:157:18: expected void const volatile [noderef] *addr drivers/pwm/pwm-tiehrpwm.c:157:18: got void * drivers/pwm/pwm-tiehrpwm.c:160:9: warning: incorrect type in argument 2 (different address spaces) drivers/pwm/pwm-tiehrpwm.c:160:9: expected void volatile [noderef] *addr drivers/pwm/pwm-tiehrpwm.c:160:9: got void * Signed-off-by: Jingoo Han Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tiehrpwm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index aa4c5586f53b..084f55246532 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -139,17 +139,17 @@ static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) return container_of(chip, struct ehrpwm_pwm_chip, chip); } -static u16 ehrpwm_read(void *base, int offset) +static u16 ehrpwm_read(void __iomem *base, int offset) { return readw(base + offset); } -static void ehrpwm_write(void *base, int offset, unsigned int val) +static void ehrpwm_write(void __iomem *base, int offset, unsigned int val) { writew(val & 0xFFFF, base + offset); } -static void ehrpwm_modify(void *base, int offset, +static void ehrpwm_modify(void __iomem *base, int offset, unsigned short mask, unsigned short val) { unsigned short regval; From 1e185c7aafbb56580feaa5bdbc9e4b1d8efaf710 Mon Sep 17 00:00:00 2001 From: Mike Dunn Date: Thu, 8 Aug 2013 10:00:37 -0700 Subject: [PATCH 11/11] pwm: pxa: Use module_platform_driver Commit 76abbdde2d95a3807d0dc6bf9f84d03d0dbd4f3d pwm: Add sysfs interface causes a kernel oops due to a null pointer dereference on PXA platforms. This happens because the class added by the patch is registered in a subsys_initcall (initcall4), but the pxa pwm driver is registered in arch_initcall (initcall3). If the class is not registered before the driver probe function runs, the oops occurs in device_add() when the uninitialized pointers in struct class are dereferenced. I don't see a reason that the driver must be an arch_initcall, so this patch makes it a regular module_platform_driver (initcall6), preventing the oops. Signed-off-by: Mike Dunn Acked-by: Robert Jarzmik Acked-by: Marek Vasut Signed-off-by: Thierry Reding --- drivers/pwm/pwm-pxa.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index dc9717551d39..a4d2164aaf55 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -182,16 +182,6 @@ static struct platform_driver pwm_driver = { .id_table = pwm_id_table, }; -static int __init pwm_init(void) -{ - return platform_driver_register(&pwm_driver); -} -arch_initcall(pwm_init); - -static void __exit pwm_exit(void) -{ - platform_driver_unregister(&pwm_driver); -} -module_exit(pwm_exit); +module_platform_driver(pwm_driver); MODULE_LICENSE("GPL v2");