Merge tag 'pwm/for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 May 2023 18:25:01 +0000 (11:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 May 2023 18:25:01 +0000 (11:25 -0700)
Pull pwm updates from Thierry Reding:
 "The bulk of this is trivial conversions to the new .remove_new()
  callback for drivers as part of Uwe's effort to clean that up.

  Other than that a driver is added for Apple devices and various small
  fixes are included for existing drivers.

  Last but not least, this finally gets rid of the old pwm_request() and
  pwm_free() APIs are removed since the last user was dropped in v6.3"

* tag 'pwm/for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (44 commits)
  pwm: Remove unused radix tree
  pwm: Delete deprecated functions pwm_request() and pwm_free()
  pwm: meson: Fix g12a ao clk81 name
  pwm: meson: Fix axg ao mux parents
  pwm: stm32: Enforce settings for PWM capture
  MAINTAINERS: Add entries for Apple PWM driver
  pwm: Add Apple PWM controller
  dt-bindings: pwm: Add Apple PWM controller
  pwm: mtk-disp: Configure double buffering before reading in .get_state()
  pwm: mtk-disp: Disable shadow registers before setting backlight values
  pwm: stm32-lp: Drop of_match_ptr for ID table
  pwm: rcar: Drop of_match_ptr for ID table
  dt-bindings: pwm: Convert Amlogic Meson PWM binding
  dt-bindings: pwm: mediatek: Add mediatek,mt7986 compatible
  pwm: xilinx: Convert to platform remove callback returning void
  pwm: vt8500: Convert to platform remove callback returning void
  pwm: tiehrpwm: Convert to platform remove callback returning void
  pwm: tiecap: Convert to platform remove callback returning void
  pwm: tegra: Convert to platform remove callback returning void
  pwm: sun4i: Convert to platform remove callback returning void
  ...

44 files changed:
Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/mediatek,mt2712-pwm.yaml
Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pwm/pwm-meson.txt [deleted file]
Documentation/driver-api/pwm.rst
MAINTAINERS
drivers/pwm/Kconfig
drivers/pwm/Makefile
drivers/pwm/core.c
drivers/pwm/pwm-apple.c [new file with mode: 0644]
drivers/pwm/pwm-atmel-hlcdc.c
drivers/pwm/pwm-atmel-tcb.c
drivers/pwm/pwm-atmel.c
drivers/pwm/pwm-bcm-iproc.c
drivers/pwm/pwm-bcm2835.c
drivers/pwm/pwm-berlin.c
drivers/pwm/pwm-brcmstb.c
drivers/pwm/pwm-clk.c
drivers/pwm/pwm-cros-ec.c
drivers/pwm/pwm-hibvt.c
drivers/pwm/pwm-img.c
drivers/pwm/pwm-imx-tpm.c
drivers/pwm/pwm-lpc18xx-sct.c
drivers/pwm/pwm-lpss-platform.c
drivers/pwm/pwm-meson.c
drivers/pwm/pwm-mtk-disp.c
drivers/pwm/pwm-omap-dmtimer.c
drivers/pwm/pwm-rcar.c
drivers/pwm/pwm-rockchip.c
drivers/pwm/pwm-samsung.c
drivers/pwm/pwm-sifive.c
drivers/pwm/pwm-spear.c
drivers/pwm/pwm-sprd.c
drivers/pwm/pwm-sti.c
drivers/pwm/pwm-stm32-lp.c
drivers/pwm/pwm-stm32.c
drivers/pwm/pwm-sun4i.c
drivers/pwm/pwm-tegra.c
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/pwm-vt8500.c
drivers/pwm/pwm-xilinx.c
include/linux/mfd/stm32-timers.h
include/linux/pwm.h

diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
new file mode 100644 (file)
index 0000000..142157b
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/apple,s5l-fpwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Apple FPWM controller
+
+maintainers:
+  - asahi@lists.linux.dev
+  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+
+description: PWM controller used for keyboard backlight on ARM Macs
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - apple,t8103-fpwm
+          - apple,t6000-fpwm
+          - apple,t8112-fpwm
+      - const: apple,s5l-fpwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#pwm-cells":
+    const: 2
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@235044000 {
+      compatible = "apple,t8103-fpwm", "apple,s5l-fpwm";
+      reg = <0x35044000 0x4000>;
+      power-domains = <&ps_fpwm1>;
+      clocks = <&clkref>;
+      #pwm-cells = <2>;
+    };
index dbc974b..8e176ba 100644 (file)
@@ -22,6 +22,7 @@ properties:
           - mediatek,mt7623-pwm
           - mediatek,mt7628-pwm
           - mediatek,mt7629-pwm
+          - mediatek,mt7986-pwm
           - mediatek,mt8183-pwm
           - mediatek,mt8365-pwm
           - mediatek,mt8516-pwm
diff --git a/Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml b/Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
new file mode 100644 (file)
index 0000000..527864a
--- /dev/null
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/pwm-amlogic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic PWM
+
+maintainers:
+  - Heiner Kallweit <hkallweit1@gmail.com>
+
+allOf:
+  - $ref: pwm.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - amlogic,meson8b-pwm
+          - amlogic,meson-gxbb-pwm
+          - amlogic,meson-gxbb-ao-pwm
+          - amlogic,meson-axg-ee-pwm
+          - amlogic,meson-axg-ao-pwm
+          - amlogic,meson-g12a-ee-pwm
+          - amlogic,meson-g12a-ao-pwm-ab
+          - amlogic,meson-g12a-ao-pwm-cd
+          - amlogic,meson-s4-pwm
+      - items:
+          - const: amlogic,meson-gx-pwm
+          - const: amlogic,meson-gxbb-pwm
+      - items:
+          - const: amlogic,meson-gx-ao-pwm
+          - const: amlogic,meson-gxbb-ao-pwm
+      - items:
+          - const: amlogic,meson8-pwm
+          - const: amlogic,meson8b-pwm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    oneOf:
+      - items:
+          - enum: [clkin0, clkin1]
+      - items:
+          - const: clkin0
+          - const: clkin1
+
+  "#pwm-cells":
+    const: 3
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    pwm@8550 {
+      compatible = "amlogic,meson-gxbb-pwm";
+      reg = <0x08550 0x10>;
+      clocks = <&xtal>, <&xtal>;
+      clock-names = "clkin0", "clkin1";
+      #pwm-cells = <3>;
+    };
diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
deleted file mode 100644 (file)
index bd02b0a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-Amlogic Meson PWM Controller
-============================
-
-Required properties:
-- compatible: Shall contain "amlogic,meson8b-pwm"
-                         or "amlogic,meson-gxbb-pwm"
-                         or "amlogic,meson-gxbb-ao-pwm"
-                         or "amlogic,meson-axg-ee-pwm"
-                         or "amlogic,meson-axg-ao-pwm"
-                         or "amlogic,meson-g12a-ee-pwm"
-                         or "amlogic,meson-g12a-ao-pwm-ab"
-                         or "amlogic,meson-g12a-ao-pwm-cd"
-- #pwm-cells: Should be 3. See pwm.yaml in this directory for a description of
-  the cells format.
-
-Optional properties:
-- clocks: Could contain one or two parents clocks phandle for each of the two
-  PWM channels.
-- clock-names: Could contain at least the "clkin0" and/or "clkin1" names.
-
-Example:
-
-       pwm_ab: pwm@8550 {
-               compatible = "amlogic,meson-gxbb-pwm";
-               reg = <0x0 0x08550 0x0 0x10>;
-               #pwm-cells = <3>;
-               clocks = <&xtal>, <&xtal>;
-               clock-names = "clkin0", "clkin1";
-       }
index 8c71a20..3fdc95f 100644 (file)
@@ -35,12 +35,9 @@ consumers to providers, as given in the following example::
 Using PWMs
 ----------
 
