Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: renesas: rcar-gen3-cpg: Refactor checks for accessing the div table

Do the checks for accessing the SD divider table only when the rate gets
updated, namely on init and set_rate. In all other cases, reuse the last
value. This simplifies code, runtime load, and error reporting.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

authored by

Wolfram Sang and committed by
Geert Uytterhoeven
2d6f2577 f317880c

+20 -26
+20 -26
drivers/clk/renesas/rcar-gen3-cpg.c
··· 60 60 unsigned int div_num; 61 61 unsigned int div_min; 62 62 unsigned int div_max; 63 + unsigned int cur_div_idx; 63 64 }; 64 65 65 66 /* SDn divider ··· 97 96 static int cpg_sd_clock_enable(struct clk_hw *hw) 98 97 { 99 98 struct sd_clock *clock = to_sd_clock(hw); 100 - u32 val, sd_fc; 101 - unsigned int i; 102 - 103 - val = readl(clock->reg); 104 - 105 - sd_fc = val & CPG_SD_FC_MASK; 106 - for (i = 0; i < clock->div_num; i++) 107 - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) 108 - break; 109 - 110 - if (i >= clock->div_num) 111 - return -EINVAL; 99 + u32 val = readl(clock->reg); 112 100 113 101 val &= ~(CPG_SD_STP_MASK); 114 - val |= clock->div_table[i].val & CPG_SD_STP_MASK; 102 + val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK; 115 103 116 104 writel(val, clock->reg); 117 105 ··· 125 135 unsigned long parent_rate) 126 136 { 127 137 struct sd_clock *clock = to_sd_clock(hw); 128 - u32 val, sd_fc; 129 - unsigned int i; 130 138 131 - val = readl(clock->reg); 132 - 133 - sd_fc = val & CPG_SD_FC_MASK; 134 - for (i = 0; i < clock->div_num; i++) 135 - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) 136 - break; 137 - 138 - if (i >= clock->div_num) 139 - return -EINVAL; 140 - 141 - return DIV_ROUND_CLOSEST(parent_rate, clock->div_table[i].div); 139 + return DIV_ROUND_CLOSEST(parent_rate, 140 + clock->div_table[clock->cur_div_idx].div); 142 141 } 143 142 144 143 static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, ··· 168 189 if (i >= clock->div_num) 169 190 return -EINVAL; 170 191 192 + clock->cur_div_idx = i; 193 + 171 194 val = readl(clock->reg); 172 195 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); 173 196 val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); ··· 195 214 struct sd_clock *clock; 196 215 struct clk *clk; 197 216 unsigned int i; 217 + u32 sd_fc; 198 218 199 219 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 200 220 if (!clock) ··· 211 229 clock->hw.init = &init; 212 230 clock->div_table = cpg_sd_div_table; 213 231 clock->div_num = ARRAY_SIZE(cpg_sd_div_table); 232 + 233 + sd_fc = readl(clock->reg) & CPG_SD_FC_MASK; 234 + for (i = 0; i < clock->div_num; i++) 235 + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) 236 + break; 237 + 238 + if (WARN_ON(i >= clock->div_num)) { 239 + kfree(clock); 240 + return ERR_PTR(-EINVAL); 241 + } 242 + 243 + clock->cur_div_idx = i; 214 244 215 245 clock->div_max = clock->div_table[0].div; 216 246 clock->div_min = clock->div_max;