Skip to content

Commit

Permalink
Merge tag 'pwm/for-3.18-rc1' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/thierry.reding/linux-pwm

Pull pwm changes from Thierry Reding:
 "There are no new drivers here, only a couple of fixes all over the
  place"

* tag 'pwm/for-3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm:
  pwm: Let PWM_CLPS711X depend on HAS_IOMEM
  pwm: atmel: Fix calculation of prescale value
  pwm: Fix uninitialized warnings in pwm_get()
  pwm: rockchip: Allow polarity invert on rk3288
  pwm: imx: Avoid sample FIFO overflow for i.MX PWM version2
  pwm: imx: Cleanup indentation for register definitions
  pwm: imx: Fix the macro MX3_PWMCR_PRESCALER(x) definition
  pwm: Fix possible ZERO_SIZE_PTR pointer dereferencing error.
  pwm: lpss: make it buildable only on X86
  pwm: lpss: use c99 initializers in structures
  pwm: lpss: Fix build failure on PowerPC
  pwm: lpss: pci: Move to use pcim_enable_device()
  pwm: lpss: Properly split driver to parts
  pwm: lpss: Add ACPI and PCI IDs for Intel Braswell
  pwm: fsl-ftm: Select REGMAP_MMIO
  pwm: fsl-ftm: Document 'big-endian' property
  pwm: fsl-ftm: Convert to direct regmap API usage
  pwm: fsl-ftm: Clean up the code
  • Loading branch information
Linus Torvalds committed Oct 21, 2014
2 parents 3d430bd + dec02f9 commit 5b9c897
Show file tree
Hide file tree
Showing 13 changed files with 399 additions and 222 deletions.
19 changes: 18 additions & 1 deletion Documentation/devicetree/bindings/pwm/pwm-fsl-ftm.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
Freescale FlexTimer Module (FTM) PWM controller

The same FTM PWM device can have a different endianness on different SoCs. The
device tree provides a property to describing this so that an operating system
device driver can handle all variants of the device. Refer to the table below
for the endianness of the FTM PWM block as integrated into the existing SoCs:

SoC | FTM-PWM endianness
--------+-------------------
Vybrid | LE
LS1 | BE
LS2 | LE

Please see ../regmap/regmap.txt for more detail about how to specify endian
modes in device tree.


Required properties:
- compatible: Should be "fsl,vf610-ftm-pwm".
- reg: Physical base address and length of the controller's registers
Expand All @@ -16,7 +31,8 @@ Required properties:
- pinctrl-names: Must contain a "default" entry.
- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
See pinctrl/pinctrl-bindings.txt for details of the property values.

- big-endian: Boolean property, required if the FTM PWM registers use a big-
endian rather than little-endian layout.

Example:

Expand All @@ -32,4 +48,5 @@ pwm0: pwm@40038000 {
<&clks VF610_CLK_FTM0_EXT_FIX_EN>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm0_1>;
big-endian;
};
4 changes: 2 additions & 2 deletions Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Required properties:
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
- reg: physical base address and length of the controller's registers
- clocks: phandle and clock specifier of the PWM reference clock
- #pwm-cells: should be 2. See pwm.txt in this directory for a
description of the cell format.
- #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
for a description of the cell format.

Example:

Expand Down
22 changes: 21 additions & 1 deletion drivers/pwm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ config PWM_BFIN
config PWM_CLPS711X
tristate "CLPS711X PWM support"
depends on ARCH_CLPS711X || COMPILE_TEST
depends on HAS_IOMEM
help
Generic PWM framework driver for Cirrus Logic CLPS711X.

Expand All @@ -101,6 +102,7 @@ config PWM_EP93XX
config PWM_FSL_FTM
tristate "Freescale FlexTimer Module (FTM) PWM support"
depends on OF
select REGMAP_MMIO
help
Generic FTM PWM framework driver for Freescale VF610 and
Layerscape LS-1 SoCs.
Expand Down Expand Up @@ -149,14 +151,32 @@ config PWM_LPC32XX

config PWM_LPSS
tristate "Intel LPSS PWM support"
depends on ACPI
depends on X86
help
Generic PWM framework driver for Intel Low Power Subsystem PWM
controller.