-Legacy users can request a PWM device using pwm_request() and free it
-after usage with pwm_free().
-
-New users should use the pwm_get() function and pass to it the consumer
-device or a consumer name. pwm_put() is used to free the PWM device. Managed
-variants of the getter, devm_pwm_get() and devm_fwnode_pwm_get(), also exist.
+Consumers use the pwm_get() function and pass to it the consumer device or a
+consumer name. pwm_put() is used to free the PWM device. Managed variants of
+the getter, devm_pwm_get() and devm_fwnode_pwm_get(), also exist.
 
 After being requested, a PWM has to be configured using::
 
@@ -165,8 +162,8 @@ consumers should implement it as described in the "Using PWMs" section.
 Locking
 -------
 
-The PWM core list manipulations are protected by a mutex, so pwm_request()
-and pwm_free() may not be called from an atomic context. Currently the
+The PWM core list manipulations are protected by a mutex, so pwm_get()
+and pwm_put() may not be called from an atomic context. Currently the
 PWM core does not enforce any locking to pwm_enable(), pwm_disable() and
 pwm_config(), so the calling context is currently driver specific. This
 is an issue derived from the former barebone API and should be fixed soon.
index 61b7465..c0cde28 100644 (file)
@@ -1961,6 +1961,7 @@ F:        Documentation/devicetree/bindings/nvmem/apple,efuses.yaml
 F:     Documentation/devicetree/bindings/pci/apple,pcie.yaml
 F:     Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
 F:     Documentation/devicetree/bindings/power/apple*
+F:     Documentation/devicetree/bindings/pwm/pwm-apple.yaml
 F:     Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
 F:     arch/arm64/boot/dts/apple/
 F:     drivers/bluetooth/hci_bcm4377.c
@@ -1976,6 +1977,7 @@ F:        drivers/mailbox/apple-mailbox.c
 F:     drivers/nvme/host/apple.c
 F:     drivers/nvmem/apple-efuses.c
 F:     drivers/pinctrl/pinctrl-apple-gpio.c
+F:     drivers/pwm/pwm-apple.c
 F:     drivers/soc/apple/*
 F:     drivers/watchdog/apple_wdt.c
 F:     include/dt-bindings/interrupt-controller/apple-aic.h
index dae023d..8df861b 100644 (file)
@@ -51,6 +51,18 @@ config PWM_AB8500
          To compile this driver as a module, choose M here: the module
          will be called pwm-ab8500.
 
+config PWM_APPLE
+       tristate "Apple SoC PWM support"
+       depends on ARCH_APPLE || COMPILE_TEST
+       help
+         Generic PWM framework driver for PWM controller present on
+         Apple SoCs
+
+         Say Y here if you have an ARM Apple laptop, otherwise say N
+
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-apple.
+
 config PWM_ATMEL
        tristate "Atmel PWM support"
        depends on ARCH_AT91 || COMPILE_TEST
index 7bf1a29..19899b9 100644 (file)
@@ -2,6 +2,7 @@
 obj-$(CONFIG_PWM)              += core.o
 obj-$(CONFIG_PWM_SYSFS)                += sysfs.o
 obj-$(CONFIG_PWM_AB8500)       += pwm-ab8500.o
+obj-$(CONFIG_PWM_APPLE)                += pwm-apple.o
 obj-$(CONFIG_PWM_ATMEL)                += pwm-atmel.o
 obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)      += pwm-atmel-hlcdc.o
 obj-$(CONFIG_PWM_ATMEL_TCB)    += pwm-atmel-tcb.o
index 4747257..3daccea 100644 (file)
 static DEFINE_MUTEX(pwm_lookup_lock);
 static LIST_HEAD(pwm_lookup_list);
 
-/* protects access to pwm_chips, allocated_pwms, and pwm_tree */
+/* protects access to pwm_chips and allocated_pwms */
 static DEFINE_MUTEX(pwm_lock);
 
 static LIST_HEAD(pwm_chips);
 static DECLARE_BITMAP(allocated_pwms, MAX_PWMS);
-static RADIX_TREE(pwm_tree, GFP_KERNEL);
-
-static struct pwm_device *pwm_to_device(unsigned int pwm)
-{
-       return radix_tree_lookup(&pwm_tree, pwm);
-}
 
 /* Called with pwm_lock held */
 static int alloc_pwms(unsigned int count)
@@ -59,14 +53,6 @@ static int alloc_pwms(unsigned int count)
 /* Called with pwm_lock held */
 static void free_pwms(struct pwm_chip *chip)
 {
-       unsigned int i;
-
-       for (i = 0; i < chip->npwm; i++) {
-               struct pwm_device *pwm = &chip->pwms[i];
-
-               radix_tree_delete(&pwm_tree, pwm->pwm);
-       }
-
        bitmap_clear(allocated_pwms, chip->base, chip->npwm);
 
        kfree(chip->pwms);
@@ -307,8 +293,6 @@ int pwmchip_add(struct pwm_chip *chip)
                pwm->chip = chip;
                pwm->pwm = chip->base + i;
                pwm->hwpwm = i;
-
-               radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
        }
 
        list_add(&chip->list, &pwm_chips);
@@ -370,43 +354,6 @@ int devm_pwmchip_add(struct device *dev, struct pwm_chip *chip)
 EXPORT_SYMBOL_GPL(devm_pwmchip_add);
 
 /**
- * pwm_request() - request a PWM device
- * @pwm: global PWM device index
- * @label: PWM device label
- *
- * This function is deprecated, use pwm_get() instead.
- *
- * Returns: A pointer to a PWM device or an ERR_PTR()-encoded error code on
- * failure.
- */
-struct pwm_device *pwm_request(int pwm, const char *label)
-{
-       struct pwm_device *dev;
-       int err;
-
-       if (pwm < 0 || pwm >= MAX_PWMS)
-               return ERR_PTR(-EINVAL);
-
-       mutex_lock(&pwm_lock);
-
-       dev = pwm_to_device(pwm);
-       if (!dev) {
-               dev = ERR_PTR(-EPROBE_DEFER);
-               goto out;
-       }
-
-       err = pwm_device_request(dev, label);
-       if (err < 0)
-               dev = ERR_PTR(err);
-
-out:
-       mutex_unlock(&pwm_lock);
-
-       return dev;
-}
-EXPORT_SYMBOL_GPL(pwm_request);
-
-/**
  * pwm_request_from_chip() - request a PWM device relative to a PWM chip
  * @chip: PWM chip
  * @index: per-chip index of the PWM to request
@@ -438,18 +385,6 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
 }
 EXPORT_SYMBOL_GPL(pwm_request_from_chip);
 
-/**
- * pwm_free() - free a PWM device
- * @pwm: PWM device
- *
- * This function is deprecated, use pwm_put() instead.
- */
-void pwm_free(struct pwm_device *pwm)
-{
-       pwm_put(pwm);
-}
-EXPORT_SYMBOL_GPL(pwm_free);
-
 static void pwm_apply_state_debug(struct pwm_device *pwm,
                                  const struct pwm_state *state)
 {
@@ -790,7 +725,7 @@ static struct pwm_device *of_pwm_get(struct device *dev, struct device_node *np,
        dl = pwm_device_link_add(dev, pwm);
        if (IS_ERR(dl)) {
                /* of_xlate ended up calling pwm_request_from_chip() */
-               pwm_free(pwm);
+               pwm_put(pwm);
                pwm = ERR_CAST(dl);
                goto put;
        }
@@ -1014,7 +949,7 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)
 
        dl = pwm_device_link_add(dev, pwm);
        if (IS_ERR(dl)) {
-               pwm_free(pwm);
+               pwm_put(pwm);
                return ERR_CAST(dl);
        }
 
diff --git a/drivers/pwm/pwm-apple.c b/drivers/pwm/pwm-apple.c
new file mode 100644 (file)
index 0000000..a38a62e
--- /dev/null
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Driver for the Apple SoC PWM controller
+ *
+ * Copyright The Asahi Linux Contributors
+ *
+ * Limitations:
+ * - The writes to cycle registers are shadowed until a write to
+ *   the control register.
+ * - If both OFF_CYCLES and ON_CYCLES are set to 0, the output
+ *   is a constant off signal.
+ * - When APPLE_PWM_CTRL is set to 0, the output is constant low
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/math64.h>
+
+#define APPLE_PWM_CTRL        0x00
+#define APPLE_PWM_ON_CYCLES   0x1c
+#define APPLE_PWM_OFF_CYCLES  0x18
+
+#define APPLE_PWM_CTRL_ENABLE        BIT(0)
+#define APPLE_PWM_CTRL_MODE          BIT(2)
+#define APPLE_PWM_CTRL_UPDATE        BIT(5)
+#define APPLE_PWM_CTRL_TRIGGER       BIT(9)
+#define APPLE_PWM_CTRL_INVERT        BIT(10)
+#define APPLE_PWM_CTRL_OUTPUT_ENABLE BIT(14)
+
+struct apple_pwm {
+       struct pwm_chip chip;
+       void __iomem *base;
+       u64 clkrate;
+};
+
+static inline struct apple_pwm *to_apple_pwm(struct pwm_chip *chip)
+{
+       return container_of(chip, struct apple_pwm, chip);
+}
+
+static int apple_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+                          const struct pwm_state *state)
+{
+       struct apple_pwm *fpwm;
+
+       if (state->polarity == PWM_POLARITY_INVERSED)
+               return -EINVAL;
+
+       fpwm = to_apple_pwm(chip);
+       if (state->enabled) {
+               u64 on_cycles, off_cycles;
+
+               on_cycles = mul_u64_u64_div_u64(fpwm->clkrate,
+                                               state->duty_cycle, NSEC_PER_SEC);
+               if (on_cycles > 0xFFFFFFFF)
+                       on_cycles = 0xFFFFFFFF;
+
+               off_cycles = mul_u64_u64_div_u64(fpwm->clkrate,
+                                                state->period, NSEC_PER_SEC) - on_cycles;
+               if (off_cycles > 0xFFFFFFFF)
+                       off_cycles = 0xFFFFFFFF;
+
+               writel(on_cycles, fpwm->base + APPLE_PWM_ON_CYCLES);
+               writel(off_cycles, fpwm->base + APPLE_PWM_OFF_CYCLES);
+               writel(APPLE_PWM_CTRL_ENABLE | APPLE_PWM_CTRL_OUTPUT_ENABLE | APPLE_PWM_CTRL_UPDATE,
+                      fpwm->base + APPLE_PWM_CTRL);
+       } else {
+               writel(0, fpwm->base + APPLE_PWM_CTRL);
+       }
+       return 0;
+}
+
+static int apple_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+                          struct pwm_state *state)
+{
+       struct apple_pwm *fpwm;
+       u32 on_cycles, off_cycles, ctrl;
+
+       fpwm = to_apple_pwm(chip);
+
+       ctrl = readl(fpwm->base + APPLE_PWM_CTRL);
+       on_cycles = readl(fpwm->base + APPLE_PWM_ON_CYCLES);
+       off_cycles = readl(fpwm->base + APPLE_PWM_OFF_CYCLES);
+
+       state->enabled = (ctrl & APPLE_PWM_CTRL_ENABLE) && (ctrl & APPLE_PWM_CTRL_OUTPUT_ENABLE);
+       state->polarity = PWM_POLARITY_NORMAL;
+       // on_cycles + off_cycles is 33 bits, NSEC_PER_SEC is 30, there is no overflow
+       state->duty_cycle = DIV64_U64_ROUND_UP((u64)on_cycles * NSEC_PER_SEC, fpwm->clkrate);
+       state->period = DIV64_U64_ROUND_UP(((u64)off_cycles + (u64)on_cycles) *
+                                           NSEC_PER_SEC, fpwm->clkrate);
+
+       return 0;
+}
+
+static const struct pwm_ops apple_pwm_ops = {
+       .apply = apple_pwm_apply,
+       .get_state = apple_pwm_get_state,
+       .owner = THIS_MODULE,
+};
+
+static int apple_pwm_probe(struct platform_device *pdev)
+{
+       struct apple_pwm *fpwm;
+       struct clk *clk;
+       int ret;
+
+       fpwm = devm_kzalloc(&pdev->dev, sizeof(*fpwm), GFP_KERNEL);
+       if (!fpwm)
+               return -ENOMEM;
+
+       fpwm->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(fpwm->base))
+               return PTR_ERR(fpwm->base);
+
+       clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(clk), "unable to get the clock");
+
+       /*
+        * Uses the 24MHz system clock on all existing devices, can only
+        * happen if the device tree is broken
+        *
+        * This check is done to prevent an overflow in .apply
+        */
+       fpwm->clkrate = clk_get_rate(clk);
+       if (fpwm->clkrate > NSEC_PER_SEC)
+               return dev_err_probe(&pdev->dev, -EINVAL, "pwm clock out of range");
+
+       fpwm->chip.dev = &pdev->dev;
+       fpwm->chip.npwm = 1;
+       fpwm->chip.ops = &apple_pwm_ops;
+
+       ret = devm_pwmchip_add(&pdev->dev, &fpwm->chip);
+       if (ret < 0)
+               return dev_err_probe(&pdev->dev, ret, "unable to add pwm chip");
+
+       return 0;
+}
+
+static const struct of_device_id apple_pwm_of_match[] = {
+       { .compatible = "apple,s5l-fpwm" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, apple_pwm_of_match);
+
+static struct platform_driver apple_pwm_driver = {
+       .probe = apple_pwm_probe,
+       .driver = {
+               .name = "apple-pwm",
+               .of_match_table = apple_pwm_of_match,
+       },
+};
+module_platform_driver(apple_pwm_driver);
+
+MODULE_DESCRIPTION("Apple SoC PWM driver");
+MODULE_LICENSE("Dual MIT/GPL");
index a43b2ba..96a709a 100644 (file)
@@ -278,15 +278,13 @@ static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int atmel_hlcdc_pwm_remove(struct platform_device *pdev)
+static void atmel_hlcdc_pwm_remove(struct platform_device *pdev)
 {
        struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev);
 
        pwmchip_remove(&chip->chip);
 
        clk_disable_unprepare(chip->hlcdc->periph_clk);
-
-       return 0;
 }
 
 static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = {
@@ -301,7 +299,7 @@ static struct platform_driver atmel_hlcdc_pwm_driver = {
                .pm = &atmel_hlcdc_pwm_pm_ops,
        },
        .probe = atmel_hlcdc_pwm_probe,
-       .remove = atmel_hlcdc_pwm_remove,
+       .remove_new = atmel_hlcdc_pwm_remove,
 };
 module_platform_driver(atmel_hlcdc_pwm_driver);
 
