Commit | Line | Data |
---|---|---|
80eded6c BB |
1 | /* |
2 | * drivers/clk/at91/clk-slow.c | |
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 | ||
13 | #include <linux/clk-provider.h> | |
14 | #include <linux/clkdev.h> | |
15 | #include <linux/clk/at91_pmc.h> | |
80eded6c | 16 | #include <linux/of.h> |
1bdf0232 BB |
17 | #include <linux/mfd/syscon.h> |
18 | #include <linux/regmap.h> | |
80eded6c BB |
19 | |
20 | #include "pmc.h" | |
80eded6c BB |
21 | |
22 | struct clk_sam9260_slow { | |
23 | struct clk_hw hw; | |
1bdf0232 | 24 | struct regmap *regmap; |
80eded6c BB |
25 | }; |
26 | ||
27 | #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) | |
28 | ||
80eded6c BB |
29 | static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) |
30 | { | |
31 | struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); | |
1bdf0232 | 32 | unsigned int status; |
80eded6c | 33 | |
1bdf0232 BB |
34 | regmap_read(slowck->regmap, AT91_PMC_SR, &status); |
35 | ||
36 | return status & AT91_PMC_OSCSEL ? 1 : 0; | |
80eded6c BB |
37 | } |
38 | ||
39 | static const struct clk_ops sam9260_slow_ops = { | |
40 | .get_parent = clk_sam9260_slow_get_parent, | |
41 | }; | |
42 | ||
b2e39dc0 | 43 | struct clk_hw * __init |
1bdf0232 | 44 | at91_clk_register_sam9260_slow(struct regmap *regmap, |
80eded6c BB |
45 | const char *name, |
46 | const char **parent_names, | |
47 | int num_parents) | |
48 | { | |
49 | struct clk_sam9260_slow *slowck; | |
f5644f10 | 50 | struct clk_hw *hw; |
80eded6c | 51 | struct clk_init_data init; |
f5644f10 | 52 | int ret; |
80eded6c | 53 | |
1bdf0232 | 54 | if (!name) |
80eded6c BB |
55 | return ERR_PTR(-EINVAL); |
56 | ||
57 | if (!parent_names || !num_parents) | |
58 | return ERR_PTR(-EINVAL); | |
59 | ||
60 | slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); | |
61 | if (!slowck) | |
62 | return ERR_PTR(-ENOMEM); | |
63 | ||
64 | init.name = name; | |
65 | init.ops = &sam9260_slow_ops; | |
66 | init.parent_names = parent_names; | |
67 | init.num_parents = num_parents; | |
68 | init.flags = 0; | |
69 | ||
70 | slowck->hw.init = &init; | |
1bdf0232 | 71 | slowck->regmap = regmap; |
80eded6c | 72 | |
f5644f10 SB |
73 | hw = &slowck->hw; |
74 | ret = clk_hw_register(NULL, &slowck->hw); | |
75 | if (ret) { | |
80eded6c | 76 | kfree(slowck); |
f5644f10 SB |
77 | hw = ERR_PTR(ret); |
78 | } | |
80eded6c | 79 | |
f5644f10 | 80 | return hw; |
80eded6c | 81 | } |