@@ -24,6 +24,7 @@ struct scmi_clk {
2424 struct clk_hw hw ;
2525 const struct scmi_clock_info * info ;
2626 const struct scmi_protocol_handle * ph ;
27+ struct clk_parent_data * parent_data ;
2728};
2829
2930#define to_scmi_clk (clk ) container_of(clk, struct scmi_clk, hw)
@@ -78,6 +79,43 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
7879 return scmi_proto_clk_ops -> rate_set (clk -> ph , clk -> id , rate );
7980}
8081
82+ static int scmi_clk_set_parent (struct clk_hw * hw , u8 parent_index )
83+ {
84+ struct scmi_clk * clk = to_scmi_clk (hw );
85+
86+ return scmi_proto_clk_ops -> parent_set (clk -> ph , clk -> id , parent_index );
87+ }
88+
89+ static u8 scmi_clk_get_parent (struct clk_hw * hw )
90+ {
91+ struct scmi_clk * clk = to_scmi_clk (hw );
92+ u32 parent_id , p_idx ;
93+ int ret ;
94+
95+ ret = scmi_proto_clk_ops -> parent_get (clk -> ph , clk -> id , & parent_id );
96+ if (ret )
97+ return 0 ;
98+
99+ for (p_idx = 0 ; p_idx < clk -> info -> num_parents ; p_idx ++ ) {
100+ if (clk -> parent_data [p_idx ].index == parent_id )
101+ break ;
102+ }
103+
104+ if (p_idx == clk -> info -> num_parents )
105+ return 0 ;
106+
107+ return p_idx ;
108+ }
109+
110+ static int scmi_clk_determine_rate (struct clk_hw * hw , struct clk_rate_request * req )
111+ {
112+ /*
113+ * Suppose all the requested rates are supported, and let firmware
114+ * to handle the left work.
115+ */
116+ return 0 ;
117+ }
118+
81119static int scmi_clk_enable (struct clk_hw * hw )
82120{
83121 struct scmi_clk * clk = to_scmi_clk (hw );
@@ -139,6 +177,9 @@ static const struct clk_ops scmi_clk_ops = {
139177 .set_rate = scmi_clk_set_rate ,
140178 .prepare = scmi_clk_enable ,
141179 .unprepare = scmi_clk_disable ,
180+ .set_parent = scmi_clk_set_parent ,
181+ .get_parent = scmi_clk_get_parent ,
182+ .determine_rate = scmi_clk_determine_rate ,
142183};
143184
144185static const struct clk_ops scmi_atomic_clk_ops = {
@@ -148,6 +189,9 @@ static const struct clk_ops scmi_atomic_clk_ops = {
148189 .enable = scmi_clk_atomic_enable ,
149190 .disable = scmi_clk_atomic_disable ,
150191 .is_enabled = scmi_clk_atomic_is_enabled ,
192+ .set_parent = scmi_clk_set_parent ,
193+ .get_parent = scmi_clk_get_parent ,
194+ .determine_rate = scmi_clk_determine_rate ,
151195};
152196
153197static int scmi_clk_ops_init (struct device * dev , struct scmi_clk * sclk ,
@@ -158,9 +202,10 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
158202
159203 struct clk_init_data init = {
160204 .flags = CLK_GET_RATE_NOCACHE ,
161- .num_parents = 0 ,
205+ .num_parents = sclk -> info -> num_parents ,
162206 .ops = scmi_ops ,
163207 .name = sclk -> info -> name ,
208+ .parent_data = sclk -> parent_data ,
164209 };
165210
166211 sclk -> hw .init = & init ;
@@ -251,9 +296,23 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
251296 else
252297 scmi_ops = & scmi_clk_ops ;
253298
299+ /* Initialize clock parent data. */
300+ if (sclk -> info -> num_parents > 0 ) {
301+ sclk -> parent_data = devm_kcalloc (dev , sclk -> info -> num_parents ,
302+ sizeof (* sclk -> parent_data ), GFP_KERNEL );
303+ if (!sclk -> parent_data )
304+ return - ENOMEM ;
305+
306+ for (int i = 0 ; i < sclk -> info -> num_parents ; i ++ ) {
307+ sclk -> parent_data [i ].index = sclk -> info -> parents [i ];
308+ sclk -> parent_data [i ].hw = hws [sclk -> info -> parents [i ]];
309+ }
310+ }
311+
254312 err = scmi_clk_ops_init (dev , sclk , scmi_ops );
255313 if (err ) {
256314 dev_err (dev , "failed to register clock %d\n" , idx );
315+ devm_kfree (dev , sclk -> parent_data );
257316 devm_kfree (dev , sclk );
258317 hws [idx ] = NULL ;
259318 } else {
0 commit comments