index 2837b4c..4a116dc 100644 (file)
@@ -500,7 +500,7 @@ err_slow_clk:
        return err;
 }
 
-static int atmel_tcb_pwm_remove(struct platform_device *pdev)
+static void atmel_tcb_pwm_remove(struct platform_device *pdev)
 {
        struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
 
@@ -509,8 +509,6 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev)
        clk_disable_unprepare(tcbpwm->slow_clk);
        clk_put(tcbpwm->slow_clk);
        clk_put(tcbpwm->clk);
-
-       return 0;
 }
 
 static const struct of_device_id atmel_tcb_pwm_dt_ids[] = {
@@ -564,7 +562,7 @@ static struct platform_driver atmel_tcb_pwm_driver = {
                .pm = &atmel_tcb_pwm_pm_ops,
        },
        .probe = atmel_tcb_pwm_probe,
-       .remove = atmel_tcb_pwm_remove,
+       .remove_new = atmel_tcb_pwm_remove,
 };
 module_platform_driver(atmel_tcb_pwm_driver);
 
index cdbc236..0c567d9 100644 (file)
@@ -511,15 +511,13 @@ unprepare_clk:
        return ret;
 }
 
-static int atmel_pwm_remove(struct platform_device *pdev)
+static void atmel_pwm_remove(struct platform_device *pdev)
 {
        struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);
 
        pwmchip_remove(&atmel_pwm->chip);
 
        clk_unprepare(atmel_pwm->clk);
-
-       return 0;
 }
 
 static struct platform_driver atmel_pwm_driver = {
@@ -528,7 +526,7 @@ static struct platform_driver atmel_pwm_driver = {
                .of_match_table = of_match_ptr(atmel_pwm_dt_ids),
        },
        .probe = atmel_pwm_probe,
-       .remove = atmel_pwm_remove,
+       .remove_new = atmel_pwm_remove,
 };
 module_platform_driver(atmel_pwm_driver);
 
index 97ec131..7d70b6f 100644 (file)
@@ -239,15 +239,13 @@ static int iproc_pwmc_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int iproc_pwmc_remove(struct platform_device *pdev)
+static void iproc_pwmc_remove(struct platform_device *pdev)
 {
        struct iproc_pwmc *ip = platform_get_drvdata(pdev);
 
        pwmchip_remove(&ip->chip);
 
        clk_disable_unprepare(ip->clk);
-
-       return 0;
 }
 
 static const struct of_device_id bcm_iproc_pwmc_dt[] = {
@@ -262,7 +260,7 @@ static struct platform_driver iproc_pwmc_driver = {
                .of_match_table = bcm_iproc_pwmc_dt,
        },
        .probe = iproc_pwmc_probe,
-       .remove = iproc_pwmc_remove,
+       .remove_new = iproc_pwmc_remove,
 };
 module_platform_driver(iproc_pwmc_driver);
 
index 50b8594..bdfc2a5 100644 (file)
@@ -173,15 +173,13 @@ add_fail:
        return ret;
 }
 
-static int bcm2835_pwm_remove(struct platform_device *pdev)
+static void bcm2835_pwm_remove(struct platform_device *pdev)
 {
        struct bcm2835_pwm *pc = platform_get_drvdata(pdev);
 
        pwmchip_remove(&pc->chip);
 
        clk_disable_unprepare(pc->clk);
-
-       return 0;
 }
 
 static const struct of_device_id bcm2835_pwm_of_match[] = {
@@ -196,7 +194,7 @@ static struct platform_driver bcm2835_pwm_driver = {
                .of_match_table = bcm2835_pwm_of_match,
        },
        .probe = bcm2835_pwm_probe,
-       .remove = bcm2835_pwm_remove,
+       .remove_new = bcm2835_pwm_remove,
 };
 module_platform_driver(bcm2835_pwm_driver);
 
