Skip to content

Commit

Permalink
Merge tag 'pwm/for-4.14-rc1' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/thierry.reding/linux-pwm

Pull pwm updates from Thierry Reding:
 "The changes for this release include a new driver for the PWM
  controller found on SoCs of the ZTX ZX family. Support for an old
  SH-Mobile SoC has been dropped and the Rockchip and MediaTek drivers
  gain support for more generations.

  Other than that there are a bunch of coding style fixes, minor bug
  fixes and cleanup as well as documentation patches"

* tag 'pwm/for-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (32 commits)
  pwm: pwm-samsung: fix suspend/resume support
  pwm: samsung: Remove redundant checks from pwm_samsung_config()
  pwm: mediatek: Disable clock on PWM configuration failure
  dt-bindings: pwm: Add MT2712/MT7622 information
  pwm: mediatek: Fix clock control issue
  pwm: mediatek: Fix PWM source clock selection
  pwm: mediatek: Fix Kconfig description
  pwm: tegra: Explicitly request exclusive reset control
  pwm: hibvt: Explicitly request exclusive reset control
  pwm: tiehrpwm: Set driver data before runtime PM enable
  pwm: tiehrpwm: Miscellaneous coding style fixups
  pwm: tiecap: Set driver data before runtime PM enable
  pwm: tiecap: Miscellaneous coding style fixups
  dt-bindings: pwm: tiecap: Add TI 66AK2G SoC specific compatible
  pwm: tiehrpwm: fix clock imbalance in probe error path
  pwm: tiehrpwm: Fix runtime PM imbalance at unbind
  pwm: Kconfig: Enable pwm-tiecap to be built for Keystone
  pwm: Add ZTE ZX PWM device driver
  dt-bindings: pwm: Add bindings doc for ZTE ZX PWM controller
  pwm: bcm2835: Support for polarity setting via DT
  ...
  • Loading branch information
torvalds committed Sep 11, 2017
2 parents 669bf77 + 7755daf commit 66c9457
Show file tree
Hide file tree
Showing 21 changed files with 699 additions and 307 deletions.
4 changes: 2 additions & 2 deletions Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Required properties:
- clocks: This clock defines the base clock frequency of the PWM hardware
system, the period and the duty_cycle of the PWM signal is a multiple of
the base period.
- #pwm-cells: Should be 2. 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.

Examples:
Expand All @@ -15,7 +15,7 @@ pwm@2020c000 {
compatible = "brcm,bcm2835-pwm";
reg = <0x2020c000 0x28>;
clocks = <&clk_pwm>;
#pwm-cells = <2>;
#pwm-cells = <3>;
};

