diff options
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/Kconfig | 7 | ||||
-rw-r--r-- | drivers/pwm/Makefile | 1 | ||||
-rw-r--r-- | drivers/pwm/core.c | 13 | ||||
-rw-r--r-- | drivers/pwm/pwm-adp5585.c | 188 | ||||
-rw-r--r-- | drivers/pwm/pwm-atmel-hlcdc.c | 7 | ||||
-rw-r--r-- | drivers/pwm/pwm-atmel-tcb.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-axi-pwmgen.c | 3 | ||||
-rw-r--r-- | drivers/pwm/pwm-clk.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-hibvt.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-img.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-lp3943.c | 10 | ||||
-rw-r--r-- | drivers/pwm/pwm-lpc18xx-sct.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-omap-dmtimer.c | 4 | ||||
-rw-r--r-- | drivers/pwm/pwm-rcar.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-rockchip.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-sifive.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-stm32.c | 4 | ||||
-rw-r--r-- | drivers/pwm/pwm-sun4i.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-tegra.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-tiecap.c | 2 | ||||
-rw-r--r-- | drivers/pwm/pwm-tiehrpwm.c | 2 |
21 files changed, 226 insertions, 35 deletions
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 3e53838990f5..0915c1e7df16 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -47,6 +47,13 @@ config PWM_AB8500 To compile this driver as a module, choose M here: the module will be called pwm-ab8500. +config PWM_ADP5585 + tristate "ADP5585 PWM support" + depends on MFD_ADP5585 + help + This option enables support for the PWM function found in the Analog + Devices ADP5585. + config PWM_APPLE tristate "Apple SoC PWM support" depends on ARCH_APPLE || COMPILE_TEST diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 0be4f3e6dd43..9081e0c0e9e0 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PWM) += core.o obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o +obj-$(CONFIG_PWM_ADP5585) += pwm-adp5585.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 diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 8acbcf5b6673..6e752e148b98 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -325,20 +325,19 @@ EXPORT_SYMBOL_GPL(pwm_adjust_config); * * Returns: 0 on success or a negative error code on failure. */ -int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, - unsigned long timeout) +static int pwm_capture(struct pwm_device *pwm, struct pwm_capture *result, + unsigned long timeout) { - if (!pwm || !pwm->chip->ops) - return -EINVAL; + struct pwm_chip *chip = pwm->chip; + const struct pwm_ops *ops = chip->ops; - if (!pwm->chip->ops->capture) + if (!ops->capture) return -ENOSYS; guard(mutex)(&pwm_lock); - return pwm->chip->ops->capture(pwm->chip, pwm, result, timeout); + return ops->capture(chip, pwm, result, timeout); } -EXPORT_SYMBOL_GPL(pwm_capture); static struct pwm_chip *pwmchip_find_by_name(const char *name) { diff --git a/drivers/pwm/pwm-adp5585.c b/drivers/pwm/pwm-adp5585.c new file mode 100644 index 000000000000..40472ac5db64 --- /dev/null +++ b/drivers/pwm/pwm-adp5585.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices ADP5585 PWM driver + * + * Copyright 2022 NXP + * Copyright 2024 Ideas on Board Oy + * + * Limitations: + * - The .apply() operation executes atomically, but may not wait for the + * period to complete (this is not documented and would need to be tested). + * - Disabling the PWM drives the output pin to a low level immediately. + * - The hardware can only generate normal polarity output. + */ + +#include <asm/byteorder.h> + +#include <linux/device.h> +#include <linux/err.h> +#include <linux/math64.h> +#include <linux/mfd/adp5585.h> +#include <linux/minmax.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pwm.h> +#include <linux/regmap.h> +#include <linux/time.h> +#include <linux/types.h> + +#define ADP5585_PWM_CHAN_NUM 1 + +#define ADP5585_PWM_OSC_FREQ_HZ 1000000U +#define ADP5585_PWM_MIN_PERIOD_NS (2ULL * NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ) +#define ADP5585_PWM_MAX_PERIOD_NS (2ULL * 0xffff * NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ) + +static int pwm_adp5585_request(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct regmap *regmap = pwmchip_get_drvdata(chip); + + /* Configure the R3 pin as PWM output. */ + return regmap_update_bits(regmap, ADP5585_PIN_CONFIG_C, + ADP5585_R3_EXTEND_CFG_MASK, + ADP5585_R3_EXTEND_CFG_PWM_OUT); +} + +static void pwm_adp5585_free(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct regmap *regmap = pwmchip_get_drvdata(chip); + + regmap_update_bits(regmap, ADP5585_PIN_CONFIG_C, + ADP5585_R3_EXTEND_CFG_MASK, + ADP5585_R3_EXTEND_CFG_GPIO4); +} + +static int pwm_adp5585_apply(struct pwm_chip *chip, + struct pwm_device *pwm, + const struct pwm_state *state) +{ + struct regmap *regmap = pwmchip_get_drvdata(chip); + u64 period, duty_cycle; + u32 on, off; + __le16 val; + int ret; + + if (!state->enabled) { + regmap_clear_bits(regmap, ADP5585_GENERAL_CFG, ADP5585_OSC_EN); + regmap_clear_bits(regmap, ADP5585_PWM_CFG, ADP5585_PWM_EN); + return 0; + } + + if (state->polarity != PWM_POLARITY_NORMAL) + return -EINVAL; + + if (state->period < ADP5585_PWM_MIN_PERIOD_NS) + return -EINVAL; + + period = min(state->period, ADP5585_PWM_MAX_PERIOD_NS); + duty_cycle = min(state->duty_cycle, period); + + /* + * Compute the on and off time. As the internal oscillator frequency is + * 1MHz, the calculation can be simplified without loss of precision. + */ + on = div_u64(duty_cycle, NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ); + off = div_u64(period, NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ) - on; + + val = cpu_to_le16(off); + ret = regmap_bulk_write(regmap, ADP5585_PWM_OFFT_LOW, &val, 2); + if (ret) + return ret; + + val = cpu_to_le16(on); + ret = regmap_bulk_write(regmap, ADP5585_PWM_ONT_LOW, &val, 2); + if (ret) + return ret; + + /* Enable PWM in continuous mode and no external AND'ing. */ + ret = regmap_update_bits(regmap, ADP5585_PWM_CFG, + ADP5585_PWM_IN_AND | ADP5585_PWM_MODE | + ADP5585_PWM_EN, ADP5585_PWM_EN); + if (ret) + return ret; + + ret = regmap_set_bits(regmap, ADP5585_GENERAL_CFG, ADP5585_OSC_EN); + if (ret) + return ret; + + return regmap_set_bits(regmap, ADP5585_PWM_CFG, ADP5585_PWM_EN); +} + +static int pwm_adp5585_get_state(struct pwm_chip *chip, + struct pwm_device *pwm, + struct pwm_state *state) +{ + struct regmap *regmap = pwmchip_get_drvdata(chip); + unsigned int on, off; + unsigned int val; + __le16 on_off; + int ret; + + ret = regmap_bulk_read(regmap, ADP5585_PWM_OFFT_LOW, &on_off, 2); + if (ret) + return ret; + off = le16_to_cpu(on_off); + + ret = regmap_bulk_read(regmap, ADP5585_PWM_ONT_LOW, &on_off, 2); + if (ret) + return ret; + on = le16_to_cpu(on_off); + + state->duty_cycle = on * (NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ); + state->period = (on + off) * (NSEC_PER_SEC / ADP5585_PWM_OSC_FREQ_HZ); + + state->polarity = PWM_POLARITY_NORMAL; + + regmap_read(regmap, ADP5585_PWM_CFG, &val); + state->enabled = !!(val & ADP5585_PWM_EN); + + return 0; +} + +static const struct pwm_ops adp5585_pwm_ops = { + .request = pwm_adp5585_request, + .free = pwm_adp5585_free, + .apply = pwm_adp5585_apply, + .get_state = pwm_adp5585_get_state, +}; + +static int adp5585_pwm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct adp5585_dev *adp5585 = dev_get_drvdata(dev->parent); + struct pwm_chip *chip; + int ret; + + chip = devm_pwmchip_alloc(dev, ADP5585_PWM_CHAN_NUM, 0); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + device_set_of_node_from_dev(dev, dev->parent); + + pwmchip_set_drvdata(chip, adp5585->regmap); + chip->ops = &adp5585_pwm_ops; + + ret = devm_pwmchip_add(dev, chip); + if (ret) + return dev_err_probe(dev, ret, "failed to add PWM chip\n"); + + return 0; +} + +static const struct platform_device_id adp5585_pwm_id_table[] = { + { "adp5585-pwm" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, adp5585_pwm_id_table); + +static struct platform_driver adp5585_pwm_driver = { + .driver = { + .name = "adp5585-pwm", + }, + .probe = adp5585_pwm_probe, + .id_table = adp5585_pwm_id_table, +}; +module_platform_driver(adp5585_pwm_driver); + +MODULE_AUTHOR("Xiaoning Wang <xiaoning.wang@nxp.com>"); +MODULE_DESCRIPTION("ADP5585 PWM Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c index 2afb302be02c..387a0d1fa4f2 100644 --- a/drivers/pwm/pwm-atmel-hlcdc.c +++ b/drivers/pwm/pwm-atmel-hlcdc.c @@ -234,7 +234,7 @@ static const struct of_device_id atmel_hlcdc_dt_ids[] = { .data = &atmel_hlcdc_pwm_sama5d3_errata, }, { .compatible = "microchip,sam9x60-hlcdc", }, - { /* sentinel */ }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, atmel_hlcdc_dt_ids); @@ -288,8 +288,9 @@ static void atmel_hlcdc_pwm_remove(struct platform_device *pdev) static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = { { .compatible = "atmel,hlcdc-pwm" }, - { /* sentinel */ }, + { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, atmel_hlcdc_pwm_dt_ids); static struct platform_driver atmel_hlcdc_pwm_driver = { .driver = { @@ -298,7 +299,7 @@ static struct platform_driver atmel_hlcdc_pwm_driver = { .pm = pm_ptr(&atmel_hlcdc_pwm_pm_ops), }, .probe = atmel_hlcdc_pwm_probe, - .remove_new = atmel_hlcdc_pwm_remove, + .remove = atmel_hlcdc_pwm_remove, }; module_platform_driver(atmel_hlcdc_pwm_driver); diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c index f9a9c12cbcdd..5ee4254d1e48 100644 --- a/drivers/pwm/pwm-atmel-tcb.c +++ b/drivers/pwm/pwm-atmel-tcb.c @@ -527,7 +527,7 @@ static struct platform_driver atmel_tcb_pwm_driver = { .pm = pm_ptr(&atmel_tcb_pwm_pm_ops), }, .probe = atmel_tcb_pwm_probe, - .remove_new = atmel_tcb_pwm_remove, + .remove = atmel_tcb_pwm_remove, }; module_platform_driver(atmel_tcb_pwm_driver); diff --git a/drivers/pwm/pwm-axi-pwmgen.c b/drivers/pwm/pwm-axi-pwmgen.c index 3ad60edf20a5..b5477659ba18 100644 --- a/drivers/pwm/pwm-axi-pwmgen.c +++ b/drivers/pwm/pwm-axi-pwmgen.c @@ -29,7 +29,6 @@ #include <linux/regmap.h> #include <linux/slab.h> -#define AXI_PWMGEN_REG_CORE_VERSION 0x00 #define AXI_PWMGEN_REG_ID 0x04 #define AXI_PWMGEN_REG_SCRATCHPAD 0x08 #define AXI_PWMGEN_REG_CORE_MAGIC 0x0C @@ -145,7 +144,7 @@ static int axi_pwmgen_setup(struct regmap *regmap, struct device *dev) "failed to read expected value from register: got %08x, expected %08x\n", val, AXI_PWMGEN_REG_CORE_MAGIC_VAL); - ret = regmap_read(regmap, AXI_PWMGEN_REG_CORE_VERSION, &val); + ret = regmap_read(regmap, ADI_AXI_REG_VERSION, &val); if (ret) return ret; diff --git a/drivers/pwm/pwm-clk.c b/drivers/pwm/pwm-clk.c index c19a482d7e28..f8f5af57acba 100644 --- a/drivers/pwm/pwm-clk.c +++ b/drivers/pwm/pwm-clk.c @@ -130,7 +130,7 @@ static struct platform_driver pwm_clk_driver = { .of_match_table = pwm_clk_dt_ids, }, .probe = pwm_clk_probe, - .remove_new = pwm_clk_remove, + .remove = pwm_clk_remove, }; module_platform_driver(pwm_clk_driver); diff --git a/drivers/pwm/pwm-hibvt.c b/drivers/pwm/pwm-hibvt.c index 2eb0b13d4e10..e02ee6383dbc 100644 --- a/drivers/pwm/pwm-hibvt.c +++ b/drivers/pwm/pwm-hibvt.c @@ -276,7 +276,7 @@ static struct platform_driver hibvt_pwm_driver = { .of_match_table = hibvt_pwm_of_match, }, .probe = hibvt_pwm_probe, - .remove_new = hibvt_pwm_remove, + .remove = hibvt_pwm_remove, }; module_platform_driver(hibvt_pwm_driver); diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index d6596583ed4e..71542956feca 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -416,7 +416,7 @@ static struct platform_driver img_pwm_driver = { .of_match_table = img_pwm_of_match, }, .probe = img_pwm_probe, - .remove_new = img_pwm_remove, + .remove = img_pwm_remove, }; module_platform_driver(img_pwm_driver); diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 61189cea1046..90b0733c00c1 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c @@ -218,8 +218,7 @@ static int lp3943_pwm_parse_dt(struct device *dev, struct lp3943_platform_data *pdata; struct lp3943_pwm_map *pwm_map; enum lp3943_pwm_output *output; - int i, err, proplen, count = 0; - u32 num_outputs; + int i, err, num_outputs, count = 0; if (!node) return -EINVAL; @@ -234,11 +233,8 @@ static int lp3943_pwm_parse_dt(struct device *dev, */ for (i = 0; i < LP3943_NUM_PWMS; i++) { - if (!of_get_property(node, name[i], &proplen)) - continue; - - num_outputs = proplen / sizeof(u32); - if (num_outputs == 0) + num_outputs = of_property_count_u32_elems(node, name[i]); + if (num_outputs <= 0) continue; output = devm_kcalloc(dev, num_outputs, sizeof(*output), diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c index 04b76d257fd8..f351baa63453 100644 --- a/drivers/pwm/pwm-lpc18xx-sct.c +++ b/drivers/pwm/pwm-lpc18xx-sct.c @@ -446,7 +446,7 @@ static struct platform_driver lpc18xx_pwm_driver = { .of_match_table = lpc18xx_pwm_of_match, }, .probe = lpc18xx_pwm_probe, - .remove_new = lpc18xx_pwm_remove, + .remove = lpc18xx_pwm_remove, }; module_platform_driver(lpc18xx_pwm_driver); diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index cd51c4a938f5..1858a77401f8 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -355,7 +355,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) goto err_platdata; } - if (!of_get_property(timer, "ti,timer-pwm", NULL)) { + if (!of_property_read_bool(timer, "ti,timer-pwm")) { dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); ret = -ENODEV; goto err_timer_property; @@ -455,7 +455,7 @@ static struct platform_driver pwm_omap_dmtimer_driver = { .of_match_table = pwm_omap_dmtimer_of_match, }, .probe = pwm_omap_dmtimer_probe, - .remove_new = pwm_omap_dmtimer_remove, + .remove = pwm_omap_dmtimer_remove, }; module_platform_driver(pwm_omap_dmtimer_driver); diff --git a/drivers/pwm/pwm-rcar.c b/drivers/pwm/pwm-rcar.c index 4cfecd88ede0..2261789cc27d 100644 --- a/drivers/pwm/pwm-rcar.c +++ b/drivers/pwm/pwm-rcar.c @@ -253,7 +253,7 @@ MODULE_DEVICE_TABLE(of, rcar_pwm_of_table); static struct platform_driver rcar_pwm_driver = { .probe = rcar_pwm_probe, - .remove_new = rcar_pwm_remove, + .remove = rcar_pwm_remove, .driver = { .name = "pwm-rcar", .of_match_table = rcar_pwm_of_table, diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index 0fa7575dbb54..c5f50e5eaf41 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -386,7 +386,7 @@ static struct platform_driver rockchip_pwm_driver = { .of_match_table = rockchip_pwm_dt_ids, }, .probe = rockchip_pwm_probe, - .remove_new = rockchip_pwm_remove, + .remove = rockchip_pwm_remove, }; module_platform_driver(rockchip_pwm_driver); diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index ed7957cc51fd..d5b647e6be78 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -336,7 +336,7 @@ MODULE_DEVICE_TABLE(of, pwm_sifive_of_match); static struct platform_driver pwm_sifive_driver = { .probe = pwm_sifive_probe, - .remove_new = pwm_sifive_remove, + .remove = pwm_sifive_remove, .driver = { .name = "pwm-sifive", .of_match_table = pwm_sifive_of_match, diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index fd754a99cf2e..eb24054f9729 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -222,7 +222,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, scale = max_arr / min(max_arr, raw_prd); } else { - scale = priv->max_arr; /* bellow resolution, use max scale */ + scale = priv->max_arr; /* below resolution, use max scale */ } if (psc && scale > 1) { @@ -412,7 +412,7 @@ static int stm32_pwm_enable(struct stm32_pwm *priv, unsigned int ch) /* Enable channel */ mask = TIM_CCER_CCxE(ch + 1); if (priv->have_complementary_output) - mask |= TIM_CCER_CCxNE(ch); + mask |= TIM_CCER_CCxNE(ch + 1); regmap_set_bits(priv->regmap, TIM_CCER, mask); diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index 5c29590d1821..e60dc7d6b591 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -493,7 +493,7 @@ static struct platform_driver sun4i_pwm_driver = { .of_match_table = sun4i_pwm_dt_ids, }, .probe = sun4i_pwm_probe, - .remove_new = sun4i_pwm_remove, + .remove = sun4i_pwm_remove, }; module_platform_driver(sun4i_pwm_driver); diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index a3d69976148f..172063b51d44 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -432,7 +432,7 @@ static struct platform_driver tegra_pwm_driver = { .pm = &tegra_pwm_pm_ops, }, .probe = tegra_pwm_probe, - .remove_new = tegra_pwm_remove, + .remove = tegra_pwm_remove, }; module_platform_driver(tegra_pwm_driver); diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index d6c2b1b1387e..d91b2bdc88fc 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c @@ -324,7 +324,7 @@ static struct platform_driver ecap_pwm_driver = { .pm = pm_ptr(&ecap_pwm_pm_ops), }, .probe = ecap_pwm_probe, - .remove_new = ecap_pwm_remove, + .remove = ecap_pwm_remove, }; module_platform_driver(ecap_pwm_driver); diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index e5104725d9b7..0125e73b98df 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c @@ -603,7 +603,7 @@ static struct platform_driver ehrpwm_pwm_driver = { .pm = pm_ptr(&ehrpwm_pwm_pm_ops), }, .probe = ehrpwm_pwm_probe, - .remove_new = ehrpwm_pwm_remove, + .remove = ehrpwm_pwm_remove, }; module_platform_driver(ehrpwm_pwm_driver); |