From 9da01759636f519967c0922ae12bd9fff739db9a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Jul 2013 15:05:39 -0700 Subject: 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(-) (limited to 'drivers') 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) -- cgit v1.2.3 From cfb9e4c40e87dffdce96d3a95c33d01f441b2470 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 9 Jul 2013 23:25:37 -0300 Subject: 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(-) (limited to 'drivers') 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) -- cgit v1.2.3 From 208be7698fe39d54242348aef375fd86180c4506 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Jul 2013 00:54:22 +0200 Subject: 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(-) (limited to 'drivers') 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); -- cgit v1.2.3 From 382457e562bbb1ea7d94923e58fcbac9e981ff18 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 26 Jul 2013 00:27:41 +0200 Subject: 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 --- .../devicetree/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 (limited to 'drivers') 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), } }; -- cgit v1.2.3 From 88d5a2e6ffaa32e2a09a994872ca10aca07a36e9 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 14 Aug 2013 11:11:25 +0200 Subject: 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(-) (limited to 'drivers') 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); -- cgit v1.2.3 From 3943a650f62d0a88788db30c92df584660f3999d Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 2 Aug 2013 15:11:18 +0900 Subject: 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(-) (limited to 'drivers') 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); -- cgit v1.2.3 From ac872bc9ed4452dccfbcebe7d273350103464998 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 2 Aug 2013 15:22:03 +0900 Subject: 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(-) (limited to 'drivers') 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; -- cgit v1.2.3 From 1e185c7aafbb56580feaa5bdbc9e4b1d8efaf710 Mon Sep 17 00:00:00 2001 From: Mike Dunn Date: Thu, 8 Aug 2013 10:00:37 -0700 Subject: 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(-) (limited to 'drivers') 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"); -- cgit v1.2.3