* [PATCHv4 0/4] pwm: imx: support output polarity inversion
@ 2014-08-20 6:55 Lothar Waßmann
2014-08-20 6:55 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Lothar Waßmann @ 2014-08-20 6:55 UTC (permalink / raw)
To: linux-arm-kernel
This patch series adds support for polarity inversion to the pwm-imx
driver. The patches have been tested on i.MX6, i.MX53 and with the
ti-ehrpwm.c driver.
Changes wrt. v2:
- make the use of '#pwm-cells = <3>' optional, so that the change does
not break existing DT blobs as suggested by Arnd Bergmann and Sascha
Hauer.
Changes wrt. v3:
- implemented the approach suggested by Sascha Hauer
- don't modify struct pwm_ops in the imx_pwm probe function
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() 2014-08-20 6:55 [PATCHv4 0/4] pwm: imx: support output polarity inversion Lothar Waßmann @ 2014-08-20 6:55 ` Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann 2014-08-26 7:24 ` [PATCHv4 0/4] " Lothar Waßmann 2014-09-29 10:07 ` Lothar Waßmann 2 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-08-20 6:55 UTC (permalink / raw) To: linux-arm-kernel Make the messages that are printed in case of fatal errors actually visible to the user without having to recompile the driver with debugging enabled. Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 4b66bf0..7af0043 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -525,13 +525,13 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index, &args); if (err) { - pr_debug("%s(): can't parse \"pwms\" property\n", __func__); + pr_err("%s(): can't parse \"pwms\" property\n", __func__); return ERR_PTR(err); } pc = of_node_to_pwmchip(args.np); if (IS_ERR(pc)) { - pr_debug("%s(): PWM chip not found\n", __func__); + pr_err("%s(): PWM chip not found\n", __func__); pwm = ERR_CAST(pc); goto put; } -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional 2014-08-20 6:55 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann @ 2014-08-20 6:55 ` Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 3/4] pwm: imx: indentation cleanup Lothar Waßmann 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-08-20 6:55 UTC (permalink / raw) To: linux-arm-kernel Change the pwm chip driver registration, so that a chip driver that supports polarity inversion can still be used with DTBs that don't provide the 'PWM_POLARITY' flag. This is done to provide polarity inversion support for the pwm-imx driver without having to modify all existing DTS files. Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/core.c | 18 ++++++------------ drivers/pwm/pwm-atmel-tcb.c | 1 - drivers/pwm/pwm-atmel.c | 4 +--- drivers/pwm/pwm-pxa.c | 5 ++--- drivers/pwm/pwm-renesas-tpu.c | 1 - drivers/pwm/pwm-samsung.c | 1 - drivers/pwm/pwm-tiecap.c | 1 - drivers/pwm/pwm-tiehrpwm.c | 1 - drivers/pwm/pwm-vt8500.c | 1 - include/linux/pwm.h | 1 - 10 files changed, 9 insertions(+), 25 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 7af0043..ab0fc5a 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -136,7 +136,7 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args) { struct pwm_device *pwm; - if (pc->of_pwm_n_cells < 3) + if (args->args_count != 3) return ERR_PTR(-EINVAL); if (args->args[0] >= pc->npwm) @@ -162,12 +162,15 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) { struct pwm_device *pwm; - if (pc->of_pwm_n_cells < 2) + if (args->args_count < 2) return ERR_PTR(-EINVAL); if (args->args[0] >= pc->npwm) return ERR_PTR(-EINVAL); + if (args->args_count > 2) + return of_pwm_xlate_with_flags(pc, args); + pwm = pwm_request_from_chip(pc, args->args[0], NULL); if (IS_ERR(pwm)) return pwm; @@ -182,10 +185,8 @@ static void of_pwmchip_add(struct pwm_chip *chip) if (!chip->dev || !chip->dev->of_node) return; - if (!chip->of_xlate) { + if (!chip->of_xlate) chip->of_xlate = of_pwm_simple_xlate; - chip->of_pwm_n_cells = 2; - } of_node_get(chip->dev->of_node); } @@ -536,13 +537,6 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) goto put; } - if (args.args_count != pc->of_pwm_n_cells) { - pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name, - args.np->full_name); - pwm = ERR_PTR(-EINVAL); - goto put; - } - pwm = pc->of_xlate(pc, &args); if (IS_ERR(pwm)) goto put; diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index f3dcd02..55fabf8 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -395,7 +395,6 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) tcbpwm->chip.dev = &pdev->dev; tcbpwm->chip.ops = &atmel_tcb_pwm_ops; tcbpwm->chip.of_xlate = of_pwm_xlate_with_flags; - tcbpwm->chip.of_pwm_n_cells = 3; tcbpwm->chip.base = -1; tcbpwm->chip.npwm = NPWM; tcbpwm->tc = tc; diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index 6e700a5..ae7c946 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c @@ -350,10 +350,8 @@ static int atmel_pwm_probe(struct platform_device *pdev) atmel_pwm->chip.dev = &pdev->dev; atmel_pwm->chip.ops = &atmel_pwm_ops; - if (pdev->dev.of_node) { + if (pdev->dev.of_node) atmel_pwm->chip.of_xlate = of_pwm_xlate_with_flags; - atmel_pwm->chip.of_pwm_n_cells = 3; - } atmel_pwm->chip.base = -1; atmel_pwm->chip.npwm = 4; diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index 0b312ec..5656052 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -191,10 +191,9 @@ static int pwm_probe(struct platform_device *pdev) pwm->chip.base = -1; pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; - if (IS_ENABLED(CONFIG_OF)) { + if (IS_ENABLED(CONFIG_OF)) pwm->chip.of_xlate = pxa_pwm_of_xlate; - pwm->chip.of_pwm_n_cells = 1; - } + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 3b71b42..5271da3 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -419,7 +419,6 @@ static int tpu_probe(struct platform_device *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; diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index ba6b650..317d7d1 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -484,7 +484,6 @@ static int pwm_samsung_probe(struct platform_device *pdev) return ret; chip->chip.of_xlate = of_pwm_xlate_with_flags; - chip->chip.of_pwm_n_cells = 3; } else { if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data specified\n"); diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 74efbe7..a8e8282 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -227,7 +227,6 @@ static int ecap_pwm_probe(struct platform_device *pdev) pc->chip.dev = &pdev->dev; pc->chip.ops = &ecap_pwm_ops; pc->chip.of_xlate = of_pwm_xlate_with_flags; - pc->chip.of_pwm_n_cells = 3; pc->chip.base = -1; pc->chip.npwm = 1; diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index cb75133..12a8ae4 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -458,7 +458,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) pc->chip.dev = &pdev->dev; pc->chip.ops = &ehrpwm_pwm_ops; pc->chip.of_xlate = of_pwm_xlate_with_flags; - pc->chip.of_pwm_n_cells = 3; pc->chip.base = -1; pc->chip.npwm = NUM_PWM_CHANNEL; diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 652e6b5..e04a3c0 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -217,7 +217,6 @@ static int vt8500_pwm_probe(struct platform_device *pdev) chip->chip.dev = &pdev->dev; chip->chip.ops = &vt8500_pwm_ops; chip->chip.of_xlate = of_pwm_xlate_with_flags; - chip->chip.of_pwm_n_cells = 3; chip->chip.base = -1; chip->chip.npwm = VT8500_NR_PWMS; diff --git a/include/linux/pwm.h b/include/linux/pwm.h index e90628c..4cf1569 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -174,7 +174,6 @@ struct pwm_chip { struct pwm_device * (*of_xlate)(struct pwm_chip *pc, const struct of_phandle_args *args); - unsigned int of_pwm_n_cells; bool can_sleep; }; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 3/4] pwm: imx: indentation cleanup 2014-08-20 6:55 ` [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann @ 2014-08-20 6:55 ` Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 4/4] pwm: imx: support output polarity inversion Lothar Waßmann 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-08-20 6:55 UTC (permalink / raw) To: linux-arm-kernel Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/pwm-imx.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 5449d91..f836635 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -25,20 +25,21 @@ #define MX1_PWMS 0x04 /* PWM Sample Register */ #define MX1_PWMP 0x08 /* PWM Period Register */ -#define MX1_PWMC_EN (1 << 4) +#define MX1_PWMC_EN (1 << 4) /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ -#define MX3_PWMCR 0x00 /* PWM Control Register */ -#define MX3_PWMSAR 0x0C /* PWM Sample Register */ -#define MX3_PWMPR 0x10 /* PWM Period Register */ -#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) -#define MX3_PWMCR_DOZEEN (1 << 24) -#define MX3_PWMCR_WAITEN (1 << 23) +#define MX3_PWMCR 0x00 /* PWM Control Register */ +#define MX3_PWMSAR 0x0C /* PWM Sample Register */ +#define MX3_PWMPR 0x10 /* PWM Period Register */ +#define MX3_PWMCR_PRESCALER(x) ((((x) - 1) & 0xFFF) << 4) +#define MX3_PWMCR_DOZEEN (1 << 24) +#define MX3_PWMCR_WAITEN (1 << 23) #define MX3_PWMCR_DBGEN (1 << 22) -#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) -#define MX3_PWMCR_CLKSRC_IPG (1 << 16) -#define MX3_PWMCR_EN (1 << 0) +#define MX3_PWMCR_POUTC (1 << 18) +#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) +#define MX3_PWMCR_CLKSRC_IPG (1 << 16) +#define MX3_PWMCR_EN (1 << 0) struct imx_chip { struct clk *clk_per; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 4/4] pwm: imx: support output polarity inversion 2014-08-20 6:55 ` [PATCHv4 3/4] pwm: imx: indentation cleanup Lothar Waßmann @ 2014-08-20 6:55 ` Lothar Waßmann 2014-08-26 7:39 ` Shawn Guo 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-08-20 6:55 UTC (permalink / raw) To: linux-arm-kernel The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable output polarity. This patch adds support to utilize this feature where available. Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/pwm-imx.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index f836635..585b0a8 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -138,6 +138,8 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, if (test_bit(PWMF_ENABLED, &pwm->flags)) cr |= MX3_PWMCR_EN; + if (pwm->polarity == PWM_POLARITY_INVERSED) + cr |= MX3_PWMCR_POUTC; writel(cr, imx->mmio_base + MX3_PWMCR); @@ -156,6 +158,11 @@ static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable) else val &= ~MX3_PWMCR_EN; + if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED) + val |= MX3_PWMCR_POUTC; + else + val &= ~MX3_PWMCR_POUTC; + writel(val, imx->mmio_base + MX3_PWMCR); } @@ -199,27 +206,49 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) clk_disable_unprepare(imx->clk_per); } -static struct pwm_ops imx_pwm_ops = { +static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct imx_chip *imx = to_imx_chip(chip); + + dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__, + polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal"); + + return 0; +} + +static struct pwm_ops imx_pwm_ops_v1 = { .enable = imx_pwm_enable, .disable = imx_pwm_disable, .config = imx_pwm_config, .owner = THIS_MODULE, }; +static struct pwm_ops imx_pwm_ops_v2 = { + .enable = imx_pwm_enable, + .disable = imx_pwm_disable, + .set_polarity = imx_pwm_set_polarity, + .config = imx_pwm_config, + .owner = THIS_MODULE, +}; + struct imx_pwm_data { int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns); void (*set_enable)(struct pwm_chip *chip, bool enable); + struct pwm_ops *pwm_ops; }; static struct imx_pwm_data imx_pwm_data_v1 = { .config = imx_pwm_config_v1, .set_enable = imx_pwm_set_enable_v1, + .pwm_ops = &imx_pwm_ops_v1, }; static struct imx_pwm_data imx_pwm_data_v2 = { .config = imx_pwm_config_v2, .set_enable = imx_pwm_set_enable_v2, + .pwm_ops = &imx_pwm_ops_v2, }; static const struct of_device_id imx_pwm_dt_ids[] = { @@ -241,6 +270,10 @@ static int imx_pwm_probe(struct platform_device *pdev) if (!of_id) return -ENODEV; + data = of_id->data; + if (data->pwm_ops->set_polarity) + dev_dbg(&pdev->dev, "PWM supports output inversion\n"); + imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) return -ENOMEM; @@ -259,7 +292,7 @@ static int imx_pwm_probe(struct platform_device *pdev) return PTR_ERR(imx->clk_ipg); } - imx->chip.ops = &imx_pwm_ops; + imx->chip.ops = data->pwm_ops; imx->chip.dev = &pdev->dev; imx->chip.base = -1; imx->chip.npwm = 1; @@ -270,7 +303,6 @@ static int imx_pwm_probe(struct platform_device *pdev) if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); - data = of_id->data; imx->config = data->config; imx->set_enable = data->set_enable; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 4/4] pwm: imx: support output polarity inversion 2014-08-20 6:55 ` [PATCHv4 4/4] pwm: imx: support output polarity inversion Lothar Waßmann @ 2014-08-26 7:39 ` Shawn Guo 0 siblings, 0 replies; 10+ messages in thread From: Shawn Guo @ 2014-08-26 7:39 UTC (permalink / raw) To: linux-arm-kernel On Wed, Aug 20, 2014 at 08:55:56AM +0200, Lothar Wa?mann wrote: > The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable > output polarity. This patch adds support to utilize this feature where > available. > > Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv4 0/4] pwm: imx: support output polarity inversion 2014-08-20 6:55 [PATCHv4 0/4] pwm: imx: support output polarity inversion Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann @ 2014-08-26 7:24 ` Lothar Waßmann 2014-09-29 10:58 ` Sascha Hauer 2014-09-29 10:07 ` Lothar Waßmann 2 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-08-26 7:24 UTC (permalink / raw) To: linux-arm-kernel Hi, Lothar Wa?mann wrote: > This patch series adds support for polarity inversion to the pwm-imx > driver. The patches have been tested on i.MX6, i.MX53 and with the > ti-ehrpwm.c driver. > > Changes wrt. v2: > - make the use of '#pwm-cells = <3>' optional, so that the change does > not break existing DT blobs as suggested by Arnd Bergmann and Sascha > Hauer. > > Changes wrt. v3: > - implemented the approach suggested by Sascha Hauer > - don't modify struct pwm_ops in the imx_pwm probe function > > Any further comments? Anyone taking care of these patches? Lothar Wa?mann -- ___________________________________________________________ Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10 Gesch?ftsf?hrer: Matthias Kaussen Handelsregistereintrag: Amtsgericht Aachen, HRB 4996 www.karo-electronics.de | info at karo-electronics.de ___________________________________________________________ ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv4 0/4] pwm: imx: support output polarity inversion 2014-08-26 7:24 ` [PATCHv4 0/4] " Lothar Waßmann @ 2014-09-29 10:58 ` Sascha Hauer 0 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2014-09-29 10:58 UTC (permalink / raw) To: linux-arm-kernel On Tue, Aug 26, 2014 at 09:24:09AM +0200, Lothar Wa?mann wrote: > Hi, > > Lothar Wa?mann wrote: > > This patch series adds support for polarity inversion to the pwm-imx > > driver. The patches have been tested on i.MX6, i.MX53 and with the > > ti-ehrpwm.c driver. > > > > Changes wrt. v2: > > - make the use of '#pwm-cells = <3>' optional, so that the change does > > not break existing DT blobs as suggested by Arnd Bergmann and Sascha > > Hauer. > > > > Changes wrt. v3: > > - implemented the approach suggested by Sascha Hauer > > - don't modify struct pwm_ops in the imx_pwm probe function > > > > > Any further comments? No, except this one: Reviewed-by: Sascha Hauer <s.hauer@pengutronix.de> Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv4 0/4] pwm: imx: support output polarity inversion 2014-08-20 6:55 [PATCHv4 0/4] pwm: imx: support output polarity inversion Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann 2014-08-26 7:24 ` [PATCHv4 0/4] " Lothar Waßmann @ 2014-09-29 10:07 ` Lothar Waßmann 2 siblings, 0 replies; 10+ messages in thread From: Lothar Waßmann @ 2014-09-29 10:07 UTC (permalink / raw) To: linux-arm-kernel Hi, Lothar Wa?mann wrote: > This patch series adds support for polarity inversion to the pwm-imx > driver. The patches have been tested on i.MX6, i.MX53 and with the > ti-ehrpwm.c driver. > > Changes wrt. v2: > - make the use of '#pwm-cells = <3>' optional, so that the change does > not break existing DT blobs as suggested by Arnd Bergmann and Sascha > Hauer. > > Changes wrt. v3: > - implemented the approach suggested by Sascha Hauer > - don't modify struct pwm_ops in the imx_pwm probe function > > Ping? It's now over a month without any reaction. What should I do with these patches? Lothar Wa?mann -- ___________________________________________________________ Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10 Gesch?ftsf?hrer: Matthias Kaussen Handelsregistereintrag: Amtsgericht Aachen, HRB 4996 www.karo-electronics.de | info at karo-electronics.de ___________________________________________________________ ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv4 0/4] pwm: imx: support output polarity inversion @ 2014-06-12 12:52 Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-06-12 12:52 UTC (permalink / raw) To: linux-arm-kernel This patch series adds support for polarity inversion to the pwm-imx driver. The patches have been tested on i.MX6, i.MX53 and with the ti-ehrpwm.c driver. Changes wrt. v2: - make the use of '#pwm-cells = <3>' optional, so that the change does not break existing DT blobs as suggested by Arnd Bergmann and Sascha Hauer. Changes wrt. v3: - implemented the approach suggested by Sascha Hauer - don't modify struct pwm_ops in the imx_pwm probe function ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() 2014-06-12 12:52 Lothar Waßmann @ 2014-06-12 12:52 ` Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-06-12 12:52 UTC (permalink / raw) To: linux-arm-kernel Make the messages that are printed in case of fatal errors actually visible to the user without having to recompile the driver with debugging enabled. Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 4b66bf0..7af0043 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -525,13 +525,13 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) err = of_parse_phandle_with_args(np, "pwms", "#pwm-cells", index, &args); if (err) { - pr_debug("%s(): can't parse \"pwms\" property\n", __func__); + pr_err("%s(): can't parse \"pwms\" property\n", __func__); return ERR_PTR(err); } pc = of_node_to_pwmchip(args.np); if (IS_ERR(pc)) { - pr_debug("%s(): PWM chip not found\n", __func__); + pr_err("%s(): PWM chip not found\n", __func__); pwm = ERR_CAST(pc); goto put; } -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional 2014-06-12 12:52 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann @ 2014-06-12 12:52 ` Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 3/4] pwm: imx: indentation cleanup Lothar Waßmann 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-06-12 12:52 UTC (permalink / raw) To: linux-arm-kernel Change the pwm chip driver registration, so that a chip driver that supports polarity inversion can still be used with DTBs that don't provide the 'PWM_POLARITY' flag. This is done to provide polarity inversion support for the pwm-imx driver without having to modify all existing DTS files. Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/core.c | 18 ++++++------------ drivers/pwm/pwm-atmel-tcb.c | 1 - drivers/pwm/pwm-atmel.c | 4 +--- drivers/pwm/pwm-pxa.c | 5 ++--- drivers/pwm/pwm-renesas-tpu.c | 1 - drivers/pwm/pwm-samsung.c | 1 - drivers/pwm/pwm-tiecap.c | 1 - drivers/pwm/pwm-tiehrpwm.c | 1 - drivers/pwm/pwm-vt8500.c | 1 - include/linux/pwm.h | 1 - 10 files changed, 9 insertions(+), 25 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 7af0043..ab0fc5a 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -136,7 +136,7 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args) { struct pwm_device *pwm; - if (pc->of_pwm_n_cells < 3) + if (args->args_count != 3) return ERR_PTR(-EINVAL); if (args->args[0] >= pc->npwm) @@ -162,12 +162,15 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) { struct pwm_device *pwm; - if (pc->of_pwm_n_cells < 2) + if (args->args_count < 2) return ERR_PTR(-EINVAL); if (args->args[0] >= pc->npwm) return ERR_PTR(-EINVAL); + if (args->args_count > 2) + return of_pwm_xlate_with_flags(pc, args); + pwm = pwm_request_from_chip(pc, args->args[0], NULL); if (IS_ERR(pwm)) return pwm; @@ -182,10 +185,8 @@ static void of_pwmchip_add(struct pwm_chip *chip) if (!chip->dev || !chip->dev->of_node) return; - if (!chip->of_xlate) { + if (!chip->of_xlate) chip->of_xlate = of_pwm_simple_xlate; - chip->of_pwm_n_cells = 2; - } of_node_get(chip->dev->of_node); } @@ -536,13 +537,6 @@ struct pwm_device *of_pwm_get(struct device_node *np, const char *con_id) goto put; } - if (args.args_count != pc->of_pwm_n_cells) { - pr_debug("%s: wrong #pwm-cells for %s\n", np->full_name, - args.np->full_name); - pwm = ERR_PTR(-EINVAL); - goto put; - } - pwm = pc->of_xlate(pc, &args); if (IS_ERR(pwm)) goto put; diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index f3dcd02..55fabf8 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -395,7 +395,6 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) tcbpwm->chip.dev = &pdev->dev; tcbpwm->chip.ops = &atmel_tcb_pwm_ops; tcbpwm->chip.of_xlate = of_pwm_xlate_with_flags; - tcbpwm->chip.of_pwm_n_cells = 3; tcbpwm->chip.base = -1; tcbpwm->chip.npwm = NPWM; tcbpwm->tc = tc; diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c index 6e700a5..ae7c946 100644 --- a/drivers/pwm/pwm-atmel.c +++ b/drivers/pwm/pwm-atmel.c @@ -350,10 +350,8 @@ static int atmel_pwm_probe(struct platform_device *pdev) atmel_pwm->chip.dev = &pdev->dev; atmel_pwm->chip.ops = &atmel_pwm_ops; - if (pdev->dev.of_node) { + if (pdev->dev.of_node) atmel_pwm->chip.of_xlate = of_pwm_xlate_with_flags; - atmel_pwm->chip.of_pwm_n_cells = 3; - } atmel_pwm->chip.base = -1; atmel_pwm->chip.npwm = 4; diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index 0b312ec..5656052 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -191,10 +191,9 @@ static int pwm_probe(struct platform_device *pdev) pwm->chip.base = -1; pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; - if (IS_ENABLED(CONFIG_OF)) { + if (IS_ENABLED(CONFIG_OF)) pwm->chip.of_xlate = pxa_pwm_of_xlate; - pwm->chip.of_pwm_n_cells = 1; - } + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 3b71b42..5271da3 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c @@ -419,7 +419,6 @@ static int tpu_probe(struct platform_device *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; diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index ba6b650..317d7d1 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -484,7 +484,6 @@ static int pwm_samsung_probe(struct platform_device *pdev) return ret; chip->chip.of_xlate = of_pwm_xlate_with_flags; - chip->chip.of_pwm_n_cells = 3; } else { if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data specified\n"); diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 74efbe7..a8e8282 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -227,7 +227,6 @@ static int ecap_pwm_probe(struct platform_device *pdev) pc->chip.dev = &pdev->dev; pc->chip.ops = &ecap_pwm_ops; pc->chip.of_xlate = of_pwm_xlate_with_flags; - pc->chip.of_pwm_n_cells = 3; pc->chip.base = -1; pc->chip.npwm = 1; diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index cb75133..12a8ae4 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -458,7 +458,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) pc->chip.dev = &pdev->dev; pc->chip.ops = &ehrpwm_pwm_ops; pc->chip.of_xlate = of_pwm_xlate_with_flags; - pc->chip.of_pwm_n_cells = 3; pc->chip.base = -1; pc->chip.npwm = NUM_PWM_CHANNEL; diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 652e6b5..e04a3c0 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c @@ -217,7 +217,6 @@ static int vt8500_pwm_probe(struct platform_device *pdev) chip->chip.dev = &pdev->dev; chip->chip.ops = &vt8500_pwm_ops; chip->chip.of_xlate = of_pwm_xlate_with_flags; - chip->chip.of_pwm_n_cells = 3; chip->chip.base = -1; chip->chip.npwm = VT8500_NR_PWMS; diff --git a/include/linux/pwm.h b/include/linux/pwm.h index e90628c..4cf1569 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -174,7 +174,6 @@ struct pwm_chip { struct pwm_device * (*of_xlate)(struct pwm_chip *pc, const struct of_phandle_args *args); - unsigned int of_pwm_n_cells; bool can_sleep; }; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 3/4] pwm: imx: indentation cleanup 2014-06-12 12:52 ` [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann @ 2014-06-12 12:52 ` Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 4/4] pwm: imx: support output polarity inversion Lothar Waßmann 0 siblings, 1 reply; 10+ messages in thread From: Lothar Waßmann @ 2014-06-12 12:52 UTC (permalink / raw) To: linux-arm-kernel Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/pwm-imx.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index d797c7b..582ac3a 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -25,20 +25,21 @@ #define MX1_PWMS 0x04 /* PWM Sample Register */ #define MX1_PWMP 0x08 /* PWM Period Register */ -#define MX1_PWMC_EN (1 << 4) +#define MX1_PWMC_EN (1 << 4) /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ -#define MX3_PWMCR 0x00 /* PWM Control Register */ -#define MX3_PWMSAR 0x0C /* PWM Sample Register */ -#define MX3_PWMPR 0x10 /* PWM Period Register */ -#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4) -#define MX3_PWMCR_DOZEEN (1 << 24) -#define MX3_PWMCR_WAITEN (1 << 23) +#define MX3_PWMCR 0x00 /* PWM Control Register */ +#define MX3_PWMSAR 0x0C /* PWM Sample Register */ +#define MX3_PWMPR 0x10 /* PWM Period Register */ +#define MX3_PWMCR_PRESCALER(x) ((((x) - 1) & 0xFFF) << 4) +#define MX3_PWMCR_DOZEEN (1 << 24) +#define MX3_PWMCR_WAITEN (1 << 23) #define MX3_PWMCR_DBGEN (1 << 22) -#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) -#define MX3_PWMCR_CLKSRC_IPG (1 << 16) -#define MX3_PWMCR_EN (1 << 0) +#define MX3_PWMCR_POUTC (1 << 18) +#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16) +#define MX3_PWMCR_CLKSRC_IPG (1 << 16) +#define MX3_PWMCR_EN (1 << 0) struct imx_chip { struct clk *clk_per; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCHv4 4/4] pwm: imx: support output polarity inversion 2014-06-12 12:52 ` [PATCHv4 3/4] pwm: imx: indentation cleanup Lothar Waßmann @ 2014-06-12 12:52 ` Lothar Waßmann 0 siblings, 0 replies; 10+ messages in thread From: Lothar Waßmann @ 2014-06-12 12:52 UTC (permalink / raw) To: linux-arm-kernel The i.MX pwm unit on i.MX27 and newer SoCs provides a configurable output polarity. This patch adds support to utilize this feature where available. Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de> --- drivers/pwm/pwm-imx.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 582ac3a..7357bbb 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c @@ -138,6 +138,8 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, if (test_bit(PWMF_ENABLED, &pwm->flags)) cr |= MX3_PWMCR_EN; + if (pwm->polarity == PWM_POLARITY_INVERSED) + cr |= MX3_PWMCR_POUTC; writel(cr, imx->mmio_base + MX3_PWMCR); @@ -156,6 +158,11 @@ static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable) else val &= ~MX3_PWMCR_EN; + if (chip->pwms[0].polarity == PWM_POLARITY_INVERSED) + val |= MX3_PWMCR_POUTC; + else + val &= ~MX3_PWMCR_POUTC; + writel(val, imx->mmio_base + MX3_PWMCR); } @@ -199,27 +206,49 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) clk_disable_unprepare(imx->clk_per); } -static struct pwm_ops imx_pwm_ops = { +static int imx_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + enum pwm_polarity polarity) +{ + struct imx_chip *imx = to_imx_chip(chip); + + dev_dbg(imx->chip.dev, "%s: polarity set to %s\n", __func__, + polarity == PWM_POLARITY_INVERSED ? "inverted" : "normal"); + + return 0; +} + +static struct pwm_ops imx_pwm_ops_v1 = { .enable = imx_pwm_enable, .disable = imx_pwm_disable, .config = imx_pwm_config, .owner = THIS_MODULE, }; +static struct pwm_ops imx_pwm_ops_v2 = { + .enable = imx_pwm_enable, + .disable = imx_pwm_disable, + .set_polarity = imx_pwm_set_polarity, + .config = imx_pwm_config, + .owner = THIS_MODULE, +}; + struct imx_pwm_data { int (*config)(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns); void (*set_enable)(struct pwm_chip *chip, bool enable); + struct pwm_ops *pwm_ops; }; static struct imx_pwm_data imx_pwm_data_v1 = { .config = imx_pwm_config_v1, .set_enable = imx_pwm_set_enable_v1, + .pwm_ops = &imx_pwm_ops_v1, }; static struct imx_pwm_data imx_pwm_data_v2 = { .config = imx_pwm_config_v2, .set_enable = imx_pwm_set_enable_v2, + .pwm_ops = &imx_pwm_ops_v2, }; static const struct of_device_id imx_pwm_dt_ids[] = { @@ -241,6 +270,10 @@ static int imx_pwm_probe(struct platform_device *pdev) if (!of_id) return -ENODEV; + data = of_id->data; + if (data->pwm_ops->set_polarity) + dev_dbg(&pdev->dev, "PWM supports output inversion\n"); + imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL); if (imx == NULL) return -ENOMEM; @@ -259,7 +292,7 @@ static int imx_pwm_probe(struct platform_device *pdev) return PTR_ERR(imx->clk_ipg); } - imx->chip.ops = &imx_pwm_ops; + imx->chip.ops = data->pwm_ops; imx->chip.dev = &pdev->dev; imx->chip.base = -1; imx->chip.npwm = 1; @@ -269,7 +302,6 @@ static int imx_pwm_probe(struct platform_device *pdev) if (IS_ERR(imx->mmio_base)) return PTR_ERR(imx->mmio_base); - data = of_id->data; imx->config = data->config; imx->set_enable = data->set_enable; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-09-29 10:58 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-08-20 6:55 [PATCHv4 0/4] pwm: imx: support output polarity inversion Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 3/4] pwm: imx: indentation cleanup Lothar Waßmann 2014-08-20 6:55 ` [PATCHv4 4/4] pwm: imx: support output polarity inversion Lothar Waßmann 2014-08-26 7:39 ` Shawn Guo 2014-08-26 7:24 ` [PATCHv4 0/4] " Lothar Waßmann 2014-09-29 10:58 ` Sascha Hauer 2014-09-29 10:07 ` Lothar Waßmann -- strict thread matches above, loose matches on Subject: below -- 2014-06-12 12:52 Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 1/4] pwm: print error messages with pr_err() instead of pr_debug() Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 2/4] pwm: make the PWM_POLARITY flag in DTB optional Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 3/4] pwm: imx: indentation cleanup Lothar Waßmann 2014-06-12 12:52 ` [PATCHv4 4/4] pwm: imx: support output polarity inversion Lothar Waßmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).