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

clk: at91: move slow clock controller clocks to sckc.c

Move all clocks related to the slow clock controller to sckc.c. This avoids
extern definitions and allows to remove sckc.h

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
[sboyd@codeaurora.org: Mark some functions static]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>

authored by

Alexandre Belloni and committed by
Stephen Boyd
ec187ef0 d8846023

+363 -388
-365
drivers/clk/at91/clk-slow.c
··· 13 13 #include <linux/clk-provider.h> 14 14 #include <linux/clkdev.h> 15 15 #include <linux/clk/at91_pmc.h> 16 - #include <linux/delay.h> 17 16 #include <linux/of.h> 18 17 #include <linux/mfd/syscon.h> 19 18 #include <linux/regmap.h> 20 19 21 20 #include "pmc.h" 22 - #include "sckc.h" 23 - 24 - #define SLOW_CLOCK_FREQ 32768 25 - #define SLOWCK_SW_CYCLES 5 26 - #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ 27 - SLOW_CLOCK_FREQ) 28 - 29 - #define AT91_SCKC_CR 0x00 30 - #define AT91_SCKC_RCEN (1 << 0) 31 - #define AT91_SCKC_OSC32EN (1 << 1) 32 - #define AT91_SCKC_OSC32BYP (1 << 2) 33 - #define AT91_SCKC_OSCSEL (1 << 3) 34 - 35 - struct clk_slow_osc { 36 - struct clk_hw hw; 37 - void __iomem *sckcr; 38 - unsigned long startup_usec; 39 - }; 40 - 41 - #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw) 42 - 43 - struct clk_slow_rc_osc { 44 - struct clk_hw hw; 45 - void __iomem *sckcr; 46 - unsigned long frequency; 47 - unsigned long accuracy; 48 - unsigned long startup_usec; 49 - }; 50 - 51 - #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw) 52 21 53 22 struct clk_sam9260_slow { 54 23 struct clk_hw hw; ··· 25 56 }; 26 57 27 58 #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) 28 - 29 - struct clk_sam9x5_slow { 30 - struct clk_hw hw; 31 - void __iomem *sckcr; 32 - u8 parent; 33 - }; 34 - 35 - #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) 36 - 37 - static int clk_slow_osc_prepare(struct clk_hw *hw) 38 - { 39 - struct clk_slow_osc *osc = to_clk_slow_osc(hw); 40 - void __iomem *sckcr = osc->sckcr; 41 - u32 tmp = readl(sckcr); 42 - 43 - if (tmp & AT91_SCKC_OSC32BYP) 44 - return 0; 45 - 46 - writel(tmp | AT91_SCKC_OSC32EN, sckcr); 47 - 48 - usleep_range(osc->startup_usec, osc->startup_usec + 1); 49 - 50 - return 0; 51 - } 52 - 53 - static void clk_slow_osc_unprepare(struct clk_hw *hw) 54 - { 55 - struct clk_slow_osc *osc = to_clk_slow_osc(hw); 56 - void __iomem *sckcr = osc->sckcr; 57 - u32 tmp = readl(sckcr); 58 - 59 - if (tmp & AT91_SCKC_OSC32BYP) 60 - return; 61 - 62 - writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); 63 - } 64 - 65 - static int clk_slow_osc_is_prepared(struct clk_hw *hw) 66 - { 67 - struct clk_slow_osc *osc = to_clk_slow_osc(hw); 68 - void __iomem *sckcr = osc->sckcr; 69 - u32 tmp = readl(sckcr); 70 - 71 - if (tmp & AT91_SCKC_OSC32BYP) 72 - return 1; 73 - 74 - return !!(tmp & AT91_SCKC_OSC32EN); 75 - } 76 - 77 - static const struct clk_ops slow_osc_ops = { 78 - .prepare = clk_slow_osc_prepare, 79 - .unprepare = clk_slow_osc_unprepare, 80 - .is_prepared = clk_slow_osc_is_prepared, 81 - }; 82 - 83 - static struct clk_hw * __init 84 - at91_clk_register_slow_osc(void __iomem *sckcr, 85 - const char *name, 86 - const char *parent_name, 87 - unsigned long startup, 88 - bool bypass) 89 - { 90 - struct clk_slow_osc *osc; 91 - struct clk_hw *hw; 92 - struct clk_init_data init; 93 - int ret; 94 - 95 - if (!sckcr || !name || !parent_name) 96 - return ERR_PTR(-EINVAL); 97 - 98 - osc = kzalloc(sizeof(*osc), GFP_KERNEL); 99 - if (!osc) 100 - return ERR_PTR(-ENOMEM); 101 - 102 - init.name = name; 103 - init.ops = &slow_osc_ops; 104 - init.parent_names = &parent_name; 105 - init.num_parents = 1; 106 - init.flags = CLK_IGNORE_UNUSED; 107 - 108 - osc->hw.init = &init; 109 - osc->sckcr = sckcr; 110 - osc->startup_usec = startup; 111 - 112 - if (bypass) 113 - writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, 114 - sckcr); 115 - 116 - hw = &osc->hw; 117 - ret = clk_hw_register(NULL, &osc->hw); 118 - if (ret) { 119 - kfree(osc); 120 - hw = ERR_PTR(ret); 121 - } 122 - 123 - return hw; 124 - } 125 - 126 - void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, 127 - void __iomem *sckcr) 128 - { 129 - struct clk_hw *hw; 130 - const char *parent_name; 131 - const char *name = np->name; 132 - u32 startup; 133 - bool bypass; 134 - 135 - parent_name = of_clk_get_parent_name(np, 0); 136 - of_property_read_string(np, "clock-output-names", &name); 137 - of_property_read_u32(np, "atmel,startup-time-usec", &startup); 138 - bypass = of_property_read_bool(np, "atmel,osc-bypass"); 139 - 140 - hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup, 141 - bypass); 142 - if (IS_ERR(hw)) 143 - return; 144 - 145 - of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 146 - } 147 - 148 - static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, 149 - unsigned long parent_rate) 150 - { 151 - struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 152 - 153 - return osc->frequency; 154 - } 155 - 156 - static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw, 157 - unsigned long parent_acc) 158 - { 159 - struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 160 - 161 - return osc->accuracy; 162 - } 163 - 164 - static int clk_slow_rc_osc_prepare(struct clk_hw *hw) 165 - { 166 - struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 167 - void __iomem *sckcr = osc->sckcr; 168 - 169 - writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); 170 - 171 - usleep_range(osc->startup_usec, osc->startup_usec + 1); 172 - 173 - return 0; 174 - } 175 - 176 - static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) 177 - { 178 - struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 179 - void __iomem *sckcr = osc->sckcr; 180 - 181 - writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); 182 - } 183 - 184 - static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) 185 - { 186 - struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 187 - 188 - return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); 189 - } 190 - 191 - static const struct clk_ops slow_rc_osc_ops = { 192 - .prepare = clk_slow_rc_osc_prepare, 193 - .unprepare = clk_slow_rc_osc_unprepare, 194 - .is_prepared = clk_slow_rc_osc_is_prepared, 195 - .recalc_rate = clk_slow_rc_osc_recalc_rate, 196 - .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy, 197 - }; 198 - 199 - static struct clk_hw * __init 200 - at91_clk_register_slow_rc_osc(void __iomem *sckcr, 201 - const char *name, 202 - unsigned long frequency, 203 - unsigned long accuracy, 204 - unsigned long startup) 205 - { 206 - struct clk_slow_rc_osc *osc; 207 - struct clk_hw *hw; 208 - struct clk_init_data init; 209 - int ret; 210 - 211 - if (!sckcr || !name) 212 - return ERR_PTR(-EINVAL); 213 - 214 - osc = kzalloc(sizeof(*osc), GFP_KERNEL); 215 - if (!osc) 216 - return ERR_PTR(-ENOMEM); 217 - 218 - init.name = name; 219 - init.ops = &slow_rc_osc_ops; 220 - init.parent_names = NULL; 221 - init.num_parents = 0; 222 - init.flags = CLK_IGNORE_UNUSED; 223 - 224 - osc->hw.init = &init; 225 - osc->sckcr = sckcr; 226 - osc->frequency = frequency; 227 - osc->accuracy = accuracy; 228 - osc->startup_usec = startup; 229 - 230 - hw = &osc->hw; 231 - ret = clk_hw_register(NULL, &osc->hw); 232 - if (ret) { 233 - kfree(osc); 234 - hw = ERR_PTR(ret); 235 - } 236 - 237 - return hw; 238 - } 239 - 240 - void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, 241 - void __iomem *sckcr) 242 - { 243 - struct clk_hw *hw; 244 - u32 frequency = 0; 245 - u32 accuracy = 0; 246 - u32 startup = 0; 247 - const char *name = np->name; 248 - 249 - of_property_read_string(np, "clock-output-names", &name); 250 - of_property_read_u32(np, "clock-frequency", &frequency); 251 - of_property_read_u32(np, "clock-accuracy", &accuracy); 252 - of_property_read_u32(np, "atmel,startup-time-usec", &startup); 253 - 254 - hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy, 255 - startup); 256 - if (IS_ERR(hw)) 257 - return; 258 - 259 - of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 260 - } 261 - 262 - static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) 263 - { 264 - struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 265 - void __iomem *sckcr = slowck->sckcr; 266 - u32 tmp; 267 - 268 - if (index > 1) 269 - return -EINVAL; 270 - 271 - tmp = readl(sckcr); 272 - 273 - if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || 274 - (index && (tmp & AT91_SCKC_OSCSEL))) 275 - return 0; 276 - 277 - if (index) 278 - tmp |= AT91_SCKC_OSCSEL; 279 - else 280 - tmp &= ~AT91_SCKC_OSCSEL; 281 - 282 - writel(tmp, sckcr); 283 - 284 - usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); 285 - 286 - return 0; 287 - } 288 - 289 - static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) 290 - { 291 - struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 292 - 293 - return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); 294 - } 295 - 296 - static const struct clk_ops sam9x5_slow_ops = { 297 - .set_parent = clk_sam9x5_slow_set_parent, 298 - .get_parent = clk_sam9x5_slow_get_parent, 299 - }; 300 - 301 - static struct clk_hw * __init 302 - at91_clk_register_sam9x5_slow(void __iomem *sckcr, 303 - const char *name, 304 - const char **parent_names, 305 - int num_parents) 306 - { 307 - struct clk_sam9x5_slow *slowck; 308 - struct clk_hw *hw; 309 - struct clk_init_data init; 310 - int ret; 311 - 312 - if (!sckcr || !name || !parent_names || !num_parents) 313 - return ERR_PTR(-EINVAL); 314 - 315 - slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 316 - if (!slowck) 317 - return ERR_PTR(-ENOMEM); 318 - 319 - init.name = name; 320 - init.ops = &sam9x5_slow_ops; 321 - init.parent_names = parent_names; 322 - init.num_parents = num_parents; 323 - init.flags = 0; 324 - 325 - slowck->hw.init = &init; 326 - slowck->sckcr = sckcr; 327 - slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); 328 - 329 - hw = &slowck->hw; 330 - ret = clk_hw_register(NULL, &slowck->hw); 331 - if (ret) { 332 - kfree(slowck); 333 - hw = ERR_PTR(ret); 334 - } 335 - 336 - return hw; 337 - } 338 - 339 - void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, 340 - void __iomem *sckcr) 341 - { 342 - struct clk_hw *hw; 343 - const char *parent_names[2]; 344 - unsigned int num_parents; 345 - const char *name = np->name; 346 - 347 - num_parents = of_clk_get_parent_count(np); 348 - if (num_parents == 0 || num_parents > 2) 349 - return; 350 - 351 - of_clk_parent_fill(np, parent_names, num_parents); 352 - 353 - of_property_read_string(np, "clock-output-names", &name); 354 - 355 - hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names, 356 - num_parents); 357 - if (IS_ERR(hw)) 358 - return; 359 - 360 - of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 361 - } 362 59 363 60 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) 364 61 {
+363 -1
drivers/clk/at91/sckc.c
··· 12 12 13 13 #include <linux/clk-provider.h> 14 14 #include <linux/clkdev.h> 15 + #include <linux/delay.h> 15 16 #include <linux/of.h> 16 17 #include <linux/of_address.h> 17 18 #include <linux/io.h> 18 19 19 - #include "sckc.h" 20 + #define SLOW_CLOCK_FREQ 32768 21 + #define SLOWCK_SW_CYCLES 5 22 + #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ 23 + SLOW_CLOCK_FREQ) 24 + 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) 30 + 31 + struct clk_slow_osc { 32 + struct clk_hw hw; 33 + void __iomem *sckcr; 34 + unsigned long startup_usec; 35 + }; 36 + 37 + #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw) 38 + 39 + struct clk_slow_rc_osc { 40 + struct clk_hw hw; 41 + void __iomem *sckcr; 42 + unsigned long frequency; 43 + unsigned long accuracy; 44 + unsigned long startup_usec; 45 + }; 46 + 47 + #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw) 48 + 49 + struct clk_sam9x5_slow { 50 + struct clk_hw hw; 51 + void __iomem *sckcr; 52 + u8 parent; 53 + }; 54 + 55 + #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) 56 + 57 + static int clk_slow_osc_prepare(struct clk_hw *hw) 58 + { 59 + struct clk_slow_osc *osc = to_clk_slow_osc(hw); 60 + void __iomem *sckcr = osc->sckcr; 61 + u32 tmp = readl(sckcr); 62 + 63 + if (tmp & AT91_SCKC_OSC32BYP) 64 + return 0; 65 + 66 + writel(tmp | AT91_SCKC_OSC32EN, sckcr); 67 + 68 + usleep_range(osc->startup_usec, osc->startup_usec + 1); 69 + 70 + return 0; 71 + } 72 + 73 + static void clk_slow_osc_unprepare(struct clk_hw *hw) 74 + { 75 + struct clk_slow_osc *osc = to_clk_slow_osc(hw); 76 + void __iomem *sckcr = osc->sckcr; 77 + u32 tmp = readl(sckcr); 78 + 79 + if (tmp & AT91_SCKC_OSC32BYP) 80 + return; 81 + 82 + writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); 83 + } 84 + 85 + static int clk_slow_osc_is_prepared(struct clk_hw *hw) 86 + { 87 + struct clk_slow_osc *osc = to_clk_slow_osc(hw); 88 + void __iomem *sckcr = osc->sckcr; 89 + u32 tmp = readl(sckcr); 90 + 91 + if (tmp & AT91_SCKC_OSC32BYP) 92 + return 1; 93 + 94 + return !!(tmp & AT91_SCKC_OSC32EN); 95 + } 96 + 97 + static const struct clk_ops slow_osc_ops = { 98 + .prepare = clk_slow_osc_prepare, 99 + .unprepare = clk_slow_osc_unprepare, 100 + .is_prepared = clk_slow_osc_is_prepared, 101 + }; 102 + 103 + static struct clk_hw * __init 104 + at91_clk_register_slow_osc(void __iomem *sckcr, 105 + const char *name, 106 + const char *parent_name, 107 + unsigned long startup, 108 + bool bypass) 109 + { 110 + struct clk_slow_osc *osc; 111 + struct clk_hw *hw; 112 + struct clk_init_data init; 113 + int ret; 114 + 115 + if (!sckcr || !name || !parent_name) 116 + return ERR_PTR(-EINVAL); 117 + 118 + osc = kzalloc(sizeof(*osc), GFP_KERNEL); 119 + if (!osc) 120 + return ERR_PTR(-ENOMEM); 121 + 122 + init.name = name; 123 + init.ops = &slow_osc_ops; 124 + init.parent_names = &parent_name; 125 + init.num_parents = 1; 126 + init.flags = CLK_IGNORE_UNUSED; 127 + 128 + osc->hw.init = &init; 129 + osc->sckcr = sckcr; 130 + osc->startup_usec = startup; 131 + 132 + if (bypass) 133 + writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, 134 + sckcr); 135 + 136 + hw = &osc->hw; 137 + ret = clk_hw_register(NULL, &osc->hw); 138 + if (ret) { 139 + kfree(osc); 140 + hw = ERR_PTR(ret); 141 + } 142 + 143 + return hw; 144 + } 145 + 146 + static void __init 147 + of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, void __iomem *sckcr) 148 + { 149 + struct clk_hw *hw; 150 + const char *parent_name; 151 + const char *name = np->name; 152 + u32 startup; 153 + bool bypass; 154 + 155 + parent_name = of_clk_get_parent_name(np, 0); 156 + of_property_read_string(np, "clock-output-names", &name); 157 + of_property_read_u32(np, "atmel,startup-time-usec", &startup); 158 + bypass = of_property_read_bool(np, "atmel,osc-bypass"); 159 + 160 + hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup, 161 + bypass); 162 + if (IS_ERR(hw)) 163 + return; 164 + 165 + of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 166 + } 167 + 168 + static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, 169 + unsigned long parent_rate) 170 + { 171 + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 172 + 173 + return osc->frequency; 174 + } 175 + 176 + static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw, 177 + unsigned long parent_acc) 178 + { 179 + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 180 + 181 + return osc->accuracy; 182 + } 183 + 184 + static int clk_slow_rc_osc_prepare(struct clk_hw *hw) 185 + { 186 + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 187 + void __iomem *sckcr = osc->sckcr; 188 + 189 + writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); 190 + 191 + usleep_range(osc->startup_usec, osc->startup_usec + 1); 192 + 193 + return 0; 194 + } 195 + 196 + static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) 197 + { 198 + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 199 + void __iomem *sckcr = osc->sckcr; 200 + 201 + writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); 202 + } 203 + 204 + static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) 205 + { 206 + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 207 + 208 + return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); 209 + } 210 + 211 + static const struct clk_ops slow_rc_osc_ops = { 212 + .prepare = clk_slow_rc_osc_prepare, 213 + .unprepare = clk_slow_rc_osc_unprepare, 214 + .is_prepared = clk_slow_rc_osc_is_prepared, 215 + .recalc_rate = clk_slow_rc_osc_recalc_rate, 216 + .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy, 217 + }; 218 + 219 + static struct clk_hw * __init 220 + at91_clk_register_slow_rc_osc(void __iomem *sckcr, 221 + const char *name, 222 + unsigned long frequency, 223 + unsigned long accuracy, 224 + unsigned long startup) 225 + { 226 + struct clk_slow_rc_osc *osc; 227 + struct clk_hw *hw; 228 + struct clk_init_data init; 229 + int ret; 230 + 231 + if (!sckcr || !name) 232 + return ERR_PTR(-EINVAL); 233 + 234 + osc = kzalloc(sizeof(*osc), GFP_KERNEL); 235 + if (!osc) 236 + return ERR_PTR(-ENOMEM); 237 + 238 + init.name = name; 239 + init.ops = &slow_rc_osc_ops; 240 + init.parent_names = NULL; 241 + init.num_parents = 0; 242 + init.flags = CLK_IGNORE_UNUSED; 243 + 244 + osc->hw.init = &init; 245 + osc->sckcr = sckcr; 246 + osc->frequency = frequency; 247 + osc->accuracy = accuracy; 248 + osc->startup_usec = startup; 249 + 250 + hw = &osc->hw; 251 + ret = clk_hw_register(NULL, &osc->hw); 252 + if (ret) { 253 + kfree(osc); 254 + hw = ERR_PTR(ret); 255 + } 256 + 257 + return hw; 258 + } 259 + 260 + static void __init 261 + of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, void __iomem *sckcr) 262 + { 263 + struct clk_hw *hw; 264 + u32 frequency = 0; 265 + u32 accuracy = 0; 266 + u32 startup = 0; 267 + const char *name = np->name; 268 + 269 + of_property_read_string(np, "clock-output-names", &name); 270 + of_property_read_u32(np, "clock-frequency", &frequency); 271 + of_property_read_u32(np, "clock-accuracy", &accuracy); 272 + of_property_read_u32(np, "atmel,startup-time-usec", &startup); 273 + 274 + hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy, 275 + startup); 276 + if (IS_ERR(hw)) 277 + return; 278 + 279 + of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 280 + } 281 + 282 + static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) 283 + { 284 + struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 285 + void __iomem *sckcr = slowck->sckcr; 286 + u32 tmp; 287 + 288 + if (index > 1) 289 + return -EINVAL; 290 + 291 + tmp = readl(sckcr); 292 + 293 + if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || 294 + (index && (tmp & AT91_SCKC_OSCSEL))) 295 + return 0; 296 + 297 + if (index) 298 + tmp |= AT91_SCKC_OSCSEL; 299 + else 300 + tmp &= ~AT91_SCKC_OSCSEL; 301 + 302 + writel(tmp, sckcr); 303 + 304 + usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); 305 + 306 + return 0; 307 + } 308 + 309 + static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) 310 + { 311 + struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 312 + 313 + return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); 314 + } 315 + 316 + static const struct clk_ops sam9x5_slow_ops = { 317 + .set_parent = clk_sam9x5_slow_set_parent, 318 + .get_parent = clk_sam9x5_slow_get_parent, 319 + }; 320 + 321 + static struct clk_hw * __init 322 + at91_clk_register_sam9x5_slow(void __iomem *sckcr, 323 + const char *name, 324 + const char **parent_names, 325 + int num_parents) 326 + { 327 + struct clk_sam9x5_slow *slowck; 328 + struct clk_hw *hw; 329 + struct clk_init_data init; 330 + int ret; 331 + 332 + if (!sckcr || !name || !parent_names || !num_parents) 333 + return ERR_PTR(-EINVAL); 334 + 335 + slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 336 + if (!slowck) 337 + return ERR_PTR(-ENOMEM); 338 + 339 + init.name = name; 340 + init.ops = &sam9x5_slow_ops; 341 + init.parent_names = parent_names; 342 + init.num_parents = num_parents; 343 + init.flags = 0; 344 + 345 + slowck->hw.init = &init; 346 + slowck->sckcr = sckcr; 347 + slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); 348 + 349 + hw = &slowck->hw; 350 + ret = clk_hw_register(NULL, &slowck->hw); 351 + if (ret) { 352 + kfree(slowck); 353 + hw = ERR_PTR(ret); 354 + } 355 + 356 + return hw; 357 + } 358 + 359 + static void __init 360 + of_at91sam9x5_clk_slow_setup(struct device_node *np, void __iomem *sckcr) 361 + { 362 + struct clk_hw *hw; 363 + const char *parent_names[2]; 364 + unsigned int num_parents; 365 + const char *name = np->name; 366 + 367 + num_parents = of_clk_get_parent_count(np); 368 + if (num_parents == 0 || num_parents > 2) 369 + return; 370 + 371 + of_clk_parent_fill(np, parent_names, num_parents); 372 + 373 + of_property_read_string(np, "clock-output-names", &name); 374 + 375 + hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names, 376 + num_parents); 377 + if (IS_ERR(hw)) 378 + return; 379 + 380 + of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 381 + } 20 382 21 383 static const struct of_device_id sckc_clk_ids[] __initconst = { 22 384 /* Slow clock */
-22
drivers/clk/at91/sckc.h
··· 1 - /* 2 - * drivers/clk/at91/sckc.h 3 - * 4 - * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - */ 11 - 12 - #ifndef __AT91_SCKC_H_ 13 - #define __AT91_SCKC_H_ 14 - 15 - extern void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, 16 - void __iomem *sckcr); 17 - extern void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, 18 - void __iomem *sckcr); 19 - extern void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, 20 - void __iomem *sckcr); 21 - 22 - #endif /* __AT91_SCKC_H_ */