aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mfd/google,cros-ec.yaml4
-rw-r--r--Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml53
-rw-r--r--Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.yaml1
-rw-r--r--Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml5
-rw-r--r--Documentation/devicetree/bindings/pwm/imx-pwm.yaml4
-rw-r--r--Documentation/devicetree/bindings/pwm/imx-tpm-pwm.yaml4
-rw-r--r--Documentation/devicetree/bindings/pwm/intel,keembay-pwm.yaml1
-rw-r--r--Documentation/devicetree/bindings/pwm/intel,lgm-pwm.yaml3
-rw-r--r--Documentation/devicetree/bindings/pwm/iqs620a-pwm.yaml4
-rw-r--r--Documentation/devicetree/bindings/pwm/mxs-pwm.yaml4
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt1
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml74
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-samsung.yaml1
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-sifive.yaml4
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-tiecap.yaml1
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.yaml1
-rw-r--r--Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml26
-rw-r--r--Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.yaml1
-rw-r--r--Documentation/devicetree/bindings/pwm/toshiba,pwm-visconti.yaml4
-rw-r--r--Documentation/devicetree/bindings/timer/ingenic,tcu.yaml1
-rw-r--r--drivers/pwm/pwm-atmel.c2
-rw-r--r--drivers/pwm/pwm-bcm-kona.c90
-rw-r--r--drivers/pwm/pwm-brcmstb.c52
-rw-r--r--drivers/pwm/pwm-img.c141
-rw-r--r--drivers/pwm/pwm-imx1.c33
-rw-r--r--drivers/pwm/pwm-jz4740.c5
-rw-r--r--drivers/pwm/pwm-lpc18xx-sct.c49
-rw-r--r--drivers/pwm/pwm-mediatek.c34
-rw-r--r--drivers/pwm/pwm-meson.c25
-rw-r--r--drivers/pwm/pwm-pca9685.c4
-rw-r--r--drivers/pwm/pwm-pxa.c33
-rw-r--r--drivers/pwm/pwm-raspberrypi-poe.c1
-rw-r--r--drivers/pwm/pwm-rcar.c2
-rw-r--r--drivers/pwm/pwm-stmpe.c18
-rw-r--r--drivers/pwm/pwm-sun4i.c70
-rw-r--r--drivers/pwm/pwm-tegra.c59
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c40
-rw-r--r--drivers/pwm/pwm-vt8500.c38
38 files changed, 492 insertions, 401 deletions
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index d8b495f71282..afec0bd2f1de 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -85,6 +85,10 @@ properties:
ec-pwm:
$ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"
+ deprecated: true
+
+ pwm:
+ $ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"
keyboard-controller:
$ref: "/schemas/input/google,cros-ec-keyb.yaml#"
diff --git a/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml b/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml
index 800d511502c4..e93e935564fb 100644
--- a/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml
@@ -52,33 +52,36 @@ properties:
resets:
maxItems: 1
-if:
- properties:
- compatible:
- contains:
- const: allwinner,sun50i-h6-pwm
-
-then:
- properties:
- clocks:
- maxItems: 2
-
- clock-names:
- items:
- - const: mod
- - const: bus
-
- required:
- - clock-names
- - resets
-
-else:
- properties:
- clocks:
- maxItems: 1
+
+allOf:
+ - $ref: pwm.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: allwinner,sun50i-h6-pwm
+
+ then:
+ properties:
+ clocks:
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: mod
+ - const: bus
+
+ required:
+ - clock-names
+ - resets
+
+ else:
+ properties:
+ clocks:
+ maxItems: 1
required:
- - "#pwm-cells"
- compatible
- reg
- clocks
diff --git a/Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.yaml b/Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.yaml
index 4080e098f746..119de3d7f9dd 100644
--- a/Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/brcm,bcm7038-pwm.yaml
@@ -28,7 +28,6 @@ properties:
required:
- compatible
- reg
- - "#pwm-cells"
- clocks
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml b/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
index 4cfbffd8414a..7ab6912a845f 100644
--- a/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/google,cros-ec-pwm.yaml
@@ -16,6 +16,9 @@ description: |
An EC PWM node should be only found as a sub-node of the EC node (see
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml).
+allOf:
+ - $ref: pwm.yaml#
+
properties:
compatible:
const: google,cros-ec-pwm
@@ -39,7 +42,7 @@ examples:
compatible = "google,cros-ec-spi";
reg = <0>;
- cros_ec_pwm: ec-pwm {
+ cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
};
diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.yaml b/Documentation/devicetree/bindings/pwm/imx-pwm.yaml
index 379d693889f6..b3da4e629341 100644
--- a/Documentation/devicetree/bindings/pwm/imx-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.yaml
@@ -9,6 +9,9 @@ title: Freescale i.MX PWM controller
maintainers:
- Philipp Zabel <p.zabel@pengutronix.de>
+allOf:
+ - $ref: pwm.yaml#
+
properties:
"#pwm-cells":
description: |
@@ -59,7 +62,6 @@ properties:
maxItems: 1
required:
- - "#pwm-cells"
- compatible
- reg
- clocks
diff --git a/Documentation/devicetree/bindings/pwm/imx-tpm-pwm.yaml b/Documentation/devicetree/bindings/pwm/imx-tpm-pwm.yaml
index fe9ef42544f1..8bef9dfeba9a 100644
--- a/Documentation/devicetree/bindings/pwm/imx-tpm-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/imx-tpm-pwm.yaml
@@ -13,6 +13,9 @@ description: |
The TPM counter and period counter are shared between multiple
channels, so all channels should use same period setting.
+allOf:
+ - $ref: pwm.yaml#
+
properties:
"#pwm-cells":
const: 3
@@ -34,7 +37,6 @@ properties:
maxItems: 1
required:
- - "#pwm-cells"
- compatible
- reg
- clocks
diff --git a/Documentation/devicetree/bindings/pwm/intel,keembay-pwm.yaml b/Documentation/devicetree/bindings/pwm/intel,keembay-pwm.yaml
index ff6880a02ce6..ec9f6bab798c 100644
--- a/Documentation/devicetree/bindings/pwm/intel,keembay-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/intel,keembay-pwm.yaml
@@ -31,7 +31,6 @@ required:
- compatible
- reg
- clocks
- - '#pwm-cells'
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/intel,lgm-pwm.yaml b/Documentation/devicetree/bindings/pwm/intel,lgm-pwm.yaml
index 11a606536169..59d7c4d864c1 100644
--- a/Documentation/devicetree/bindings/pwm/intel,lgm-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/intel,lgm-pwm.yaml
@@ -9,6 +9,9 @@ title: LGM SoC PWM fan controller
maintainers:
- Rahul Tanwar <rtanwar@maxlinear.com>
+allOf:
+ - $ref: pwm.yaml#
+
properties:
compatible:
const: intel,lgm-pwm
diff --git a/Documentation/devicetree/bindings/pwm/iqs620a-pwm.yaml b/Documentation/devicetree/bindings/pwm/iqs620a-pwm.yaml
index 1d7c27be50da..0a46af240d83 100644
--- a/Documentation/devicetree/bindings/pwm/iqs620a-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/iqs620a-pwm.yaml
@@ -15,6 +15,9 @@ description: |
Documentation/devicetree/bindings/mfd/iqs62x.yaml for further details as
well as an example.
+allOf:
+ - $ref: pwm.yaml#
+
properties:
compatible:
enum:
@@ -25,7 +28,6 @@ properties:
required:
- compatible
- - "#pwm-cells"
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/mxs-pwm.yaml b/Documentation/devicetree/bindings/pwm/mxs-pwm.yaml
index 8740e076061e..a34cbc13f691 100644
--- a/Documentation/devicetree/bindings/pwm/mxs-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/mxs-pwm.yaml
@@ -10,6 +10,9 @@ maintainers:
- Shawn Guo <shawnguo@kernel.org>
- Anson Huang <anson.huang@nxp.com>
+allOf:
+ - $ref: pwm.yaml#
+
properties:
compatible:
enum:
@@ -28,7 +31,6 @@ properties:
required:
- compatible
- reg
- - "#pwm-cells"
- fsl,pwm-number
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
index 902b271891ae..691e58b6c223 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
@@ -6,6 +6,7 @@ Required properties:
- "mediatek,mt6595-disp-pwm": found on mt6595 SoC.
- "mediatek,mt8167-disp-pwm", "mediatek,mt8173-disp-pwm": found on mt8167 SoC.
- "mediatek,mt8173-disp-pwm": found on mt8173 SoC.
+ - "mediatek,mt8183-disp-pwm": found on mt8183 SoC.$
- reg: physical base address and length of the controller's registers.
- #pwm-cells: must be 2. See pwm.yaml in this directory for a description of
the cell format.
diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml b/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml
index 81a54a4e8e3e..a336ff9364a9 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.yaml
@@ -51,42 +51,44 @@ properties:
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
+
+allOf:
+ - $ref: pwm.yaml#
+
+ - 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
diff --git a/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml b/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml
index 188679cb8b8c..fe603fb1b2cc 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-samsung.yaml
@@ -86,7 +86,6 @@ required:
- clocks
- clock-names
- compatible
- - "#pwm-cells"
- reg
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
index db41cd7bf150..605c1766dba8 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml
@@ -21,6 +21,9 @@ description:
https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm
+allOf:
+ - $ref: pwm.yaml#
+
properties:
compatible:
items:
@@ -54,7 +57,6 @@ required:
- compatible
- reg
- clocks
- - "#pwm-cells"
- interrupts
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.yaml b/Documentation/devicetree/bindings/pwm/pwm-tiecap.yaml
index ed35b6cc48d5..3840ae709bc6 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.yaml
@@ -47,7 +47,6 @@ properties:
required:
- compatible
- reg
- - "#pwm-cells"
- clocks
- clock-names
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.yaml b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.yaml
index ee312cb210e6..70a8f766212e 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.yaml
@@ -48,7 +48,6 @@ properties:
required:
- compatible
- reg
- - "#pwm-cells"
- clocks
- clock-names
diff --git a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
index 7ea1070b4b3a..1c94acbc2b4a 100644
--- a/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
+++ b/Documentation/devicetree/bindings/pwm/renesas,pwm-rcar.yaml
@@ -59,21 +59,23 @@ properties:
required:
- compatible
- reg
- - '#pwm-cells'
- clocks
- power-domains
-if:
- not:
- properties:
- compatible:
- contains:
- enum:
- - renesas,pwm-r8a7778
- - renesas,pwm-r8a7779
-then:
- required:
- - resets
+allOf:
+ - $ref: pwm.yaml#
+
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - renesas,pwm-r8a7778
+ - renesas,pwm-r8a7779
+ then:
+ required:
+ - resets
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.yaml b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.yaml
index 1f5c6384182e..c6b2ab56b7fe 100644
--- a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.yaml
@@ -68,7 +68,6 @@ properties:
required:
- compatible
- reg
- - '#pwm-cells'
- clocks
- power-domains
diff --git a/Documentation/devicetree/bindings/pwm/toshiba,pwm-visconti.yaml b/Documentation/devicetree/bindings/pwm/toshiba,pwm-visconti.yaml
index d350f5edfb67..46622661e5fb 100644
--- a/Documentation/devicetree/bindings/pwm/toshiba,pwm-visconti.yaml
+++ b/Documentation/devicetree/bindings/pwm/toshiba,pwm-visconti.yaml
@@ -9,6 +9,9 @@ title: Toshiba Visconti PWM Controller
maintainers:
- Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
+allOf:
+ - $ref: pwm.yaml#
+
properties:
compatible:
items:
@@ -23,7 +26,6 @@ properties:
required:
- compatible
- reg
- - '#pwm-cells'
additionalProperties: false
diff --git a/Documentation/devicetree/bindings/timer/ingenic,tcu.yaml b/Documentation/devicetree/bindings/timer/ingenic,tcu.yaml
index 7fb37eae9da7..d541cf2067bc 100644
--- a/Documentation/devicetree/bindings/timer/ingenic,tcu.yaml
+++ b/Documentation/devicetree/bindings/timer/ingenic,tcu.yaml
@@ -152,6 +152,7 @@ patternProperties:
- enum:
- ingenic,jz4740-pwm
- ingenic,jz4725b-pwm
+ - ingenic,x1000-pwm
- items:
- enum:
- ingenic,jz4760-pwm
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index 98b34ea9f38e..8e00a4286145 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -271,7 +271,7 @@ static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm,
bool disable_clk)
{
struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
- unsigned long timeout = jiffies + 2 * HZ;
+ unsigned long timeout;
atmel_pwm_wait_nonpending(atmel_pwm, pwm->hwpwm);
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index 64148f5f81d0..f171169c1c1f 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -109,10 +109,10 @@ static void kona_pwmc_apply_settings(struct kona_pwmc *kp, unsigned int chan)
}
static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
- int duty_ns, int period_ns)
+ u64 duty_ns, u64 period_ns)
{
struct kona_pwmc *kp = to_kona_pwmc(chip);
- u64 val, div, rate;
+ u64 div, rate;
unsigned long prescale = PRESCALE_MIN, pc, dc;
unsigned int value, chan = pwm->hwpwm;
@@ -132,10 +132,8 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
while (1) {
div = 1000000000;
div *= 1 + prescale;
- val = rate * period_ns;
- pc = div64_u64(val, div);
- val = rate * duty_ns;
- dc = div64_u64(val, div);
+ pc = mul_u64_u64_div_u64(rate, period_ns, div);
+ dc = mul_u64_u64_div_u64(rate, duty_ns, div);
/* If duty_ns or period_ns are not achievable then return */
if (pc < PERIOD_COUNT_MIN)
@@ -150,25 +148,18 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
return -EINVAL;
}
- /*
- * Don't apply settings if disabled. The period and duty cycle are
- * always calculated above to ensure the new values are
- * validated immediately instead of on enable.
- */
- if (pwm_is_enabled(pwm)) {
- kona_pwmc_prepare_for_settings(kp, chan);
+ kona_pwmc_prepare_for_settings(kp, chan);
- value = readl(kp->base + PRESCALE_OFFSET);
- value &= ~PRESCALE_MASK(chan);
- value |= prescale << PRESCALE_SHIFT(chan);
- writel(value, kp->base + PRESCALE_OFFSET);
+ value = readl(kp->base + PRESCALE_OFFSET);
+ value &= ~PRESCALE_MASK(chan);
+ value |= prescale << PRESCALE_SHIFT(chan);
+ writel(value, kp->base + PRESCALE_OFFSET);
- writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
+ writel(pc, kp->base + PERIOD_COUNT_OFFSET(chan));
- writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
+ writel(dc, kp->base + DUTY_CYCLE_HIGH_OFFSET(chan));
- kona_pwmc_apply_settings(kp, chan);
- }
+ kona_pwmc_apply_settings(kp, chan);
return 0;
}
@@ -216,13 +207,6 @@ static int kona_pwmc_enable(struct pwm_chip *chip, struct pwm_device *pwm)
return ret;
}
- ret = kona_pwmc_config(chip, pwm, pwm_get_duty_cycle(pwm),
- pwm_get_period(pwm));
- if (ret < 0) {
- clk_disable_unprepare(kp->clk);
- return ret;
- }
-
return 0;
}
@@ -248,11 +232,53 @@ static void kona_pwmc_disable(struct pwm_chip *chip, struct pwm_device *pwm)
clk_disable_unprepare(kp->clk);
}
+static int kona_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ int err;
+ struct kona_pwmc *kp = to_kona_pwmc(chip);
+ bool enabled = pwm->state.enabled;
+
+ if (state->polarity != pwm->state.polarity) {
+ if (enabled) {
+ kona_pwmc_disable(chip, pwm);
+ enabled = false;
+ }
+
+ err = kona_pwmc_set_polarity(chip, pwm, state->polarity);
+ if (err)
+ return err;
+
+ pwm->state.polarity = state->polarity;
+ }
+
+ if (!state->enabled) {
+ if (enabled)
+ kona_pwmc_disable(chip, pwm);
+ return 0;
+ } else if (!enabled) {
+ /*
+ * This is a bit special here, usually the PWM should only be
+ * enabled when duty and period are setup. But before this
+ * driver was converted to .apply it was done the other way
+ * around and so this behaviour was kept even though this might
+ * result in a glitch. This might be improvable by someone with
+ * hardware and/or documentation.
+ */
+ err = kona_pwmc_enable(chip, pwm);
+ if (err)
+ return err;
+ }
+
+ err = kona_pwmc_config(pwm->chip, pwm, state->duty_cycle, state->period);
+ if (err && !pwm->state.enabled)
+ clk_disable_unprepare(kp->clk);
+
+ return err;
+}
+
static const struct pwm_ops kona_pwm_ops = {
- .config = kona_pwmc_config,
- .set_polarity = kona_pwmc_set_polarity,
- .enable = kona_pwmc_enable,
- .disable = kona_pwmc_disable,
+ .apply = kona_pwmc_apply,
.owner = THIS_MODULE,
};
diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c
index 3b529f82b97c..3db3f96edf78 100644
--- a/drivers/pwm/pwm-brcmstb.c
+++ b/drivers/pwm/pwm-brcmstb.c
@@ -53,7 +53,6 @@
struct brcmstb_pwm {
void __iomem *base;
- spinlock_t lock;
struct clk *clk;
struct pwm_chip chip;
};
@@ -95,7 +94,7 @@ static inline struct brcmstb_pwm *to_brcmstb_pwm(struct pwm_chip *chip)
* "on" time, so this translates directly into our HW programming here.
*/
static int brcmstb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
- int duty_ns, int period_ns)
+ u64 duty_ns, u64 period_ns)
{
struct brcmstb_pwm *p = to_brcmstb_pwm(chip);
unsigned long pc, dc, cword = CONST_VAR_F_MAX;
@@ -114,22 +113,17 @@ static int brcmstb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
}
while (1) {
- u64 rate, tmp;
+ u64 rate;
/*
* Calculate the base rate from base frequency and current
* cword
*/
rate = (u64)clk_get_rate(p->clk) * (u64)cword;
- do_div(rate, 1 << CWORD_BIT_SIZE);
+ rate >>= CWORD_BIT_SIZE;
- tmp = period_ns * rate;
- do_div(tmp, NSEC_PER_SEC);
- pc = tmp;
-
- tmp = (duty_ns + 1) * rate;
- do_div(tmp, NSEC_PER_SEC);
- dc = tmp;
+ pc = mul_u64_u64_div_u64(period_ns, rate, NSEC_PER_SEC);
+ dc = mul_u64_u64_div_u64(duty_ns + 1, rate, NSEC_PER_SEC);
/*
* We can be called with separate duty and period updates,
@@ -164,7 +158,6 @@ done:
* generator output a base frequency for the constant frequency
* generator to derive from.
*/
- spin_lock(&p->lock);
brcmstb_pwm_writel(p, cword >> 8, PWM_CWORD_MSB(channel));
brcmstb_pwm_writel(p, cword & 0xff, PWM_CWORD_LSB(channel));
@@ -176,7 +169,6 @@ done:
/* Configure on and period value */
brcmstb_pwm_writel(p, pc, PWM_PERIOD(channel));
brcmstb_pwm_writel(p, dc, PWM_ON(channel));
- spin_unlock(&p->lock);
return 0;
}
@@ -187,7 +179,6 @@ static inline void brcmstb_pwm_enable_set(struct brcmstb_pwm *p,
unsigned int shift = channel * CTRL_CHAN_OFFS;
u32 value;
- spin_lock(&p->lock);
value = brcmstb_pwm_readl(p, PWM_CTRL);
if (enable) {
@@ -199,29 +190,36 @@ static inline void brcmstb_pwm_enable_set(struct brcmstb_pwm *p,
}
brcmstb_pwm_writel(p, value, PWM_CTRL);
- spin_unlock(&p->lock);
}
-static int brcmstb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+static int brcmstb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
{
struct brcmstb_pwm *p = to_brcmstb_pwm(chip);
+ int err;
- brcmstb_pwm_enable_set(p, pwm->hwpwm, true);
+ if (state->polarity != PWM_POLARITY_NORMAL)
+ return -EINVAL;
- return 0;
-}
+ if (!state->enabled) {
+ if (pwm->state.enabled)
+ brcmstb_pwm_enable_set(p, pwm->hwpwm, false);
-static void brcmstb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
- struct brcmstb_pwm *p = to_brcmstb_pwm(chip);
+ return 0;
+ }
+
+ err = brcmstb_pwm_config(chip, pwm, state->duty_cycle, state->period);
+ if (err)
+ return err;
+
+ if (!pwm->state.enabled)
+ brcmstb_pwm_enable_set(p, pwm->hwpwm, true);
- brcmstb_pwm_enable_set(p, pwm->hwpwm, false);
+ return 0;
}
static const struct pwm_ops brcmstb_pwm_ops = {
- .config = brcmstb_pwm_config,
- .enable = brcmstb_pwm_enable,
- .disable = brcmstb_pwm_disable,
+ .apply = brcmstb_pwm_apply,
.owner = THIS_MODULE,
};
@@ -240,8 +238,6 @@ static int brcmstb_pwm_probe(struct platform_device *pdev)
if (!p)
return -ENOMEM;
- spin_lock_init(&p->lock);
-
p->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(p->clk)) {
dev_err(&pdev->dev, "failed to obtain clock\n");
diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c
index 5996049f66ec..0fccf061ab95 100644
--- a/