clocks {
Expand Down
6 changes: 5 additions & 1 deletion Documentation/devicetree/bindings/pwm/pwm-mediatek.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ MediaTek PWM controller

Required properties:
- compatible: should be "mediatek,<name>-pwm":
- "mediatek,mt2712-pwm": found on mt2712 SoC.
- "mediatek,mt7622-pwm": found on mt7622 SoC.
- "mediatek,mt7623-pwm": found on mt7623 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
Expand All @@ -10,7 +12,9 @@ Required properties:
- clock-names: must contain the following:
- "top": the top clock generator
- "main": clock used by the PWM core
- "pwm1-5": the five per PWM clocks
- "pwm1-8": the eight per PWM clocks for mt2712
- "pwm1-6": the six per PWM clocks for mt7622
- "pwm1-5": the five per PWM clocks for mt7623
- pinctrl-names: Must contain a "default" entry.
- pinctrl-0: One property must exist for each entry in pinctrl-names.
See pinctrl/pinctrl-bindings.txt for details of the property values.
Expand Down
11 changes: 9 additions & 2 deletions Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@ Rockchip PWM controller
Required properties:
- compatible: should be "rockchip,<name>-pwm"
"rockchip,rk2928-pwm": found on RK29XX,RK3066 and RK3188 SoCs
"rockchip,rk3288-pwm": found on RK3288 SoC
"rockchip,rk3288-pwm": found on RK3288 SOC
"rockchip,rv1108-pwm", "rockchip,rk3288-pwm": found on RV1108 SoC
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
- reg: physical base address and length of the controller's registers
- clocks: phandle and clock specifier of the PWM reference clock
- clocks: See ../clock/clock-bindings.txt
- For older hardware (rk2928, rk3066, rk3188, rk3228, rk3288, rk3399):
- There is one clock that's used both to derive the functional clock
for the device and as the bus clock.
- For newer hardware (rk3328 and future socs): specified by name
- "pwm": This is used to derive the functional clock.
- "pclk": This is the APB bus clock.
- #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
for a description of the cell format.

Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/pwm/pwm-tiecap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Required properties:
for am4372 - compatible = "ti,am4372-ecap", "ti,am3352-ecap", "ti,am33xx-ecap";
for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap";
for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap";
for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap";
- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
the cells format. The PWM channel index ranges from 0 to 4. The only third
cell flag supported by this binding is PWM_POLARITY_INVERTED.
Expand Down
22 changes: 22 additions & 0 deletions Documentation/devicetree/bindings/pwm/pwm-zx.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ZTE ZX PWM controller

Required properties:
- compatible: Should be "zte,zx296718-pwm".
- reg: Physical base address and length of the controller's registers.
- clocks : The phandle and specifier referencing the controller's clocks.
- clock-names: "pclk" for PCLK, "wclk" for WCLK to the PWM controller. The
PCLK is for register access, while WCLK is the reference clock for
calculating period and duty cycles.
- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
the cells format.

Example:

pwm: pwm@1439000 {
compatible = "zte,zx296718-pwm";
reg = <0x1439000 0x1000>;
clocks = <&lsp1crm LSP1_PWM_PCLK>,
<&lsp1crm LSP1_PWM_WCLK>;
clock-names = "pclk", "wclk";
#pwm-cells = <3>;
};
1 change: 0 additions & 1 deletion Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Required Properties:
- "renesas,tpu-r8a73a4": for R8A77A4 (R-Mobile APE6) compatible PWM controller.
- "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller.
- "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller.
- "renesas,tpu-sh7372": for SH7372 (SH-Mobile AP4) compatible PWM controller.
- "renesas,tpu": for generic R-Car TPU PWM controller.

- reg: Base address and length of each memory resource used by the PWM
Expand Down
13 changes: 11 additions & 2 deletions drivers/pwm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ config PWM_MEDIATEK
Generic PWM framework driver for Mediatek ARM SoC.

To compile this driver as a module, choose M here: the module
will be called pwm-mxs.
will be called pwm-mediatek.

config PWM_MXS
tristate "Freescale MXS PWM support"
Expand Down Expand Up @@ -456,7 +456,7 @@ config PWM_TEGRA

config PWM_TIECAP
tristate "ECAP PWM support"
depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX
depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE
help
PWM driver support for the ECAP APWM controller found on AM33XX
TI SOC
Expand Down Expand Up @@ -510,4 +510,13 @@ config PWM_VT8500
To compile this driver as a module, choose M here: the module
will be called pwm-vt8500.

config PWM_ZX
tristate "ZTE ZX PWM support"
depends on ARCH_ZX
help
Generic PWM framework driver for ZTE ZX family SoCs.

To compile this driver as a module, choose M here: the module
will be called pwm-zx.

endif
1 change: 1 addition & 0 deletions drivers/pwm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ obj-$(CONFIG_PWM_TIPWMSS) += pwm-tipwmss.o
obj-$(CONFIG_PWM_TWL) += pwm-twl.o
obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o
obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
obj-$(CONFIG_PWM_ZX) += pwm-zx.o
2 changes: 2 additions & 0 deletions drivers/pwm/pwm-bcm2835.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
pc->chip.dev = &pdev->dev;
pc->chip.ops = &bcm2835_pwm_ops;
pc->chip.npwm = 2;
pc->chip.of_xlate = of_pwm_xlate_with_flags;
pc->chip.of_pwm_n_cells = 3;

platform_set_drvdata(pdev, pc);

Expand Down
2 changes: 1 addition & 1 deletion drivers/pwm/pwm-hibvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ static int hibvt_pwm_probe(struct platform_device *pdev)
if (ret < 0)
return ret;

pwm_chip->rstc = devm_reset_control_get(&pdev->dev, NULL);
pwm_chip->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(pwm_chip->rstc)) {
clk_disable_unprepare(pwm_chip->clk);
return PTR_ERR(pwm_chip->rstc);
Expand Down
78 changes: 54 additions & 24 deletions drivers/pwm/pwm-mediatek.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Mediatek Pulse Width Modulator driver
*
* Copyright (C) 2015 John Crispin <[email protected]>
* Copyright (C) 2017 Zhi Mao <[email protected]>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
Expand Down Expand Up @@ -29,6 +30,8 @@
#define PWMDWIDTH 0x2c
#define PWMTHRES 0x30

#define PWM_CLK_DIV_MAX 7

enum {
MTK_CLK_MAIN = 0,
MTK_CLK_TOP,
Expand Down Expand Up @@ -61,6 +64,42 @@ static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
return container_of(chip, struct mtk_pwm_chip, chip);
}

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;

ret = clk_prepare_enable(pc->clks[MTK_CLK_TOP]);
if (ret < 0)
return ret;

ret = clk_prepare_enable(pc->clks[MTK_CLK_MAIN]);
if (ret < 0)
goto disable_clk_top;

ret = clk_prepare_enable(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
if (ret < 0)
goto disable_clk_main;

return 0;

disable_clk_main:
clk_disable_unprepare(pc->clks[MTK_CLK_MAIN]);
disable_clk_top:
clk_disable_unprepare(pc->clks[MTK_CLK_TOP]);

return ret;
}

static void mtk_pwm_clk_disable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);

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]);
}

