Commit 7b9df264 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pwm/for-5.13-rc1' of...

Merge tag 'pwm/for-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "This adds support for the PWM controller found on Toshiba Visconti
  SoCs and converts a couple of drivers to the atomic API.

  There's also a bunch of cleanups and minor fixes across the board"

* tag 'pwm/for-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (35 commits)
  pwm: Reword docs about pwm_apply_state()
  pwm: atmel: Improve duty cycle calculation in .apply()
  pwm: atmel: Fix duty cycle calculation in .get_state()
  pwm: visconti: Add Toshiba Visconti SoC PWM support
  dt-bindings: pwm: Add bindings for Toshiba Visconti PWM Controller
  arm64: dts: rockchip: Remove clock-names from PWM nodes
  ARM: dts: rockchip: Remove clock-names from PWM nodes
  dt-bindings: pwm: rockchip: Add more compatible strings
  dt-bindings: pwm: Convert pwm-rockchip.txt to YAML
  pwm: mediatek: Remove unused function
  pwm: pca9685: Improve runtime PM behavior
  pwm: pca9685: Support hardware readout
  pwm: pca9685: Switch to atomic API
  pwm: lpss: Don't modify HW state in .remove callback
  pwm: sti: Free resources only after pwmchip_remove()
  pwm: sti: Don't modify HW state in .remove callback
  pwm: lpc3200: Don't modify HW state in .remove callback
  pwm: lpc18xx-sct: Free resources only after pwmchip_remove()
  pwm: bcm-kona: Don't modify HW state in .remove callback
  pwm: bcm2835: Free resources only after pwmchip_remove()
  ...