index e157273..0c5992a 100644 (file)
@@ -250,15 +250,13 @@ static int berlin_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int berlin_pwm_remove(struct platform_device *pdev)
+static void berlin_pwm_remove(struct platform_device *pdev)
 {
        struct berlin_pwm_chip *bpc = platform_get_drvdata(pdev);
 
        pwmchip_remove(&bpc->chip);
 
        clk_disable_unprepare(bpc->clk);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -317,7 +315,7 @@ static SIMPLE_DEV_PM_OPS(berlin_pwm_pm_ops, berlin_pwm_suspend,
 
 static struct platform_driver berlin_pwm_driver = {
        .probe = berlin_pwm_probe,
-       .remove = berlin_pwm_remove,
+       .remove_new = berlin_pwm_remove,
        .driver = {
                .name = "berlin-pwm",
                .of_match_table = berlin_pwm_match,
index 3db3f96..a3faa9a 100644 (file)
@@ -275,14 +275,12 @@ out_clk:
        return ret;
 }
 
-static int brcmstb_pwm_remove(struct platform_device *pdev)
+static void brcmstb_pwm_remove(struct platform_device *pdev)
 {
        struct brcmstb_pwm *p = platform_get_drvdata(pdev);
 
        pwmchip_remove(&p->chip);
        clk_disable_unprepare(p->clk);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -310,7 +308,7 @@ static SIMPLE_DEV_PM_OPS(brcmstb_pwm_pm_ops, brcmstb_pwm_suspend,
 
 static struct platform_driver brcmstb_pwm_driver = {
        .probe = brcmstb_pwm_probe,
-       .remove = brcmstb_pwm_remove,
+       .remove_new = brcmstb_pwm_remove,
        .driver = {
                .name = "pwm-brcmstb",
                .of_match_table = brcmstb_pwm_of_match,
index c2a503d..f1da998 100644 (file)
@@ -112,7 +112,7 @@ static int pwm_clk_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int pwm_clk_remove(struct platform_device *pdev)
+static void pwm_clk_remove(struct platform_device *pdev)
 {
        struct pwm_clk_chip *pcchip = platform_get_drvdata(pdev);
 
@@ -122,8 +122,6 @@ static int pwm_clk_remove(struct platform_device *pdev)
                clk_disable(pcchip->clk);
 
        clk_unprepare(pcchip->clk);
-
-       return 0;
 }
 
 static const struct of_device_id pwm_clk_dt_ids[] = {
@@ -138,7 +136,7 @@ static struct platform_driver pwm_clk_driver = {
                .of_match_table = pwm_clk_dt_ids,
        },
        .probe = pwm_clk_probe,
-       .remove = pwm_clk_remove,
+       .remove_new = pwm_clk_remove,
 };
 module_platform_driver(pwm_clk_driver);
 
index ad18b0e..74e863a 100644 (file)
@@ -329,14 +329,12 @@ static int cros_ec_pwm_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int cros_ec_pwm_remove(struct platform_device *dev)
+static void cros_ec_pwm_remove(struct platform_device *dev)
 {
        struct cros_ec_pwm_device *ec_pwm = platform_get_drvdata(dev);
        struct pwm_chip *chip = &ec_pwm->chip;
 
        pwmchip_remove(chip);
-
-       return 0;
 }
 
 #ifdef CONFIG_OF
@@ -350,7 +348,7 @@ MODULE_DEVICE_TABLE(of, cros_ec_pwm_of_match);
 
 static struct platform_driver cros_ec_pwm_driver = {
        .probe = cros_ec_pwm_probe,
-       .remove = cros_ec_pwm_remove,
+       .remove_new = cros_ec_pwm_remove,
        .driver = {
                .name = "cros-ec-pwm",
                .of_match_table = of_match_ptr(cros_ec_pwm_of_match),
index 1b9274c..b95df1a 100644 (file)
@@ -245,7 +245,7 @@ static int hibvt_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int hibvt_pwm_remove(struct platform_device *pdev)
+static void hibvt_pwm_remove(struct platform_device *pdev)
 {
        struct hibvt_pwm_chip *pwm_chip;
 
@@ -258,8 +258,6 @@ static int hibvt_pwm_remove(struct platform_device *pdev)
        reset_control_deassert(pwm_chip->rstc);
 
        clk_disable_unprepare(pwm_chip->clk);
-
-       return 0;
 }
 
 static const struct of_device_id hibvt_pwm_of_match[] = {
@@ -281,7 +279,7 @@ static struct platform_driver hibvt_pwm_driver = {
                .of_match_table = hibvt_pwm_of_match,
        },
        .probe = hibvt_pwm_probe,
-       .remove = hibvt_pwm_remove,
+       .remove_new = hibvt_pwm_remove,
 };
 module_platform_driver(hibvt_pwm_driver);
 
index 89362af..326af85 100644 (file)
@@ -343,7 +343,7 @@ err_pm_disable:
        return ret;
 }
 
-static int img_pwm_remove(struct platform_device *pdev)
+static void img_pwm_remove(struct platform_device *pdev)
 {
        struct img_pwm_chip *imgchip = platform_get_drvdata(pdev);
 
@@ -352,8 +352,6 @@ static int img_pwm_remove(struct platform_device *pdev)
                img_pwm_runtime_suspend(&pdev->dev);
 
        pwmchip_remove(&imgchip->chip);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -423,7 +421,7 @@ static struct platform_driver img_pwm_driver = {
                .of_match_table = img_pwm_of_match,
        },
        .probe = img_pwm_probe,
-       .remove = img_pwm_remove,
+       .remove_new = img_pwm_remove,
 };
 module_platform_driver(img_pwm_driver);
 
index ed1aad9..5e2b452 100644 (file)
@@ -381,15 +381,13 @@ static int pwm_imx_tpm_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int pwm_imx_tpm_remove(struct platform_device *pdev)
+static void pwm_imx_tpm_remove(struct platform_device *pdev)
 {
        struct imx_tpm_pwm_chip *tpm = platform_get_drvdata(pdev);
 
        pwmchip_remove(&tpm->chip);
 
        clk_disable_unprepare(tpm->clk);
-
-       return 0;
 }
 
 static int __maybe_unused pwm_imx_tpm_suspend(struct device *dev)
@@ -432,7 +430,7 @@ static struct platform_driver imx_tpm_pwm_driver = {
                .pm = &imx_tpm_pwm_pm,
        },
        .probe  = pwm_imx_tpm_probe,
-       .remove = pwm_imx_tpm_remove,
+       .remove_new = pwm_imx_tpm_remove,
 };
 module_platform_driver(imx_tpm_pwm_driver);
 
index 378e1df..b9bf5b3 100644 (file)
@@ -449,7 +449,7 @@ disable_pwmclk:
        return ret;
 }
 
-static int lpc18xx_pwm_remove(struct platform_device *pdev)
+static void lpc18xx_pwm_remove(struct platform_device *pdev)
 {
        struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev);
        u32 val;
@@ -461,8 +461,6 @@ static int lpc18xx_pwm_remove(struct platform_device *pdev)
                           val | LPC18XX_PWM_CTRL_HALT);
 
        clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
-
-       return 0;
 }
 
 static struct platform_driver lpc18xx_pwm_driver = {
@@ -471,7 +469,7 @@ static struct platform_driver lpc18xx_pwm_driver = {
                .of_match_table = lpc18xx_pwm_of_match,
        },
        .probe = lpc18xx_pwm_probe,
-       .remove = lpc18xx_pwm_remove,
+       .remove_new = lpc18xx_pwm_remove,
 };
 module_platform_driver(lpc18xx_pwm_driver);
 
index f350607..319809a 100644 (file)
@@ -62,10 +62,9 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
        return 0;
 }
 
-static int pwm_lpss_remove_platform(struct platform_device *pdev)
+static void pwm_lpss_remove_platform(struct platform_device *pdev)
 {
        pm_runtime_disable(&pdev->dev);
-       return 0;
 }
 
 static const struct acpi_device_id pwm_lpss_acpi_match[] = {
@@ -83,7 +82,7 @@ static struct platform_driver pwm_lpss_driver_platform = {
                .acpi_match_table = pwm_lpss_acpi_match,
        },
        .probe = pwm_lpss_probe_platform,
-       .remove = pwm_lpss_remove_platform,
+       .remove_new = pwm_lpss_remove_platform,
 };
 module_platform_driver(pwm_lpss_driver_platform);
 
index 5cd7b90..5732300 100644 (file)
@@ -418,7 +418,7 @@ static const struct meson_pwm_data pwm_axg_ee_data = {
 };
 
 static const char * const pwm_axg_ao_parent_names[] = {
-       "aoclk81", "xtal", "fclk_div4", "fclk_div5"
+       "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5"
 };
 
 static const struct meson_pwm_data pwm_axg_ao_data = {
@@ -427,7 +427,7 @@ static const struct meson_pwm_data pwm_axg_ao_data = {
 };
 
 static const char * const pwm_g12a_ao_ab_parent_names[] = {
-       "xtal", "aoclk81", "fclk_div4", "fclk_div5"
+       "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5"
 };
 
 static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
@@ -436,7 +436,7 @@ static const struct meson_pwm_data pwm_g12a_ao_ab_data = {
 };
 
 static const char * const pwm_g12a_ao_cd_parent_names[] = {
-       "xtal", "aoclk81",
+       "xtal", "g12a_ao_clk81",
 };
 
 static const struct meson_pwm_data pwm_g12a_ao_cd_data = {
index 692a061..79e321e 100644 (file)
@@ -138,6 +138,19 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
        value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
+       if (mdp->data->bls_debug && !mdp->data->has_commit) {
+               /*
+                * For MT2701, disable double buffer before writing register
+                * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
+                */
+               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+                                        mdp->data->bls_debug_mask,
+                                        mdp->data->bls_debug_mask);
+               mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
+                                        mdp->data->con0_sel,
+                                        mdp->data->con0_sel);
+       }
+
        mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
                                 PWM_CLKDIV_MASK,
                                 clk_div << PWM_CLKDIV_SHIFT);
@@ -152,17 +165,6 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
                                         mdp->data->commit_mask,
                                         0x0);
-       } else {
-               /*
-                * For MT2701, disable double buffer before writing register
-                * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
-                */
-               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
-                                        mdp->data->bls_debug_mask,
-                                        mdp->data->bls_debug_mask);
-               mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-                                        mdp->data->con0_sel,
-                                        mdp->data->con0_sel);
        }
 
        mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
@@ -194,6 +196,16 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip,
                return err;
        }
 
+       /*
+        * Apply DISP_PWM_DEBUG settings to choose whether to enable or disable
+        * registers double buffer and manual commit to working register before
+        * performing any read/write operation
+        */
+       if (mdp->data->bls_debug)
+               mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
+                                        mdp->data->bls_debug_mask,
+                                        mdp->data->bls_debug_mask);
+
        rate = clk_get_rate(mdp->clk_main);
        con0 = readl(mdp->base + mdp->data->con0);
        con1 = readl(mdp->base + mdp->data->con1);
@@ -260,13 +272,11 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int mtk_disp_pwm_remove(struct platform_device *pdev)
+static void mtk_disp_pwm_remove(struct platform_device *pdev)
 {
        struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
 
        pwmchip_remove(&mdp->chip);
-
-       return 0;
 }
 
 static const struct mtk_pwm_data mt2701_pwm_data = {
@@ -314,7 +324,7 @@ static struct platform_driver mtk_disp_pwm_driver = {
                .of_match_table = mtk_disp_pwm_of_match,
        },
        .probe = mtk_disp_pwm_probe,
-       .remove = mtk_disp_pwm_remove,
+       .remove_new = mtk_disp_pwm_remove,
 };
 module_platform_driver(mtk_disp_pwm_driver);
 
index fa800fc..4889fbd 100644 (file)
@@ -441,7 +441,7 @@ err_find_timer_pdev:
        return ret;
 }
 
-static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
+static void pwm_omap_dmtimer_remove(struct platform_device *pdev)
 {
        struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
 
@@ -455,8 +455,6 @@ static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
        put_device(&omap->dm_timer_pdev->dev);
 
        mutex_destroy(&omap->mutex);
-
-       return 0;
 }
 
 static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
@@ -471,7 +469,7 @@ static struct platform_driver pwm_omap_dmtimer_driver = {
                .of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match),
        },
        .probe = pwm_omap_dmtimer_probe,
-       .remove = pwm_omap_dmtimer_remove,
+       .remove_new = pwm_omap_dmtimer_remove,
 };
 module_platform_driver(pwm_omap_dmtimer_driver);
 
index 55f46d0..5b5f357 100644 (file)
@@ -238,15 +238,13 @@ static int rcar_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int rcar_pwm_remove(struct platform_device *pdev)
+static void rcar_pwm_remove(struct platform_device *pdev)
 {
        struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev);
 
        pwmchip_remove(&rcar_pwm->chip);
 
        pm_runtime_disable(&pdev->dev);
-
-       return 0;
 }
 
 static const struct of_device_id rcar_pwm_of_table[] = {
@@ -257,10 +255,10 @@ MODULE_DEVICE_TABLE(of, rcar_pwm_of_table);
 
 static struct platform_driver rcar_pwm_driver = {
        .probe = rcar_pwm_probe,
-       .remove = rcar_pwm_remove,
+       .remove_new = rcar_pwm_remove,
        .driver = {
                .name = "pwm-rcar",
-               .of_match_table = of_match_ptr(rcar_pwm_of_table),
+               .of_match_table = rcar_pwm_of_table,
        }
 };
 module_platform_driver(rcar_pwm_driver);
index 7f084eb..c1a1f2d 100644 (file)
@@ -376,7 +376,7 @@ err_clk:
        return ret;
 }
 
-static int rockchip_pwm_remove(struct platform_device *pdev)
+static void rockchip_pwm_remove(struct platform_device *pdev)
 {
        struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev);
 
@@ -384,8 +384,6 @@ static int rockchip_pwm_remove(struct platform_device *pdev)
 
        clk_unprepare(pc->pclk);
        clk_unprepare(pc->clk);
-
-       return 0;
 }
 
 static struct platform_driver rockchip_pwm_driver = {
@@ -394,7 +392,7 @@ static struct platform_driver rockchip_pwm_driver = {
                .of_match_table = rockchip_pwm_dt_ids,
        },
        .probe = rockchip_pwm_probe,
-       .remove = rockchip_pwm_remove,
+       .remove_new = rockchip_pwm_remove,
 };
 module_platform_driver(rockchip_pwm_driver);
 