static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
unsigned int offset)
{
Expand All @@ -80,6 +119,11 @@ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm];
u32 resolution, clkdiv = 0;
int ret;

ret = mtk_pwm_clk_enable(chip, pwm);
if (ret < 0)
return ret;

resolution = NSEC_PER_SEC / clk_get_rate(clk);

Expand All @@ -88,13 +132,18 @@ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
clkdiv++;
}

if (clkdiv > 7)
if (clkdiv > PWM_CLK_DIV_MAX) {
mtk_pwm_clk_disable(chip, pwm);
dev_err(chip->dev, "period %d not supported\n", period_ns);
return -EINVAL;
}

mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv);
mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);

mtk_pwm_clk_disable(chip, pwm);

return 0;
}

Expand All @@ -104,7 +153,7 @@ static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
u32 value;
int ret;

ret = clk_prepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
ret = mtk_pwm_clk_enable(chip, pwm);
if (ret < 0)
return ret;

Expand All @@ -124,7 +173,7 @@ static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
value &= ~BIT(pwm->hwpwm);
writel(value, pc->regs);

clk_unprepare(pc->clks[MTK_CLK_PWM1 + pwm->hwpwm]);
mtk_pwm_clk_disable(chip, pwm);
}

static const struct pwm_ops mtk_pwm_ops = {
Expand Down Expand Up @@ -156,14 +205,6 @@ static int mtk_pwm_probe(struct platform_device *pdev)
return PTR_ERR(pc->clks[i]);
}

ret = clk_prepare(pc->clks[MTK_CLK_TOP]);
if (ret < 0)
return ret;

ret = clk_prepare(pc->clks[MTK_CLK_MAIN]);
if (ret < 0)
goto disable_clk_top;

platform_set_drvdata(pdev, pc);

pc->chip.dev = &pdev->dev;
Expand All @@ -174,26 +215,15 @@ static int mtk_pwm_probe(struct platform_device *pdev)
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
goto disable_clk_main;
return ret;
}

return 0;

disable_clk_main:
clk_unprepare(pc->clks[MTK_CLK_MAIN]);
disable_clk_top:
clk_unprepare(pc->clks[MTK_CLK_TOP]);

return ret;
}

static int mtk_pwm_remove(struct platform_device *pdev)
{
struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
unsigned int i;

for (i = 0; i < pc->chip.npwm; i++)
pwm_disable(&pc->chip.pwms[i]);

return pwmchip_remove(&pc->chip);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/pwm/pwm-meson.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,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), "%s#mux%u", np->full_name, i);
snprintf(name, sizeof(name), "%pOF#mux%u", np, i);

init.name = name;
init.ops = &clk_mux_ops;
Expand Down
14 changes: 7 additions & 7 deletions drivers/pwm/pwm-pca9685.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,11 @@ static inline int pca9685_pwm_gpio_probe(struct pca9685 *pca)
}
#endif

static void pca9685_set_sleep_mode(struct pca9685 *pca, int sleep)
static void pca9685_set_sleep_mode(struct pca9685 *pca, bool enable)
{
regmap_update_bits(pca->regmap, PCA9685_MODE1,
MODE1_SLEEP, sleep ? MODE1_SLEEP : 0);
if (!sleep) {
MODE1_SLEEP, enable ? MODE1_SLEEP : 0);
if (!enable) {
/* Wait 500us for the oscillator to be back up */
udelay(500);
}
Expand All @@ -272,13 +272,13 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
* state is guaranteed active here.
*/
/* Put chip into sleep mode */
pca9685_set_sleep_mode(pca, 1);
pca9685_set_sleep_mode(pca, true);

/* Change the chip-wide output frequency */
regmap_write(pca->regmap, PCA9685_PRESCALE, prescale);

/* Wake the chip up */
pca9685_set_sleep_mode(pca, 0);
pca9685_set_sleep_mode(pca, false);

pca->period_ns = period_ns;
} else {
Expand Down Expand Up @@ -534,7 +534,7 @@ static int pca9685_pwm_runtime_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct pca9685 *pca = i2c_get_clientdata(client);

pca9685_set_sleep_mode(pca, 1);
pca9685_set_sleep_mode(pca, true);
return 0;
}

Expand All @@ -543,7 +543,7 @@ static int pca9685_pwm_runtime_resume(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct pca9685 *pca = i2c_get_clientdata(client);

pca9685_set_sleep_mode(pca, 0);
pca9685_set_sleep_mode(pca, false);
return 0;
}
#endif
Expand Down
1 change: 0 additions & 1 deletion drivers/pwm/pwm-renesas-tpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ static const struct of_device_id tpu_of_table[] = {
{ .compatible = "renesas,tpu-r8a73a4", },
{ .compatible = "renesas,tpu-r8a7740", },
{ .compatible = "renesas,tpu-r8a7790", },
{ .compatible = "renesas,tpu-sh7372", },
{ .compatible = "renesas,tpu", },
{ },
};
Expand Down
Loading

0 comments on commit 66c9457

Please sign in to comment.