parents 583f2bcf a6efb350
Rockchip PWM controller
Required properties:
- compatible: should be "rockchip,<name>-pwm"
"rockchip,rk2928-pwm": found on RK29XX,RK3066 and RK3188 SoCs
"rockchip,rk3288-pwm": found on RK3288 SOC
"rockchip,rv1108-pwm", "rockchip,rk3288-pwm": found on RV1108 SoC
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
- reg: physical base address and length of the controller's registers
- clocks: See ../clock/clock-bindings.txt
- For older hardware (rk2928, rk3066, rk3188, rk3228, rk3288, rk3399):
- There is one clock that's used both to derive the functional clock
for the device and as the bus clock.
- For newer hardware (rk3328 and future socs): specified by name
- "pwm": This is used to derive the functional clock.
- "pclk": This is the APB bus clock.
- #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.yaml in this directory
for a description of the cell format.
Example:
pwm0: pwm@20030000 {
compatible = "rockchip,rk2928-pwm";
reg = <0x20030000 0x10>;
clocks = <&cru PCLK_PWM01>;
#pwm-cells = <2>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/pwm/pwm-rockchip.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip PWM controller
maintainers:
- Heiko Stuebner <heiko@sntech.de>
properties:
compatible:
oneOf:
- const: rockchip,rk2928-pwm
- const: rockchip,rk3288-pwm
- const: rockchip,rk3328-pwm
- const: rockchip,vop-pwm
- items:
- const: rockchip,rk3036-pwm
- const: rockchip,rk2928-pwm
- items:
- enum:
- rockchip,rk3368-pwm
- rockchip,rk3399-pwm
- rockchip,rv1108-pwm
- const: rockchip,rk3288-pwm
- items:
- enum:
- rockchip,px30-pwm
- rockchip,rk3308-pwm
- const: rockchip,rk3328-pwm
reg:
maxItems: 1
clocks:
minItems: 1
maxItems: 2
clock-names:
maxItems: 2
"#pwm-cells":
enum: [2, 3]
description:
Must be 2 (rk2928) or 3 (rk3288 and later).
See pwm.yaml for a description of the cell format.
required:
- compatible
- reg
- "#pwm-cells"
if:
properties:
compatible:
contains:
enum:
- rockchip,rk3328-pwm
- rockchip,rv1108-pwm
then:
properties:
clocks:
items:
- description: Used to derive the functional clock for the device.
- description: Used as the APB bus clock.
clock-names:
items:
- const: pwm
- const: pclk
required:
- clocks
- clock-names
else:
properties:
clocks:
maxItems: 1
description:
Used both to derive the functional clock
for the device and as the bus clock.
required:
- clocks
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/rk3188-cru-common.h>
pwm0: pwm@20030000 {
compatible = "rockchip,rk2928-pwm";
reg = <0x20030000 0x10>;
clocks = <&cru PCLK_PWM01>;
#pwm-cells = <2>;
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/pwm/toshiba,pwm-visconti.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Toshiba Visconti PWM Controller
maintainers:
- Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
properties:
compatible:
items:
- const: toshiba,visconti-pwm
reg:
maxItems: 1
'#pwm-cells':
const: 2
required:
- compatible
- reg
- '#pwm-cells'
additionalProperties: false
examples:
- |
soc {
#address-cells = <2>;
#size-cells = <2>;
pwm: pwm@241c0000 {
compatible = "toshiba,visconti-pwm";
reg = <0 0x241c0000 0 0x1000>;
pinctrl-names = "default";
pinctrl-0 = <&pwm_mux>;
#pwm-cells = <2>;
};
};
...@@ -55,7 +55,11 @@ several parameter at once. For example, if you see pwm_config() and ...@@ -55,7 +55,11 @@ several parameter at once. For example, if you see pwm_config() and
pwm_{enable,disable}() calls in the same function, this probably means you pwm_{enable,disable}() calls in the same function, this probably means you
should switch to pwm_apply_state(). should switch to pwm_apply_state().
The PWM user API also allows one to query the PWM state with pwm_get_state(). The PWM user API also allows one to query the PWM state that was passed to the
last invocation of pwm_apply_state() using pwm_get_state(). Note this is
different to what the driver has actually implemented if the request cannot be
satisfied exactly with the hardware in use. There is currently no way for
consumers to get the actually implemented settings.
In addition to the PWM state, the PWM API also exposes PWM arguments, which In addition to the PWM state, the PWM API also exposes PWM arguments, which
are the reference PWM config one should use on this PWM. are the reference PWM config one should use on this PWM.
......
...@@ -355,7 +355,6 @@ pwm0: pwm@20050000 { ...@@ -355,7 +355,6 @@ pwm0: pwm@20050000 {
reg = <0x20050000 0x10>; reg = <0x20050000 0x10>;
#pwm-cells = <3>; #pwm-cells = <3>;
clocks = <&cru PCLK_PWM>; clocks = <&cru PCLK_PWM>;
clock-names = "pwm";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm0_pin>; pinctrl-0 = <&pwm0_pin>;
status = "disabled"; status = "disabled";
...@@ -366,7 +365,6 @@ pwm1: pwm@20050010 { ...@@ -366,7 +365,6 @@ pwm1: pwm@20050010 {
reg = <0x20050010 0x10>; reg = <0x20050010 0x10>;
#pwm-cells = <3>; #pwm-cells = <3>;
clocks = <&cru PCLK_PWM>; clocks = <&cru PCLK_PWM>;
clock-names = "pwm";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm1_pin>; pinctrl-0 = <&pwm1_pin>;
status = "disabled"; status = "disabled";
...@@ -377,7 +375,6 @@ pwm2: pwm@20050020 { ...@@ -377,7 +375,6 @@ pwm2: pwm@20050020 {
reg = <0x20050020 0x10>; reg = <0x20050020 0x10>;
#pwm-cells = <3>; #pwm-cells = <3>;
clocks = <&cru PCLK_PWM>; clocks = <&cru PCLK_PWM>;
clock-names = "pwm";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm2_pin>; pinctrl-0 = <&pwm2_pin>;
status = "disabled"; status = "disabled";
...@@ -388,7 +385,6 @@ pwm3: pwm@20050030 { ...@@ -388,7 +385,6 @@ pwm3: pwm@20050030 {
reg = <0x20050030 0x10>; reg = <0x20050030 0x10>;
#pwm-cells = <2>; #pwm-cells = <2>;
clocks = <&cru PCLK_PWM>; clocks = <&cru PCLK_PWM>;
clock-names = "pwm";
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm3_pin>; pinctrl-0 = <&pwm3_pin>;
status = "disabled"; status = "disabled";
......
...@@ -679,7 +679,6 @@ pwm0: pwm@ff680000 { ...@@ -679,7 +679,6 @@ pwm0: pwm@ff680000 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm0_pin>; pinctrl-0 = <&pwm0_pin>;
clocks = <&cru PCLK_RKPWM>; clocks = <&cru PCLK_RKPWM>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -690,7 +689,6 @@ pwm1: pwm@ff680010 { ...@@ -690,7 +689,6 @@ pwm1: pwm@ff680010 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm1_pin>; pinctrl-0 = <&pwm1_pin>;
clocks = <&cru PCLK_RKPWM>; clocks = <&cru PCLK_RKPWM>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -701,7 +699,6 @@ pwm2: pwm@ff680020 { ...@@ -701,7 +699,6 @@ pwm2: pwm@ff680020 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm2_pin>; pinctrl-0 = <&pwm2_pin>;
clocks = <&cru PCLK_RKPWM>; clocks = <&cru PCLK_RKPWM>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -712,7 +709,6 @@ pwm3: pwm@ff680030 { ...@@ -712,7 +709,6 @@ pwm3: pwm@ff680030 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm3_pin>; pinctrl-0 = <&pwm3_pin>;
clocks = <&cru PCLK_RKPWM>; clocks = <&cru PCLK_RKPWM>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
......
...@@ -558,7 +558,6 @@ pwm0: pwm@ff680000 { ...@@ -558,7 +558,6 @@ pwm0: pwm@ff680000 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm0_pin>; pinctrl-0 = <&pwm0_pin>;
clocks = <&cru PCLK_PWM1>; clocks = <&cru PCLK_PWM1>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -569,7 +568,6 @@ pwm1: pwm@ff680010 { ...@@ -569,7 +568,6 @@ pwm1: pwm@ff680010 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm1_pin>; pinctrl-0 = <&pwm1_pin>;
clocks = <&cru PCLK_PWM1>; clocks = <&cru PCLK_PWM1>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -578,7 +576,6 @@ pwm2: pwm@ff680020 { ...@@ -578,7 +576,6 @@ pwm2: pwm@ff680020 {
reg = <0x0 0xff680020 0x0 0x10>; reg = <0x0 0xff680020 0x0 0x10>;
#pwm-cells = <3>; #pwm-cells = <3>;
clocks = <&cru PCLK_PWM1>; clocks = <&cru PCLK_PWM1>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -589,7 +586,6 @@ pwm3: pwm@ff680030 { ...@@ -589,7 +586,6 @@ pwm3: pwm@ff680030 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm3_pin>; pinctrl-0 = <&pwm3_pin>;
clocks = <&cru PCLK_PWM1>; clocks = <&cru PCLK_PWM1>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
......
...@@ -1182,7 +1182,6 @@ pwm0: pwm@ff420000 { ...@@ -1182,7 +1182,6 @@ pwm0: pwm@ff420000 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm0_pin>; pinctrl-0 = <&pwm0_pin>;
clocks = <&pmucru PCLK_RKPWM_PMU>; clocks = <&pmucru PCLK_RKPWM_PMU>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -1193,7 +1192,6 @@ pwm1: pwm@ff420010 { ...@@ -1193,7 +1192,6 @@ pwm1: pwm@ff420010 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm1_pin>; pinctrl-0 = <&pwm1_pin>;
clocks = <&pmucru PCLK_RKPWM_PMU>; clocks = <&pmucru PCLK_RKPWM_PMU>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -1204,7 +1202,6 @@ pwm2: pwm@ff420020 { ...@@ -1204,7 +1202,6 @@ pwm2: pwm@ff420020 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm2_pin>; pinctrl-0 = <&pwm2_pin>;
clocks = <&pmucru PCLK_RKPWM_PMU>; clocks = <&pmucru PCLK_RKPWM_PMU>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
...@@ -1215,7 +1212,6 @@ pwm3: pwm@ff420030 { ...@@ -1215,7 +1212,6 @@ pwm3: pwm@ff420030 {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pwm3a_pin>; pinctrl-0 = <&pwm3a_pin>;
clocks = <&pmucru PCLK_RKPWM_PMU>; clocks = <&pmucru PCLK_RKPWM_PMU>;
clock-names = "pwm";
status = "disabled"; status = "disabled";
}; };
......
...@@ -618,6 +618,15 @@ config PWM_TWL_LED ...@@ -618,6 +618,15 @@ config PWM_TWL_LED
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called pwm-twl-led. will be called pwm-twl-led.
config PWM_VISCONTI
tristate "Toshiba Visconti PWM support"
depends on ARCH_VISCONTI || COMPILE_TEST
help
PWM Subsystem driver support for Toshiba Visconti SoCs.
To compile this driver as a module, choose M here: the module
will be called pwm-visconti.
config PWM_VT8500 config PWM_VT8500
tristate "vt8500 PWM support" tristate "vt8500 PWM support"
depends on ARCH_VT8500 || COMPILE_TEST depends on ARCH_VT8500 || COMPILE_TEST
......
...@@ -58,4 +58,5 @@ obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o ...@@ -58,4 +58,5 @@ obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
obj-$(CONFIG_PWM_TWL) += pwm-twl.o obj-$(CONFIG_PWM_TWL) += pwm-twl.o
obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o
obj-$(CONFIG_PWM_VISCONTI) += pwm-visconti.o
obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
...@@ -37,23 +37,13 @@ static struct pwm_device *pwm_to_device(unsigned int pwm) ...@@ -37,23 +37,13 @@ static struct pwm_device *pwm_to_device(unsigned int pwm)
return radix_tree_lookup(&pwm_tree, pwm); return radix_tree_lookup(&pwm_tree, pwm);
} }
static int alloc_pwms(int pwm, unsigned int count) static int alloc_pwms(unsigned int count)
{ {
unsigned int from = 0;
unsigned int start; unsigned int start;
if (pwm >= MAX_PWMS) start = bitmap_find_next_zero_area(allocated_pwms, MAX_PWMS, 0,
return -EINVAL;
if (pwm >= 0)
from = pwm;
start = bitmap_find_next_zero_area(allocated_pwms, MAX_PWMS, from,
count, 0); count, 0);
if (pwm >= 0 && start != pwm)
return -EEXIST;
if (start + count > MAX_PWMS) if (start + count > MAX_PWMS)
return -ENOSPC; return -ENOSPC;
...@@ -260,18 +250,14 @@ static bool pwm_ops_check(const struct pwm_chip *chip) ...@@ -260,18 +250,14 @@ static bool pwm_ops_check(const struct pwm_chip *chip)
} }
/** /**
* pwmchip_add_with_polarity() - register a new PWM chip * pwmchip_add() - register a new PWM chip
* @chip: the PWM chip to add * @chip: the PWM chip to add
* @polarity: initial polarity of PWM channels
* *
* Register a new PWM chip. If chip->base < 0 then a dynamically assigned base * Register a new PWM chip.
* will be used. The initial polarity for all channels is specified by the
* @polarity parameter.
* *
* Returns: 0 on success or a negative error code on failure. * Returns: 0 on success or a negative error code on failure.
*/ */
int pwmchip_add_with_polarity(struct pwm_chip *chip, int pwmchip_add(struct pwm_chip *chip)
enum pwm_polarity polarity)
{ {
struct pwm_device *pwm; struct pwm_device *pwm;
unsigned int i; unsigned int i;
...@@ -285,25 +271,24 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip, ...@@ -285,25 +271,24 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
mutex_lock(&pwm_lock); mutex_lock(&pwm_lock);
ret = alloc_pwms(chip->base, chip->npwm); ret = alloc_pwms(chip->npwm);
if (ret < 0) if (ret < 0)
goto out; goto out;
chip->base = ret;
chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL); chip->pwms = kcalloc(chip->npwm, sizeof(*pwm), GFP_KERNEL);
if (!chip->pwms) { if (!chip->pwms) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
chip->base = ret;
for (i = 0; i < chip->npwm; i++) { for (i = 0; i < chip->npwm; i++) {
pwm = &chip->pwms[i]; pwm = &chip->pwms[i];
pwm->chip = chip; pwm->chip = chip;
pwm->pwm = chip->base + i; pwm->pwm = chip->base + i;
pwm->hwpwm = i; pwm->hwpwm = i;
pwm->state.polarity = polarity;
radix_tree_insert(&pwm_tree, pwm->pwm, pwm); radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
} }
...@@ -326,21 +311,6 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip, ...@@ -326,21 +311,6 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(pwmchip_add_with_polarity);
/**
* pwmchip_add() - register a new PWM chip
* @chip: the PWM chip to add
*
* Register a new PWM chip. If chip->base < 0 then a dynamically assigned base
* will be used. The initial polarity for all channels is normal.
*
* Returns: 0 on success or a negative error code on failure.
*/
int pwmchip_add(struct pwm_chip *chip)
{
return pwmchip_add_with_polarity(chip, PWM_POLARITY_NORMAL);
}
EXPORT_SYMBOL_GPL(pwmchip_add); EXPORT_SYMBOL_GPL(pwmchip_add);
/** /**
...@@ -607,7 +577,7 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) ...@@ -607,7 +577,7 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
*/ */
if (state->polarity != pwm->state.polarity) { if (state->polarity != pwm->state.polarity) {
if (!chip->ops->set_polarity) if (!chip->ops->set_polarity)
return -ENOTSUPP; return -EINVAL;
/* /*
* Changing the polarity of a running PWM is * Changing the polarity of a running PWM is
......
...@@ -24,23 +24,37 @@ struct ab8500_pwm_chip { ...@@ -24,23 +24,37 @@ struct ab8500_pwm_chip {
struct pwm_chip chip; struct pwm_chip chip;
}; };
static int ab8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
int duty_ns, int period_ns) const struct pwm_state *state)
{ {
int ret = 0; int ret;
unsigned int higher_val, lower_val;
u8 reg; u8 reg;
unsigned int higher_val, lower_val;
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
if (!state->enabled) {
ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
1 << (chip->base - 1), 0);
if (ret < 0)
dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
pwm->label, ret);
return ret;
}
/* /*
* get the first 8 bits that are be written to * get the first 8 bits that are be written to
* AB8500_PWM_OUT_CTRL1_REG[0:7] * AB8500_PWM_OUT_CTRL1_REG[0:7]
*/ */
lower_val = duty_ns & 0x00FF; lower_val = state->duty_cycle & 0x00FF;
/* /*
* get bits [9:10] that are to be written to * get bits [9:10] that are to be written to
* AB8500_PWM_OUT_CTRL2_REG[0:1] * AB8500_PWM_OUT_CTRL2_REG[0:1]
*/ */
higher_val = ((duty_ns & 0x0300) >> 8); higher_val = ((state->duty_cycle & 0x0300) >> 8);
reg = AB8500_PWM_OUT_CTRL1_REG + ((chip->base - 1) * 2); reg = AB8500_PWM_OUT_CTRL1_REG + ((chip->base - 1) * 2);
...@@ -48,15 +62,11 @@ static int ab8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -48,15 +62,11 @@ static int ab8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
reg, (u8)lower_val); reg, (u8)lower_val);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
(reg + 1), (u8)higher_val); (reg + 1), (u8)higher_val);
if (ret < 0)
return ret; return ret;
}
static int ab8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
int ret;
ret = abx500_mask_and_set_register_interruptible(chip->dev, ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
...@@ -64,25 +74,12 @@ static int ab8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -64,25 +74,12 @@ static int ab8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
if (ret < 0) if (ret < 0)
dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
pwm->label, ret); pwm->label, ret);
return ret;
}
static void ab8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) return ret;
{
int ret;
ret = abx500_mask_and_set_register_interruptible(chip->dev,
AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
1 << (chip->base - 1), 0);
if (ret < 0)
dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
pwm->label, ret);
} }
static const struct pwm_ops ab8500_pwm_ops = { static const struct pwm_ops ab8500_pwm_ops = {
.config = ab8500_pwm_config, .apply = ab8500_pwm_apply,
.enable = ab8500_pwm_enable,
.disable = ab8500_pwm_disable,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -101,7 +98,6 @@ static int ab8500_pwm_probe(struct platform_device *pdev) ...@@ -101,7 +98,6 @@ static int ab8500_pwm_probe(struct platform_device *pdev)
ab8500->chip.dev = &pdev->dev; ab8500->chip.dev = &pdev->dev;
ab8500->chip.ops = &ab8500_pwm_ops; ab8500->chip.ops = &ab8500_pwm_ops;
ab8500->chip.base = -1;
ab8500->chip.npwm = 1; ab8500->chip.npwm = 1;
err = pwmchip_add(&ab8500->chip); err = pwmchip_add(&ab8500->chip);
......
...@@ -265,12 +265,11 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev) ...@@ -265,12 +265,11 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
chip->hlcdc = hlcdc; chip->hlcdc = hlcdc;
chip->chip.ops = &atmel_hlcdc_pwm_ops; chip->chip.ops = &atmel_hlcdc_pwm_ops;
chip->chip.dev = dev; chip->chip.dev = dev;
chip->chip.base = -1;
chip->chip.npwm = 1; chip->chip.npwm = 1;
chip->chip.of_xlate = of_pwm_xlate_with_flags; chip->chip.of_xlate = of_pwm_xlate_with_flags;
chip->chip.of_pwm_n_cells = 3; chip->chip.of_pwm_n_cells = 3;
ret = pwmchip_add_with_polarity(&chip->chip, PWM_POLARITY_INVERSED); ret = pwmchip_add(&chip->chip);
if (ret) { if (ret) {
clk_disable_unprepare(hlcdc->periph_clk); clk_disable_unprepare(hlcdc->periph_clk);
return ret; return ret;
......
...@@ -362,20 +362,37 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -362,20 +362,37 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
tcbpwm->div = i; tcbpwm->div = i;
tcbpwm->duty = duty; tcbpwm->duty = duty;
/* If the PWM is enabled, call enable to apply the new conf */
if (pwm_is_enabled(pwm))
atmel_tcb_pwm_enable(chip, pwm);
return 0; return 0;
} }
static int atmel_tcb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
int duty_cycle, period;
int ret;
/* This function only sets a flag in driver data */
atmel_tcb_pwm_set_polarity(chip, pwm, state->polarity);
if (!state->enabled) {
atmel_tcb_pwm_disable(chip, pwm);
return 0;
}
period = state->period < INT_MAX ? state->period : INT_MAX;
duty_cycle = state->duty_cycle < INT_MAX ? state->duty_cycle : INT_MAX;
ret = atmel_tcb_pwm_config(chip, pwm, duty_cycle, period);
if (ret)
return ret;
return atmel_tcb_pwm_enable(chip, pwm);
}
static const struct pwm_ops atmel_tcb_pwm_ops = { static const struct pwm_ops atmel_tcb_pwm_ops = {
.request = atmel_tcb_pwm_request, .request = atmel_tcb_pwm_request,
.free = atmel_tcb_pwm_free, .free = atmel_tcb_pwm_free,
.config = atmel_tcb_pwm_config, .apply = atmel_tcb_pwm_apply,
.set_polarity = atmel_tcb_pwm_set_polarity,
.enable = atmel_tcb_pwm_enable,
.disable = atmel_tcb_pwm_disable,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -454,7 +471,6 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev) ...@@ -454,7 +471,6 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
tcbpwm->chip.ops = &atmel_tcb_pwm_ops; tcbpwm->chip.ops = &atmel_tcb_pwm_ops;
tcbpwm->chip.of_xlate = of_pwm_xlate_with_flags; tcbpwm->chip.of_xlate = of_pwm_xlate_with_flags;
tcbpwm->chip.of_pwm_n_cells = 3; tcbpwm->chip.of_pwm_n_cells = 3;
tcbpwm->chip.base = -1;
tcbpwm->chip.npwm = NPWM; tcbpwm->chip.npwm = NPWM;
tcbpwm->channel = channel; tcbpwm->channel = channel;
tcbpwm->regmap = regmap; tcbpwm->regmap = regmap;
...@@ -491,14 +507,14 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev) ...@@ -491,14 +507,14 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev)
struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
int err; int err;
clk_disable_unprepare(tcbpwm->slow_clk);
clk_put(tcbpwm->slow_clk);
clk_put(tcbpwm->clk);
err = pwmchip_remove(&tcbpwm->chip); err = pwmchip_remove(&tcbpwm->chip);
if (err < 0) if (err < 0)
return err; return err;
clk_disable_unprepare(tcbpwm->slow_clk);
clk_put(tcbpwm->slow_clk);
clk_put(tcbpwm->clk);
return 0; return 0;
} }
......
...@@ -124,6 +124,7 @@ static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip, ...@@ -124,6 +124,7 @@ static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
} }
static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip, static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
unsigned long clkrate,
const struct pwm_state *state, const struct pwm_state *state,
unsigned long *cprd, u32 *pres) unsigned long *cprd, u32 *pres)
{ {
...@@ -132,7 +133,7 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip, ...@@ -132,7 +133,7 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
int shift; int shift;
/* Calculate the period cycles and prescale value */ /* Calculate the period cycles and prescale value */
cycles *= clk_get_rate(atmel_pwm->clk); cycles *= clkrate;
do_div(cycles, NSEC_PER_SEC); do_div(cycles, NSEC_PER_SEC);
/* /*
...@@ -158,12 +159,14 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip, ...@@ -158,12 +159,14 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
} }
static void atmel_pwm_calculate_cdty(const struct pwm_state *state, static void atmel_pwm_calculate_cdty(const struct pwm_state *state,
unsigned long cprd, unsigned long *cdty) unsigned long clkrate, unsigned long cprd,
u32 pres, unsigned long *cdty)
{ {
unsigned long long cycles = state->duty_cycle; unsigned long long cycles = state->duty_cycle;
cycles *= cprd; cycles *= clkrate;
do_div(cycles, state->period); do_div(cycles, NSEC_PER_SEC);
cycles >>= pres;
*cdty = cprd - cycles; *cdty = cprd - cycles;
} }
...@@ -244,17 +247,23 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -244,17 +247,23 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
pwm_get_state(pwm, &cstate); pwm_get_state(pwm, &cstate);
if (state->enabled) { if (state->enabled) {
unsigned long clkrate = clk_get_rate(atmel_pwm->clk);
if (cstate.enabled && if (cstate.enabled &&
cstate.polarity == state->polarity && cstate.polarity == state->polarity &&
cstate.period == state->period) { cstate.period == state->period) {
u32 cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
atmel_pwm->data->regs.period); atmel_pwm->data->regs.period);
atmel_pwm_calculate_cdty(state, cprd, &cdty); pres = cmr & PWM_CMR_CPRE_MSK;
atmel_pwm_calculate_cdty(state, clkrate, cprd, pres, &cdty);
atmel_pwm_update_cdty(chip, pwm, cdty); atmel_pwm_update_cdty(chip, pwm, cdty);
return 0; return 0;
} }
ret = atmel_pwm_calculate_cprd_and_pres(chip, state, &cprd, ret = atmel_pwm_calculate_cprd_and_pres(chip, clkrate, state, &cprd,
&pres); &pres);
if (ret) { if (ret) {
dev_err(chip->dev, dev_err(chip->dev,
...@@ -262,7 +271,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -262,7 +271,7 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return ret; return ret;
} }
atmel_pwm_calculate_cdty(state, cprd, &cdty); atmel_pwm_calculate_cdty(state, clkrate, cprd, pres, &cdty);
if (cstate.enabled) { if (cstate.enabled) {
atmel_pwm_disable(chip, pwm, false); atmel_pwm_disable(chip, pwm, false);
...@@ -319,7 +328,7 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -319,7 +328,7 @@ static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
atmel_pwm->data->regs.duty); atmel_pwm->data->regs.duty);
tmp = (u64)cdty * NSEC_PER_SEC; tmp = (u64)(cprd - cdty) * NSEC_PER_SEC;
tmp <<= pres; tmp <<= pres;
state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate); state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate);
...@@ -429,7 +438,6 @@ static int atmel_pwm_probe(struct platform_device *pdev) ...@@ -429,7 +438,6 @@ static int atmel_pwm_probe(struct platform_device *pdev)
atmel_pwm->chip.ops = &atmel_pwm_ops; atmel_pwm->chip.ops = &atmel_pwm_ops;
atmel_pwm->chip.of_xlate = of_pwm_xlate_with_flags; atmel_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
atmel_pwm->chip.of_pwm_n_cells = 3; atmel_pwm->chip.of_pwm_n_cells = 3;
atmel_pwm->chip.base = -1;
atmel_pwm->chip.npwm = 4; atmel_pwm->chip.npwm = 4;
ret = pwmchip_add(&atmel_pwm->chip); ret = pwmchip_add(&atmel_pwm->chip);
...@@ -451,10 +459,12 @@ static int atmel_pwm_remove(struct platform_device *pdev) ...@@ -451,10 +459,12 @@ static int atmel_pwm_remove(struct platform_device *pdev)
{ {
struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev); struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);
pwmchip_remove(&atmel_pwm->chip);
clk_unprepare(atmel_pwm->clk); clk_unprepare(atmel_pwm->clk);
mutex_destroy(&atmel_pwm->isr_lock); mutex_destroy(&atmel_pwm->isr_lock);
return pwmchip_remove(&atmel_pwm->chip); return 0;
} }
static struct platform_driver atmel_pwm_driver = { static struct platform_driver atmel_pwm_driver = {
......
...@@ -209,7 +209,6 @@ static int iproc_pwmc_probe(struct platform_device *pdev) ...@@ -209,7 +209,6 @@ static int iproc_pwmc_probe(struct platform_device *pdev)
ip->chip.dev = &pdev->dev; ip->chip.dev = &pdev->dev;
ip->chip.ops = &iproc_pwm_ops; ip->chip.ops = &iproc_pwm_ops;
ip->chip.base = -1;
ip->chip.npwm = 4; ip->chip.npwm = 4;
ip->chip.of_xlate = of_pwm_xlate_with_flags; ip->chip.of_xlate = of_pwm_xlate_with_flags;
ip->chip.of_pwm_n_cells = 3; ip->chip.of_pwm_n_cells = 3;
...@@ -254,9 +253,11 @@ static int iproc_pwmc_remove(struct platform_device *pdev) ...@@ -254,9 +253,11 @@ static int iproc_pwmc_remove(struct platform_device *pdev)
{ {
struct iproc_pwmc *ip = platform_get_drvdata(pdev); struct iproc_pwmc *ip = platform_get_drvdata(pdev);
pwmchip_remove(&ip->chip);
clk_disable_unprepare(ip->clk); clk_disable_unprepare(ip->clk);
return pwmchip_remove(&ip->chip); return 0;
} }
static const struct of_device_id bcm_iproc_pwmc_dt[] = { static const struct of_device_id bcm_iproc_pwmc_dt[] = {
......
...@@ -271,7 +271,6 @@ static int kona_pwmc_probe(struct platform_device *pdev) ...@@ -271,7 +271,6 @@ static int kona_pwmc_probe(struct platform_device *pdev)
kp->chip.dev = &pdev->dev; kp->chip.dev = &pdev->dev;
kp->chip.ops = &kona_pwm_ops; kp->chip.ops = &kona_pwm_ops;
kp->chip.base = -1;
kp->chip.npwm = 6; kp->chip.npwm = 6;
kp->chip.of_xlate = of_pwm_xlate_with_flags; kp->chip.of_xlate = of_pwm_xlate_with_flags;
kp->chip.of_pwm_n_cells = 3; kp->chip.of_pwm_n_cells = 3;
...@@ -301,7 +300,7 @@ static int kona_pwmc_probe(struct platform_device *pdev) ...@@ -301,7 +300,7 @@ static int kona_pwmc_probe(struct platform_device *pdev)
clk_disable_unprepare(kp->clk); clk_disable_unprepare(kp->clk);
ret = pwmchip_add_with_polarity(&kp->chip, PWM_POLARITY_INVERSED); ret = pwmchip_add(&kp->chip);
if (ret < 0) if (ret < 0)
dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
...@@ -311,11 +310,6 @@ static int kona_pwmc_probe(struct platform_device *pdev) ...@@ -311,11 +310,6 @@ static int kona_pwmc_probe(struct platform_device *pdev)
static int kona_pwmc_remove(struct platform_device *pdev) static int kona_pwmc_remove(struct platform_device *pdev)
{ {
struct kona_pwmc *kp = platform_get_drvdata(pdev); struct kona_pwmc *kp = platform_get_drvdata(pdev);
unsigned int chan;
for (chan = 0; chan < kp->chip.npwm; chan++)
if (pwm_is_enabled(&kp->chip.pwms[chan]))
clk_disable_unprepare(kp->clk);
return pwmchip_remove(&kp->chip); return pwmchip_remove(&kp->chip);
} }
......
...@@ -64,8 +64,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -64,8 +64,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); struct bcm2835_pwm *pc = to_bcm2835_pwm(chip);
unsigned long rate = clk_get_rate(pc->clk); unsigned long rate = clk_get_rate(pc->clk);
unsigned long long period; unsigned long long period_cycles;
unsigned long scaler; u64 max_period;
u32 val; u32 val;
if (!rate) { if (!rate) {
...@@ -73,18 +74,36 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -73,18 +74,36 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
return -EINVAL; return -EINVAL;
} }
scaler = DIV_ROUND_CLOSEST(NSEC_PER_SEC, rate); /*
* period_cycles must be a 32 bit value, so period * rate / NSEC_PER_SEC
* must be <= U32_MAX. As U32_MAX * NSEC_PER_SEC < U64_MAX the
* multiplication period * rate doesn't overflow.
* To calculate the maximal possible period that guarantees the
* above inequality:
*
* round(period * rate / NSEC_PER_SEC) <= U32_MAX
* <=> period * rate / NSEC_PER_SEC < U32_MAX + 0.5
* <=> period * rate < (U32_MAX + 0.5) * NSEC_PER_SEC
* <=> period < ((U32_MAX + 0.5) * NSEC_PER_SEC) / rate
* <=> period < ((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate
* <=> period <= ceil((U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC/2) / rate) - 1
*/
max_period = DIV_ROUND_UP_ULL((u64)U32_MAX * NSEC_PER_SEC + NSEC_PER_SEC / 2, rate) - 1;
if (state->period > max_period)
return -EINVAL;
/* set period */ /* set period */
period = DIV_ROUND_CLOSEST_ULL(state->period, scaler); period_cycles = DIV_ROUND_CLOSEST_ULL(state->period * rate, NSEC_PER_SEC);
/* dont accept a period that is too small or has been truncated */ /* don't accept a period that is too small */
if ((period < PERIOD_MIN) || (period > U32_MAX)) if (period_cycles < PERIOD_MIN)
return -EINVAL; return -EINVAL;
writel(period, pc->base + PERIOD(pwm->hwpwm)); writel(period_cycles, pc->base + PERIOD(pwm->hwpwm));
/* set duty cycle */ /* set duty cycle */
val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle, scaler); val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle * rate, NSEC_PER_SEC);
writel(val, pc->base + DUTY(pwm->hwpwm)); writel(val, pc->base + DUTY(pwm->hwpwm));
/* set polarity */ /* set polarity */
...@@ -139,7 +158,6 @@ static int bcm2835_pwm_probe(struct platform_device *pdev) ...@@ -139,7 +158,6 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev; pc->chip.dev = &pdev->dev;
pc->chip.ops = &bcm2835_pwm_ops; pc->chip.ops = &bcm2835_pwm_ops;
pc->chip.base = -1;
pc->chip.npwm = 2; pc->chip.npwm = 2;
pc->chip.of_xlate = of_pwm_xlate_with_flags; pc->chip.of_xlate = of_pwm_xlate_with_flags;
pc->chip.of_pwm_n_cells = 3; pc->chip.of_pwm_n_cells = 3;
...@@ -161,9 +179,11 @@ static int bcm2835_pwm_remove(struct platform_device *pdev) ...@@ -161,9 +179,11 @@ static int bcm2835_pwm_remove(struct platform_device *pdev)
{ {
struct bcm2835_pwm *pc = platform_get_drvdata(pdev); struct bcm2835_pwm *pc = platform_get_drvdata(pdev);
pwmchip_remove(&pc->chip);
clk_disable_unprepare(pc->clk); clk_disable_unprepare(pc->clk);
return pwmchip_remove(&pc->chip); return 0;
} }
static const struct of_device_id bcm2835_pwm_of_match[] = { static const struct of_device_id bcm2835_pwm_of_match[] = {
......
...@@ -206,7 +206,6 @@ static int berlin_pwm_probe(struct platform_device *pdev) ...@@ -206,7 +206,6 @@ static int berlin_pwm_probe(struct platform_device *pdev)
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &berlin_pwm_ops; pwm->chip.ops = &berlin_pwm_ops;
pwm->chip.base = -1;
pwm->chip.npwm = 4; pwm->chip.npwm = 4;
pwm->chip.of_xlate = of_pwm_xlate_with_flags; pwm->chip.of_xlate = of_pwm_xlate_with_flags;
pwm->chip.of_pwm_n_cells = 3; pwm->chip.of_pwm_n_cells = 3;
......
...@@ -258,7 +258,6 @@ static int brcmstb_pwm_probe(struct platform_device *pdev) ...@@ -258,7 +258,6 @@ static int brcmstb_pwm_probe(struct platform_device *pdev)
p->chip.dev = &pdev->dev; p->chip.dev = &pdev->dev;
p->chip.ops = &brcmstb_pwm_ops; p->chip.ops = &brcmstb_pwm_ops;
p->chip.base = -1;
p->chip.npwm = 2; p->chip.npwm = 2;
p->base = devm_platform_ioremap_resource(pdev, 0); p->base = devm_platform_ioremap_resource(pdev, 0);
......
...@@ -128,7 +128,6 @@ static int clps711x_pwm_probe(struct platform_device *pdev) ...@@ -128,7 +128,6 @@ static int clps711x_pwm_probe(struct platform_device *pdev)
priv->chip.ops = &clps711x_pwm_ops; priv->chip.ops = &clps711x_pwm_ops;
priv->chip.dev = &pdev->dev; priv->chip.dev = &pdev->dev;
priv->chip.base = -1;
priv->chip.npwm = 2; priv->chip.npwm = 2;
priv->chip.of_xlate = clps711x_pwm_xlate; priv->chip.of_xlate = clps711x_pwm_xlate;
priv->chip.of_pwm_n_cells = 1; priv->chip.of_pwm_n_cells = 1;
......
...@@ -168,7 +168,6 @@ static int crystalcove_pwm_probe(struct platform_device *pdev) ...@@ -168,7 +168,6 @@ static int crystalcove_pwm_probe(struct platform_device *pdev)
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &crc_pwm_ops; pwm->chip.ops = &crc_pwm_ops;
pwm->chip.base = -1;
pwm->chip.npwm = 1; pwm->chip.npwm = 1;
/* get the PMIC regmap */ /* get the PMIC regmap */
......
...@@ -124,6 +124,9 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -124,6 +124,9 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (state->period != EC_PWM_MAX_DUTY) if (state->period != EC_PWM_MAX_DUTY)
return -EINVAL; return -EINVAL;
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
/* /*
* EC doesn't separate the concept of duty cycle and enabled, but * EC doesn't separate the concept of duty cycle and enabled, but
* kernel does. Translate. * kernel does. Translate.
...@@ -253,7 +256,6 @@ static int cros_ec_pwm_probe(struct platform_device *pdev) ...@@ -253,7 +256,6 @@ static int cros_ec_pwm_probe(struct platform_device *pdev)
chip->ops = &cros_ec_pwm_ops; chip->ops = &cros_ec_pwm_ops;
chip->of_xlate = cros_ec_pwm_xlate; chip->of_xlate = cros_ec_pwm_xlate;
chip->of_pwm_n_cells = 1; chip->of_pwm_n_cells = 1;
chip->base = -1;
ret = cros_ec_num_pwms(ec); ret = cros_ec_num_pwms(ec);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Couldn't find PWMs: %d\n", ret); dev_err(dev, "Couldn't find PWMs: %d\n", ret);
......
...@@ -233,7 +233,6 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id) ...@@ -233,7 +233,6 @@ static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
dwc->chip.dev = dev; dwc->chip.dev = dev;
dwc->chip.ops = &dwc_pwm_ops; dwc->chip.ops = &dwc_pwm_ops;
dwc->chip.npwm = DWC_TIMERS_TOTAL; dwc->chip.npwm = DWC_TIMERS_TOTAL;
dwc->chip.base = -1;
ret = pwmchip_add(&dwc->chip); ret = pwmchip_add(&dwc->chip);
if (ret) if (ret)
......
...@@ -185,7 +185,6 @@ static int ep93xx_pwm_probe(struct platform_device *pdev) ...@@ -185,7 +185,6 @@ static int ep93xx_pwm_probe(struct platform_device *pdev)
ep93xx_pwm->chip.dev = &pdev->dev; ep93xx_pwm->chip.dev = &pdev->dev;
ep93xx_pwm->chip.ops = &ep93xx_pwm_ops; ep93xx_pwm->chip.ops = &ep93xx_pwm_ops;
ep93xx_pwm->chip.base = -1;
ep93xx_pwm->chip.npwm = 1; ep93xx_pwm->chip.npwm = 1;
ret = pwmchip_add(&ep93xx_pwm->chip); ret = pwmchip_add(&ep93xx_pwm->chip);
......
...@@ -453,7 +453,6 @@ static int fsl_pwm_probe(struct platform_device *pdev) ...@@ -453,7 +453,6 @@ static int fsl_pwm_probe(struct platform_device *pdev)
fpc->chip.ops = &fsl_pwm_ops; fpc->chip.ops = &fsl_pwm_ops;
fpc->chip.of_xlate = of_pwm_xlate_with_flags; fpc->chip.of_xlate = of_pwm_xlate_with_flags;
fpc->chip.of_pwm_n_cells = 3; fpc->chip.of_pwm_n_cells = 3;
fpc->chip.base = -1;
fpc->chip.npwm = 8; fpc->chip.npwm = 8;
ret = pwmchip_add(&fpc->chip); ret = pwmchip_add(&fpc->chip);
......
...@@ -205,7 +205,6 @@ static int hibvt_pwm_probe(struct platform_device *pdev) ...@@ -205,7 +205,6 @@ static int hibvt_pwm_probe(struct platform_device *pdev)
pwm_chip->chip.ops = &hibvt_pwm_ops; pwm_chip->chip.ops = &hibvt_pwm_ops;
pwm_chip->chip.dev = &pdev->dev; pwm_chip->chip.dev = &pdev->dev;
pwm_chip->chip.base = -1;
pwm_chip->chip.npwm = soc->num_pwms; pwm_chip->chip.npwm = soc->num_pwms;
pwm_chip->chip.of_xlate = of_pwm_xlate_with_flags; pwm_chip->chip.of_xlate = of_pwm_xlate_with_flags;
pwm_chip->chip.of_pwm_n_cells = 3; pwm_chip->chip.of_pwm_n_cells = 3;
......
...@@ -304,7 +304,6 @@ static int img_pwm_probe(struct platform_device *pdev) ...@@ -304,7 +304,6 @@ static int img_pwm_probe(struct platform_device *pdev)
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &img_pwm_ops; pwm->chip.ops = &img_pwm_ops;
pwm->chip.base = -1;
pwm->chip.npwm = IMG_PWM_NPWM; pwm->chip.npwm = IMG_PWM_NPWM;
ret = pwmchip_add(&pwm->chip); ret = pwmchip_add(&pwm->chip);
......
...@@ -363,7 +363,6 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev) ...@@ -363,7 +363,6 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
tpm->chip.dev = &pdev->dev; tpm->chip.dev = &pdev->dev;
tpm->chip.ops = &imx_tpm_pwm_ops; tpm->chip.ops = &imx_tpm_pwm_ops;
tpm->chip.base = -1;
tpm->chip.of_xlate = of_pwm_xlate_with_flags; tpm->chip.of_xlate = of_pwm_xlate_with_flags;
tpm->chip.of_pwm_n_cells = 3; tpm->chip.of_pwm_n_cells = 3;
...@@ -411,9 +410,7 @@ static int __maybe_unused pwm_imx_tpm_resume(struct device *dev) ...@@ -411,9 +410,7 @@ static int __maybe_unused pwm_imx_tpm_resume(struct device *dev)
ret = clk_prepare_enable(tpm->clk); ret = clk_prepare_enable(tpm->clk);
if (ret) if (ret)
dev_err(dev, dev_err(dev, "failed to prepare or enable clock: %d\n", ret);
"failed to prepare or enable clock: %d\n",
ret);
return ret; return ret;
} }
......
...@@ -155,7 +155,6 @@ static int pwm_imx1_probe(struct platform_device *pdev) ...@@ -155,7 +155,6 @@ static int pwm_imx1_probe(struct platform_device *pdev)
imx->chip.ops = &pwm_imx1_ops; imx->chip.ops = &pwm_imx1_ops;
imx->chip.dev = &pdev->dev; imx->chip.dev = &pdev->dev;
imx->chip.base = -1;
imx->chip.npwm = 1; imx->chip.npwm = 1;
imx->mmio_base = devm_platform_ioremap_resource(pdev, 0); imx->mmio_base = devm_platform_ioremap_resource(pdev, 0);
......
...@@ -327,7 +327,6 @@ static int pwm_imx27_probe(struct platform_device *pdev) ...@@ -327,7 +327,6 @@ static int pwm_imx27_probe(struct platform_device *pdev)
imx->chip.ops = &pwm_imx27_ops; imx->chip.ops = &pwm_imx27_ops;
imx->chip.dev = &pdev->dev; imx->chip.dev = &pdev->dev;
imx->chip.base = -1;
imx->chip.npwm = 1; imx->chip.npwm = 1;
imx->chip.of_xlate = of_pwm_xlate_with_flags; imx->chip.of_xlate = of_pwm_xlate_with_flags;
......
...@@ -207,7 +207,6 @@ static int lgm_pwm_probe(struct platform_device *pdev) ...@@ -207,7 +207,6 @@ static int lgm_pwm_probe(struct platform_device *pdev)
pc->chip.dev = dev; pc->chip.dev = dev;
pc->chip.ops = &lgm_pwm_ops; pc->chip.ops = &lgm_pwm_ops;
pc->chip.npwm = 1; pc->chip.npwm = 1;
pc->chip.base = -1;
lgm_pwm_init(pc); lgm_pwm_init(pc);
......
...@@ -206,7 +206,6 @@ static int iqs620_pwm_probe(struct platform_device *pdev) ...@@ -206,7 +206,6 @@ static int iqs620_pwm_probe(struct platform_device *pdev)
iqs620_pwm->chip.dev = &pdev->dev; iqs620_pwm->chip.dev = &pdev->dev;
iqs620_pwm->chip.ops = &iqs620_pwm_ops; iqs620_pwm->chip.ops = &iqs620_pwm_ops;
iqs620_pwm->chip.base = -1;
iqs620_pwm->chip.npwm = 1; iqs620_pwm->chip.npwm = 1;
mutex_init(&iqs620_pwm->lock); mutex_init(&iqs620_pwm->lock);
......
...@@ -244,7 +244,6 @@ static int jz4740_pwm_probe(struct platform_device *pdev) ...@@ -244,7 +244,6 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
jz4740->chip.dev = dev; jz4740->chip.dev = dev;
jz4740->chip.ops = &jz4740_pwm_ops; jz4740->chip.ops = &jz4740_pwm_ops;
jz4740->chip.npwm = info->num_pwms; jz4740->chip.npwm = info->num_pwms;
jz4740->chip.base = -1;
jz4740->chip.of_xlate = of_pwm_xlate_with_flags; jz4740->chip.of_xlate = of_pwm_xlate_with_flags;
jz4740->chip.of_pwm_n_cells = 3; jz4740->chip.of_pwm_n_cells = 3;
......
...@@ -203,7 +203,6 @@ static int keembay_pwm_probe(struct platform_device *pdev) ...@@ -203,7 +203,6 @@ static int keembay_pwm_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
priv->chip.base = -1;
priv->chip.dev = dev; priv->chip.dev = dev;
priv->chip.ops = &keembay_pwm_ops; priv->chip.ops = &keembay_pwm_ops;
priv->chip.npwm = KMB_TOTAL_PWM_CHANNELS; priv->chip.npwm = KMB_TOTAL_PWM_CHANNELS;
......
...@@ -275,7 +275,6 @@ static int lp3943_pwm_probe(struct platform_device *pdev) ...@@ -275,7 +275,6 @@ static int lp3943_pwm_probe(struct platform_device *pdev)
lp3943_pwm->chip.dev = &pdev->dev; lp3943_pwm->chip.dev = &pdev->dev;
lp3943_pwm->chip.ops = &lp3943_pwm_ops; lp3943_pwm->chip.ops = &lp3943_pwm_ops;
lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; lp3943_pwm->chip.npwm = LP3943_NUM_PWMS;
lp3943_pwm->chip.base = -1;
platform_set_drvdata(pdev, lp3943_pwm); platform_set_drvdata(pdev, lp3943_pwm);
......
...@@ -370,7 +370,6 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev) ...@@ -370,7 +370,6 @@ static int lpc18xx_pwm_probe(struct platform_device *pdev)
lpc18xx_pwm->chip.dev = &pdev->dev; lpc18xx_pwm->chip.dev = &pdev->dev;
lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops; lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops;
lpc18xx_pwm->chip.base = -1;
lpc18xx_pwm->chip.npwm = 16; lpc18xx_pwm->chip.npwm = 16;
lpc18xx_pwm->chip.of_xlate = of_pwm_xlate_with_flags; lpc18xx_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
lpc18xx_pwm->chip.of_pwm_n_cells = 3; lpc18xx_pwm->chip.of_pwm_n_cells = 3;
...@@ -442,13 +441,15 @@ static int lpc18xx_pwm_remove(struct platform_device *pdev) ...@@ -442,13 +441,15 @@ static int lpc18xx_pwm_remove(struct platform_device *pdev)
struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev); struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev);
u32 val; u32 val;
pwmchip_remove(&lpc18xx_pwm->chip);
val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL); val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL,
val | LPC18XX_PWM_CTRL_HALT); val | LPC18XX_PWM_CTRL_HALT);
clk_disable_unprepare(lpc18xx_pwm->pwm_clk); clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
return pwmchip_remove(&lpc18xx_pwm->chip); return 0;
} }
static struct platform_driver lpc18xx_pwm_driver = { static struct platform_driver lpc18xx_pwm_driver = {
......
...@@ -116,7 +116,6 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) ...@@ -116,7 +116,6 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
lpc32xx->chip.dev = &pdev->dev; lpc32xx->chip.dev = &pdev->dev;
lpc32xx->chip.ops = &lpc32xx_pwm_ops; lpc32xx->chip.ops = &lpc32xx_pwm_ops;
lpc32xx->chip.npwm = 1; lpc32xx->chip.npwm = 1;
lpc32xx->chip.base = -1;
ret = pwmchip_add(&lpc32xx->chip); ret = pwmchip_add(&lpc32xx->chip);
if (ret < 0) { if (ret < 0) {
...@@ -137,10 +136,6 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) ...@@ -137,10 +136,6 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
static int lpc32xx_pwm_remove(struct platform_device *pdev) static int lpc32xx_pwm_remove(struct platform_device *pdev)
{ {
struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev); struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev);
unsigned int i;
for (i = 0; i < lpc32xx->chip.npwm; i++)
pwm_disable(&lpc32xx->chip.pwms[i]);
return pwmchip_remove(&lpc32xx->chip); return pwmchip_remove(&lpc32xx->chip);
} }
......
...@@ -234,7 +234,6 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r, ...@@ -234,7 +234,6 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
lpwm->chip.dev = dev; lpwm->chip.dev = dev;
lpwm->chip.ops = &pwm_lpss_ops; lpwm->chip.ops = &pwm_lpss_ops;
lpwm->chip.base = -1;
lpwm->chip.npwm = info->npwm; lpwm->chip.npwm = info->npwm;
ret = pwmchip_add(&lpwm->chip); ret = pwmchip_add(&lpwm->chip);
...@@ -255,12 +254,6 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe); ...@@ -255,12 +254,6 @@ EXPORT_SYMBOL_GPL(pwm_lpss_probe);
int pwm_lpss_remove(struct pwm_lpss_chip *lpwm) int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
{ {
int i;
for (i = 0; i < lpwm->info->npwm; i++) {
if (pwm_is_enabled(&lpwm->chip.pwms[i]))
pm_runtime_put(lpwm->chip.dev);
}
return pwmchip_remove(&lpwm->chip); return pwmchip_remove(&lpwm->chip);
} }
EXPORT_SYMBOL_GPL(pwm_lpss_remove); EXPORT_SYMBOL_GPL(pwm_lpss_remove);
......
...@@ -107,12 +107,6 @@ static void pwm_mediatek_clk_disable(struct pwm_chip *chip, ...@@ -107,12 +107,6 @@ static void pwm_mediatek_clk_disable(struct pwm_chip *chip,
clk_disable_unprepare(pc->clk_top); clk_disable_unprepare(pc->clk_top);
} }
static inline u32 pwm_mediatek_readl(struct pwm_mediatek_chip *chip,
unsigned int num, unsigned int offset)
{
return readl(chip->regs + pwm_mediatek_reg_offset[num] + offset);
}
static inline void pwm_mediatek_writel(struct pwm_mediatek_chip *chip, static inline void pwm_mediatek_writel(struct pwm_mediatek_chip *chip,
unsigned int num, unsigned int offset, unsigned int num, unsigned int offset,
u32 value) u32 value)
...@@ -263,7 +257,6 @@ static int pwm_mediatek_probe(struct platform_device *pdev) ...@@ -263,7 +257,6 @@ static int pwm_mediatek_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev; pc->chip.dev = &pdev->dev;
pc->chip.ops = &pwm_mediatek_ops; pc->chip.ops = &pwm_mediatek_ops;
pc->chip.base = -1;
pc->chip.npwm = pc->soc->num_pwms; pc->chip.npwm = pc->soc->num_pwms;
ret = pwmchip_add(&pc->chip); ret = pwmchip_add(&pc->chip);
......
...@@ -550,7 +550,6 @@ static int meson_pwm_probe(struct platform_device *pdev) ...@@ -550,7 +550,6 @@ static int meson_pwm_probe(struct platform_device *pdev)
spin_lock_init(&meson->lock); spin_lock_init(&meson->lock);
meson->chip.dev = &pdev->dev; meson->chip.dev = &pdev->dev;
meson->chip.ops = &meson_pwm_ops; meson->chip.ops = &meson_pwm_ops;
meson->chip.base = -1;
meson->chip.npwm = MESON_NUM_PWMS; meson->chip.npwm = MESON_NUM_PWMS;
meson->chip.of_xlate = of_pwm_xlate_with_flags; meson->chip.of_xlate = of_pwm_xlate_with_flags;
meson->chip.of_pwm_n_cells = 3; meson->chip.of_pwm_n_cells = 3;
......
...@@ -202,7 +202,6 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev) ...@@ -202,7 +202,6 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
mdp->chip.dev = &pdev->dev; mdp->chip.dev = &pdev->dev;
mdp->chip.ops = &mtk_disp_pwm_ops; mdp->chip.ops = &mtk_disp_pwm_ops;
mdp->chip.base = -1;
mdp->chip.npwm = 1; mdp->chip.npwm = 1;
ret = pwmchip_add(&mdp->chip); ret = pwmchip_add(&mdp->chip);
......
...@@ -140,7 +140,6 @@ static int mxs_pwm_probe(struct platform_device *pdev) ...@@ -140,7 +140,6 @@ static int mxs_pwm_probe(struct platform_device *pdev)
mxs->chip.ops = &mxs_pwm_ops; mxs->chip.ops = &mxs_pwm_ops;
mxs->chip.of_xlate = of_pwm_xlate_with_flags; mxs->chip.of_xlate = of_pwm_xlate_with_flags;
mxs->chip.of_pwm_n_cells = 3; mxs->chip.of_pwm_n_cells = 3;
mxs->chip.base = -1;
ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm); ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm);
if (ret < 0) { if (ret < 0) {
......
...@@ -403,7 +403,6 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) ...@@ -403,7 +403,6 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
omap->chip.dev = &pdev->dev; omap->chip.dev = &pdev->dev;
omap->chip.ops = &pwm_omap_dmtimer_ops; omap->chip.ops = &pwm_omap_dmtimer_ops;
omap->chip.base = -1;
omap->chip.npwm = 1; omap->chip.npwm = 1;
omap->chip.of_xlate = of_pwm_xlate_with_flags; omap->chip.of_xlate = of_pwm_xlate_with_flags;
omap->chip.of_pwm_n_cells = 3; omap->chip.of_pwm_n_cells = 3;
......
This diff is collapsed.
...@@ -184,7 +184,6 @@ static int pwm_probe(struct platform_device *pdev) ...@@ -184,7 +184,6 @@ static int pwm_probe(struct platform_device *pdev)
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &pxa_pwm_ops; pwm->chip.ops = &pxa_pwm_ops;
pwm->chip.base = -1;
pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1;
if (IS_ENABLED(CONFIG_OF)) { if (IS_ENABLED(CONFIG_OF)) {
......
...@@ -224,7 +224,6 @@ static int rcar_pwm_probe(struct platform_device *pdev) ...@@ -224,7 +224,6 @@ static int rcar_pwm_probe(struct platform_device *pdev)
rcar_pwm->chip.dev = &pdev->dev; rcar_pwm->chip.dev = &pdev->dev;
rcar_pwm->chip.ops = &rcar_pwm_ops; rcar_pwm->chip.ops = &rcar_pwm_ops;
rcar_pwm->chip.base = -1;
rcar_pwm->chip.npwm = 1; rcar_pwm->chip.npwm = 1;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
......
...@@ -410,7 +410,6 @@ static int tpu_probe(struct platform_device *pdev) ...@@ -410,7 +410,6 @@ static int tpu_probe(struct platform_device *pdev)
tpu->chip.ops = &tpu_pwm_ops; tpu->chip.ops = &tpu_pwm_ops;
tpu->chip.of_xlate = of_pwm_xlate_with_flags; tpu->chip.of_xlate = of_pwm_xlate_with_flags;
tpu->chip.of_pwm_n_cells = 3; tpu->chip.of_pwm_n_cells = 3;
tpu->chip.base = -1;
tpu->chip.npwm = TPU_CHANNEL_MAX; tpu->chip.npwm = TPU_CHANNEL_MAX;
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
......
...@@ -352,7 +352,6 @@ static int rockchip_pwm_probe(struct platform_device *pdev) ...@@ -352,7 +352,6 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
pc->data = id->data; pc->data = id->data;
pc->chip.dev = &pdev->dev; pc->chip.dev = &pdev->dev;
pc->chip.ops = &rockchip_pwm_ops; pc->chip.ops = &rockchip_pwm_ops;
pc->chip.base = -1;
pc->chip.npwm = 1; pc->chip.npwm = 1;
if (pc->data->supports_polarity) { if (pc->data->supports_polarity) {
......
...@@ -519,7 +519,6 @@ static int pwm_samsung_probe(struct platform_device *pdev) ...@@ -519,7 +519,6 @@ static int pwm_samsung_probe(struct platform_device *pdev)
chip->chip.dev = &pdev->dev; chip->chip.dev = &pdev->dev;
chip->chip.ops = &pwm_samsung_ops; chip->chip.ops = &pwm_samsung_ops;
chip->chip.base = -1;
chip->chip.npwm = SAMSUNG_PWM_NUM; chip->chip.npwm = SAMSUNG_PWM_NUM;
chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1; chip->inverter_mask = BIT(SAMSUNG_PWM_NUM) - 1;
......
...@@ -244,7 +244,6 @@ static int pwm_sifive_probe(struct platform_device *pdev) ...@@ -244,7 +244,6 @@ static int pwm_sifive_probe(struct platform_device *pdev)
chip->ops = &pwm_sifive_ops; chip->ops = &pwm_sifive_ops;
chip->of_xlate = of_pwm_xlate_with_flags; chip->of_xlate = of_pwm_xlate_with_flags;
chip->of_pwm_n_cells = 3; chip->of_pwm_n_cells = 3;
chip->base = -1;
chip->npwm = 4; chip->npwm = 4;
ddata->regs = devm_platform_ioremap_resource(pdev, 0); ddata->regs = devm_platform_ioremap_resource(pdev, 0);
......
...@@ -229,7 +229,6 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev) ...@@ -229,7 +229,6 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev)
chip = &priv->pwm_chip; chip = &priv->pwm_chip;
chip->dev = &pdev->dev; chip->dev = &pdev->dev;
chip->ops = &sl28cpld_pwm_ops; chip->ops = &sl28cpld_pwm_ops;
chip->base = -1;
chip->npwm = 1; chip->npwm = 1;
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
......
...@@ -193,7 +193,6 @@ static int spear_pwm_probe(struct platform_device *pdev) ...@@ -193,7 +193,6 @@ static int spear_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev; pc->chip.dev = &pdev->dev;
pc->chip.ops = &spear_pwm_ops; pc->chip.ops = &spear_pwm_ops;
pc->chip.base = -1;
pc->chip.npwm = NUM_PWM; pc->chip.npwm = NUM_PWM;
ret = clk_prepare(pc->clk); ret = clk_prepare(pc->clk);
......
...@@ -164,6 +164,9 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ...@@ -164,6 +164,9 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *cstate = &pwm->state; struct pwm_state *cstate = &pwm->state;
int ret; int ret;
if (state->polarity != PWM_POLARITY_NORMAL)
return -EINVAL;
if (state->enabled) { if (state->enabled) {
if (!cstate->enabled) { if (!cstate->enabled) {
/* /*
...@@ -268,7 +271,6 @@ static int sprd_pwm_probe(struct platform_device *pdev) ...@@ -268,7 +271,6 @@ static int sprd_pwm_probe(struct platform_device *pdev)
spc->chip.dev = &pdev->dev; spc->chip.dev = &pdev->dev;
spc->chip.ops = &sprd_pwm_ops; spc->chip.ops = &sprd_pwm_ops;
spc->chip.base = -1;
spc->chip.npwm = spc->num_pwms; spc->chip.npwm = spc->num_pwms;
ret = pwmchip_add(&spc->chip); ret = pwmchip_add(&spc->chip);
......
...@@ -619,7 +619,6 @@ static int sti_pwm_probe(struct platform_device *pdev) ...@@ -619,7 +619,6 @@ static int sti_pwm_probe(struct platform_device *pdev)
pc->chip.dev = dev; pc->chip.dev = dev;
pc->chip.ops = &sti_pwm_ops; pc->chip.ops = &sti_pwm_ops;
pc->chip.base = -1;
pc->chip.npwm = pc->cdata->pwm_num_devs; pc->chip.npwm = pc->cdata->pwm_num_devs;
ret = pwmchip_add(&pc->chip); ret = pwmchip_add(&pc->chip);
...@@ -650,15 +649,13 @@ static int sti_pwm_probe(struct platform_device *pdev) ...@@ -650,15 +649,13 @@ static int sti_pwm_probe(struct platform_device *pdev)
static int sti_pwm_remove(struct platform_device *pdev) static int sti_pwm_remove(struct platform_device *pdev)
{ {
struct sti_pwm_chip *pc = platform_get_drvdata(pdev); struct sti_pwm_chip *pc = platform_get_drvdata(pdev);
unsigned int i;
for (i = 0; i < pc->cdata->pwm_num_devs; i++) pwmchip_remove(&pc->chip);
pwm_disable(&pc->chip.pwms[i]);
clk_unprepare(pc->pwm_clk); clk_unprepare(pc->pwm_clk);
clk_unprepare(pc->cpt_clk); clk_unprepare(pc->cpt_clk);
return pwmchip_remove(&pc->chip); return 0;
} }
static const struct of_device_id sti_pwm_of_match[] = { static const struct of_device_id sti_pwm_of_match[] = {
......
...@@ -205,7 +205,6 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev) ...@@ -205,7 +205,6 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
priv->regmap = ddata->regmap; priv->regmap = ddata->regmap;
priv->clk = ddata->clk; priv->clk = ddata->clk;
priv->chip.base = -1;
priv->chip.dev = &pdev->dev; priv->chip.dev = &pdev->dev;
priv->chip.ops = &stm32_pwm_lp_ops; priv->chip.ops = &stm32_pwm_lp_ops;
priv->chip.npwm = 1; priv->chip.npwm = 1;
......
...@@ -633,7 +633,6 @@ static int stm32_pwm_probe(struct platform_device *pdev) ...@@ -633,7 +633,6 @@ static int stm32_pwm_probe(struct platform_device *pdev)
stm32_pwm_detect_complementary(priv); stm32_pwm_detect_complementary(priv);
priv->chip.base = -1;
priv->chip.dev = dev; priv->chip.dev = dev;
priv->chip.ops = &stm32pwm_ops; priv->chip.ops = &stm32pwm_ops;
priv->chip.npwm = stm32_pwm_detect_channels(priv); priv->chip.npwm = stm32_pwm_detect_channels(priv);
......
...@@ -278,7 +278,6 @@ static int __init stmpe_pwm_probe(struct platform_device *pdev) ...@@ -278,7 +278,6 @@ static int __init stmpe_pwm_probe(struct platform_device *pdev)
pwm->stmpe = stmpe; pwm->stmpe = stmpe;
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.base = -1;
if (stmpe->partnum == STMPE2401 || stmpe->partnum == STMPE2403) { if (stmpe->partnum == STMPE2401 || stmpe->partnum == STMPE2403) {
pwm->chip.ops = &stmpe_24xx_pwm_ops; pwm->chip.ops = &stmpe_24xx_pwm_ops;
......
...@@ -459,7 +459,6 @@ static int sun4i_pwm_probe(struct platform_device *pdev) ...@@ -459,7 +459,6 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &sun4i_pwm_ops; pwm->chip.ops = &sun4i_pwm_ops;
pwm->chip.base = -1;
pwm->chip.npwm = pwm->data->npwm; pwm->chip.npwm = pwm->data->npwm;
pwm->chip.of_xlate = of_pwm_xlate_with_flags; pwm->chip.of_xlate = of_pwm_xlate_with_flags;
pwm->chip.of_pwm_n_cells = 3; pwm->chip.of_pwm_n_cells = 3;
......
...@@ -285,7 +285,6 @@ static int tegra_pwm_probe(struct platform_device *pdev) ...@@ -285,7 +285,6 @@ static int tegra_pwm_probe(struct platform_device *pdev)
pwm->chip.dev = &pdev->dev; pwm->chip.dev = &pdev->dev;
pwm->chip.ops = &tegra_pwm_ops; pwm->chip.ops = &tegra_pwm_ops;
pwm->chip.base = -1;
pwm->chip.npwm = pwm->soc->num_channels; pwm->chip.npwm = pwm->soc->num_channels;
ret = pwmchip_add(&pwm->chip); ret = pwmchip_add(&pwm->chip);
......
...@@ -226,7 +226,6 @@ static int ecap_pwm_probe(struct platform_device *pdev) ...@@ -226,7 +226,6 @@ static int ecap_pwm_probe(struct platform_device *pdev)
pc->chip.ops = &ecap_pwm_ops; pc->chip.ops = &ecap_pwm_ops;
pc->chip.of_xlate = of_pwm_xlate_with_flags; pc->chip.of_xlate = of_pwm_xlate_with_flags;
pc->chip.of_pwm_n_cells = 3; pc->chip.of_pwm_n_cells = 3;
pc->chip.base = -1;
pc->chip.npwm = 1; pc->chip.npwm = 1;
pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); pc->mmio_base = devm_platform_ioremap_resource(pdev, 0);
......
...@@ -449,7 +449,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) ...@@ -449,7 +449,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev)
pc->chip.ops = &ehrpwm_pwm_ops; pc->chip.ops = &ehrpwm_pwm_ops;
pc->chip.of_xlate = of_pwm_xlate_with_flags; pc->chip.of_xlate = of_pwm_xlate_with_flags;
pc->chip.of_pwm_n_cells = 3; pc->chip.of_pwm_n_cells = 3;
pc->chip.base = -1;
pc->chip.npwm = NUM_PWM_CHANNEL; pc->chip.npwm = NUM_PWM_CHANNEL;
pc->mmio_base = devm_platform_ioremap_resource(pdev, 0); pc->mmio_base = devm_platform_ioremap_resource(pdev, 0);
......
...@@ -291,7 +291,6 @@ static int twl_pwmled_probe(struct platform_device *pdev) ...@@ -291,7 +291,6 @@ static int twl_pwmled_probe(struct platform_device *pdev)
} }
twl->chip.dev = &pdev->dev; twl->chip.dev = &pdev->dev;
twl->chip.base = -1;
mutex_init(&twl->mutex); mutex_init(&twl->mutex);
......
...@@ -310,7 +310,6 @@ static int twl_pwm_probe(struct platform_device *pdev) ...@@ -310,7 +310,6 @@ static int twl_pwm_probe(struct platform_device *pdev)
twl->chip.ops = &twl6030_pwm_ops; twl->chip.ops = &twl6030_pwm_ops;
twl->chip.dev = &pdev->dev; twl->chip.dev = &pdev->dev;
twl->chip.base = -1;
twl->chip.npwm = 2; twl->chip.npwm = 2;
mutex_init(&twl->mutex); mutex_init(&twl->mutex);
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Toshiba Visconti pulse-width-modulation controller driver
*
* Copyright (c) 2020 - 2021 TOSHIBA CORPORATION
* Copyright (c) 2020 - 2021 Toshiba Electronic Devices & Storage Corporation
*
* Authors: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
*
* Limitations:
* - The fixed input clock is running at 1 MHz and is divided by either 1,
* 2, 4 or 8.
* - When the settings of the PWM are modified, the new values are shadowed
* in hardware until the PIPGM_PCSR register is written and the currently
* running period is completed. This way the hardware switches atomically
* from the old setting to the new.
* - Disabling the hardware completes the currently running period and keeps
* the output at low level at all times.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#define PIPGM_PCSR(ch) (0x400 + 4 * (ch))
#define PIPGM_PDUT(ch) (0x420 + 4 * (ch))
#define PIPGM_PWMC(ch) (0x440 + 4 * (ch))
#define PIPGM_PWMC_PWMACT BIT(5)
#define PIPGM_PWMC_CLK_MASK GENMASK(1, 0)
#define PIPGM_PWMC_POLARITY_MASK GENMASK(5, 5)
struct visconti_pwm_chip {
struct pwm_chip chip;
void __iomem *base;
};
static inline struct visconti_pwm_chip *visconti_pwm_from_chip(struct pwm_chip *chip)
{
return container_of(chip, struct visconti_pwm_chip, chip);
}
static int visconti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
struct visconti_pwm_chip *priv = visconti_pwm_from_chip(chip);
u32 period, duty_cycle, pwmc0;
if (!state->enabled) {
writel(0, priv->base + PIPGM_PCSR(pwm->hwpwm));
return 0;
}
/*
* The biggest period the hardware can provide is
* (0xffff << 3) * 1000 ns
* This value fits easily in an u32, so simplify the maths by
* capping the values to 32 bit integers.
*/
if (state->period > (0xffff << 3) * 1000)
period = (0xffff << 3) * 1000;
else
period = state->period;
if (state->duty_cycle > period)
duty_cycle = period;
else
duty_cycle = state->duty_cycle;
/*
* The input clock runs fixed at 1 MHz, so we have only
* microsecond resolution and so can divide by
* NSEC_PER_SEC / CLKFREQ = 1000 without losing precision.
*/
period /= 1000;
duty_cycle /= 1000;
if (!period)
return -ERANGE;
/*
* PWMC controls a divider that divides the input clk by a
* power of two between 1 and 8. As a smaller divider yields
* higher precision, pick the smallest possible one.
*/
if (period > 0xffff) {
pwmc0 = ilog2(period >> 16);
if (WARN_ON(pwmc0 > 3))
return -EINVAL;
} else {
pwmc0 = 0;
}
period >>= pwmc0;
duty_cycle >>= pwmc0;
if (state->polarity == PWM_POLARITY_INVERSED)
pwmc0 |= PIPGM_PWMC_PWMACT;
writel(pwmc0, priv->base + PIPGM_PWMC(pwm->hwpwm));
writel(duty_cycle, priv->base + PIPGM_PDUT(pwm->hwpwm));
writel(period, priv->base + PIPGM_PCSR(pwm->hwpwm));
return 0;
}
static void visconti_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
struct visconti_pwm_chip *priv = visconti_pwm_from_chip(chip);
u32 period, duty, pwmc0, pwmc0_clk;
period = readl(priv->base + PIPGM_PCSR(pwm->hwpwm));
duty = readl(priv->base + PIPGM_PDUT(pwm->hwpwm));
pwmc0 = readl(priv->base + PIPGM_PWMC(pwm->hwpwm));
pwmc0_clk = pwmc0 & PIPGM_PWMC_CLK_MASK;
state->period = (period << pwmc0_clk) * NSEC_PER_USEC;
state->duty_cycle = (duty << pwmc0_clk) * NSEC_PER_USEC;
if (pwmc0 & PIPGM_PWMC_POLARITY_MASK)
state->polarity = PWM_POLARITY_INVERSED;
else
state->polarity = PWM_POLARITY_NORMAL;
state->enabled = true;
}
static const struct pwm_ops visconti_pwm_ops = {
.apply = visconti_pwm_apply,
.get_state = visconti_pwm_get_state,
.owner = THIS_MODULE,
};
static int visconti_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct visconti_pwm_chip *priv;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
platform_set_drvdata(pdev, priv);
priv->chip.dev = dev;
priv->chip.ops = &visconti_pwm_ops;
priv->chip.npwm = 4;
ret = pwmchip_add(&priv->chip);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret, "Cannot register visconti PWM\n");
return 0;
}
static int visconti_pwm_remove(struct platform_device *pdev)
{
struct visconti_pwm_chip *priv = platform_get_drvdata(pdev);
pwmchip_remove(&priv->chip);
return 0;
}
static const struct of_device_id visconti_pwm_of_match[] = {
{ .compatible = "toshiba,visconti-pwm", },
{ }
};
MODULE_DEVICE_TABLE(of, visconti_pwm_of_match);
static struct platform_driver visconti_pwm_driver = {
.driver = {
.name = "pwm-visconti",
.of_match_table = visconti_pwm_of_match,
},
.probe = visconti_pwm_probe,
.remove = visconti_pwm_remove,
};
module_platform_driver(visconti_pwm_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>");
MODULE_ALIAS("platform:pwm-visconti");
...@@ -209,7 +209,6 @@ static int vt8500_pwm_probe(struct platform_device *pdev) ...@@ -209,7 +209,6 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
chip->chip.ops = &vt8500_pwm_ops; chip->chip.ops = &vt8500_pwm_ops;
chip->chip.of_xlate = of_pwm_xlate_with_flags; chip->chip.of_xlate = of_pwm_xlate_with_flags;
chip->chip.of_pwm_n_cells = 3; chip->chip.of_pwm_n_cells = 3;
chip->chip.base = -1;
chip->chip.npwm = VT8500_NR_PWMS; chip->chip.npwm = VT8500_NR_PWMS;
chip->clk = devm_clk_get(&pdev->dev, NULL); chip->clk = devm_clk_get(&pdev->dev, NULL);
......
...@@ -91,6 +91,11 @@ struct pwm_device { ...@@ -91,6 +91,11 @@ struct pwm_device {
* pwm_get_state() - retrieve the current PWM state * pwm_get_state() - retrieve the current PWM state
* @pwm: PWM device * @pwm: PWM device
* @state: state to fill with the current PWM state * @state: state to fill with the current PWM state
*
* The returned PWM state represents the state that was applied by a previous call to
* pwm_apply_state(). Drivers may have to slightly tweak that state before programming it to
* hardware. If pwm_apply_state() was never called, this returns either the current hardware
* state (if supported) or the default settings.
*/ */
static inline void pwm_get_state(const struct pwm_device *pwm, static inline void pwm_get_state(const struct pwm_device *pwm,
struct pwm_state *state) struct pwm_state *state)
...@@ -392,8 +397,6 @@ int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, ...@@ -392,8 +397,6 @@ int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result,
int pwm_set_chip_data(struct pwm_device *pwm, void *data); int pwm_set_chip_data(struct pwm_device *pwm, void *data);
void *pwm_get_chip_data(struct pwm_device *pwm); void *pwm_get_chip_data(struct pwm_device *pwm);
int pwmchip_add_with_polarity(struct pwm_chip *chip,
enum pwm_polarity polarity);
int pwmchip_add(struct pwm_chip *chip); int pwmchip_add(struct pwm_chip *chip);
int pwmchip_remove(struct pwm_chip *chip); int pwmchip_remove(struct pwm_chip *chip);
struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
......
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