Commit 458c3f60 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-3.12-rc1' of git://gitorious.org/linux-pwm/linux-pwm

Pull pwm changes from Thierry Reding:
 "A set of patches makes the device tree documentation for the various
  PWM drivers more consistent.  Device tree support is added to the
  Renesas TPU driver.  The sysfs interface now makes use of dev_groups.
  Other than that there is a healthy assortment of fixes and
  enhancements for minor issues that have shown up"

* tag 'for-3.12-rc1' of git://gitorious.org/linux-pwm/linux-pwm:
  pwm: pxa: Use module_platform_driver
  pwm: tiehrpwm: add missing __iomem annotation
  pwm: tiecap: add CONFIG_PM_SLEEP to ecap_pwm_{save,restore}_context()
  pwm: simplify use of devm_ioremap_resource
  pwm: renesas-tpu: Add DT support
  ARM: dts: Use the PWM polarity flags
  pwm: Update DT bindings to reference pwm.txt for cells documentation
  pwm: Use the DT macro directly when parsing PWM DT flags
  pwm: Add PWM polarity flag macro for DT
  pwm: mxs: Check the return value from stmp_reset_block()
  pwm: convert class code to use dev_groups
parents f83b0a4e 1e185c7a
......@@ -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:
......
......@@ -3,8 +3,8 @@ Freescale i.MX PWM controller
Required properties:
- compatible: should be "fsl,<soc>-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:
......
......@@ -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:
......
......@@ -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:
......
......@@ -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.
......
......@@ -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
......
......@@ -4,11 +4,9 @@ Required properties:
- compatible: Must be "ti,<soc>-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:
......
......@@ -4,11 +4,9 @@ Required properties:
- compatible: Must be "ti,<soc>-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:
......
......@@ -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
<dt-bindings/pwm/pwm.h>) 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";
};
......
* 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>;
};
......@@ -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:
......
......@@ -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:
......
......@@ -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:
......
......@@ -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:
......
......@@ -14,6 +14,7 @@
/dts-v1/;
#include "am33xx.dtsi"
#include <dt-bindings/pwm/pwm.h>
/ {
model = "TI AM335x EVM-SK";
......@@ -314,7 +315,7 @@ switch@4 {
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>;
};
......
......@@ -11,13 +11,14 @@
/dts-v1/;
/include/ "wm8850.dtsi"
#include <dt-bindings/pwm/pwm.h>
/ {
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>;
......
......@@ -30,10 +30,9 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#define MAX_PWMS 1024
#include <dt-bindings/pwm/pwm.h>
/* 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);
......
......@@ -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);
......
......@@ -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)
......
......@@ -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");
......@@ -20,6 +20,7 @@
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_data/pwm-renesas-tpu.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
......@@ -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,15 +410,14 @@ 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);
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);
......@@ -422,11 +431,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 +465,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),
}
};
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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,
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)
......
/*
* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment