When the enable bit is undefined, the clock is assumed to be always on and enable/disable is a no-op. When the stable bit is undefined, the PLL stable check is a no-op. Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@xxxxxxxxx> --- drivers/clk/ingenic/cgu.c | 14 +++++++++++++- drivers/clk/ingenic/cgu.h | 10 ++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 3481129114b1..aea01b6b2764 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -189,6 +189,9 @@ static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu, { u32 ctl; + if (pll_info->stable_bit < 0) + return 0; + return readl_poll_timeout(cgu->base + pll_info->reg, ctl, ctl & BIT(pll_info->stable_bit), 0, 100 * USEC_PER_MSEC); @@ -230,7 +233,7 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate, writel(ctl, cgu->base + pll_info->reg); /* If the PLL is enabled, verify that it's stable */ - if (ctl & BIT(pll_info->enable_bit)) + if (pll_info->enable_bit >= 0 && (ctl & BIT(pll_info->enable_bit))) ret = ingenic_pll_check_stable(cgu, pll_info); spin_unlock_irqrestore(&cgu->lock, flags); @@ -248,6 +251,9 @@ static int ingenic_pll_enable(struct clk_hw *hw) int ret; u32 ctl; + if (pll_info->enable_bit < 0) + return 0; + spin_lock_irqsave(&cgu->lock, flags); if (pll_info->bypass_bit >= 0) { ctl = readl(cgu->base + pll_info->bypass_reg); @@ -278,6 +284,9 @@ static void ingenic_pll_disable(struct clk_hw *hw) unsigned long flags; u32 ctl; + if (pll_info->enable_bit < 0) + return; + spin_lock_irqsave(&cgu->lock, flags); ctl = readl(cgu->base + pll_info->reg); @@ -295,6 +304,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw) const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; u32 ctl; + if (pll_info->enable_bit < 0) + return true; + ctl = readl(cgu->base + pll_info->reg); return !!(ctl & BIT(pll_info->enable_bit)); diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h index 567142b584bb..a5e44ca7f969 100644 --- a/drivers/clk/ingenic/cgu.h +++ b/drivers/clk/ingenic/cgu.h @@ -42,8 +42,10 @@ * @bypass_reg: the offset of the bypass control register within the CGU * @bypass_bit: the index of the bypass bit in the PLL control register, or * -1 if there is no bypass bit - * @enable_bit: the index of the enable bit in the PLL control register - * @stable_bit: the index of the stable bit in the PLL control register + * @enable_bit: the index of the enable bit in the PLL control register, or + * -1 if there is no enable bit (ie, the PLL is always on) + * @stable_bit: the index of the stable bit in the PLL control register, or + * -1 if there is no stable bit */ struct ingenic_cgu_pll_info { unsigned reg; @@ -54,8 +56,8 @@ struct ingenic_cgu_pll_info { u8 od_shift, od_bits, od_max; unsigned bypass_reg; s8 bypass_bit; - u8 enable_bit; - u8 stable_bit; + s8 enable_bit; + s8 stable_bit; void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info, unsigned long rate, unsigned long parent_rate, unsigned int *m, unsigned int *n, unsigned int *od); -- 2.38.1