Commit b39d7efc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pwm/for-4.19-rc1' of...

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
parents 06e386a1 8cdc43af
...@@ -16,7 +16,10 @@ modes in device tree. ...@@ -16,7 +16,10 @@ modes in device tree.
Required properties: 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 - 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 - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
the cells format. the cells format.
......
...@@ -5,11 +5,13 @@ Required properties: ...@@ -5,11 +5,13 @@ Required properties:
- "mediatek,mt2712-pwm": found on mt2712 SoC. - "mediatek,mt2712-pwm": found on mt2712 SoC.
- "mediatek,mt7622-pwm": found on mt7622 SoC. - "mediatek,mt7622-pwm": found on mt7622 SoC.
- "mediatek,mt7623-pwm": found on mt7623 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. - 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 - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
the cell format. the cell format.
- clocks: phandle and clock specifier of the PWM reference clock. - 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 - "top": the top clock generator
- "main": clock used by the PWM core - "main": clock used by the PWM core
- "pwm1-8": the eight per PWM clocks for mt2712 - "pwm1-8": the eight per PWM clocks for mt2712
......
...@@ -12,6 +12,7 @@ Required Properties: ...@@ -12,6 +12,7 @@ Required Properties:
- "renesas,pwm-r8a7795": for R-Car H3 - "renesas,pwm-r8a7795": for R-Car H3
- "renesas,pwm-r8a7796": for R-Car M3-W - "renesas,pwm-r8a7796": for R-Car M3-W
- "renesas,pwm-r8a77965": for R-Car M3-N - "renesas,pwm-r8a77965": for R-Car M3-N
- "renesas,pwm-r8a77990": for R-Car E3
- "renesas,pwm-r8a77995": for R-Car D3 - "renesas,pwm-r8a77995": for R-Car D3
- reg: base address and length of the registers block for the PWM. - 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 - #pwm-cells: should be 2. See pwm.txt in this directory for a description of
......
...@@ -286,7 +286,7 @@ config PWM_MTK_DISP ...@@ -286,7 +286,7 @@ config PWM_MTK_DISP
config PWM_MEDIATEK config PWM_MEDIATEK
tristate "MediaTek PWM support" tristate "MediaTek PWM support"
depends on ARCH_MEDIATEK || COMPILE_TEST depends on ARCH_MEDIATEK || RALINK || COMPILE_TEST
help help
Generic PWM framework driver for Mediatek ARM SoC. Generic PWM framework driver for Mediatek ARM SoC.
......
...@@ -21,8 +21,18 @@ ...@@ -21,8 +21,18 @@
#define BERLIN_PWM_EN 0x0 #define BERLIN_PWM_EN 0x0
#define BERLIN_PWM_ENABLE BIT(0) #define BERLIN_PWM_ENABLE BIT(0)
#define BERLIN_PWM_CONTROL 0x4 #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_INVERT_POLARITY BIT(3)
#define BERLIN_PWM_DUTY 0x8 #define BERLIN_PWM_DUTY 0x8
#define BERLIN_PWM_TCNT 0xc #define BERLIN_PWM_TCNT 0xc
...@@ -46,10 +56,6 @@ static inline struct berlin_pwm_chip *to_berlin_pwm_chip(struct pwm_chip *chip) ...@@ -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); 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, static inline u32 berlin_pwm_readl(struct berlin_pwm_chip *chip,
unsigned int channel, unsigned long offset) unsigned int channel, unsigned long offset)
{ {
...@@ -86,33 +92,32 @@ static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev, ...@@ -86,33 +92,32 @@ static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
int duty_ns, int period_ns) int duty_ns, int period_ns)
{ {
struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip); struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
unsigned int prescale; bool prescale_4096 = false;
u32 value, duty, period; u32 value, duty, period;
u64 cycles, tmp; u64 cycles;
cycles = clk_get_rate(pwm->clk); cycles = clk_get_rate(pwm->clk);
cycles *= period_ns; cycles *= period_ns;
do_div(cycles, NSEC_PER_SEC); do_div(cycles, NSEC_PER_SEC);
for (prescale = 0; prescale < ARRAY_SIZE(prescaler_table); prescale++) { if (cycles > BERLIN_PWM_MAX_TCNT) {
tmp = cycles; prescale_4096 = true;
do_div(tmp, prescaler_table[prescale]); cycles >>= 12; // Prescaled by 4096
if (tmp <= BERLIN_PWM_MAX_TCNT) if (cycles > BERLIN_PWM_MAX_TCNT)
break;
}
if (tmp > BERLIN_PWM_MAX_TCNT)
return -ERANGE; return -ERANGE;
}
period = tmp; period = cycles;
cycles = tmp * duty_ns; cycles *= duty_ns;
do_div(cycles, period_ns); do_div(cycles, period_ns);
duty = cycles; duty = cycles;
value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL); value = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
value &= ~BERLIN_PWM_PRESCALE_MASK; if (prescale_4096)
value |= prescale; 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, value, BERLIN_PWM_CONTROL);
berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY); berlin_pwm_writel(pwm, pwm_dev->hwpwm, duty, BERLIN_PWM_DUTY);
......
// 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. * Expose a PWM controlled by the ChromeOS EC to the host processor.
*
* Copyright (C) 2016 Google, Inc.
*/ */
#include <linux/module.h> #include <linux/module.h>
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/pwm.h> #include <linux/pwm.h>
...@@ -75,6 +76,10 @@ enum fsl_pwm_clk { ...@@ -75,6 +76,10 @@ enum fsl_pwm_clk {
FSL_PWM_CLK_MAX FSL_PWM_CLK_MAX
}; };
struct fsl_ftm_soc {
bool has_enable_bits;
};
struct fsl_pwm_chip { struct fsl_pwm_chip {
struct pwm_chip chip; struct pwm_chip chip;
...@@ -87,7 +92,10 @@ struct fsl_pwm_chip { ...@@ -87,7 +92,10 @@ struct fsl_pwm_chip {
int period_ns; int period_ns;
struct clk *ipg_clk;
struct clk *clk[FSL_PWM_CLK_MAX]; 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) 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) ...@@ -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) static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{ {
int ret;
struct fsl_pwm_chip *fpc = to_fsl_chip(chip); 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) static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{ {
struct fsl_pwm_chip *fpc = to_fsl_chip(chip); 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, 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) ...@@ -363,7 +387,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
{ {
int ret; int ret;
ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]); ret = clk_prepare_enable(fpc->ipg_clk);
if (ret) if (ret)
return ret; return ret;
...@@ -371,7 +395,7 @@ static int fsl_pwm_init(struct fsl_pwm_chip *fpc) ...@@ -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_OUTINIT, 0x00);
regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF); regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]); clk_disable_unprepare(fpc->ipg_clk);
return 0; return 0;
} }
...@@ -408,6 +432,7 @@ static int fsl_pwm_probe(struct platform_device *pdev) ...@@ -408,6 +432,7 @@ static int fsl_pwm_probe(struct platform_device *pdev)
mutex_init(&fpc->lock); mutex_init(&fpc->lock);
fpc->soc = of_device_get_match_data(&pdev->dev);
fpc->chip.dev = &pdev->dev; fpc->chip.dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
...@@ -441,6 +466,15 @@ static int fsl_pwm_probe(struct platform_device *pdev) ...@@ -441,6 +466,15 @@ static int fsl_pwm_probe(struct platform_device *pdev)
if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN])) if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
return PTR_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.ops = &fsl_pwm_ops;
fpc->chip.of_xlate = of_pwm_xlate_with_flags; fpc->chip.of_xlate = of_pwm_xlate_with_flags;
fpc->chip.of_pwm_n_cells = 3; fpc->chip.of_pwm_n_cells = 3;
...@@ -480,7 +514,7 @@ static int fsl_pwm_suspend(struct device *dev) ...@@ -480,7 +514,7 @@ static int fsl_pwm_suspend(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags)) if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue; continue;
clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]); clk_disable_unprepare(fpc->ipg_clk);
if (!pwm_is_enabled(pwm)) if (!pwm_is_enabled(pwm))
continue; continue;
...@@ -503,7 +537,7 @@ static int fsl_pwm_resume(struct device *dev) ...@@ -503,7 +537,7 @@ static int fsl_pwm_resume(struct device *dev)
if (!test_bit(PWMF_REQUESTED, &pwm->flags)) if (!test_bit(PWMF_REQUESTED, &pwm->flags))
continue; continue;
clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]); clk_prepare_enable(fpc->ipg_clk);
if (!pwm_is_enabled(pwm)) if (!pwm_is_enabled(pwm))
continue; continue;
...@@ -524,8 +558,17 @@ static const struct dev_pm_ops fsl_pwm_pm_ops = { ...@@ -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) 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[] = { 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 */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids); MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* simple driver for PWM (Pulse Width Modulator) controller * 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> * 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] = { ...@@ -57,6 +57,7 @@ static const char * const mtk_pwm_clk_name[MTK_CLK_MAX] = {
struct mtk_pwm_platform_data { struct mtk_pwm_platform_data {
unsigned int num_pwms; unsigned int num_pwms;
bool pwm45_fixup; bool pwm45_fixup;
bool has_clks;
}; };
/** /**
...@@ -86,6 +87,9 @@ static int mtk_pwm_clk_enable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -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); struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
int ret; int ret;
if (!pc->soc->has_clks)
return 0;
ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]); ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -112,6 +116,9 @@ static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -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); 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_PWM1 + pwm->hwpwm]);
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]); clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]); clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);
...@@ -239,7 +246,7 @@ static int mtk_pwm_probe(struct platform_device *pdev) ...@@ -239,7 +246,7 @@ static int mtk_pwm_probe(struct platform_device *pdev)
if (IS_ERR(pc->regs)) if (IS_ERR(pc->regs))
return PTR_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]); pc->clks[i] = devm_clk_get(&pdev->dev, mtk_pwm_clk_name[i]);
if (IS_ERR(pc->clks[i])) { if (IS_ERR(pc->clks[i])) {
dev_err(&pdev->dev, "clock: %s fail: %ld\n", dev_err(&pdev->dev, "clock: %s fail: %ld\n",
...@@ -274,22 +281,32 @@ static int mtk_pwm_remove(struct platform_device *pdev) ...@@ -274,22 +281,32 @@ static int mtk_pwm_remove(struct platform_device *pdev)
static const struct mtk_pwm_platform_data mt2712_pwm_data = { static const struct mtk_pwm_platform_data mt2712_pwm_data = {
.num_pwms = 8, .num_pwms = 8,
.pwm45_fixup = false, .pwm45_fixup = false,
.has_clks = true,
}; };
static const struct mtk_pwm_platform_data mt7622_pwm_data = { static const struct mtk_pwm_platform_data mt7622_pwm_data = {
.num_pwms = 6, .num_pwms = 6,
.pwm45_fixup = false, .pwm45_fixup = false,
.has_clks = true,
}; };
static const struct mtk_pwm_platform_data mt7623_pwm_data = { static const struct mtk_pwm_platform_data mt7623_pwm_data = {
.num_pwms = 5, .num_pwms = 5,
.pwm45_fixup = true, .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[] = { static const struct of_device_id mtk_pwm_of_match[] = {
{ .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data }, { .compatible = "mediatek,mt2712-pwm", .data = &mt2712_pwm_data },
{ .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data }, { .compatible = "mediatek,mt7622-pwm", .data = &mt7622_pwm_data },
{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_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); MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
......
...@@ -458,7 +458,6 @@ static int meson_pwm_init_channels(struct meson_pwm *meson, ...@@ -458,7 +458,6 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
struct meson_pwm_channel *channels) struct meson_pwm_channel *channels)
{ {
struct device *dev = meson->chip.dev; struct device *dev = meson->chip.dev;
struct device_node *np = dev->of_node;
struct clk_init_data init; struct clk_init_data init;
unsigned int i; unsigned int i;
char name[255]; char name[255];
...@@ -467,7 +466,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson, ...@@ -467,7 +466,7 @@ static int meson_pwm_init_channels(struct meson_pwm *meson,
for (i = 0; i < meson->chip.npwm; i++) { for (i = 0; i < meson->chip.npwm; i++) {
struct meson_pwm_channel *channel = &channels[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.name = name;
init.ops = &clk_mux_ops; init.ops = &clk_mux_ops;
......
// SPDX-License-Identifier: GPL-2.0+
/* /*
* Copyright 2012 Freescale Semiconductor, Inc. * 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> #include <linux/clk.h>
......
...@@ -264,8 +264,9 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) ...@@ -264,8 +264,9 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
timer_pdata = dev_get_platdata(&timer_pdev->dev); timer_pdata = dev_get_platdata(&timer_pdev->dev);
if (!timer_pdata) { if (!timer_pdata) {
dev_err(&pdev->dev, "dmtimer pdata structure NULL\n"); dev_dbg(&pdev->dev,
ret = -EINVAL; "dmtimer pdata structure NULL, deferring probe\n");
ret = -EPROBE_DEFER;
goto put; goto put;
} }
......
...@@ -217,10 +217,8 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev) ...@@ -217,10 +217,8 @@ static int stm32_pwm_lp_probe(struct platform_device *pdev)
static int stm32_pwm_lp_remove(struct platform_device *pdev) static int stm32_pwm_lp_remove(struct platform_device *pdev)
{ {
struct stm32_pwm_lp *priv = platform_get_drvdata(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[0]);
pwm_disable(&priv->chip.pwms[i]);
return pwmchip_remove(&priv->chip); return pwmchip_remove(&priv->chip);
} }
......
...@@ -33,10 +33,6 @@ ...@@ -33,10 +33,6 @@
#define TBCTL 0x00 #define TBCTL 0x00
#define TBPRD 0x0A #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_MASK BIT(3)
#define TBCTL_PRDLD_SHDW 0 #define TBCTL_PRDLD_SHDW 0
#define TBCTL_PRDLD_IMDT BIT(3) #define TBCTL_PRDLD_IMDT BIT(3)
...@@ -360,7 +356,7 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -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 */ /* Channels polarity can be configured from action qualifier module */
configure_polarity(pc, pwm->hwpwm); configure_polarity(pc, pwm->hwpwm);
/* Enable TBCLK before enabling PWM device */ /* Enable TBCLK */
ret = clk_enable(pc->tbclk); ret = clk_enable(pc->tbclk);
if (ret) { if (ret) {
dev_err(chip->dev, "Failed to enable TBCLK for %s: %d\n", 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) ...@@ -368,9 +364,6 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
return ret; return ret;
} }
/* Enable time counter for free_run */
ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
return 0; return 0;
} }
...@@ -388,6 +381,8 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ...@@ -388,6 +381,8 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
aqcsfrc_mask = AQCSFRC_CSFA_MASK; 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 * Changes to immediate action on Action Qualifier. This puts
* Action Qualifier control on PWM output from next TBCLK * 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) ...@@ -400,9 +395,6 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
/* Disabling TBCLK on PWM disable */ /* Disabling TBCLK on PWM disable */
clk_disable(pc->tbclk); 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 */ /* Disable clock on PWM disable */
pm_runtime_put_sync(chip->dev); pm_runtime_put_sync(chip->dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment