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

clk: at91: sckc: add support to specify registers bit offsets

Different IPs uses different bit offsets in registers for the same
functionality, thus adapt the driver to support this.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Claudiu Beznea and committed by
Stephen Boyd
abaceffc 5cf6d876

+61 -32
+61 -32
drivers/clk/at91/sckc.c
··· 23 23 SLOW_CLOCK_FREQ) 24 24 25 25 #define AT91_SCKC_CR 0x00 26 - #define AT91_SCKC_RCEN (1 << 0) 27 - #define AT91_SCKC_OSC32EN (1 << 1) 28 - #define AT91_SCKC_OSC32BYP (1 << 2) 29 - #define AT91_SCKC_OSCSEL (1 << 3) 26 + 27 + struct clk_slow_bits { 28 + u32 cr_rcen; 29 + u32 cr_osc32en; 30 + u32 cr_osc32byp; 31 + u32 cr_oscsel; 32 + }; 30 33 31 34 struct clk_slow_osc { 32 35 struct clk_hw hw; 33 36 void __iomem *sckcr; 37 + const struct clk_slow_bits *bits; 34 38 unsigned long startup_usec; 35 39 }; 36 40 ··· 43 39 struct clk_sama5d4_slow_osc { 44 40 struct clk_hw hw; 45 41 void __iomem *sckcr; 42 + const struct clk_slow_bits *bits; 46 43 unsigned long startup_usec; 47 44 bool prepared; 48 45 }; ··· 53 48 struct clk_slow_rc_osc { 54 49 struct clk_hw hw; 55 50 void __iomem *sckcr; 51 + const struct clk_slow_bits *bits; 56 52 unsigned long frequency; 57 53 unsigned long accuracy; 58 54 unsigned long startup_usec; ··· 64 58 struct clk_sam9x5_slow { 65 59 struct clk_hw hw; 66 60 void __iomem *sckcr; 61 + const struct clk_slow_bits *bits; 67 62 u8 parent; 68 63 }; 69 64 ··· 76 69 void __iomem *sckcr = osc->sckcr; 77 70 u32 tmp = readl(sckcr); 78 71 79 - if (tmp & (AT91_SCKC_OSC32BYP | AT91_SCKC_OSC32EN)) 72 + if (tmp & (osc->bits->cr_osc32byp | osc->bits->cr_osc32en)) 80 73 return 0; 81 74 82 - writel(tmp | AT91_SCKC_OSC32EN, sckcr); 75 + writel(tmp | osc->bits->cr_osc32en, sckcr); 83 76 84 77 usleep_range(osc->startup_usec, osc->startup_usec + 1); 85 78 ··· 92 85 void __iomem *sckcr = osc->sckcr; 93 86 u32 tmp = readl(sckcr); 94 87 95 - if (tmp & AT91_SCKC_OSC32BYP) 88 + if (tmp & osc->bits->cr_osc32byp) 96 89 return; 97 90 98 - writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); 91 + writel(tmp & ~osc->bits->cr_osc32en, sckcr); 99 92 } 100 93 101 94 static int clk_slow_osc_is_prepared(struct clk_hw *hw) ··· 104 97 void __iomem *sckcr = osc->sckcr; 105 98 u32 tmp = readl(sckcr); 106 99 107 - if (tmp & AT91_SCKC_OSC32BYP) 100 + if (tmp & osc->bits->cr_osc32byp) 108 101 return 1; 109 102 110 - return !!(tmp & AT91_SCKC_OSC32EN); 103 + return !!(tmp & osc->bits->cr_osc32en); 111 104 } 112 105 113 106 static const struct clk_ops slow_osc_ops = { ··· 121 114 const char *name, 122 115 const char *parent_name, 123 116 unsigned long startup, 124 - bool bypass) 117 + bool bypass, 118 + const struct clk_slow_bits *bits) 125 119 { 126 120 struct clk_slow_osc *osc; 127 121 struct clk_hw *hw; ··· 145 137 osc->hw.init = &init; 146 138 osc->sckcr = sckcr; 147 139 osc->startup_usec = startup; 140 + osc->bits = bits; 148 141 149 142 if (bypass) 150 - writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, 151 - sckcr); 143 + writel((readl(sckcr) & ~osc->bits->cr_osc32en) | 144 + osc->bits->cr_osc32byp, sckcr); 152 145 153 146 hw = &osc->hw; 154 147 ret = clk_hw_register(NULL, &osc->hw); ··· 182 173 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 183 174 void __iomem *sckcr = osc->sckcr; 184 175 185 - writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); 176 + writel(readl(sckcr) | osc->bits->cr_rcen, sckcr); 186 177 187 178 usleep_range(osc->startup_usec, osc->startup_usec + 1); 188 179 ··· 194 185 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 195 186 void __iomem *sckcr = osc->sckcr; 196 187 197 - writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); 188 + writel(readl(sckcr) & ~osc->bits->cr_rcen, sckcr); 198 189 } 199 190 200 191 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) 201 192 { 202 193 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 203 194 204 - return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); 195 + return !!(readl(osc->sckcr) & osc->bits->cr_rcen); 205 196 } 206 197 207 198 static const struct clk_ops slow_rc_osc_ops = { ··· 217 208 const char *name, 218 209 unsigned long frequency, 219 210 unsigned long accuracy, 220 - unsigned long startup) 211 + unsigned long startup, 212 + const struct clk_slow_bits *bits) 221 213 { 222 214 struct clk_slow_rc_osc *osc; 223 215 struct clk_hw *hw; ··· 240 230 241 231 osc->hw.init = &init; 242 232 osc->sckcr = sckcr; 233 + osc->bits = bits; 243 234 osc->frequency = frequency; 244 235 osc->accuracy = accuracy; 245 236 osc->startup_usec = startup; ··· 266 255 267 256 tmp = readl(sckcr); 268 257 269 - if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || 270 - (index && (tmp & AT91_SCKC_OSCSEL))) 258 + if ((!index && !(tmp & slowck->bits->cr_oscsel)) || 259 + (index && (tmp & slowck->bits->cr_oscsel))) 271 260 return 0; 272 261 273 262 if (index) 274 - tmp |= AT91_SCKC_OSCSEL; 263 + tmp |= slowck->bits->cr_oscsel; 275 264 else 276 - tmp &= ~AT91_SCKC_OSCSEL; 265 + tmp &= ~slowck->bits->cr_oscsel; 277 266 278 267 writel(tmp, sckcr); 279 268 ··· 286 275 { 287 276 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 288 277 289 - return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); 278 + return !!(readl(slowck->sckcr) & slowck->bits->cr_oscsel); 290 279 } 291 280 292 281 static const struct clk_ops sam9x5_slow_ops = { ··· 298 287 at91_clk_register_sam9x5_slow(void __iomem *sckcr, 299 288 const char *name, 300 289 const char **parent_names, 301 - int num_parents) 290 + int num_parents, 291 + const struct clk_slow_bits *bits) 302 292 { 303 293 struct clk_sam9x5_slow *slowck; 304 294 struct clk_hw *hw; ··· 321 309 322 310 slowck->hw.init = &init; 323 311 slowck->sckcr = sckcr; 324 - slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); 312 + slowck->bits = bits; 313 + slowck->parent = !!(readl(sckcr) & slowck->bits->cr_oscsel); 325 314 326 315 hw = &slowck->hw; 327 316 ret = clk_hw_register(NULL, &slowck->hw); ··· 335 322 } 336 323 337 324 static void __init at91sam9x5_sckc_register(struct device_node *np, 338 - unsigned int rc_osc_startup_us) 325 + unsigned int rc_osc_startup_us, 326 + const struct clk_slow_bits *bits) 339 327 { 340 328 const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; 341 329 void __iomem *regbase = of_iomap(np, 0); ··· 349 335 return; 350 336 351 337 hw = at91_clk_register_slow_rc_osc(regbase, parent_names[0], 32768, 352 - 50000000, rc_osc_startup_us); 338 + 50000000, rc_osc_startup_us, 339 + bits); 353 340 if (IS_ERR(hw)) 354 341 return; 355 342 ··· 373 358 return; 374 359 375 360 hw = at91_clk_register_slow_osc(regbase, parent_names[1], xtal_name, 376 - 1200000, bypass); 361 + 1200000, bypass, bits); 377 362 if (IS_ERR(hw)) 378 363 return; 379 364 380 - hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2); 365 + hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2, 366 + bits); 381 367 if (IS_ERR(hw)) 382 368 return; 383 369 ··· 389 373 of_clk_add_hw_provider(child, of_clk_hw_simple_get, hw); 390 374 } 391 375 376 + static const struct clk_slow_bits at91sam9x5_bits = { 377 + .cr_rcen = BIT(0), 378 + .cr_osc32en = BIT(1), 379 + .cr_osc32byp = BIT(2), 380 + .cr_oscsel = BIT(3), 381 + }; 382 + 392 383 static void __init of_at91sam9x5_sckc_setup(struct device_node *np) 393 384 { 394 - at91sam9x5_sckc_register(np, 75); 385 + at91sam9x5_sckc_register(np, 75, &at91sam9x5_bits); 395 386 } 396 387 CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", 397 388 of_at91sam9x5_sckc_setup); 398 389 399 390 static void __init of_sama5d3_sckc_setup(struct device_node *np) 400 391 { 401 - at91sam9x5_sckc_register(np, 500); 392 + at91sam9x5_sckc_register(np, 500, &at91sam9x5_bits); 402 393 } 403 394 CLK_OF_DECLARE(sama5d3_clk_sckc, "atmel,sama5d3-sckc", 404 395 of_sama5d3_sckc_setup); ··· 421 398 * Assume that if it has already been selected (for example by the 422 399 * bootloader), enough time has aready passed. 423 400 */ 424 - if ((readl(osc->sckcr) & AT91_SCKC_OSCSEL)) { 401 + if ((readl(osc->sckcr) & osc->bits->cr_oscsel)) { 425 402 osc->prepared = true; 426 403 return 0; 427 404 } ··· 442 419 static const struct clk_ops sama5d4_slow_osc_ops = { 443 420 .prepare = clk_sama5d4_slow_osc_prepare, 444 421 .is_prepared = clk_sama5d4_slow_osc_is_prepared, 422 + }; 423 + 424 + static const struct clk_slow_bits at91sama5d4_bits = { 425 + .cr_oscsel = BIT(3), 445 426 }; 446 427 447 428 static void __init of_sama5d4_sckc_setup(struct device_node *np) ··· 482 455 osc->hw.init = &init; 483 456 osc->sckcr = regbase; 484 457 osc->startup_usec = 1200000; 458 + osc->bits = &at91sama5d4_bits; 485 459 486 460 hw = &osc->hw; 487 461 ret = clk_hw_register(NULL, &osc->hw); ··· 491 463 return; 492 464 } 493 465 494 - hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2); 466 + hw = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, 2, 467 + &at91sama5d4_bits); 495 468 if (IS_ERR(hw)) 496 469 return; 497 470