From bcdc525901b550fd91f461f149c457f153501b61 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 15 Oct 2020 18:31:11 +0800 Subject: [PATCH] pwm: rockchip: Get pwm clk_rate in pwm_probe function The clk_get_rate function is used in pwm_apply and pwm_config. And it is not allowed in interrupt calls due to a mutex. So move it into pwm_probe function. Signed-off-by: Steven Liu Change-Id: I1766f282ccd1047e41f30cc55e3312fefe4b7388 --- drivers/pwm/pwm-rockchip.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index 367916838a9e..1f0131235561 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c @@ -36,6 +36,7 @@ struct rockchip_pwm_chip { struct clk *pclk; const struct rockchip_pwm_data *data; void __iomem *base; + unsigned long clk_rate; bool vop_pwm_en; /* indicate voppwm mirror register state */ bool center_aligned; }; @@ -68,7 +69,6 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip, { struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); u32 enable_conf = pc->data->enable_conf; - unsigned long clk_rate; u64 tmp; u32 val; int ret; @@ -77,15 +77,13 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip, if (ret) return; - clk_rate = clk_get_rate(pc->clk); - tmp = readl_relaxed(pc->base + pc->data->regs.period); tmp *= pc->data->prescaler * NSEC_PER_SEC; - state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); + state->period = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate); tmp = readl_relaxed(pc->base + pc->data->regs.duty); tmp *= pc->data->prescaler * NSEC_PER_SEC; - state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); + state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pc->clk_rate); val = readl_relaxed(pc->base + pc->data->regs.ctrl); state->enabled = (val & enable_conf) == enable_conf; @@ -104,21 +102,19 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); unsigned long period, duty; unsigned long flags; - u64 clk_rate, div; + u64 div; u32 ctrl; - clk_rate = clk_get_rate(pc->clk); - /* * Since period and duty cycle registers have a width of 32 * bits, every possible input period can be obtained using the * default prescaler value for all practical clock rate values. */ - div = clk_rate * state->period; + div = (u64)pc->clk_rate * state->period; period = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC); - div = clk_rate * state->duty_cycle; + div = (u64)pc->clk_rate * state->duty_cycle; duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC); local_irq_save(flags); @@ -378,6 +374,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev) pc->chip.ops = &rockchip_pwm_ops; pc->chip.base = -1; pc->chip.npwm = 1; + pc->clk_rate = clk_get_rate(pc->clk); if (pc->data->supports_polarity) { pc->chip.of_xlate = of_pwm_xlate_with_flags;