To compile this driver as a module, choose M here: the module
will be called pwm-lpss.

config PWM_LPSS_PCI
tristate "Intel LPSS PWM PCI driver"
depends on PWM_LPSS && PCI
help
The PCI driver for Intel Low Power Subsystem PWM controller.

To compile this driver as a module, choose M here: the module
will be called pwm-lpss-pci.

config PWM_LPSS_PLATFORM
tristate "Intel LPSS PWM platform driver"
depends on PWM_LPSS && ACPI
help
The platform driver for Intel Low Power Subsystem PWM controller.

To compile this driver as a module, choose M here: the module
will be called pwm-lpss-platform.

config PWM_MXS
tristate "Freescale MXS PWM support"
depends on ARCH_MXS && OF
Expand Down
2 changes: 2 additions & 0 deletions drivers/pwm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
obj-$(CONFIG_PWM_LP3943) += pwm-lp3943.o
obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o
obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
obj-$(CONFIG_PWM_PUV3) += pwm-puv3.o
Expand Down
31 changes: 15 additions & 16 deletions drivers/pwm/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ int pwmchip_add(struct pwm_chip *chip)
int ret;

if (!chip || !chip->dev || !chip->ops || !chip->ops->config ||
!chip->ops->enable || !chip->ops->disable)
!chip->ops->enable || !chip->ops->disable || !chip->npwm)
return -EINVAL;

mutex_lock(&pwm_lock);
Expand Down Expand Up @@ -602,12 +602,9 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER);
const char *dev_id = dev ? dev_name(dev) : NULL;
struct pwm_chip *chip = NULL;
unsigned int index = 0;
unsigned int best = 0;
struct pwm_lookup *p;
struct pwm_lookup *p, *chosen = NULL;
unsigned int match;
unsigned int period;
enum pwm_polarity polarity;

/* look up via DT first */
if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
Expand Down Expand Up @@ -653,10 +650,7 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
}

if (match > best) {
chip = pwmchip_find_by_name(p->provider);
index = p->index;
period = p->period;
polarity = p->polarity;
chosen = p;

if (match != 3)
best = match;
Expand All @@ -665,17 +659,22 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
}
}

mutex_unlock(&pwm_lookup_lock);
if (!chosen)
goto out;

if (chip)
pwm = pwm_request_from_chip(chip, index, con_id ?: dev_id);
if (IS_ERR(pwm))
return pwm;
chip = pwmchip_find_by_name(chosen->provider);
if (!chip)
goto out;

pwm_set_period(pwm, period);
pwm_set_polarity(pwm, polarity);
pwm = pwm_request_from_chip(chip, chosen->index, con_id ?: dev_id);
if (IS_ERR(pwm))
goto out;

pwm_set_period(pwm, chosen->period);
pwm_set_polarity(pwm, chosen->polarity);

out:
mutex_unlock(&pwm_lookup_lock);
return pwm;
}
EXPORT_SYMBOL_GPL(pwm_get);
Expand Down
24 changes: 11 additions & 13 deletions drivers/pwm/pwm-atmel.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns)
{
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
unsigned long clk_rate, prd, dty;
unsigned long prd, dty;
unsigned long long div;
unsigned int pres = 0;
u32 val;
Expand All @@ -113,20 +113,18 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
return -EBUSY;
}

clk_rate = clk_get_rate(atmel_pwm->clk);
div = clk_rate;
/* Calculate the period cycles and prescale value */
div = (unsigned long long)clk_get_rate(atmel_pwm->clk) * period_ns;
do_div(div, NSEC_PER_SEC);

/* Calculate the period cycles */
while (div > PWM_MAX_PRD) {
div = clk_rate / (1 << pres);
div = div * period_ns;
/* 1/Hz = 100000000 ns */
do_div(div, 1000000000);

if (pres++ > PRD_MAX_PRES) {
dev_err(chip->dev, "pres exceeds the maximum value\n");
return -EINVAL;
}
div >>= 1;
pres++;
}

if (pres > PRD_MAX_PRES) {
dev_err(chip->dev, "pres exceeds the maximum value\n");
return -EINVAL;
}

/* Calculate the duty cycles */
Expand Down
Loading

0 comments on commit 5b9c897

Please sign in to comment.