mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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 <steven.liu@rock-chips.com> Change-Id: I1766f282ccd1047e41f30cc55e3312fefe4b7388
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user