forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge tag 'pwm/for-4.14-rc1' of git://git.kernel.org/pub/scm/linux/ke…
…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
Showing
21 changed files
with
699 additions
and
307 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -29,6 +30,8 @@ | |
#define PWMDWIDTH 0x2c | ||
#define PWMTHRES 0x30 | ||
|
||
#define PWM_CLK_DIV_MAX 7 | ||
|
||
enum { | ||
MTK_CLK_MAIN = 0, | ||
MTK_CLK_TOP, | ||
|
@@ -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) | ||
{ | ||
|
@@ -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); | ||
|
||
|
@@ -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; | ||
} | ||
|
||
|
@@ -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; | ||
|
||
|
@@ -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 = { | ||
|
@@ -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; | ||
|
@@ -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); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.