0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk-provider.h>
0009 #include <linux/clkdev.h>
0010 #include <linux/clk/at91_pmc.h>
0011 #include <linux/of.h>
0012 #include <linux/mfd/syscon.h>
0013 #include <linux/regmap.h>
0014
0015 #include "pmc.h"
0016
0017 struct clk_sam9260_slow {
0018 struct clk_hw hw;
0019 struct regmap *regmap;
0020 };
0021
0022 #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
0023
0024 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
0025 {
0026 struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
0027 unsigned int status;
0028
0029 regmap_read(slowck->regmap, AT91_PMC_SR, &status);
0030
0031 return status & AT91_PMC_OSCSEL ? 1 : 0;
0032 }
0033
0034 static const struct clk_ops sam9260_slow_ops = {
0035 .get_parent = clk_sam9260_slow_get_parent,
0036 };
0037
0038 struct clk_hw * __init
0039 at91_clk_register_sam9260_slow(struct regmap *regmap,
0040 const char *name,
0041 const char **parent_names,
0042 int num_parents)
0043 {
0044 struct clk_sam9260_slow *slowck;
0045 struct clk_hw *hw;
0046 struct clk_init_data init;
0047 int ret;
0048
0049 if (!name)
0050 return ERR_PTR(-EINVAL);
0051
0052 if (!parent_names || !num_parents)
0053 return ERR_PTR(-EINVAL);
0054
0055 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
0056 if (!slowck)
0057 return ERR_PTR(-ENOMEM);
0058
0059 init.name = name;
0060 init.ops = &sam9260_slow_ops;
0061 init.parent_names = parent_names;
0062 init.num_parents = num_parents;
0063 init.flags = 0;
0064
0065 slowck->hw.init = &init;
0066 slowck->regmap = regmap;
0067
0068 hw = &slowck->hw;
0069 ret = clk_hw_register(NULL, &slowck->hw);
0070 if (ret) {
0071 kfree(slowck);
0072 hw = ERR_PTR(ret);
0073 }
0074
0075 return hw;
0076 }