Skip to content

Commit

Permalink
pwm: i.MX: fix clock lookup
Browse files Browse the repository at this point in the history
The i.MX PWM core has two clocks: The ipg clock and the ipg highfreq
(peripheral) clock. The ipg clock has to be enabled for this hardware
to work. The actual PWM output can either be driven by the ipg clock
or the ipg highfreq. The ipg highfreq has the advantage that it runs
even when the SoC is in low power modes.
This patch requests both clocks and enables the ipg clock for accessing
registers and the peripheral clock to actually turn on the PWM.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
  • Loading branch information
Philipp Zabel authored and Thierry Reding committed Sep 12, 2012
1 parent 8d1c24b commit 7b27c16
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions drivers/pwm/pwm-imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
#define MX3_PWMCR_EN (1 << 0)

struct imx_chip {
struct clk *clk;
struct clk *clk_per;
struct clk *clk_ipg;

int enabled;
void __iomem *mmio_base;
Expand Down Expand Up @@ -106,7 +107,7 @@ static int imx_pwm_config_v2(struct pwm_chip *chip,
unsigned long period_cycles, duty_cycles, prescale;
u32 cr;

c = clk_get_rate(imx->clk);
c = clk_get_rate(imx->clk_per);
c = c * period_ns;
do_div(c, 1000000000);
period_cycles = c;
Expand Down Expand Up @@ -161,16 +162,25 @@ static int imx_pwm_config(struct pwm_chip *chip,
struct pwm_device *pwm, int duty_ns, int period_ns)
{
struct imx_chip *imx = to_imx_chip(chip);
int ret;

ret = clk_prepare_enable(imx->clk_ipg);
if (ret)
return ret;

return imx->config(chip, pwm, duty_ns, period_ns);
ret = imx->config(chip, pwm, duty_ns, period_ns);

clk_disable_unprepare(imx->clk_ipg);

return ret;
}

static int imx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
{
struct imx_chip *imx = to_imx_chip(chip);
int ret;

ret = clk_prepare_enable(imx->clk);
ret = clk_prepare_enable(imx->clk_per);
if (ret)
return ret;

Expand All @@ -187,7 +197,7 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)

imx->set_enable(chip, false);

clk_disable_unprepare(imx->clk);
clk_disable_unprepare(imx->clk_per);
imx->enabled = 0;
}

Expand Down Expand Up @@ -239,10 +249,19 @@ static int __devinit imx_pwm_probe(struct platform_device *pdev)
return -ENOMEM;
}

imx->clk = devm_clk_get(&pdev->dev, "pwm");
imx->clk_per = devm_clk_get(&pdev->dev, "per");
if (IS_ERR(imx->clk_per)) {
dev_err(&pdev->dev, "getting per clock failed with %ld\n",
PTR_ERR(imx->clk_per));
return PTR_ERR(imx->clk_per);
}

if (IS_ERR(imx->clk))
return PTR_ERR(imx->clk);
imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(imx->clk_ipg)) {
dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
PTR_ERR(imx->clk_ipg));
return PTR_ERR(imx->clk_ipg);
}

imx->chip.ops = &imx_pwm_ops;
imx->chip.dev = &pdev->dev;
Expand Down

0 comments on commit 7b27c16

Please sign in to comment.