index 9c5b4f5..e8828f5 100644 (file)
@@ -621,15 +621,13 @@ static int pwm_samsung_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int pwm_samsung_remove(struct platform_device *pdev)
+static void pwm_samsung_remove(struct platform_device *pdev)
 {
        struct samsung_pwm_chip *chip = platform_get_drvdata(pdev);
 
        pwmchip_remove(&chip->chip);
 
        clk_disable_unprepare(chip->base_clk);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -676,7 +674,7 @@ static struct platform_driver pwm_samsung_driver = {
                .of_match_table = of_match_ptr(samsung_pwm_matches),
        },
        .probe          = pwm_samsung_probe,
-       .remove         = pwm_samsung_remove,
+       .remove_new     = pwm_samsung_remove,
 };
 module_platform_driver(pwm_samsung_driver);
 
index 393a4b9..5b0574f 100644 (file)
@@ -313,7 +313,7 @@ disable_clk:
        return ret;
 }
 
-static int pwm_sifive_remove(struct platform_device *dev)
+static void pwm_sifive_remove(struct platform_device *dev)
 {
        struct pwm_sifive_ddata *ddata = platform_get_drvdata(dev);
        struct pwm_device *pwm;
@@ -329,8 +329,6 @@ static int pwm_sifive_remove(struct platform_device *dev)
        }
 
        clk_unprepare(ddata->clk);
-
-       return 0;
 }
 
 static const struct of_device_id pwm_sifive_of_match[] = {
@@ -341,7 +339,7 @@ MODULE_DEVICE_TABLE(of, pwm_sifive_of_match);
 
 static struct platform_driver pwm_sifive_driver = {
        .probe = pwm_sifive_probe,
-       .remove = pwm_sifive_remove,
+       .remove_new = pwm_sifive_remove,
        .driver = {
                .name = "pwm-sifive",
                .of_match_table = pwm_sifive_of_match,
index 54c7990..4e1cfd8 100644 (file)
@@ -247,7 +247,7 @@ static int spear_pwm_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int spear_pwm_remove(struct platform_device *pdev)
+static void spear_pwm_remove(struct platform_device *pdev)
 {
        struct spear_pwm_chip *pc = platform_get_drvdata(pdev);
 
@@ -255,8 +255,6 @@ static int spear_pwm_remove(struct platform_device *pdev)
 
        /* clk was prepared in probe, hence unprepare it here */
        clk_unprepare(pc->clk);
-
-       return 0;
 }
 
 static const struct of_device_id spear_pwm_of_match[] = {
@@ -273,7 +271,7 @@ static struct platform_driver spear_pwm_driver = {
                .of_match_table = spear_pwm_of_match,
        },
        .probe = spear_pwm_probe,
-       .remove = spear_pwm_remove,
+       .remove_new = spear_pwm_remove,
 };
 
 module_platform_driver(spear_pwm_driver);
index bde579a..d43a6fa 100644 (file)
@@ -280,13 +280,11 @@ static int sprd_pwm_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int sprd_pwm_remove(struct platform_device *pdev)
+static void sprd_pwm_remove(struct platform_device *pdev)
 {
        struct sprd_pwm_chip *spc = platform_get_drvdata(pdev);
 
        pwmchip_remove(&spc->chip);
-
-       return 0;
 }
 
 static const struct of_device_id sprd_pwm_of_match[] = {
@@ -301,7 +299,7 @@ static struct platform_driver sprd_pwm_driver = {
                .of_match_table = sprd_pwm_of_match,
        },
        .probe = sprd_pwm_probe,
-       .remove = sprd_pwm_remove,
+       .remove_new = sprd_pwm_remove,
 };
 
 module_platform_driver(sprd_pwm_driver);
index 44b1f93..b1d1373 100644 (file)
@@ -669,7 +669,7 @@ static int sti_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int sti_pwm_remove(struct platform_device *pdev)
+static void sti_pwm_remove(struct platform_device *pdev)
 {
        struct sti_pwm_chip *pc = platform_get_drvdata(pdev);
 
@@ -677,8 +677,6 @@ static int sti_pwm_remove(struct platform_device *pdev)
 
        clk_unprepare(pc->pwm_clk);
        clk_unprepare(pc->cpt_clk);
-
-       return 0;
 }
 
 static const struct of_device_id sti_pwm_of_match[] = {
@@ -693,7 +691,7 @@ static struct platform_driver sti_pwm_driver = {
                .of_match_table = sti_pwm_of_match,
        },
        .probe = sti_pwm_probe,
-       .remove = sti_pwm_remove,
+       .remove_new = sti_pwm_remove,
 };
 module_platform_driver(sti_pwm_driver);
 
index f315fa1..bb3a045 100644 (file)
@@ -252,7 +252,7 @@ static struct platform_driver stm32_pwm_lp_driver = {
        .probe  = stm32_pwm_lp_probe,
        .driver = {
                .name = "stm32-pwm-lp",
-               .of_match_table = of_match_ptr(stm32_pwm_lp_of_match),
+               .of_match_table = stm32_pwm_lp_of_match,
                .pm = &stm32_pwm_lp_pm_ops,
        },
 };
index 21e4a34..62e397a 100644 (file)
@@ -207,6 +207,10 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
        regmap_write(priv->regmap, TIM_ARR, priv->max_arr);
        regmap_write(priv->regmap, TIM_PSC, psc);
 
+       /* Reset input selector to its default input and disable slave mode */
+       regmap_write(priv->regmap, TIM_TISEL, 0x0);
+       regmap_write(priv->regmap, TIM_SMCR, 0x0);
+
        /* Map TI1 or TI2 PWM input to IC1 & IC2 (or TI3/4 to IC3 & IC4) */
        regmap_update_bits(priv->regmap,
                           pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2,
@@ -642,7 +646,7 @@ static int stm32_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int stm32_pwm_remove(struct platform_device *pdev)
+static void stm32_pwm_remove(struct platform_device *pdev)
 {
        struct stm32_pwm *priv = platform_get_drvdata(pdev);
        unsigned int i;
@@ -651,8 +655,6 @@ static int stm32_pwm_remove(struct platform_device *pdev)
                pwm_disable(&priv->chip.pwms[i]);
 
        pwmchip_remove(&priv->chip);
-
-       return 0;
 }
 
 static int __maybe_unused stm32_pwm_suspend(struct device *dev)
@@ -699,7 +701,7 @@ MODULE_DEVICE_TABLE(of, stm32_pwm_of_match);
 
 static struct platform_driver stm32_pwm_driver = {
        .probe  = stm32_pwm_probe,
-       .remove = stm32_pwm_remove,
+       .remove_new = stm32_pwm_remove,
        .driver = {
                .name = "stm32-pwm",
                .of_match_table = stm32_pwm_of_match,
index b973da7..a8790a8 100644 (file)
@@ -477,7 +477,7 @@ err_bus:
        return ret;
 }
 
-static int sun4i_pwm_remove(struct platform_device *pdev)
+static void sun4i_pwm_remove(struct platform_device *pdev)
 {
        struct sun4i_pwm_chip *sun4ichip = platform_get_drvdata(pdev);
 
@@ -485,8 +485,6 @@ static int sun4i_pwm_remove(struct platform_device *pdev)
 
        clk_disable_unprepare(sun4ichip->bus_clk);
        reset_control_assert(sun4ichip->rst);
-
-       return 0;
 }
 
 static struct platform_driver sun4i_pwm_driver = {
@@ -495,7 +493,7 @@ static struct platform_driver sun4i_pwm_driver = {
                .of_match_table = sun4i_pwm_dt_ids,
        },
        .probe = sun4i_pwm_probe,
-       .remove = sun4i_pwm_remove,
+       .remove_new = sun4i_pwm_remove,
 };
 module_platform_driver(sun4i_pwm_driver);
 
index 249dc01..5810abf 100644 (file)
@@ -350,7 +350,7 @@ put_pm:
        return ret;
 }
 
-static int tegra_pwm_remove(struct platform_device *pdev)
+static void tegra_pwm_remove(struct platform_device *pdev)
 {
        struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
 
@@ -359,8 +359,6 @@ static int tegra_pwm_remove(struct platform_device *pdev)
        reset_control_assert(pc->rst);
 
        pm_runtime_force_suspend(&pdev->dev);
-
-       return 0;
 }
 
 static int __maybe_unused tegra_pwm_runtime_suspend(struct device *dev)
@@ -434,7 +432,7 @@ static struct platform_driver tegra_pwm_driver = {
                .pm = &tegra_pwm_pm_ops,
        },
        .probe = tegra_pwm_probe,
-       .remove = tegra_pwm_remove,
+       .remove_new = tegra_pwm_remove,
 };
 
 module_platform_driver(tegra_pwm_driver);
index 4701f0c..1094499 100644 (file)
@@ -265,11 +265,9 @@ static int ecap_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int ecap_pwm_remove(struct platform_device *pdev)
+static void ecap_pwm_remove(struct platform_device *pdev)
 {
        pm_runtime_disable(&pdev->dev);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -326,7 +324,7 @@ static struct platform_driver ecap_pwm_driver = {
                .pm = &ecap_pwm_pm_ops,
        },
        .probe = ecap_pwm_probe,
-       .remove = ecap_pwm_remove,
+       .remove_new = ecap_pwm_remove,
 };
 module_platform_driver(ecap_pwm_driver);
 
index 48ca0ff..bb3959a 100644 (file)
@@ -511,7 +511,7 @@ err_clk_unprepare:
        return ret;
 }
 
-static int ehrpwm_pwm_remove(struct platform_device *pdev)
+static void ehrpwm_pwm_remove(struct platform_device *pdev)
 {
        struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev);
 
@@ -520,8 +520,6 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev)
        clk_unprepare(pc->tbclk);
 
        pm_runtime_disable(&pdev->dev);
-
-       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -604,7 +602,7 @@ static struct platform_driver ehrpwm_pwm_driver = {
                .pm = &ehrpwm_pwm_pm_ops,
        },
        .probe = ehrpwm_pwm_probe,
-       .remove = ehrpwm_pwm_remove,
+       .remove_new = ehrpwm_pwm_remove,
 };
 module_platform_driver(ehrpwm_pwm_driver);
 
