pwm: Changes for v4.19-rc1
This contains mostly minor bug fixes as well as some new chip support for existing drivers. -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAlt+tkoZHHRoaWVycnku cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zod9ED/9PpR9nHTyi9yQdLsAykSwg AaM59A0A/ZFYW24RoB3FNq0xLV7H0qIVK4XXZNtWMQh2qTK8QRkfKCH+pdlveN/t guMunVNau6hr42tay/OtCcHPulDs/qlndwDeqymFwbYFIcVFkx5BpGthimntYHra rwzIqvz1u1eRY8O4czQSWXctJR/LWn+8xLzQrToGoa+7UjZJ1Dj9PYuTT7ePOc7Q /OrR5M+f6CGc99PaA39oMfmoqe/HCXIEWBhuMS8CJJMW1JFozNKHraOTcT25pPCt 6cxDmOZn/RlVY3bwjy4AInikbcVOmjTT7uCRuFTiB890prLMeBHlL51gzxQgo/Qk 1eelpW/E1YOMt8eULm0K5o+wrFepWto/fiH17SvjxDJKMM0YAoCJhrSvD794lF3u e8ISDB1rw7RoE8NsByAsnde5IrRl0jBdjHHi4gMt+34iMzMsWoA0GNwFB0DjclEU DVEsqLbVzpRFSaWTR6pqJIEJBmKJtd4JdvgNDSsVIp5ungrwYxmr2Ta1VnvroWYo Wt42MCv37jhBF4o50CVKgEcGX8g4Ka4hwSxXJTt142hIQ8xQNGXNBx5tzBlFwPnl WxwzbCxdsVCW53/EHaUDc7114pRPD/p8zaGn91kh99eh8hxZJcDNqAQlt2Xgv2Ek 260ZlHXYdKCa1/FGEuk93A== =Y0ng -----END PGP SIGNATURE----- Merge tag 'pwm/for-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm Pull pwm updates from Thierry Reding: "This contains mostly minor bug fixes as well as some new chip support for existing drivers" * tag 'pwm/for-4.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: pwm: mediatek: Add MT7628 support dt-bindings: pwm: Add MT7628 information dt-bindings: pwm: rcar: Add bindings for R-Car E3 support pwm: meson: Fix mux clock names pwm: stm32-lp: Remove useless loop in stm32_pwm_lp_remove() pwm: omap-dmtimer: Return -EPROBE_DEFER if no dmtimer platform data pwm: mxs: Switch to SPDX identifier dt-bindings: pwm: fsl-ftm: Add compatible string for i.MX8QM pwm: fsl-ftm: Enable support for the new SoC i.MX8QM pwm: fsl-ftm: Added the support of per-compatible data pwm: fsl-ftm: Added a dedicated IP interface clock pwm: cros-ec: Switch to SPDX identifier pwm: imx: Switch to SPDX identifier pwm: tiehrpwm: Fix disabling of output of PWMs pwm: tiehrpwm: Don't use emulation mode bits to control PWM output pwm: berlin: Don't use broken prescaler values
This commit is contained in:
commit
b39d7efc11
|
@ -16,7 +16,10 @@ modes in device tree.
|
|||
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,vf610-ftm-pwm".
|
||||
- compatible : should be "fsl,<soc>-ftm-pwm" and one of the following
|
||||
compatible strings:
|
||||
- "fsl,vf610-ftm-pwm" for PWM compatible with the one integrated on VF610
|
||||
- "fsl,imx8qm-ftm-pwm" for PWM compatible with the one integrated on i.MX8QM
|
||||
- reg: Physical base address and length of the controller's registers
|
||||
- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
|
||||
the cells format.
|
||||
|
|
|
@ -5,11 +5,13 @@ Required properties:
|
|||
- "mediatek,mt2712-pwm": found on mt2712 SoC.
|
||||
- "mediatek,mt7622-pwm": found on mt7622 SoC.
|
||||
- "mediatek,mt7623-pwm": found on mt7623 SoC.
|
||||
- "mediatek,mt7628-pwm": found on mt7628 SoC.
|
||||
- reg: physical base address and length of the controller's registers.
|
||||
- #pwm-cells: must be 2. See pwm.txt in this directory for a description of
|
||||
the cell format.
|
||||
- clocks: phandle and clock specifier of the PWM reference clock.
|
||||
- clock-names: must contain the following:
|
||||
- clock-names: must contain the following, except for MT7628 which
|
||||
has no clocks
|
||||
- "top": the top clock generator
|
||||
- "main": clock used by the PWM core
|
||||
- "pwm1-8": the eight per PWM clocks for mt2712
|
||||
|
|
|
@ -12,6 +12,7 @@ Required Properties:
|
|||
- "renesas,pwm-r8a7795": for R-Car H3
|
||||
- "renesas,pwm-r8a7796": for R-Car M3-W
|
||||
- "renesas,pwm-r8a77965": for R-Car M3-N
|
||||
- "renesas,pwm-r8a77990": for R-Car E3
|
||||
- "renesas,pwm-r8a77995": for R-Car D3
|
||||
- reg: base address and length of the registers block for the PWM.
|
||||
- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
|
||||
|
|
|
@ -286,7 +286,7 @@ config PWM_MTK_DISP
|
|||
|
||||
config PWM_MEDIATEK
|
||||
tristate "MediaTek PWM support"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST
|
||||
help
|
||||
Generic PWM framework driver for Mediatek ARM SoC.
|
||||
|
||||
|
|
|
@ -21,8 +21,18 @@
|
|||
#define BERLIN_PWM_EN 0x0
|
||||
#define BERLIN_PWM_ENABLE BIT(0)
|
||||
#define BERLIN_PWM_CONTROL 0x4
|
||||
#define BERLIN_PWM_PRESCALE_MASK 0x7
|
||||
#define BERLIN_PWM_PRESCALE_MAX 4096
|
||||
/*
|
||||
* The prescaler claims to support 8 different moduli, configured using the
|
||||
* low three bits of PWM_CONTROL. (Sequentially, they are 1, 4, 8, 16, 64,
|
||||
* 256, 1024, and 4096.) However, the moduli from 4 to 1024 appear to be
|
||||
* implemented by internally shifting TCNT left without adding additional
|
||||
* bits. So, the max TCNT that actually works for a modulus of 4 is 0x3fff;
|
||||
* for 8, 0x1fff; and so on. This means that those moduli are entirely
|
||||
* useless, as we could just do the shift ourselves. The 4096 modulus is
|
||||
* implemented with a real prescaler, so we do use that, but we treat it
|
||||
* as a flag instead of pretending the modulus is actually configurable.
|
||||
*/
|
||||
#define BERLIN_PWM_PRESCALE_4096 0x7
|
||||
#define BERLIN_PWM_INVERT_POLARITY BIT(3)
|
||||
#define BERLIN_PWM_DUTY 0x8
|
||||
#define BERLIN_PWM_TCNT 0xc
|
||||
|
@ -46,10 +56,6 @@ static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip)
|
|||
return container_of(chip, struct berlin_pwm_chip, chip);
|
||||
}
|
||||
|
||||
static const u32 prescaler_table[] = {
|
||||
1, 4, 8, 16, 64, 256, 1024, 4096
|
||||
};
|
||||
|
||||
static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *chip,
|
||||
unsigned int channel, unsigned long offset)
|
||||
{
|
||||
|
@ -86,33 +92,32 @@ static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
|
|||
int duty_ns, int period_ns)
|
||||
{
|
||||
struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
|
||||
unsigned int prescale;
|
||||
bool prescale_4096 = false;
|
||||
u32 value, duty, period;
|
||||
u64 cycles, tmp;
|
||||
u64 cycles;
|
||||
|
||||
cycles = clk_get_rate(pwm->clk);
|
||||
cycles *= period_ns;
|
||||
do_div(cycles, NSEC_PER_SEC);
|
||||
|
||||
for (prescale = 0; prescale < ARRAY_SIZE(prescaler_table); prescale++) {
|
||||
tmp = cycles;
|
||||
do_div(tmp, prescaler_table[prescale]);
|
||||
if (cycles > BERLIN_PWM_MAX_TCNT) {
|
||||
prescale_4096 = true;
|
||||
cycles >>= 12; // Prescaled by 4096
|
||||
|
||||
if (tmp <= BERLIN_PWM_MAX_TCNT)
|
||||
break;
|
||||
if (cycles > BERLIN_PWM_MAX_TCNT)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (tmp > BERLIN_PWM_MAX_TCNT)
|
||||
return -ERANGE;
|
||||
|
||||
period = tmp;
|
||||
cycles = tmp * duty_ns;
|
||||
period = cycles;
|
||||
cycles *= duty_ns;
|
||||
do_div(cycles, period_ns);
|
||||
duty = cycles;
|
||||
|
||||
value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
|
||||
value &= ~BERLIN_PWM_PRESCALE_MASK;
|
||||
value |= prescale;
|
||||
if (prescale_4096)
|
||||
value |= BERLIN_PWM_PRESCALE_4096;
|
||||
else
|
||||
value &= ~BERLIN_PWM_PRESCALE_4096;
|
||||
berlin_pwm_writel(pwm, pwm_dev->hwpwm, value, BERLIN_PWM_CONTROL);
|
||||
|
||||
berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY);
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2016 Google, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2, as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* Expose a PWM controlled by the ChromeOS EC to the host processor.
|
||||
*
|
||||
* Copyright (C) 2016 Google, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pwm.h>
|
||||
|
@ -75,6 +76,10 @@ enum fsl_pwm_clk {
|
|||
FSL_PWM_CLK_MAX
|
||||
};
|
||||
|
||||
struct fsl_ftm_soc {
|
||||
bool has_enable_bits;
|
||||
};
|
||||
|
||||
struct fsl_pwm_chip {
|
||||
struct pwm_chip chip;
|
||||
|
||||
|
@ -87,7 +92,10 @@ struct fsl_pwm_chip {
|
|||
|
||||
int period_ns;
|
||||
|
||||
struct clk *ipg_clk;
|
||||
struct clk *clk[FSL_PWM_CLK_MAX];
|
||||
|
||||
const struct fsl_ftm_soc *soc;
|
||||
};
|
||||
|
||||
static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
|
||||
|
@ -97,16 +105,32 @@ static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
|
|||
|
||||
static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
int ret;
|
||||
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
|
||||
|
||||
return clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
|
||||
ret = clk_prepare_enable(fpc->ipg_clk);
|
||||
if (!ret && fpc->soc->has_enable_bits) {
|
||||
mutex_lock(&fpc->lock);
|
||||
regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
|
||||
BIT(pwm->hwpwm + 16));
|
||||
mutex_unlock(&fpc->lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
{
|
||||
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
|
||||
|
||||
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
|
||||
if (fpc->soc->has_enable_bits) {
|
||||
mutex_lock(&fpc->lock);
|
||||
regmap_update_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16),
|
||||
0);
|
||||
mutex_unlock(&fpc->lock);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(fpc->ipg_clk);
|
||||
}
|
||||
|
||||
static int fsl_pwm_calculate_default_ps(struct fsl_pwm_chip *fpc,
|
||||
|
@ -363,7 +387,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
|
||||
ret = clk_prepare_enable(fpc->ipg_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -371,7 +395,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
|
|||
regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
|
||||
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
|
||||
|
||||
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
|
||||
clk_disable_unprepare(fpc->ipg_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -408,6 +432,7 @@ static int fsl_pwm_probe(struct platform_device *pdev)
|
|||
|
||||
mutex_init(&fpc->lock);
|
||||
|
||||
fpc->soc = of_device_get_match_data(&pdev->dev);
|
||||
fpc->chip.dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
@ -441,6 +466,15 @@ static int fsl_pwm_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
|
||||
return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);
|
||||
|
||||
/*
|
||||
* ipg_clk is the interface clock for the IP. If not provided, use the
|
||||
* ftm_sys clock as the default.
|
||||
*/
|
||||
fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
|
||||
if (IS_ERR(fpc->ipg_clk))
|
||||
fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
|
||||
|
||||
|
||||
fpc->chip.ops = &fsl_pwm_ops;
|
||||
fpc->chip.of_xlate = of_pwm_xlate_with_flags;
|
||||
fpc->chip.of_pwm_n_cells = 3;
|
||||
|
@ -480,7 +514,7 @@ static int fsl_pwm_suspend(struct device *dev)
|
|||
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
|
||||
continue;
|
||||
|
||||
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
|
||||
clk_disable_unprepare(fpc->ipg_clk);
|
||||
|
||||
if (!pwm_is_enabled(pwm))
|
||||
continue;
|
||||
|
@ -503,7 +537,7 @@ static int fsl_pwm_resume(struct device *dev)
|
|||
if (!test_bit(PWMF_REQUESTED, &pwm->flags))
|
||||
continue;
|
||||
|
||||
clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
|
||||
clk_prepare_enable(fpc->ipg_clk);
|
||||
|
||||
if (!pwm_is_enabled(pwm))
|
||||
continue;
|
||||
|
@ -524,8 +558,17 @@ static const struct dev_pm_ops fsl_pwm_pm_ops = {
|
|||
SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
|
||||
};
|
||||
|
||||
static const struct fsl_ftm_soc vf610_ftm_pwm = {
|
||||
.has_enable_bits = false,
|
||||
};
|
||||
|
||||
static const struct fsl_ftm_soc imx8qm_ftm_pwm = {
|
||||
.has_enable_bits = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id fsl_pwm_dt_ids[] = {
|
||||
{ .compatible = "fsl,vf610-ftm-pwm", },
|
||||
{ .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
|
||||
{ .compatible = "fsl,imx8qm-ftm-pwm", .data = &imx8qm_ftm_pwm },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* simple driver for PWM (Pulse Width Modulator) controller
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
|
||||
*/
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
|
|||
struct mtk_pwm_platform_data {
|
||||
unsigned int num_pwms;
|
||||
bool pwm45_fixup;
|
||||
bool has_clks;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -86,6 +87,9 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
int ret;
|
||||
|
||||
if (!pc->soc->has_clks)
|
||||
return 0;
|
||||
|
||||
ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -112,6 +116,9 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
{
|
||||
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
|
||||
|
||||
if (!pc->soc->has_clks)
|
||||
return;
|
||||
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
|
||||
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
|
||||
|
@ -239,7 +246,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(pc->regs))
|
||||
return PTR_ERR(pc->regs);
|
||||
|
||||
for (i = 0; i < data->num_pwms + 2; i++) {
|
||||
for (i = 0; i < data->num_pwms + 2 && pc->soc->has_clks; i++) {
|
||||
pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
|
||||
if (IS_ERR(pc->clks[i])) {
|
||||
dev_err(&pdev->dev, "clock: %s fail: %ld\n",
|
||||
|
@ -274,22 +281,32 @@ static int mtk_pwm_remove(struct platform_device *pdev)
|
|||
static const struct mtk_pwm_platform_data mt2712_pwm_data = {
|
||||
.num_pwms = 8,
|
||||
.pwm45_fixup = false,
|
||||
.has_clks = true,
|
||||
};
|
||||
|
||||
static const struct mtk_pwm_platform_data mt7622_pwm_data = {
|
||||
.num_pwms = 6,
|
||||
.pwm45_fixup = false,
|
||||
.has_clks = true,
|
||||
};
|
||||
|
||||
static const struct mtk_pwm_platform_data mt7623_pwm_data = {
|
||||
.num_pwms = 5,
|
||||
.pwm45_fixup = true,
|
||||
.has_clks = true,
|
||||
};
|
||||
|
||||
static const struct mtk_pwm_platform_data mt7628_pwm_data = {
|
||||
.num_pwms = 4,
|
||||
.pwm45_fixup = true,
|
||||
.has_clks = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_pwm_of_match[] = {
|
||||
{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
|
||||
{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
|
||||
{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
|
||||
{ .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
|
||||
|
|
|
@ -458,7 +458,6 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
|
|||
struct meson_pwm_channel *channels)
|
||||
{
|
||||
struct device *dev = meson->chip.dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct clk_init_data init;
|
||||
unsigned int i;
|
||||
char name[255];
|
||||
|
@ -467,7 +466,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
|
|||
for (i = 0; i < meson->chip.npwm; i++) {
|
||||
struct meson_pwm_channel *channel = &channels[i];
|
||||
|
||||
snprintf(name, sizeof(name), "%pOF#mux%u", np, i);
|
||||
snprintf(name, sizeof(name), "%s#mux%u", dev_name(dev), i);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &clk_mux_ops;
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2012 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* The code contained herein is licensed under the GNU General Public
|
||||
* License. You may obtain a copy of the GNU General Public License
|
||||
* Version 2 or later at the following locations:
|
||||
*
|
||||
* http://www.opensource.org/licenses/gpl-license.html
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
|
|
|
@ -264,8 +264,9 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
|
|||
|
||||
timer_pdata = dev_get_platdata(&timer_pdev->dev);
|
||||
if (!timer_pdata) {
|
||||
dev_err(&pdev->dev, "dmtimer pdata structure NULL\n");
|
||||
ret = -EINVAL;
|
||||
dev_dbg(&pdev->dev,
|
||||
"dmtimer pdata structure NULL, deferring probe\n");
|
||||
ret = -EPROBE_DEFER;
|
||||
goto put;
|
||||
}
|
||||
|
||||
|
|
|
@ -217,10 +217,8 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
|
|||
static int stm32_pwm_lp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_pwm_lp *priv = platform_get_drvdata(pdev);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < priv->chip.npwm; i++)
|
||||
pwm_disable(&priv->chip.pwms[i]);
|
||||
pwm_disable(&priv->chip.pwms[0]);
|
||||
|
||||
return pwmchip_remove(&priv->chip);
|
||||
}
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#define TBCTL 0x00
|
||||
#define TBPRD 0x0A
|
||||
|
||||
#define TBCTL_RUN_MASK (BIT(15) | BIT(14))
|
||||
#define TBCTL_STOP_NEXT 0
|
||||
#define TBCTL_STOP_ON_CYCLE BIT(14)
|
||||
#define TBCTL_FREE_RUN (BIT(15) | BIT(14))
|
||||
#define TBCTL_PRDLD_MASK BIT(3)
|
||||
#define TBCTL_PRDLD_SHDW 0
|
||||
#define TBCTL_PRDLD_IMDT BIT(3)
|
||||
|
@ -360,7 +356,7 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
/* Channels polarity can be configured from action qualifier module */
|
||||
configure_polarity(pc, pwm->hwpwm);
|
||||
|
||||
/* Enable TBCLK before enabling PWM device */
|
||||
/* Enable TBCLK */
|
||||
ret = clk_enable(pc->tbclk);
|
||||
if (ret) {
|
||||
dev_err(chip->dev, "Failed to enable TBCLK for %s: %d\n",
|
||||
|
@ -368,9 +364,6 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Enable time counter for free_run */
|
||||
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -388,6 +381,8 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
aqcsfrc_mask = AQCSFRC_CSFA_MASK;
|
||||
}
|
||||
|
||||
/* Update shadow register first before modifying active register */
|
||||
ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
|
||||
/*
|
||||
* Changes to immediate action on Action Qualifier. This puts
|
||||
* Action Qualifier control on PWM output from next TBCLK
|
||||
|
@ -400,9 +395,6 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
|||
/* Disabling TBCLK on PWM disable */
|
||||
clk_disable(pc->tbclk);
|
||||
|
||||
/* Stop Time base counter */
|
||||
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
|
||||
|
||||
/* Disable clock on PWM disable */
|
||||
pm_runtime_put_sync(chip->dev);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue