mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
pwm: Changes for v6.4-rc1
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. -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmRSgJcZHHRoaWVycnku cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zoUZzEACcLaLRRvAsgsrrnunQ1sNT y5Haep7FjYF8W0cn3MJbH4efdtW6mKJxMV7ZCvbPYXi79Q//4J3oeXV/miRcYTLf OqALvWKlaXJ3bbwddOdsxjqBBRDPfo3hMTZjSkfiTTbH1vIx3lD/nAdogrVHPBh+ Ap6RMFqb5xnJtefxWNaQ6puWY6XjA9jznitQtMMEkjZqjQtqNd+QX149tFU3avwo 0S4cjUB3FKiSctUXW5EZh3jNSDgB/TYmeslkpmnozkde9DK3ooYMRDMkV0jTaGSb EKPLWmLSoIDH+ghG7r5KGkE7x5mBELtBbW/KxXBFpro/x528VxYdTgAGOn54XWmn NcsWiMdReWmPbPDQzZcUBDn8boxyw4jtqsdwzu96G1KHdKcVH6EH00XcH+Pi9KG9 HqPBMvqAjxAn3GK6SdfjGU1KmGB3MYCi4u+twAyycDOEMkxA+FzHSs+OD1a2iaK/ AIYXMjZ4KdVIvIIjJzJttdkTOzt/R6xfn4okvlBzQpD34c7eyi6U+S24+I4yX4y5 wGmZ52h5VvWaBXPaDPYaziyhfRn0nzBSVRXqV62jAusON/xcU6tc1L5YYX0GRNfv NG264HBAdlUVERs6XDqC+meKwFSzLEmt47pWCBCnOfck/KXLqdsM2tQtMTmI0p4l 9vncNSofIexg/HcrdOFbug== =slCK -----END PGP SIGNATURE----- Merge tag 'pwm/for-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm 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 ...
This commit is contained in:
commit
89b7fd5d7f
51
Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
Normal file
51
Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
Normal file
@ -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>;
|
||||
};
|
@ -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
|
||||
|
70
Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
Normal file
70
Documentation/devicetree/bindings/pwm/pwm-amlogic.yaml
Normal file
@ -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>;
|
||||
};
|
@ -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";
|
||||
}
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -28,17 +28,11 @@
|
||||
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);
|
||||
@ -369,43 +353,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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
159
drivers/pwm/pwm-apple.c
Normal file
159
drivers/pwm/pwm-apple.c
Normal file
@ -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");
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user