2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * Copyright (C) 2012 ARM Limited
14 #define pr_fmt(fmt) "vexpress-osc: " fmt
16 #include <linux/clkdev.h>
17 #include <linux/clk-provider.h>
18 #include <linux/err.h>
20 #include <linux/platform_device.h>
21 #include <linux/slab.h>
22 #include <linux/vexpress.h>
25 struct vexpress_config_func
*func
;
27 unsigned long rate_min
;
28 unsigned long rate_max
;
31 #define to_vexpress_osc(osc) container_of(osc, struct vexpress_osc, hw)
33 static unsigned long vexpress_osc_recalc_rate(struct clk_hw
*hw
,
34 unsigned long parent_rate
)
36 struct vexpress_osc
*osc
= to_vexpress_osc(hw
);
39 vexpress_config_read(osc
->func
, 0, &rate
);
44 static long vexpress_osc_round_rate(struct clk_hw
*hw
, unsigned long rate
,
45 unsigned long *parent_rate
)
47 struct vexpress_osc
*osc
= to_vexpress_osc(hw
);
49 if (WARN_ON(osc
->rate_min
&& rate
< osc
->rate_min
))
52 if (WARN_ON(osc
->rate_max
&& rate
> osc
->rate_max
))
58 static int vexpress_osc_set_rate(struct clk_hw
*hw
, unsigned long rate
,
59 unsigned long parent_rate
)
61 struct vexpress_osc
*osc
= to_vexpress_osc(hw
);
63 return vexpress_config_write(osc
->func
, 0, rate
);
66 static struct clk_ops vexpress_osc_ops
= {
67 .recalc_rate
= vexpress_osc_recalc_rate
,
68 .round_rate
= vexpress_osc_round_rate
,
69 .set_rate
= vexpress_osc_set_rate
,
73 struct clk
* __init
vexpress_osc_setup(struct device
*dev
)
75 struct clk_init_data init
;
76 struct vexpress_osc
*osc
= kzalloc(sizeof(*osc
), GFP_KERNEL
);
81 osc
->func
= vexpress_config_func_get_by_dev(dev
);
87 init
.name
= dev_name(dev
);
88 init
.ops
= &vexpress_osc_ops
;
89 init
.flags
= CLK_IS_ROOT
;
93 return clk_register(NULL
, &osc
->hw
);
96 void __init
vexpress_osc_of_setup(struct device_node
*node
)
98 struct clk_init_data init
;
99 struct vexpress_osc
*osc
;
103 osc
= kzalloc(sizeof(*osc
), GFP_KERNEL
);
107 osc
->func
= vexpress_config_func_get_by_node(node
);
109 pr_err("Failed to obtain config func for node '%s'!\n",
114 if (of_property_read_u32_array(node
, "freq-range", range
,
115 ARRAY_SIZE(range
)) == 0) {
116 osc
->rate_min
= range
[0];
117 osc
->rate_max
= range
[1];
120 of_property_read_string(node
, "clock-output-names", &init
.name
);
122 init
.name
= node
->full_name
;
124 init
.ops
= &vexpress_osc_ops
;
125 init
.flags
= CLK_IS_ROOT
;
126 init
.num_parents
= 0;
128 osc
->hw
.init
= &init
;
130 clk
= clk_register(NULL
, &osc
->hw
);
132 pr_err("Failed to register clock '%s'!\n", init
.name
);
136 of_clk_add_provider(node
, of_clk_src_simple_get
, clk
);
138 pr_debug("Registered clock '%s'\n", init
.name
);
144 vexpress_config_func_put(osc
->func
);
147 CLK_OF_DECLARE(vexpress_soc
, "arm,vexpress-osc", vexpress_osc_of_setup
);