summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-09-07 14:48:05 +0100
committerMark Brown <broonie@kernel.org>2026-09-07 14:48:05 +0100
commit81c92f53e0aabf6a1ba9402a3ceff4bfcb959a0f (patch)
tree859e94d491ccf2dab62bd182fe2938c89de278b1
parent11da46955ffef271fed051924240be84a9e30066 (diff)
parenta662d944da1e9236a99355aa3e8a93735d8b3521 (diff)
downloadlinux-next-81c92f53e0aabf6a1ba9402a3ceff4bfcb959a0f.tar.gz
linux-next-81c92f53e0aabf6a1ba9402a3ceff4bfcb959a0f.zip
Merge branch 'pwm/for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux.git
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt58
-rw-r--r--Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml82
-rw-r--r--Documentation/driver-api/pwm.rst2
-rw-r--r--drivers/pwm/pwm-brcmstb.c2
-rw-r--r--drivers/pwm/pwm-ipq.c2
-rw-r--r--drivers/pwm/pwm-iqs620a.c23
-rw-r--r--drivers/pwm/pwm-loongson.c2
-rw-r--r--drivers/pwm/pwm-pca9685.c2
-rw-r--r--drivers/pwm/pwm-renesas-tpu.c23
9 files changed, 109 insertions, 87 deletions
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt
deleted file mode 100644
index 4633697fbda1..000000000000
--- a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-TI SOC based PWM Subsystem
-
-Required properties:
-- compatible: Must be "ti,<soc>-pwmss".
- for am33xx - compatible = "ti,am33xx-pwmss";
- for am4372 - compatible = "ti,am4372-pwmss","ti,am33xx-pwmss";
- for dra746 - compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"
-
-- reg: physical base address and size of the registers map.
-- address-cells: Specify the number of u32 entries needed in child nodes.
- Should set to 1.
-- size-cells: specify number of u32 entries needed to specify child nodes size
- in reg property. Should set to 1.
-- ranges: describes the address mapping of a memory-mapped bus. Should set to
- physical address map of child's base address, physical address within
- parent's address space and length of the address map. For am33xx,
- 3 set of child register maps present, ECAP register space, EQEP
- register space, EHRPWM register space.
-
-Also child nodes should also populated under PWMSS DT node.
-
-Example:
-epwmss0: epwmss@48300000 { /* PWMSS for am33xx */
- compatible = "ti,am33xx-pwmss";
- reg = <0x48300000 0x10>;
- ti,hwmods = "epwmss0";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x48300100 0x48300100 0x80 /* ECAP */
- 0x48300180 0x48300180 0x80 /* EQEP */
- 0x48300200 0x48300200 0x80>; /* EHRPWM */
-
- /* child nodes go here */
-};
-
-epwmss0: epwmss@48300000 { /* PWMSS for am4372 */
- compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"
- reg = <0x48300000 0x10>;
- ti,hwmods = "epwmss0";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0x48300100 0x48300100 0x80 /* ECAP */
- 0x48300180 0x48300180 0x80 /* EQEP */
- 0x48300200 0x48300200 0x80>; /* EHRPWM */
-
- /* child nodes go here */
-};
-
-epwmss0: epwmss@4843e000 { /* PWMSS for DRA7xx */
- compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss";
- reg = <0x4843e000 0x30>;
- ti,hwmods = "epwmss0";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- /* child nodes go here */
-};
diff --git a/Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml b/Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml
new file mode 100644
index 000000000000..89ce6b02b70c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/ti,am33xx-pwmss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments SoC PWM Subsystem
+
+maintainers:
+ - Eduard Bostina <egbostina@gmail.com>
+
+properties:
+ compatible:
+ oneOf:
+ - const: ti,am33xx-pwmss
+ - items:
+ - enum:
+ - ti,am4372-pwmss
+ - ti,dra746-pwmss
+ - const: ti,am33xx-pwmss
+
+ reg:
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ ranges: true
+
+patternProperties:
+ "^(ecap|eqep|pwm|counter)@[0-9a-f]+$":
+ type: object
+ description: Child nodes for ECAP, EQEP (counter), and EHRPWM
+ required:
+ - compatible
+
+required:
+ - compatible
+ - reg
+ - "#address-cells"
+ - "#size-cells"
+ - ranges
+
+additionalProperties: false
+
+examples:
+ - |
+ pwm@48300000 {
+ compatible = "ti,am33xx-pwmss";
+ reg = <0x48300000 0x10>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x48300100 0x48300100 0x80>, /* ECAP */
+ <0x48300180 0x48300180 0x80>, /* EQEP */
+ <0x48300200 0x48300200 0x80>; /* EHRPWM */
+
+ pwm@48300100 {
+ compatible = "ti,am3352-ecap";
+ #pwm-cells = <3>;
+ reg = <0x48300100 0x80>;
+ clocks = <&l4ls_gclk>;
+ clock-names = "fck";
+ };
+
+ counter@48300180 {
+ compatible = "ti,am3352-eqep";
+ reg = <0x48300180 0x80>;
+ clocks = <&l4ls_gclk>;
+ interrupts = <79>;
+ };
+
+ pwm@48300200 {
+ compatible = "ti,am3352-ehrpwm";
+ #pwm-cells = <3>;
+ reg = <0x48300200 0x80>;
+ clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>;
+ clock-names = "tbclk", "fck";
+ };
+ };
diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst
index 0d27a40f5818..b6b67f7d4905 100644
--- a/Documentation/driver-api/pwm.rst
+++ b/Documentation/driver-api/pwm.rst
@@ -177,7 +177,7 @@ and pwm_put() may not be called from an atomic context.
Most functions in the PWM consumer API might sleep and so must not be called
from atomic context. The notable exception is pwm_apply_atomic() which has the
same semantics as pwm_apply_might_sleep() but can be called from atomic context.
-(The price for that is that it doesn't work for all PWM devices, use
+The price for that is that it doesn't work for all PWM devices. Use
pwm_might_sleep() to check if a given PWM supports atomic operation.
Locking in the PWM core ensures that callbacks related to a single chip are
diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c
index 790ef7ffbbe5..78378787e4e9 100644
--- a/drivers/pwm/pwm-brcmstb.c
+++ b/drivers/pwm/pwm-brcmstb.c
@@ -101,7 +101,7 @@ static int brcmstb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
u32 value;
/*
- * If asking for a duty_ns equal to period_ns, we need to substract
+ * If asking for a duty_ns equal to period_ns, we need to subtract
* the period value by 1 to make it shorter than the "on" time and
* produce a flat 100% duty cycle signal, and max out the "on" time
*/
diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c
index 6b7aec566f7e..3e1231b212b1 100644
--- a/drivers/pwm/pwm-ipq.c
+++ b/drivers/pwm/pwm-ipq.c
@@ -186,7 +186,7 @@ static int ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC,
ipq_chip->clk_rate);
- hi_div = hi_dur * (pre_div + 1);
+ hi_div = (u64)hi_dur * (pre_div + 1);
state->duty_cycle = DIV64_U64_ROUND_UP(hi_div * NSEC_PER_SEC,
ipq_chip->clk_rate);
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c
index 13e5e138c8e9..6c6caee65b8f 100644
--- a/drivers/pwm/pwm-iqs620a.c
+++ b/drivers/pwm/pwm-iqs620a.c
@@ -173,18 +173,6 @@ static const struct pwm_ops iqs620_pwm_ops = {
.get_state = iqs620_pwm_get_state,
};
-static void iqs620_pwm_notifier_unregister(void *context)
-{
- struct iqs620_pwm_private *iqs620_pwm = context;
- int ret;
-
- ret = blocking_notifier_chain_unregister(&iqs620_pwm->iqs62x->nh,
- &iqs620_pwm->notifier);
- if (ret)
- dev_err(iqs620_pwm->dev,
- "Failed to unregister notifier: %d\n", ret);
-}
-
static int iqs620_pwm_probe(struct platform_device *pdev)
{
struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent);
@@ -218,19 +206,14 @@ static int iqs620_pwm_probe(struct platform_device *pdev)
mutex_init(&iqs620_pwm->lock);
iqs620_pwm->notifier.notifier_call = iqs620_pwm_notifier;
- ret = blocking_notifier_chain_register(&iqs620_pwm->iqs62x->nh,
- &iqs620_pwm->notifier);
+ ret = devm_blocking_notifier_chain_register(&pdev->dev,
+ &iqs620_pwm->iqs62x->nh,
+ &iqs620_pwm->notifier);
if (ret) {
dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret);
return ret;
}
- ret = devm_add_action_or_reset(&pdev->dev,
- iqs620_pwm_notifier_unregister,
- iqs620_pwm);
- if (ret)
- return ret;
-
ret = devm_pwmchip_add(&pdev->dev, chip);
if (ret)
dev_err(&pdev->dev, "Failed to add device: %d\n", ret);
diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c
index f2fb35b7af2b..98c809bde2b3 100644
--- a/drivers/pwm/pwm-loongson.c
+++ b/drivers/pwm/pwm-loongson.c
@@ -99,6 +99,7 @@ static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm)
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL);
+ val |= LOONGSON_PWM_CTRL_REG_RST;
val &= ~LOONGSON_PWM_CTRL_REG_EN;
pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL);
}
@@ -109,6 +110,7 @@ static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm)
struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip);
val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL);
+ val &= ~LOONGSON_PWM_CTRL_REG_RST;
val |= LOONGSON_PWM_CTRL_REG_EN;
pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL);
diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
index a2792b803643..3374ed76f8d3 100644
--- a/drivers/pwm/pwm-pca9685.c
+++ b/drivers/pwm/pwm-pca9685.c
@@ -54,7 +54,7 @@
/*
* The time value of one counter tick. Note that NSEC_PER_SEC is an integer
* multiple of PCA9685_OSC_CLOCK_HZ, so there is no rounding involved and we're
- * not loosing precision due to the early division.
+ * not losing precision due to the early division.
*/
#define PCA9685_QUANTUM_NS(_prescale) ((NSEC_PER_SEC / PCA9685_OSC_CLOCK_HZ) * (_prescale + 1))
diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c
index 140fd0bcb93f..e35f2e14777d 100644
--- a/drivers/pwm/pwm-renesas-tpu.c
+++ b/drivers/pwm/pwm-renesas-tpu.c
@@ -149,10 +149,14 @@ static int tpu_pwm_timer_start(struct tpu_pwm_device *tpd)
if (!tpd->timer_on) {
/* Wake up device and enable clock. */
- pm_runtime_get_sync(&tpd->tpu->pdev->dev);
+ ret = pm_runtime_resume_and_get(&tpd->tpu->pdev->dev);
+ if (ret < 0)
+ return ret;
+
ret = clk_prepare_enable(tpd->tpu->clk);
if (ret) {
dev_err(&tpd->tpu->pdev->dev, "cannot enable clock\n");
+ pm_runtime_put(&tpd->tpu->pdev->dev);
return ret;
}
tpd->timer_on = true;
@@ -382,15 +386,21 @@ static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
return 0;
}
-static void tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+static int tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct tpu_device *tpu = to_tpu_device(chip);
struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm];
+ int ret;
/* The timer must be running to modify the pin output configuration. */
- tpu_pwm_timer_start(tpd);
+ ret = tpu_pwm_timer_start(tpd);
+ if (ret < 0)
+ return ret;
+
tpu_pwm_set_pin(tpd, TPU_PIN_INACTIVE);
tpu_pwm_timer_stop(tpd);
+
+ return 0;
}
static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -401,7 +411,10 @@ static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (state->polarity != pwm->state.polarity) {
if (enabled) {
- tpu_pwm_disable(chip, pwm);
+ err = tpu_pwm_disable(chip, pwm);
+ if (err)
+ return err;
+
enabled = false;
}
@@ -412,7 +425,7 @@ static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
if (!state->enabled) {
if (enabled)
- tpu_pwm_disable(chip, pwm);
+ return tpu_pwm_disable(chip, pwm);
return 0;
}