index f1ff994..d2c48fd 100644 (file)
@@ -279,20 +279,18 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int vt8500_pwm_remove(struct platform_device *pdev)
+static void vt8500_pwm_remove(struct platform_device *pdev)
 {
        struct vt8500_chip *vt8500 = platform_get_drvdata(pdev);
 
        pwmchip_remove(&vt8500->chip);
 
        clk_unprepare(vt8500->clk);
-
-       return 0;
 }
 
 static struct platform_driver vt8500_pwm_driver = {
        .probe          = vt8500_pwm_probe,
-       .remove         = vt8500_pwm_remove,
+       .remove_new     = vt8500_pwm_remove,
        .driver         = {
                .name   = "vt8500-pwm",
                .of_match_table = vt8500_pwm_dt_ids,
index f7a50fd..85153ee 100644 (file)
@@ -292,14 +292,13 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int xilinx_pwm_remove(struct platform_device *pdev)
+static void xilinx_pwm_remove(struct platform_device *pdev)
 {
        struct xilinx_pwm_device *xilinx_pwm = platform_get_drvdata(pdev);
 
        pwmchip_remove(&xilinx_pwm->chip);
        clk_rate_exclusive_put(xilinx_pwm->priv.clk);
        clk_disable_unprepare(xilinx_pwm->priv.clk);
-       return 0;
 }
 
 static const struct of_device_id xilinx_pwm_of_match[] = {
@@ -310,7 +309,7 @@ MODULE_DEVICE_TABLE(of, xilinx_pwm_of_match);
 
 static struct platform_driver xilinx_pwm_driver = {
        .probe = xilinx_pwm_probe,
-       .remove = xilinx_pwm_remove,
+       .remove_new = xilinx_pwm_remove,
        .driver = {
                .name = "xilinx-pwm",
                .of_match_table = of_match_ptr(xilinx_pwm_of_match),
index 5f5c43f..1b94325 100644 (file)
@@ -31,6 +31,7 @@
 #define TIM_BDTR       0x44    /* Break and Dead-Time Reg */
 #define TIM_DCR                0x48    /* DMA control register    */
 #define TIM_DMAR       0x4C    /* DMA register for transfer */
+#define TIM_TISEL      0x68    /* Input Selection         */
 
 #define TIM_CR1_CEN    BIT(0)  /* Counter Enable          */
 #define TIM_CR1_DIR    BIT(4)  /* Counter Direction       */
index 7b7b93b..04ae1d9 100644 (file)
@@ -309,8 +309,6 @@ struct pwm_chip {
 
 #if IS_ENABLED(CONFIG_PWM)
 /* PWM user APIs */
-struct pwm_device *pwm_request(int pwm_id, const char *label);
-void pwm_free(struct pwm_device *pwm);
 int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state);
 int pwm_adjust_config(struct pwm_device *pwm);
 
@@ -410,17 +408,6 @@ struct pwm_device *devm_fwnode_pwm_get(struct device *dev,
                                       struct fwnode_handle *fwnode,
                                       const char *con_id);
 #else
-static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-       might_sleep();
-       return ERR_PTR(-ENODEV);
-}
-
-static inline void pwm_free(struct pwm_device *pwm)
-{
-       might_sleep();
-}
-
 static inline int pwm_apply_state(struct pwm_device *pwm,
                                  const struct pwm_state *state)
 {