1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Generic netlink for DPLL management framework
4 *
5 * Copyright (c) 2023 Meta Platforms, Inc. and affiliates
6 * Copyright (c) 2023 Intel and affiliates
7 *
8 */
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/netdevice.h>
12 #include <net/genetlink.h>
13 #include "dpll_core.h"
14 #include "dpll_netlink.h"
15 #include "dpll_nl.h"
16 #include <uapi/linux/dpll.h>
17
18 #define ASSERT_NOT_NULL(ptr) (WARN_ON(!ptr))
19
20 #define xa_for_each_marked_start(xa, index, entry, filter, start) \
21 for (index = start, entry = xa_find(xa, &index, ULONG_MAX, filter); \
22 entry; entry = xa_find_after(xa, &index, ULONG_MAX, filter))
23
24 struct dpll_dump_ctx {
25 unsigned long idx;
26 };
27
dpll_dump_context(struct netlink_callback * cb)28 static struct dpll_dump_ctx *dpll_dump_context(struct netlink_callback *cb)
29 {
30 return (struct dpll_dump_ctx *)cb->ctx;
31 }
32
33 static int
dpll_msg_add_dev_handle(struct sk_buff * msg,struct dpll_device * dpll)34 dpll_msg_add_dev_handle(struct sk_buff *msg, struct dpll_device *dpll)
35 {
36 if (nla_put_u32(msg, DPLL_A_ID, dpll->id))
37 return -EMSGSIZE;
38
39 return 0;
40 }
41
42 static int
dpll_msg_add_dev_parent_handle(struct sk_buff * msg,u32 id)43 dpll_msg_add_dev_parent_handle(struct sk_buff *msg, u32 id)
44 {
45 if (nla_put_u32(msg, DPLL_A_PIN_PARENT_ID, id))
46 return -EMSGSIZE;
47
48 return 0;
49 }
50
dpll_pin_available(struct dpll_pin * pin)51 static bool dpll_pin_available(struct dpll_pin *pin)
52 {
53 struct dpll_pin_ref *par_ref;
54 unsigned long i;
55
56 if (!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED))
57 return false;
58 xa_for_each(&pin->parent_refs, i, par_ref)
59 if (xa_get_mark(&dpll_pin_xa, par_ref->pin->id,
60 DPLL_REGISTERED))
61 return true;
62 xa_for_each(&pin->dpll_refs, i, par_ref)
63 if (xa_get_mark(&dpll_device_xa, par_ref->dpll->id,
64 DPLL_REGISTERED))
65 return true;
66 return false;
67 }
68
69 /**
70 * dpll_msg_add_pin_handle - attach pin handle attribute to a given message
71 * @msg: pointer to sk_buff message to attach a pin handle
72 * @pin: pin pointer
73 *
74 * Return:
75 * * 0 - success
76 * * -EMSGSIZE - no space in message to attach pin handle
77 */
dpll_msg_add_pin_handle(struct sk_buff * msg,struct dpll_pin * pin)78 static int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
79 {
80 if (!pin)
81 return 0;
82 if (nla_put_u32(msg, DPLL_A_PIN_ID, pin->id))
83 return -EMSGSIZE;
84 return 0;
85 }
86
dpll_netdev_pin(const struct net_device * dev)87 static struct dpll_pin *dpll_netdev_pin(const struct net_device *dev)
88 {
89 return rcu_dereference_rtnl(dev->dpll_pin);
90 }
91
92 /**
93 * dpll_netdev_pin_handle_size - get size of pin handle attribute of a netdev
94 * @dev: netdev from which to get the pin
95 *
96 * Return: byte size of pin handle attribute, or 0 if @dev has no pin.
97 */
dpll_netdev_pin_handle_size(const struct net_device * dev)98 size_t dpll_netdev_pin_handle_size(const struct net_device *dev)
99 {
100 return dpll_netdev_pin(dev) ? nla_total_size(4) : 0; /* DPLL_A_PIN_ID */
101 }
102
dpll_netdev_add_pin_handle(struct sk_buff * msg,const struct net_device * dev)103 int dpll_netdev_add_pin_handle(struct sk_buff *msg,
104 const struct net_device *dev)
105 {
106 return dpll_msg_add_pin_handle(msg, dpll_netdev_pin(dev));
107 }
108
109 static int
dpll_msg_add_mode(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)110 dpll_msg_add_mode(struct sk_buff *msg, struct dpll_device *dpll,
111 struct netlink_ext_ack *extack)
112 {
113 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
114 enum dpll_mode mode;
115 int ret;
116
117 ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
118 if (ret)
119 return ret;
120 if (nla_put_u32(msg, DPLL_A_MODE, mode))
121 return -EMSGSIZE;
122
123 return 0;
124 }
125
126 static int
dpll_msg_add_mode_supported(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)127 dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll,
128 struct netlink_ext_ack *extack)
129 {
130 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
131 DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 };
132 enum dpll_mode mode;
133 int ret;
134
135 if (ops->supported_modes_get) {
136 ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes,
137 extack);
138 if (ret)
139 return ret;
140 } else {
141 /* If the supported modes are not reported by the driver, the
142 * only supported mode is the one obtained by mode_get().
143 */
144 ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
145 if (ret)
146 return ret;
147
148 __set_bit(mode, modes);
149 }
150
151 for_each_set_bit(mode, modes, DPLL_MODE_MAX + 1)
152 if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
153 return -EMSGSIZE;
154
155 return 0;
156 }
157
158 static int
dpll_msg_add_phase_offset_monitor(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)159 dpll_msg_add_phase_offset_monitor(struct sk_buff *msg, struct dpll_device *dpll,
160 struct netlink_ext_ack *extack)
161 {
162 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
163 enum dpll_feature_state state;
164 int ret;
165
166 if (ops->phase_offset_monitor_set && ops->phase_offset_monitor_get) {
167 ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll),
168 &state, extack);
169 if (ret)
170 return ret;
171 if (nla_put_u32(msg, DPLL_A_PHASE_OFFSET_MONITOR, state))
172 return -EMSGSIZE;
173 }
174
175 return 0;
176 }
177
178 static int
dpll_msg_add_freq_monitor(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)179 dpll_msg_add_freq_monitor(struct sk_buff *msg, struct dpll_device *dpll,
180 struct netlink_ext_ack *extack)
181 {
182 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
183 enum dpll_feature_state state;
184 int ret;
185
186 if (ops->freq_monitor_set && ops->freq_monitor_get) {
187 ret = ops->freq_monitor_get(dpll, dpll_priv(dpll),
188 &state, extack);
189 if (ret)
190 return ret;
191 if (nla_put_u32(msg, DPLL_A_FREQUENCY_MONITOR, state))
192 return -EMSGSIZE;
193 }
194
195 return 0;
196 }
197
198 static int
dpll_msg_add_phase_offset_avg_factor(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)199 dpll_msg_add_phase_offset_avg_factor(struct sk_buff *msg,
200 struct dpll_device *dpll,
201 struct netlink_ext_ack *extack)
202 {
203 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
204 u32 factor;
205 int ret;
206
207 if (ops->phase_offset_avg_factor_get) {
208 ret = ops->phase_offset_avg_factor_get(dpll, dpll_priv(dpll),
209 &factor, extack);
210 if (ret)
211 return ret;
212 if (nla_put_u32(msg, DPLL_A_PHASE_OFFSET_AVG_FACTOR, factor))
213 return -EMSGSIZE;
214 }
215
216 return 0;
217 }
218
219 static int
dpll_msg_add_lock_status(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)220 dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll,
221 struct netlink_ext_ack *extack)
222 {
223 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
224 enum dpll_lock_status_error status_error = 0;
225 enum dpll_lock_status status;
226 int ret;
227
228 ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status,
229 &status_error, extack);
230 if (ret)
231 return ret;
232 if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status))
233 return -EMSGSIZE;
234 if (status_error &&
235 (status == DPLL_LOCK_STATUS_UNLOCKED ||
236 status == DPLL_LOCK_STATUS_HOLDOVER) &&
237 nla_put_u32(msg, DPLL_A_LOCK_STATUS_ERROR, status_error))
238 return -EMSGSIZE;
239
240 return 0;
241 }
242
243 static int
dpll_msg_add_temp(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)244 dpll_msg_add_temp(struct sk_buff *msg, struct dpll_device *dpll,
245 struct netlink_ext_ack *extack)
246 {
247 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
248 s32 temp;
249 int ret;
250
251 if (!ops->temp_get)
252 return 0;
253 ret = ops->temp_get(dpll, dpll_priv(dpll), &temp, extack);
254 if (ret)
255 return ret;
256 if (nla_put_s32(msg, DPLL_A_TEMP, temp))
257 return -EMSGSIZE;
258
259 return 0;
260 }
261
262 static int
dpll_msg_add_clock_quality_level(struct sk_buff * msg,struct dpll_device * dpll,struct netlink_ext_ack * extack)263 dpll_msg_add_clock_quality_level(struct sk_buff *msg, struct dpll_device *dpll,
264 struct netlink_ext_ack *extack)
265 {
266 DECLARE_BITMAP(qls, DPLL_CLOCK_QUALITY_LEVEL_MAX + 1) = { 0 };
267 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
268 enum dpll_clock_quality_level ql;
269 int ret;
270
271 if (!ops->clock_quality_level_get)
272 return 0;
273 ret = ops->clock_quality_level_get(dpll, dpll_priv(dpll), qls, extack);
274 if (ret)
275 return ret;
276 for_each_set_bit(ql, qls, DPLL_CLOCK_QUALITY_LEVEL_MAX + 1)
277 if (nla_put_u32(msg, DPLL_A_CLOCK_QUALITY_LEVEL, ql))
278 return -EMSGSIZE;
279
280 return 0;
281 }
282
283 static int
dpll_msg_add_pin_prio(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)284 dpll_msg_add_pin_prio(struct sk_buff *msg, struct dpll_pin *pin,
285 struct dpll_pin_ref *ref,
286 struct netlink_ext_ack *extack)
287 {
288 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
289 struct dpll_device *dpll = ref->dpll;
290 u32 prio;
291 int ret;
292
293 if (!ops->prio_get)
294 return 0;
295 ret = ops->prio_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
296 dpll_priv(dpll), &prio, extack);
297 if (ret)
298 return ret;
299 if (nla_put_u32(msg, DPLL_A_PIN_PRIO, prio))
300 return -EMSGSIZE;
301
302 return 0;
303 }
304
305 static int
dpll_msg_add_pin_on_dpll_state(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)306 dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, struct dpll_pin *pin,
307 struct dpll_pin_ref *ref,
308 struct netlink_ext_ack *extack)
309 {
310 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
311 struct dpll_device *dpll = ref->dpll;
312 enum dpll_pin_state state;
313 int ret;
314
315 if (!ops->state_on_dpll_get)
316 return 0;
317 ret = ops->state_on_dpll_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
318 dpll, dpll_priv(dpll), &state, extack);
319 if (ret)
320 return ret;
321 if (nla_put_u32(msg, DPLL_A_PIN_STATE, state))
322 return -EMSGSIZE;
323
324 return 0;
325 }
326
327 static int
dpll_msg_add_pin_direction(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)328 dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
329 struct dpll_pin_ref *ref,
330 struct netlink_ext_ack *extack)
331 {
332 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
333 struct dpll_device *dpll = ref->dpll;
334 enum dpll_pin_direction direction;
335 int ret;
336
337 ret = ops->direction_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
338 dpll_priv(dpll), &direction, extack);
339 if (ret)
340 return ret;
341 if (nla_put_u32(msg, DPLL_A_PIN_DIRECTION, direction))
342 return -EMSGSIZE;
343
344 return 0;
345 }
346
347 static int
dpll_msg_add_pin_phase_adjust(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)348 dpll_msg_add_pin_phase_adjust(struct sk_buff *msg, struct dpll_pin *pin,
349 struct dpll_pin_ref *ref,
350 struct netlink_ext_ack *extack)
351 {
352 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
353 struct dpll_device *dpll = ref->dpll;
354 s32 phase_adjust;
355 int ret;
356
357 if (!ops->phase_adjust_get)
358 return 0;
359 ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
360 dpll, dpll_priv(dpll),
361 &phase_adjust, extack);
362 if (ret)
363 return ret;
364 if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST, phase_adjust))
365 return -EMSGSIZE;
366
367 return 0;
368 }
369
370 static int
dpll_msg_add_phase_offset(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)371 dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
372 struct dpll_pin_ref *ref,
373 struct netlink_ext_ack *extack)
374 {
375 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
376 struct dpll_device *dpll = ref->dpll;
377 s64 phase_offset;
378 int ret;
379
380 if (!ops->phase_offset_get)
381 return 0;
382 ret = ops->phase_offset_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
383 dpll, dpll_priv(dpll), &phase_offset,
384 extack);
385 if (ret)
386 return ret;
387 if (nla_put_64bit(msg, DPLL_A_PIN_PHASE_OFFSET, sizeof(phase_offset),
388 &phase_offset, DPLL_A_PIN_PAD))
389 return -EMSGSIZE;
390
391 return 0;
392 }
393
dpll_msg_add_ffo(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)394 static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
395 struct dpll_pin_ref *ref,
396 struct netlink_ext_ack *extack)
397 {
398 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
399 struct dpll_device *dpll = ref->dpll;
400 s64 ffo;
401 int ret;
402
403 if (!ops->ffo_get)
404 return 0;
405 ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
406 dpll, dpll_priv(dpll), &ffo, extack);
407 if (ret) {
408 if (ret == -ENODATA)
409 return 0;
410 return ret;
411 }
412 /* Put the FFO value in PPM to preserve compatibility with older
413 * programs.
414 */
415 ret = nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
416 div_s64(ffo, 1000000));
417 if (ret)
418 return -EMSGSIZE;
419 return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
420 ffo);
421 }
422
dpll_msg_add_measured_freq(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)423 static int dpll_msg_add_measured_freq(struct sk_buff *msg, struct dpll_pin *pin,
424 struct dpll_pin_ref *ref,
425 struct netlink_ext_ack *extack)
426 {
427 const struct dpll_device_ops *dev_ops = dpll_device_ops(ref->dpll);
428 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
429 struct dpll_device *dpll = ref->dpll;
430 enum dpll_feature_state state;
431 u64 measured_freq;
432 int ret;
433
434 if (!ops->measured_freq_get)
435 return 0;
436 ret = dev_ops->freq_monitor_get(dpll, dpll_priv(dpll),
437 &state, extack);
438 if (ret)
439 return ret;
440 if (state == DPLL_FEATURE_STATE_DISABLE)
441 return 0;
442 ret = ops->measured_freq_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
443 dpll, dpll_priv(dpll), &measured_freq,
444 extack);
445 if (ret)
446 return ret;
447 if (nla_put_64bit(msg, DPLL_A_PIN_MEASURED_FREQUENCY,
448 sizeof(measured_freq), &measured_freq,
449 DPLL_A_PIN_PAD))
450 return -EMSGSIZE;
451
452 return 0;
453 }
454
455 static int
dpll_msg_add_pin_freq(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)456 dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
457 struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
458 {
459 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
460 struct dpll_device *dpll = ref->dpll;
461 struct nlattr *nest;
462 int fs, ret;
463 u64 freq;
464
465 if (!ops->frequency_get)
466 return 0;
467 ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
468 dpll_priv(dpll), &freq, extack);
469 if (ret)
470 return ret;
471 if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq,
472 DPLL_A_PIN_PAD))
473 return -EMSGSIZE;
474 for (fs = 0; fs < pin->prop.freq_supported_num; fs++) {
475 nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED);
476 if (!nest)
477 return -EMSGSIZE;
478 freq = pin->prop.freq_supported[fs].min;
479 if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq),
480 &freq, DPLL_A_PIN_PAD)) {
481 nla_nest_cancel(msg, nest);
482 return -EMSGSIZE;
483 }
484 freq = pin->prop.freq_supported[fs].max;
485 if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq),
486 &freq, DPLL_A_PIN_PAD)) {
487 nla_nest_cancel(msg, nest);
488 return -EMSGSIZE;
489 }
490 nla_nest_end(msg, nest);
491 }
492
493 return 0;
494 }
495
496 static int
dpll_msg_add_pin_esync(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)497 dpll_msg_add_pin_esync(struct sk_buff *msg, struct dpll_pin *pin,
498 struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
499 {
500 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
501 struct dpll_device *dpll = ref->dpll;
502 struct dpll_pin_esync esync;
503 struct nlattr *nest;
504 int ret, i;
505
506 if (!ops->esync_get)
507 return 0;
508 ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
509 dpll_priv(dpll), &esync, extack);
510 if (ret == -EOPNOTSUPP)
511 return 0;
512 else if (ret)
513 return ret;
514 if (nla_put_64bit(msg, DPLL_A_PIN_ESYNC_FREQUENCY, sizeof(esync.freq),
515 &esync.freq, DPLL_A_PIN_PAD))
516 return -EMSGSIZE;
517 if (nla_put_u32(msg, DPLL_A_PIN_ESYNC_PULSE, esync.pulse))
518 return -EMSGSIZE;
519 for (i = 0; i < esync.range_num; i++) {
520 nest = nla_nest_start(msg,
521 DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED);
522 if (!nest)
523 return -EMSGSIZE;
524 if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN,
525 sizeof(esync.range[i].min),
526 &esync.range[i].min, DPLL_A_PIN_PAD))
527 goto nest_cancel;
528 if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX,
529 sizeof(esync.range[i].max),
530 &esync.range[i].max, DPLL_A_PIN_PAD))
531 goto nest_cancel;
532 nla_nest_end(msg, nest);
533 }
534 return 0;
535
536 nest_cancel:
537 nla_nest_cancel(msg, nest);
538 return -EMSGSIZE;
539 }
540
541 static int
dpll_msg_add_pin_ref_sync(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * ref,struct netlink_ext_ack * extack)542 dpll_msg_add_pin_ref_sync(struct sk_buff *msg, struct dpll_pin *pin,
543 struct dpll_pin_ref *ref,
544 struct netlink_ext_ack *extack)
545 {
546 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
547 struct dpll_device *dpll = ref->dpll;
548 void *pin_priv, *ref_sync_pin_priv;
549 struct dpll_pin *ref_sync_pin;
550 enum dpll_pin_state state;
551 struct nlattr *nest;
552 unsigned long index;
553 int ret;
554
555 pin_priv = dpll_pin_on_dpll_priv(dpll, pin);
556 xa_for_each(&pin->ref_sync_pins, index, ref_sync_pin) {
557 if (!dpll_pin_available(ref_sync_pin))
558 continue;
559 ref_sync_pin_priv = dpll_pin_on_dpll_priv(dpll, ref_sync_pin);
560 if (WARN_ON(!ops->ref_sync_get))
561 return -EOPNOTSUPP;
562 ret = ops->ref_sync_get(pin, pin_priv, ref_sync_pin,
563 ref_sync_pin_priv, &state, extack);
564 if (ret)
565 return ret;
566 nest = nla_nest_start(msg, DPLL_A_PIN_REFERENCE_SYNC);
567 if (!nest)
568 return -EMSGSIZE;
569 if (nla_put_s32(msg, DPLL_A_PIN_ID, ref_sync_pin->id))
570 goto nest_cancel;
571 if (nla_put_s32(msg, DPLL_A_PIN_STATE, state))
572 goto nest_cancel;
573 nla_nest_end(msg, nest);
574 }
575 return 0;
576
577 nest_cancel:
578 nla_nest_cancel(msg, nest);
579 return -EMSGSIZE;
580 }
581
dpll_pin_is_freq_supported(struct dpll_pin * pin,u32 freq)582 static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
583 {
584 int fs;
585
586 for (fs = 0; fs < pin->prop.freq_supported_num; fs++)
587 if (freq >= pin->prop.freq_supported[fs].min &&
588 freq <= pin->prop.freq_supported[fs].max)
589 return true;
590 return false;
591 }
592
593 static int
dpll_msg_add_pin_parents(struct sk_buff * msg,struct dpll_pin * pin,struct dpll_pin_ref * dpll_ref,struct netlink_ext_ack * extack)594 dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin,
595 struct dpll_pin_ref *dpll_ref,
596 struct netlink_ext_ack *extack)
597 {
598 enum dpll_pin_state state;
599 struct dpll_pin_ref *ref;
600 struct dpll_pin *ppin;
601 struct nlattr *nest;
602 unsigned long index;
603 int ret;
604
605 xa_for_each(&pin->parent_refs, index, ref) {
606 const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
607 void *parent_priv;
608
609 ppin = ref->pin;
610 parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
611 ret = ops->state_on_pin_get(pin,
612 dpll_pin_on_pin_priv(ppin, pin),
613 ppin, parent_priv, &state, extack);
614 if (ret)
615 return ret;
616 nest = nla_nest_start(msg, DPLL_A_PIN_PARENT_PIN);
617 if (!nest)
618 return -EMSGSIZE;
619 ret = dpll_msg_add_dev_parent_handle(msg, ppin->id);
620 if (ret)
621 goto nest_cancel;
622 if (nla_put_u32(msg, DPLL_A_PIN_STATE, state)) {
623 ret = -EMSGSIZE;
624 goto nest_cancel;
625 }
626 nla_nest_end(msg, nest);
627 }
628
629 return 0;
630
631 nest_cancel:
632 nla_nest_cancel(msg, nest);
633 return ret;
634 }
635
636 static int
dpll_msg_add_pin_dplls(struct sk_buff * msg,struct dpll_pin * pin,struct netlink_ext_ack * extack)637 dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
638 struct netlink_ext_ack *extack)
639 {
640 struct dpll_pin_ref *ref;
641 struct nlattr *attr;
642 unsigned long index;
643 int ret;
644
645 xa_for_each(&pin->dpll_refs, index, ref) {
646 attr = nla_nest_start(msg, DPLL_A_PIN_PARENT_DEVICE);
647 if (!attr)
648 return -EMSGSIZE;
649 ret = dpll_msg_add_dev_parent_handle(msg, ref->dpll->id);
650 if (ret)
651 goto nest_cancel;
652 ret = dpll_msg_add_pin_on_dpll_state(msg, pin, ref, extack);
653 if (ret)
654 goto nest_cancel;
655 ret = dpll_msg_add_pin_prio(msg, pin, ref, extack);
656 if (ret)
657 goto nest_cancel;
658 ret = dpll_msg_add_pin_direction(msg, pin, ref, extack);
659 if (ret)
660 goto nest_cancel;
661 ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
662 if (ret)
663 goto nest_cancel;
664 nla_nest_end(msg, attr);
665 }
666
667 return 0;
668
669 nest_cancel:
670 nla_nest_end(msg, attr);
671 return ret;
672 }
673
674 static int
dpll_cmd_pin_get_one(struct sk_buff * msg,struct dpll_pin * pin,struct netlink_ext_ack * extack)675 dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
676 struct netlink_ext_ack *extack)
677 {
678 const struct dpll_pin_properties *prop = &pin->prop;
679 struct dpll_pin_ref *ref;
680 int ret;
681
682 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
683 ASSERT_NOT_NULL(ref);
684
685 ret = dpll_msg_add_pin_handle(msg, pin);
686 if (ret)
687 return ret;
688 if (nla_put_string(msg, DPLL_A_PIN_MODULE_NAME,
689 module_name(pin->module)))
690 return -EMSGSIZE;
691 if (nla_put_64bit(msg, DPLL_A_PIN_CLOCK_ID, sizeof(pin->clock_id),
692 &pin->clock_id, DPLL_A_PIN_PAD))
693 return -EMSGSIZE;
694 if (prop->board_label &&
695 nla_put_string(msg, DPLL_A_PIN_BOARD_LABEL, prop->board_label))
696 return -EMSGSIZE;
697 if (prop->panel_label &&
698 nla_put_string(msg, DPLL_A_PIN_PANEL_LABEL, prop->panel_label))
699 return -EMSGSIZE;
700 if (prop->package_label &&
701 nla_put_string(msg, DPLL_A_PIN_PACKAGE_LABEL,
702 prop->package_label))
703 return -EMSGSIZE;
704 if (nla_put_u32(msg, DPLL_A_PIN_TYPE, prop->type))
705 return -EMSGSIZE;
706 if (nla_put_u32(msg, DPLL_A_PIN_CAPABILITIES, prop->capabilities))
707 return -EMSGSIZE;
708 ret = dpll_msg_add_pin_freq(msg, pin, ref, extack);
709 if (ret)
710 return ret;
711 if (prop->phase_gran &&
712 nla_put_u32(msg, DPLL_A_PIN_PHASE_ADJUST_GRAN,
713 prop->phase_gran))
714 return -EMSGSIZE;
715 if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MIN,
716 prop->phase_range.min))
717 return -EMSGSIZE;
718 if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MAX,
719 prop->phase_range.max))
720 return -EMSGSIZE;
721 ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
722 if (ret)
723 return ret;
724 ret = dpll_msg_add_ffo(msg, pin, ref, extack);
725 if (ret)
726 return ret;
727 ret = dpll_msg_add_measured_freq(msg, pin, ref, extack);
728 if (ret)
729 return ret;
730 ret = dpll_msg_add_pin_esync(msg, pin, ref, extack);
731 if (ret)
732 return ret;
733 if (!xa_empty(&pin->ref_sync_pins))
734 ret = dpll_msg_add_pin_ref_sync(msg, pin, ref, extack);
735 if (ret)
736 return ret;
737 if (xa_empty(&pin->parent_refs))
738 ret = dpll_msg_add_pin_dplls(msg, pin, extack);
739 else
740 ret = dpll_msg_add_pin_parents(msg, pin, ref, extack);
741
742 return ret;
743 }
744
745 static int
dpll_device_get_one(struct dpll_device * dpll,struct sk_buff * msg,struct netlink_ext_ack * extack)746 dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
747 struct netlink_ext_ack *extack)
748 {
749 int ret;
750
751 ret = dpll_msg_add_dev_handle(msg, dpll);
752 if (ret)
753 return ret;
754 if (nla_put_string(msg, DPLL_A_MODULE_NAME, module_name(dpll->module)))
755 return -EMSGSIZE;
756 if (nla_put_64bit(msg, DPLL_A_CLOCK_ID, sizeof(dpll->clock_id),
757 &dpll->clock_id, DPLL_A_PAD))
758 return -EMSGSIZE;
759 ret = dpll_msg_add_temp(msg, dpll, extack);
760 if (ret)
761 return ret;
762 ret = dpll_msg_add_lock_status(msg, dpll, extack);
763 if (ret)
764 return ret;
765 ret = dpll_msg_add_clock_quality_level(msg, dpll, extack);
766 if (ret)
767 return ret;
768 ret = dpll_msg_add_mode(msg, dpll, extack);
769 if (ret)
770 return ret;
771 ret = dpll_msg_add_mode_supported(msg, dpll, extack);
772 if (ret)
773 return ret;
774 if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type))
775 return -EMSGSIZE;
776 ret = dpll_msg_add_phase_offset_monitor(msg, dpll, extack);
777 if (ret)
778 return ret;
779 ret = dpll_msg_add_phase_offset_avg_factor(msg, dpll, extack);
780 if (ret)
781 return ret;
782 ret = dpll_msg_add_freq_monitor(msg, dpll, extack);
783 if (ret)
784 return ret;
785
786 return 0;
787 }
788
789 static int
dpll_device_event_send(enum dpll_cmd event,struct dpll_device * dpll)790 dpll_device_event_send(enum dpll_cmd event, struct dpll_device *dpll)
791 {
792 struct sk_buff *msg;
793 int ret = -ENOMEM;
794 void *hdr;
795
796 if (WARN_ON(!xa_get_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED)))
797 return -ENODEV;
798 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
799 if (!msg)
800 return -ENOMEM;
801 hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event);
802 if (!hdr)
803 goto err_free_msg;
804 ret = dpll_device_get_one(dpll, msg, NULL);
805 if (ret)
806 goto err_cancel_msg;
807 genlmsg_end(msg, hdr);
808 genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL);
809
810 return 0;
811
812 err_cancel_msg:
813 genlmsg_cancel(msg, hdr);
814 err_free_msg:
815 nlmsg_free(msg);
816
817 return ret;
818 }
819
dpll_device_create_ntf(struct dpll_device * dpll)820 int dpll_device_create_ntf(struct dpll_device *dpll)
821 {
822 dpll_device_notify(dpll, DPLL_DEVICE_CREATED);
823 return dpll_device_event_send(DPLL_CMD_DEVICE_CREATE_NTF, dpll);
824 }
825
dpll_device_delete_ntf(struct dpll_device * dpll)826 int dpll_device_delete_ntf(struct dpll_device *dpll)
827 {
828 dpll_device_notify(dpll, DPLL_DEVICE_DELETED);
829 return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll);
830 }
831
832 /**
833 * __dpll_device_change_ntf - notify that the dpll device has been changed
834 * @dpll: registered dpll pointer
835 *
836 * Context: caller must hold dpll_lock. Suitable for use inside device
837 * callbacks which are already invoked under dpll_lock.
838 * Return: 0 if succeeds, error code otherwise.
839 */
__dpll_device_change_ntf(struct dpll_device * dpll)840 int __dpll_device_change_ntf(struct dpll_device *dpll)
841 {
842 lockdep_assert_held(&dpll_lock);
843 dpll_device_notify(dpll, DPLL_DEVICE_CHANGED);
844 return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll);
845 }
846 EXPORT_SYMBOL_GPL(__dpll_device_change_ntf);
847
848 /**
849 * dpll_device_change_ntf - notify that the dpll device has been changed
850 * @dpll: registered dpll pointer
851 *
852 * Context: acquires and holds a dpll_lock.
853 * Return: 0 if succeeds, error code otherwise.
854 */
dpll_device_change_ntf(struct dpll_device * dpll)855 int dpll_device_change_ntf(struct dpll_device *dpll)
856 {
857 int ret;
858
859 mutex_lock(&dpll_lock);
860 ret = __dpll_device_change_ntf(dpll);
861 mutex_unlock(&dpll_lock);
862
863 return ret;
864 }
865 EXPORT_SYMBOL_GPL(dpll_device_change_ntf);
866
867 static int
dpll_pin_event_send(enum dpll_cmd event,struct dpll_pin * pin)868 dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin)
869 {
870 struct sk_buff *msg;
871 int ret = -ENOMEM;
872 void *hdr;
873
874 if (!dpll_pin_available(pin))
875 return -ENODEV;
876
877 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
878 if (!msg)
879 return -ENOMEM;
880
881 hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event);
882 if (!hdr)
883 goto err_free_msg;
884 ret = dpll_cmd_pin_get_one(msg, pin, NULL);
885 if (ret)
886 goto err_cancel_msg;
887 genlmsg_end(msg, hdr);
888 genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL);
889
890 return 0;
891
892 err_cancel_msg:
893 genlmsg_cancel(msg, hdr);
894 err_free_msg:
895 nlmsg_free(msg);
896
897 return ret;
898 }
899
dpll_pin_create_ntf(struct dpll_pin * pin)900 int dpll_pin_create_ntf(struct dpll_pin *pin)
901 {
902 dpll_pin_notify(pin, DPLL_PIN_CREATED);
903 return dpll_pin_event_send(DPLL_CMD_PIN_CREATE_NTF, pin);
904 }
905
dpll_pin_delete_ntf(struct dpll_pin * pin)906 int dpll_pin_delete_ntf(struct dpll_pin *pin)
907 {
908 dpll_pin_notify(pin, DPLL_PIN_DELETED);
909 return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin);
910 }
911
912 /**
913 * __dpll_pin_change_ntf - notify that the pin has been changed
914 * @pin: registered pin pointer
915 *
916 * Context: caller must hold dpll_lock. Suitable for use inside pin
917 * callbacks which are already invoked under dpll_lock.
918 * Return: 0 if succeeds, error code otherwise.
919 */
__dpll_pin_change_ntf(struct dpll_pin * pin)920 int __dpll_pin_change_ntf(struct dpll_pin *pin)
921 {
922 lockdep_assert_held(&dpll_lock);
923 dpll_pin_notify(pin, DPLL_PIN_CHANGED);
924 return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin);
925 }
926 EXPORT_SYMBOL_GPL(__dpll_pin_change_ntf);
927
928 /**
929 * dpll_pin_change_ntf - notify that the pin has been changed
930 * @pin: registered pin pointer
931 *
932 * Context: acquires and holds a dpll_lock.
933 * Return: 0 if succeeds, error code otherwise.
934 */
dpll_pin_change_ntf(struct dpll_pin * pin)935 int dpll_pin_change_ntf(struct dpll_pin *pin)
936 {
937 int ret;
938
939 mutex_lock(&dpll_lock);
940 ret = __dpll_pin_change_ntf(pin);
941 mutex_unlock(&dpll_lock);
942
943 return ret;
944 }
945 EXPORT_SYMBOL_GPL(dpll_pin_change_ntf);
946
947 static int
dpll_mode_set(struct dpll_device * dpll,struct nlattr * a,struct netlink_ext_ack * extack)948 dpll_mode_set(struct dpll_device *dpll, struct nlattr *a,
949 struct netlink_ext_ack *extack)
950 {
951 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
952 DECLARE_BITMAP(modes, DPLL_MODE_MAX + 1) = { 0 };
953 enum dpll_mode mode = nla_get_u32(a), old_mode;
954 int ret;
955
956 if (!(ops->mode_set && ops->supported_modes_get)) {
957 NL_SET_ERR_MSG_ATTR(extack, a,
958 "dpll device does not support mode switch");
959 return -EOPNOTSUPP;
960 }
961
962 ret = ops->mode_get(dpll, dpll_priv(dpll), &old_mode, extack);
963 if (ret) {
964 NL_SET_ERR_MSG(extack, "unable to get current mode");
965 return ret;
966 }
967
968 if (mode == old_mode)
969 return 0;
970
971 ret = ops->supported_modes_get(dpll, dpll_priv(dpll), modes, extack);
972 if (ret) {
973 NL_SET_ERR_MSG(extack, "unable to get supported modes");
974 return ret;
975 }
976
977 if (!test_bit(mode, modes)) {
978 NL_SET_ERR_MSG(extack,
979 "dpll device does not support requested mode");
980 return -EINVAL;
981 }
982
983 return ops->mode_set(dpll, dpll_priv(dpll), mode, extack);
984 }
985
986 static int
dpll_phase_offset_monitor_set(struct dpll_device * dpll,struct nlattr * a,struct netlink_ext_ack * extack)987 dpll_phase_offset_monitor_set(struct dpll_device *dpll, struct nlattr *a,
988 struct netlink_ext_ack *extack)
989 {
990 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
991 enum dpll_feature_state state = nla_get_u32(a), old_state;
992 int ret;
993
994 if (!(ops->phase_offset_monitor_set && ops->phase_offset_monitor_get)) {
995 NL_SET_ERR_MSG_ATTR(extack, a, "dpll device not capable of phase offset monitor");
996 return -EOPNOTSUPP;
997 }
998 ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll), &old_state,
999 extack);
1000 if (ret) {
1001 NL_SET_ERR_MSG(extack, "unable to get current state of phase offset monitor");
1002 return ret;
1003 }
1004 if (state == old_state)
1005 return 0;
1006
1007 return ops->phase_offset_monitor_set(dpll, dpll_priv(dpll), state,
1008 extack);
1009 }
1010
1011 static int
dpll_phase_offset_avg_factor_set(struct dpll_device * dpll,struct nlattr * a,struct netlink_ext_ack * extack)1012 dpll_phase_offset_avg_factor_set(struct dpll_device *dpll, struct nlattr *a,
1013 struct netlink_ext_ack *extack)
1014 {
1015 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
1016 u32 factor = nla_get_u32(a);
1017
1018 if (!ops->phase_offset_avg_factor_set) {
1019 NL_SET_ERR_MSG_ATTR(extack, a,
1020 "device not capable of changing phase offset average factor");
1021 return -EOPNOTSUPP;
1022 }
1023
1024 return ops->phase_offset_avg_factor_set(dpll, dpll_priv(dpll), factor,
1025 extack);
1026 }
1027
1028 static int
dpll_freq_monitor_set(struct dpll_device * dpll,struct nlattr * a,struct netlink_ext_ack * extack)1029 dpll_freq_monitor_set(struct dpll_device *dpll, struct nlattr *a,
1030 struct netlink_ext_ack *extack)
1031 {
1032 const struct dpll_device_ops *ops = dpll_device_ops(dpll);
1033 enum dpll_feature_state state = nla_get_u32(a), old_state;
1034 int ret;
1035
1036 if (!(ops->freq_monitor_set && ops->freq_monitor_get)) {
1037 NL_SET_ERR_MSG_ATTR(extack, a,
1038 "dpll device not capable of frequency monitor");
1039 return -EOPNOTSUPP;
1040 }
1041 ret = ops->freq_monitor_get(dpll, dpll_priv(dpll), &old_state,
1042 extack);
1043 if (ret) {
1044 NL_SET_ERR_MSG(extack,
1045 "unable to get current state of frequency monitor");
1046 return ret;
1047 }
1048 if (state == old_state)
1049 return 0;
1050
1051 return ops->freq_monitor_set(dpll, dpll_priv(dpll), state, extack);
1052 }
1053
1054 static int
dpll_pin_freq_set(struct dpll_pin * pin,struct nlattr * a,struct netlink_ext_ack * extack)1055 dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
1056 struct netlink_ext_ack *extack)
1057 {
1058 u64 freq = nla_get_u64(a), old_freq;
1059 struct dpll_pin_ref *ref, *failed;
1060 const struct dpll_pin_ops *ops;
1061 struct dpll_device *dpll;
1062 unsigned long i;
1063 int ret;
1064
1065 if (!dpll_pin_is_freq_supported(pin, freq)) {
1066 NL_SET_ERR_MSG_ATTR(extack, a, "frequency is not supported by the device");
1067 return -EINVAL;
1068 }
1069
1070 xa_for_each(&pin->dpll_refs, i, ref) {
1071 ops = dpll_pin_ops(ref);
1072 if (!ops->frequency_set || !ops->frequency_get) {
1073 NL_SET_ERR_MSG(extack, "frequency set not supported by the device");
1074 return -EOPNOTSUPP;
1075 }
1076 }
1077 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
1078 ops = dpll_pin_ops(ref);
1079 dpll = ref->dpll;
1080 ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
1081 dpll_priv(dpll), &old_freq, extack);
1082 if (ret) {
1083 NL_SET_ERR_MSG(extack, "unable to get old frequency value");
1084 return ret;
1085 }
1086 if (freq == old_freq)
1087 return 0;
1088
1089 xa_for_each(&pin->dpll_refs, i, ref) {
1090 ops = dpll_pin_ops(ref);
1091 dpll = ref->dpll;
1092 ret = ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1093 dpll, dpll_priv(dpll), freq, extack);
1094 if (ret) {
1095 failed = ref;
1096 NL_SET_ERR_MSG_FMT(extack, "frequency set failed for dpll_id:%u",
1097 dpll->id);
1098 goto rollback;
1099 }
1100 }
1101 __dpll_pin_change_ntf(pin);
1102
1103 return 0;
1104
1105 rollback:
1106 xa_for_each(&pin->dpll_refs, i, ref) {
1107 if (ref == failed)
1108 break;
1109 ops = dpll_pin_ops(ref);
1110 dpll = ref->dpll;
1111 if (ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1112 dpll, dpll_priv(dpll), old_freq, extack))
1113 NL_SET_ERR_MSG(extack, "set frequency rollback failed");
1114 }
1115 return ret;
1116 }
1117
1118 static int
dpll_pin_esync_set(struct dpll_pin * pin,struct nlattr * a,struct netlink_ext_ack * extack)1119 dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a,
1120 struct netlink_ext_ack *extack)
1121 {
1122 struct dpll_pin_ref *ref, *failed;
1123 const struct dpll_pin_ops *ops;
1124 struct dpll_pin_esync esync;
1125 u64 freq = nla_get_u64(a);
1126 struct dpll_device *dpll;
1127 bool supported = false;
1128 unsigned long i;
1129 int ret;
1130
1131 xa_for_each(&pin->dpll_refs, i, ref) {
1132 ops = dpll_pin_ops(ref);
1133 if (!ops->esync_set || !ops->esync_get) {
1134 NL_SET_ERR_MSG(extack,
1135 "embedded sync feature is not supported by this device");
1136 return -EOPNOTSUPP;
1137 }
1138 }
1139 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
1140 ops = dpll_pin_ops(ref);
1141 dpll = ref->dpll;
1142 ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
1143 dpll_priv(dpll), &esync, extack);
1144 if (ret) {
1145 NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value");
1146 return ret;
1147 }
1148 if (freq == esync.freq)
1149 return 0;
1150 for (i = 0; i < esync.range_num; i++)
1151 if (freq <= esync.range[i].max && freq >= esync.range[i].min)
1152 supported = true;
1153 if (!supported) {
1154 NL_SET_ERR_MSG_ATTR(extack, a,
1155 "requested embedded sync frequency value is not supported by this device");
1156 return -EINVAL;
1157 }
1158
1159 xa_for_each(&pin->dpll_refs, i, ref) {
1160 void *pin_dpll_priv;
1161
1162 ops = dpll_pin_ops(ref);
1163 dpll = ref->dpll;
1164 pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
1165 ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
1166 freq, extack);
1167 if (ret) {
1168 failed = ref;
1169 NL_SET_ERR_MSG_FMT(extack,
1170 "embedded sync frequency set failed for dpll_id: %u",
1171 dpll->id);
1172 goto rollback;
1173 }
1174 }
1175 __dpll_pin_change_ntf(pin);
1176
1177 return 0;
1178
1179 rollback:
1180 xa_for_each(&pin->dpll_refs, i, ref) {
1181 void *pin_dpll_priv;
1182
1183 if (ref == failed)
1184 break;
1185 ops = dpll_pin_ops(ref);
1186 dpll = ref->dpll;
1187 pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
1188 if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
1189 esync.freq, extack))
1190 NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed");
1191 }
1192 return ret;
1193 }
1194
1195 static int
dpll_pin_ref_sync_state_set(struct dpll_pin * pin,unsigned long ref_sync_pin_idx,const enum dpll_pin_state state,struct netlink_ext_ack * extack)1196 dpll_pin_ref_sync_state_set(struct dpll_pin *pin,
1197 unsigned long ref_sync_pin_idx,
1198 const enum dpll_pin_state state,
1199 struct netlink_ext_ack *extack)
1200
1201 {
1202 struct dpll_pin_ref *ref, *failed;
1203 const struct dpll_pin_ops *ops;
1204 enum dpll_pin_state old_state;
1205 struct dpll_pin *ref_sync_pin;
1206 struct dpll_device *dpll;
1207 unsigned long i;
1208 int ret;
1209
1210 ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx,
1211 ULONG_MAX, XA_PRESENT);
1212 if (!ref_sync_pin) {
1213 NL_SET_ERR_MSG(extack, "reference sync pin not found");
1214 return -EINVAL;
1215 }
1216 if (!dpll_pin_available(ref_sync_pin)) {
1217 NL_SET_ERR_MSG(extack, "reference sync pin not available");
1218 return -EINVAL;
1219 }
1220 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
1221 ASSERT_NOT_NULL(ref);
1222 ops = dpll_pin_ops(ref);
1223 if (!ops->ref_sync_set || !ops->ref_sync_get) {
1224 NL_SET_ERR_MSG(extack, "reference sync not supported by this pin");
1225 return -EOPNOTSUPP;
1226 }
1227 dpll = ref->dpll;
1228 ret = ops->ref_sync_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
1229 ref_sync_pin,
1230 dpll_pin_on_dpll_priv(dpll, ref_sync_pin),
1231 &old_state, extack);
1232 if (ret) {
1233 NL_SET_ERR_MSG(extack, "unable to get old reference sync state");
1234 return ret;
1235 }
1236 if (state == old_state)
1237 return 0;
1238 xa_for_each(&pin->dpll_refs, i, ref) {
1239 ops = dpll_pin_ops(ref);
1240 dpll = ref->dpll;
1241 ret = ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1242 ref_sync_pin,
1243 dpll_pin_on_dpll_priv(dpll,
1244 ref_sync_pin),
1245 state, extack);
1246 if (ret) {
1247 failed = ref;
1248 NL_SET_ERR_MSG_FMT(extack, "reference sync set failed for dpll_id:%u",
1249 dpll->id);
1250 goto rollback;
1251 }
1252 }
1253 __dpll_pin_change_ntf(pin);
1254
1255 return 0;
1256
1257 rollback:
1258 xa_for_each(&pin->dpll_refs, i, ref) {
1259 if (ref == failed)
1260 break;
1261 ops = dpll_pin_ops(ref);
1262 dpll = ref->dpll;
1263 if (ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1264 ref_sync_pin,
1265 dpll_pin_on_dpll_priv(dpll, ref_sync_pin),
1266 old_state, extack))
1267 NL_SET_ERR_MSG(extack, "set reference sync rollback failed");
1268 }
1269 return ret;
1270 }
1271
1272 static int
dpll_pin_ref_sync_set(struct dpll_pin * pin,struct nlattr * nest,struct netlink_ext_ack * extack)1273 dpll_pin_ref_sync_set(struct dpll_pin *pin, struct nlattr *nest,
1274 struct netlink_ext_ack *extack)
1275 {
1276 struct nlattr *tb[DPLL_A_PIN_MAX + 1];
1277 enum dpll_pin_state state;
1278 u32 sync_pin_id;
1279
1280 nla_parse_nested(tb, DPLL_A_PIN_MAX, nest,
1281 dpll_reference_sync_nl_policy, extack);
1282 if (!tb[DPLL_A_PIN_ID]) {
1283 NL_SET_ERR_MSG(extack, "sync pin id expected");
1284 return -EINVAL;
1285 }
1286 sync_pin_id = nla_get_u32(tb[DPLL_A_PIN_ID]);
1287
1288 if (!tb[DPLL_A_PIN_STATE]) {
1289 NL_SET_ERR_MSG(extack, "sync pin state expected");
1290 return -EINVAL;
1291 }
1292 state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
1293
1294 return dpll_pin_ref_sync_state_set(pin, sync_pin_id, state, extack);
1295 }
1296
1297 static int
dpll_pin_on_pin_state_set(struct dpll_pin * pin,u32 parent_idx,enum dpll_pin_state state,struct netlink_ext_ack * extack)1298 dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
1299 enum dpll_pin_state state,
1300 struct netlink_ext_ack *extack)
1301 {
1302 struct dpll_pin_ref *parent_ref;
1303 const struct dpll_pin_ops *ops;
1304 struct dpll_pin_ref *dpll_ref;
1305 void *pin_priv, *parent_priv;
1306 struct dpll_pin *parent;
1307 unsigned long i;
1308 int ret;
1309
1310 if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
1311 pin->prop.capabilities)) {
1312 NL_SET_ERR_MSG(extack, "state changing is not allowed");
1313 return -EOPNOTSUPP;
1314 }
1315 parent = xa_load(&dpll_pin_xa, parent_idx);
1316 if (!parent)
1317 return -EINVAL;
1318 parent_ref = xa_load(&pin->parent_refs, parent->pin_idx);
1319 if (!parent_ref)
1320 return -EINVAL;
1321 xa_for_each(&parent->dpll_refs, i, dpll_ref) {
1322 ops = dpll_pin_ops(parent_ref);
1323 if (!ops->state_on_pin_set)
1324 return -EOPNOTSUPP;
1325 pin_priv = dpll_pin_on_pin_priv(parent, pin);
1326 parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, parent);
1327 ret = ops->state_on_pin_set(pin, pin_priv, parent, parent_priv,
1328 state, extack);
1329 if (ret)
1330 return ret;
1331 }
1332 __dpll_pin_change_ntf(pin);
1333
1334 return 0;
1335 }
1336
1337 static int
dpll_pin_state_set(struct dpll_device * dpll,struct dpll_pin * pin,enum dpll_pin_state state,struct netlink_ext_ack * extack)1338 dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
1339 enum dpll_pin_state state,
1340 struct netlink_ext_ack *extack)
1341 {
1342 const struct dpll_pin_ops *ops;
1343 struct dpll_pin_ref *ref;
1344 int ret;
1345
1346 if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
1347 pin->prop.capabilities)) {
1348 NL_SET_ERR_MSG(extack, "state changing is not allowed");
1349 return -EOPNOTSUPP;
1350 }
1351 ref = xa_load(&pin->dpll_refs, dpll->id);
1352 ASSERT_NOT_NULL(ref);
1353 ops = dpll_pin_ops(ref);
1354 if (!ops->state_on_dpll_set)
1355 return -EOPNOTSUPP;
1356 ret = ops->state_on_dpll_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1357 dpll, dpll_priv(dpll), state, extack);
1358 if (ret)
1359 return ret;
1360 __dpll_pin_change_ntf(pin);
1361
1362 return 0;
1363 }
1364
1365 static int
dpll_pin_prio_set(struct dpll_device * dpll,struct dpll_pin * pin,u32 prio,struct netlink_ext_ack * extack)1366 dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin,
1367 u32 prio, struct netlink_ext_ack *extack)
1368 {
1369 const struct dpll_pin_ops *ops;
1370 struct dpll_pin_ref *ref;
1371 int ret;
1372
1373 if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE &
1374 pin->prop.capabilities)) {
1375 NL_SET_ERR_MSG(extack, "prio changing is not allowed");
1376 return -EOPNOTSUPP;
1377 }
1378 ref = xa_load(&pin->dpll_refs, dpll->id);
1379 ASSERT_NOT_NULL(ref);
1380 ops = dpll_pin_ops(ref);
1381 if (!ops->prio_set)
1382 return -EOPNOTSUPP;
1383 ret = ops->prio_set(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
1384 dpll_priv(dpll), prio, extack);
1385 if (ret)
1386 return ret;
1387 __dpll_pin_change_ntf(pin);
1388
1389 return 0;
1390 }
1391
1392 static int
dpll_pin_direction_set(struct dpll_pin * pin,struct dpll_device * dpll,enum dpll_pin_direction direction,struct netlink_ext_ack * extack)1393 dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
1394 enum dpll_pin_direction direction,
1395 struct netlink_ext_ack *extack)
1396 {
1397 const struct dpll_pin_ops *ops;
1398 struct dpll_pin_ref *ref;
1399 int ret;
1400
1401 if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE &
1402 pin->prop.capabilities)) {
1403 NL_SET_ERR_MSG(extack, "direction changing is not allowed");
1404 return -EOPNOTSUPP;
1405 }
1406 ref = xa_load(&pin->dpll_refs, dpll->id);
1407 ASSERT_NOT_NULL(ref);
1408 ops = dpll_pin_ops(ref);
1409 if (!ops->direction_set)
1410 return -EOPNOTSUPP;
1411 ret = ops->direction_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1412 dpll, dpll_priv(dpll), direction, extack);
1413 if (ret)
1414 return ret;
1415 __dpll_pin_change_ntf(pin);
1416
1417 return 0;
1418 }
1419
1420 static int
dpll_pin_phase_adj_set(struct dpll_pin * pin,struct nlattr * phase_adj_attr,struct netlink_ext_ack * extack)1421 dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
1422 struct netlink_ext_ack *extack)
1423 {
1424 struct dpll_pin_ref *ref, *failed;
1425 const struct dpll_pin_ops *ops;
1426 s32 phase_adj, old_phase_adj;
1427 struct dpll_device *dpll;
1428 unsigned long i;
1429 int ret;
1430
1431 phase_adj = nla_get_s32(phase_adj_attr);
1432 if (phase_adj > pin->prop.phase_range.max ||
1433 phase_adj < pin->prop.phase_range.min) {
1434 NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr,
1435 "phase adjust value of out range");
1436 return -EINVAL;
1437 }
1438 if (pin->prop.phase_gran && phase_adj % (s32)pin->prop.phase_gran) {
1439 NL_SET_ERR_MSG_ATTR_FMT(extack, phase_adj_attr,
1440 "phase adjust value not multiple of %u",
1441 pin->prop.phase_gran);
1442 return -EINVAL;
1443 }
1444
1445 xa_for_each(&pin->dpll_refs, i, ref) {
1446 ops = dpll_pin_ops(ref);
1447 if (!ops->phase_adjust_set || !ops->phase_adjust_get) {
1448 NL_SET_ERR_MSG(extack, "phase adjust not supported");
1449 return -EOPNOTSUPP;
1450 }
1451 }
1452 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
1453 ops = dpll_pin_ops(ref);
1454 dpll = ref->dpll;
1455 ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
1456 dpll, dpll_priv(dpll), &old_phase_adj,
1457 extack);
1458 if (ret) {
1459 NL_SET_ERR_MSG(extack, "unable to get old phase adjust value");
1460 return ret;
1461 }
1462 if (phase_adj == old_phase_adj)
1463 return 0;
1464
1465 xa_for_each(&pin->dpll_refs, i, ref) {
1466 ops = dpll_pin_ops(ref);
1467 dpll = ref->dpll;
1468 ret = ops->phase_adjust_set(pin,
1469 dpll_pin_on_dpll_priv(dpll, pin),
1470 dpll, dpll_priv(dpll), phase_adj,
1471 extack);
1472 if (ret) {
1473 failed = ref;
1474 NL_SET_ERR_MSG_FMT(extack,
1475 "phase adjust set failed for dpll_id:%u",
1476 dpll->id);
1477 goto rollback;
1478 }
1479 }
1480 __dpll_pin_change_ntf(pin);
1481
1482 return 0;
1483
1484 rollback:
1485 xa_for_each(&pin->dpll_refs, i, ref) {
1486 if (ref == failed)
1487 break;
1488 ops = dpll_pin_ops(ref);
1489 dpll = ref->dpll;
1490 if (ops->phase_adjust_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
1491 dpll, dpll_priv(dpll), old_phase_adj,
1492 extack))
1493 NL_SET_ERR_MSG(extack, "set phase adjust rollback failed");
1494 }
1495 return ret;
1496 }
1497
1498 static int
dpll_pin_parent_device_set(struct dpll_pin * pin,struct nlattr * parent_nest,struct netlink_ext_ack * extack)1499 dpll_pin_parent_device_set(struct dpll_pin *pin, struct nlattr *parent_nest,
1500 struct netlink_ext_ack *extack)
1501 {
1502 struct nlattr *tb[DPLL_A_PIN_MAX + 1];
1503 enum dpll_pin_direction direction;
1504 enum dpll_pin_state state;
1505 struct dpll_pin_ref *ref;
1506 struct dpll_device *dpll;
1507 u32 pdpll_idx, prio;
1508 int ret;
1509
1510 nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest,
1511 dpll_pin_parent_device_nl_policy, extack);
1512 if (!tb[DPLL_A_PIN_PARENT_ID]) {
1513 NL_SET_ERR_MSG(extack, "device parent id expected");
1514 return -EINVAL;
1515 }
1516 pdpll_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
1517 dpll = xa_load(&dpll_device_xa, pdpll_idx);
1518 if (!dpll) {
1519 NL_SET_ERR_MSG(extack, "parent device not found");
1520 return -EINVAL;
1521 }
1522 ref = xa_load(&pin->dpll_refs, dpll->id);
1523 if (!ref) {
1524 NL_SET_ERR_MSG(extack, "pin not connected to given parent device");
1525 return -EINVAL;
1526 }
1527 if (tb[DPLL_A_PIN_STATE]) {
1528 state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
1529 ret = dpll_pin_state_set(dpll, pin, state, extack);
1530 if (ret)
1531 return ret;
1532 }
1533 if (tb[DPLL_A_PIN_PRIO]) {
1534 prio = nla_get_u32(tb[DPLL_A_PIN_PRIO]);
1535 ret = dpll_pin_prio_set(dpll, pin, prio, extack);
1536 if (ret)
1537 return ret;
1538 }
1539 if (tb[DPLL_A_PIN_DIRECTION]) {
1540 direction = nla_get_u32(tb[DPLL_A_PIN_DIRECTION]);
1541 ret = dpll_pin_direction_set(pin, dpll, direction, extack);
1542 if (ret)
1543 return ret;
1544 }
1545 return 0;
1546 }
1547
1548 static int
dpll_pin_parent_pin_set(struct dpll_pin * pin,struct nlattr * parent_nest,struct netlink_ext_ack * extack)1549 dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
1550 struct netlink_ext_ack *extack)
1551 {
1552 struct nlattr *tb[DPLL_A_PIN_MAX + 1];
1553 u32 ppin_idx;
1554 int ret;
1555
1556 nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest,
1557 dpll_pin_parent_pin_nl_policy, extack);
1558 if (!tb[DPLL_A_PIN_PARENT_ID]) {
1559 NL_SET_ERR_MSG(extack, "device parent id expected");
1560 return -EINVAL;
1561 }
1562 ppin_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
1563
1564 if (tb[DPLL_A_PIN_STATE]) {
1565 enum dpll_pin_state state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
1566
1567 ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
1568 if (ret)
1569 return ret;
1570 }
1571
1572 return 0;
1573 }
1574
1575 static int
dpll_pin_set_from_nlattr(struct dpll_pin * pin,struct genl_info * info)1576 dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info)
1577 {
1578 struct nlattr *a;
1579 int rem, ret;
1580
1581 nla_for_each_attr(a, genlmsg_data(info->genlhdr),
1582 genlmsg_len(info->genlhdr), rem) {
1583 switch (nla_type(a)) {
1584 case DPLL_A_PIN_FREQUENCY:
1585 ret = dpll_pin_freq_set(pin, a, info->extack);
1586 if (ret)
1587 return ret;
1588 break;
1589 case DPLL_A_PIN_PHASE_ADJUST:
1590 ret = dpll_pin_phase_adj_set(pin, a, info->extack);
1591 if (ret)
1592 return ret;
1593 break;
1594 case DPLL_A_PIN_PARENT_DEVICE:
1595 ret = dpll_pin_parent_device_set(pin, a, info->extack);
1596 if (ret)
1597 return ret;
1598 break;
1599 case DPLL_A_PIN_PARENT_PIN:
1600 ret = dpll_pin_parent_pin_set(pin, a, info->extack);
1601 if (ret)
1602 return ret;
1603 break;
1604 case DPLL_A_PIN_ESYNC_FREQUENCY:
1605 ret = dpll_pin_esync_set(pin, a, info->extack);
1606 if (ret)
1607 return ret;
1608 break;
1609 case DPLL_A_PIN_REFERENCE_SYNC:
1610 ret = dpll_pin_ref_sync_set(pin, a, info->extack);
1611 if (ret)
1612 return ret;
1613 break;
1614 }
1615 }
1616
1617 return 0;
1618 }
1619
1620 static struct dpll_pin *
dpll_pin_find(u64 clock_id,struct nlattr * mod_name_attr,enum dpll_pin_type type,struct nlattr * board_label,struct nlattr * panel_label,struct nlattr * package_label,struct netlink_ext_ack * extack)1621 dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
1622 enum dpll_pin_type type, struct nlattr *board_label,
1623 struct nlattr *panel_label, struct nlattr *package_label,
1624 struct netlink_ext_ack *extack)
1625 {
1626 bool board_match, panel_match, package_match;
1627 struct dpll_pin *pin_match = NULL, *pin;
1628 const struct dpll_pin_properties *prop;
1629 bool cid_match, mod_match, type_match;
1630 unsigned long i;
1631
1632 xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) {
1633 prop = &pin->prop;
1634 cid_match = clock_id ? pin->clock_id == clock_id : true;
1635 mod_match = mod_name_attr && module_name(pin->module) ?
1636 !nla_strcmp(mod_name_attr,
1637 module_name(pin->module)) : true;
1638 type_match = type ? prop->type == type : true;
1639 board_match = board_label ? (prop->board_label ?
1640 !nla_strcmp(board_label, prop->board_label) : false) :
1641 true;
1642 panel_match = panel_label ? (prop->panel_label ?
1643 !nla_strcmp(panel_label, prop->panel_label) : false) :
1644 true;
1645 package_match = package_label ? (prop->package_label ?
1646 !nla_strcmp(package_label, prop->package_label) :
1647 false) : true;
1648 if (cid_match && mod_match && type_match && board_match &&
1649 panel_match && package_match) {
1650 if (pin_match) {
1651 NL_SET_ERR_MSG(extack, "multiple matches");
1652 return ERR_PTR(-EINVAL);
1653 }
1654 pin_match = pin;
1655 }
1656 }
1657 if (!pin_match) {
1658 NL_SET_ERR_MSG(extack, "not found");
1659 return ERR_PTR(-ENODEV);
1660 }
1661 return pin_match;
1662 }
1663
dpll_pin_find_from_nlattr(struct genl_info * info)1664 static struct dpll_pin *dpll_pin_find_from_nlattr(struct genl_info *info)
1665 {
1666 struct nlattr *attr, *mod_name_attr = NULL, *board_label_attr = NULL,
1667 *panel_label_attr = NULL, *package_label_attr = NULL;
1668 enum dpll_pin_type type = 0;
1669 u64 clock_id = 0;
1670 int rem = 0;
1671
1672 nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
1673 genlmsg_len(info->genlhdr), rem) {
1674 switch (nla_type(attr)) {
1675 case DPLL_A_PIN_CLOCK_ID:
1676 if (clock_id)
1677 goto duplicated_attr;
1678 clock_id = nla_get_u64(attr);
1679 break;
1680 case DPLL_A_PIN_MODULE_NAME:
1681 if (mod_name_attr)
1682 goto duplicated_attr;
1683 mod_name_attr = attr;
1684 break;
1685 case DPLL_A_PIN_TYPE:
1686 if (type)
1687 goto duplicated_attr;
1688 type = nla_get_u32(attr);
1689 break;
1690 case DPLL_A_PIN_BOARD_LABEL:
1691 if (board_label_attr)
1692 goto duplicated_attr;
1693 board_label_attr = attr;
1694 break;
1695 case DPLL_A_PIN_PANEL_LABEL:
1696 if (panel_label_attr)
1697 goto duplicated_attr;
1698 panel_label_attr = attr;
1699 break;
1700 case DPLL_A_PIN_PACKAGE_LABEL:
1701 if (package_label_attr)
1702 goto duplicated_attr;
1703 package_label_attr = attr;
1704 break;
1705 default:
1706 break;
1707 }
1708 }
1709 if (!(clock_id || mod_name_attr || board_label_attr ||
1710 panel_label_attr || package_label_attr)) {
1711 NL_SET_ERR_MSG(info->extack, "missing attributes");
1712 return ERR_PTR(-EINVAL);
1713 }
1714 return dpll_pin_find(clock_id, mod_name_attr, type, board_label_attr,
1715 panel_label_attr, package_label_attr,
1716 info->extack);
1717 duplicated_attr:
1718 NL_SET_ERR_MSG(info->extack, "duplicated attribute");
1719 return ERR_PTR(-EINVAL);
1720 }
1721
dpll_nl_pin_id_get_doit(struct sk_buff * skb,struct genl_info * info)1722 int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
1723 {
1724 struct dpll_pin *pin;
1725 struct sk_buff *msg;
1726 struct nlattr *hdr;
1727 int ret;
1728
1729 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1730 if (!msg)
1731 return -ENOMEM;
1732 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
1733 DPLL_CMD_PIN_ID_GET);
1734 if (!hdr) {
1735 nlmsg_free(msg);
1736 return -EMSGSIZE;
1737 }
1738 pin = dpll_pin_find_from_nlattr(info);
1739 if (IS_ERR(pin)) {
1740 nlmsg_free(msg);
1741 return PTR_ERR(pin);
1742 }
1743 if (!dpll_pin_available(pin)) {
1744 nlmsg_free(msg);
1745 return -ENODEV;
1746 }
1747 ret = dpll_msg_add_pin_handle(msg, pin);
1748 if (ret) {
1749 nlmsg_free(msg);
1750 return ret;
1751 }
1752 genlmsg_end(msg, hdr);
1753
1754 return genlmsg_reply(msg, info);
1755 }
1756
dpll_nl_pin_get_doit(struct sk_buff * skb,struct genl_info * info)1757 int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info)
1758 {
1759 struct dpll_pin *pin = info->user_ptr[0];
1760 struct sk_buff *msg;
1761 struct nlattr *hdr;
1762 int ret;
1763
1764 if (!pin)
1765 return -ENODEV;
1766 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1767 if (!msg)
1768 return -ENOMEM;
1769 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
1770 DPLL_CMD_PIN_GET);
1771 if (!hdr) {
1772 nlmsg_free(msg);
1773 return -EMSGSIZE;
1774 }
1775 ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
1776 if (ret) {
1777 nlmsg_free(msg);
1778 return ret;
1779 }
1780 genlmsg_end(msg, hdr);
1781
1782 return genlmsg_reply(msg, info);
1783 }
1784
dpll_nl_pin_get_dumpit(struct sk_buff * skb,struct netlink_callback * cb)1785 int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
1786 {
1787 struct dpll_dump_ctx *ctx = dpll_dump_context(cb);
1788 struct dpll_pin *pin;
1789 struct nlattr *hdr;
1790 unsigned long i;
1791 int ret = 0;
1792
1793 mutex_lock(&dpll_lock);
1794 xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED,
1795 ctx->idx) {
1796 if (!dpll_pin_available(pin))
1797 continue;
1798 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
1799 cb->nlh->nlmsg_seq,
1800 &dpll_nl_family, NLM_F_MULTI,
1801 DPLL_CMD_PIN_GET);
1802 if (!hdr) {
1803 ret = -EMSGSIZE;
1804 break;
1805 }
1806 ret = dpll_cmd_pin_get_one(skb, pin, cb->extack);
1807 if (ret) {
1808 genlmsg_cancel(skb, hdr);
1809 break;
1810 }
1811 genlmsg_end(skb, hdr);
1812 }
1813 mutex_unlock(&dpll_lock);
1814
1815 if (ret == -EMSGSIZE) {
1816 ctx->idx = i;
1817 return skb->len;
1818 }
1819 return ret;
1820 }
1821
dpll_nl_pin_set_doit(struct sk_buff * skb,struct genl_info * info)1822 int dpll_nl_pin_set_doit(struct sk_buff *skb, struct genl_info *info)
1823 {
1824 struct dpll_pin *pin = info->user_ptr[0];
1825
1826 return dpll_pin_set_from_nlattr(pin, info);
1827 }
1828
1829 static struct dpll_device *
dpll_device_find(u64 clock_id,struct nlattr * mod_name_attr,enum dpll_type type,struct netlink_ext_ack * extack)1830 dpll_device_find(u64 clock_id, struct nlattr *mod_name_attr,
1831 enum dpll_type type, struct netlink_ext_ack *extack)
1832 {
1833 struct dpll_device *dpll_match = NULL, *dpll;
1834 bool cid_match, mod_match, type_match;
1835 unsigned long i;
1836
1837 xa_for_each_marked(&dpll_device_xa, i, dpll, DPLL_REGISTERED) {
1838 cid_match = clock_id ? dpll->clock_id == clock_id : true;
1839 mod_match = mod_name_attr ? (module_name(dpll->module) ?
1840 !nla_strcmp(mod_name_attr,
1841 module_name(dpll->module)) : false) : true;
1842 type_match = type ? dpll->type == type : true;
1843 if (cid_match && mod_match && type_match) {
1844 if (dpll_match) {
1845 NL_SET_ERR_MSG(extack, "multiple matches");
1846 return ERR_PTR(-EINVAL);
1847 }
1848 dpll_match = dpll;
1849 }
1850 }
1851 if (!dpll_match) {
1852 NL_SET_ERR_MSG(extack, "not found");
1853 return ERR_PTR(-ENODEV);
1854 }
1855
1856 return dpll_match;
1857 }
1858
1859 static struct dpll_device *
dpll_device_find_from_nlattr(struct genl_info * info)1860 dpll_device_find_from_nlattr(struct genl_info *info)
1861 {
1862 struct nlattr *attr, *mod_name_attr = NULL;
1863 enum dpll_type type = 0;
1864 u64 clock_id = 0;
1865 int rem = 0;
1866
1867 nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
1868 genlmsg_len(info->genlhdr), rem) {
1869 switch (nla_type(attr)) {
1870 case DPLL_A_CLOCK_ID:
1871 if (clock_id)
1872 goto duplicated_attr;
1873 clock_id = nla_get_u64(attr);
1874 break;
1875 case DPLL_A_MODULE_NAME:
1876 if (mod_name_attr)
1877 goto duplicated_attr;
1878 mod_name_attr = attr;
1879 break;
1880 case DPLL_A_TYPE:
1881 if (type)
1882 goto duplicated_attr;
1883 type = nla_get_u32(attr);
1884 break;
1885 default:
1886 break;
1887 }
1888 }
1889 if (!clock_id && !mod_name_attr && !type) {
1890 NL_SET_ERR_MSG(info->extack, "missing attributes");
1891 return ERR_PTR(-EINVAL);
1892 }
1893 return dpll_device_find(clock_id, mod_name_attr, type, info->extack);
1894 duplicated_attr:
1895 NL_SET_ERR_MSG(info->extack, "duplicated attribute");
1896 return ERR_PTR(-EINVAL);
1897 }
1898
dpll_nl_device_id_get_doit(struct sk_buff * skb,struct genl_info * info)1899 int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
1900 {
1901 struct dpll_device *dpll;
1902 struct sk_buff *msg;
1903 struct nlattr *hdr;
1904 int ret;
1905
1906 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1907 if (!msg)
1908 return -ENOMEM;
1909 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
1910 DPLL_CMD_DEVICE_ID_GET);
1911 if (!hdr) {
1912 nlmsg_free(msg);
1913 return -EMSGSIZE;
1914 }
1915
1916 dpll = dpll_device_find_from_nlattr(info);
1917 if (IS_ERR(dpll)) {
1918 nlmsg_free(msg);
1919 return PTR_ERR(dpll);
1920 }
1921 ret = dpll_msg_add_dev_handle(msg, dpll);
1922 if (ret) {
1923 nlmsg_free(msg);
1924 return ret;
1925 }
1926 genlmsg_end(msg, hdr);
1927
1928 return genlmsg_reply(msg, info);
1929 }
1930
dpll_nl_device_get_doit(struct sk_buff * skb,struct genl_info * info)1931 int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
1932 {
1933 struct dpll_device *dpll = info->user_ptr[0];
1934 struct sk_buff *msg;
1935 struct nlattr *hdr;
1936 int ret;
1937
1938 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1939 if (!msg)
1940 return -ENOMEM;
1941 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
1942 DPLL_CMD_DEVICE_GET);
1943 if (!hdr) {
1944 nlmsg_free(msg);
1945 return -EMSGSIZE;
1946 }
1947
1948 ret = dpll_device_get_one(dpll, msg, info->extack);
1949 if (ret) {
1950 nlmsg_free(msg);
1951 return ret;
1952 }
1953 genlmsg_end(msg, hdr);
1954
1955 return genlmsg_reply(msg, info);
1956 }
1957
1958 static int
dpll_set_from_nlattr(struct dpll_device * dpll,struct genl_info * info)1959 dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info)
1960 {
1961 struct nlattr *a;
1962 int rem, ret;
1963
1964 nla_for_each_attr(a, genlmsg_data(info->genlhdr),
1965 genlmsg_len(info->genlhdr), rem) {
1966 switch (nla_type(a)) {
1967 case DPLL_A_MODE:
1968 ret = dpll_mode_set(dpll, a, info->extack);
1969 if (ret)
1970 return ret;
1971 break;
1972 case DPLL_A_PHASE_OFFSET_MONITOR:
1973 ret = dpll_phase_offset_monitor_set(dpll, a,
1974 info->extack);
1975 if (ret)
1976 return ret;
1977 break;
1978 case DPLL_A_PHASE_OFFSET_AVG_FACTOR:
1979 ret = dpll_phase_offset_avg_factor_set(dpll, a,
1980 info->extack);
1981 if (ret)
1982 return ret;
1983 break;
1984 case DPLL_A_FREQUENCY_MONITOR:
1985 ret = dpll_freq_monitor_set(dpll, a,
1986 info->extack);
1987 if (ret)
1988 return ret;
1989 break;
1990 }
1991 }
1992
1993 return 0;
1994 }
1995
dpll_nl_device_set_doit(struct sk_buff * skb,struct genl_info * info)1996 int dpll_nl_device_set_doit(struct sk_buff *skb, struct genl_info *info)
1997 {
1998 struct dpll_device *dpll = info->user_ptr[0];
1999
2000 return dpll_set_from_nlattr(dpll, info);
2001 }
2002
dpll_nl_device_get_dumpit(struct sk_buff * skb,struct netlink_callback * cb)2003 int dpll_nl_device_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
2004 {
2005 struct dpll_dump_ctx *ctx = dpll_dump_context(cb);
2006 struct dpll_device *dpll;
2007 struct nlattr *hdr;
2008 unsigned long i;
2009 int ret = 0;
2010
2011 mutex_lock(&dpll_lock);
2012 xa_for_each_marked_start(&dpll_device_xa, i, dpll, DPLL_REGISTERED,
2013 ctx->idx) {
2014 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
2015 cb->nlh->nlmsg_seq, &dpll_nl_family,
2016 NLM_F_MULTI, DPLL_CMD_DEVICE_GET);
2017 if (!hdr) {
2018 ret = -EMSGSIZE;
2019 break;
2020 }
2021 ret = dpll_device_get_one(dpll, skb, cb->extack);
2022 if (ret) {
2023 genlmsg_cancel(skb, hdr);
2024 break;
2025 }
2026 genlmsg_end(skb, hdr);
2027 }
2028 mutex_unlock(&dpll_lock);
2029
2030 if (ret == -EMSGSIZE) {
2031 ctx->idx = i;
2032 return skb->len;
2033 }
2034 return ret;
2035 }
2036
dpll_pre_doit(const struct genl_split_ops * ops,struct sk_buff * skb,struct genl_info * info)2037 int dpll_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
2038 struct genl_info *info)
2039 {
2040 u32 id;
2041
2042 if (GENL_REQ_ATTR_CHECK(info, DPLL_A_ID))
2043 return -EINVAL;
2044
2045 mutex_lock(&dpll_lock);
2046 id = nla_get_u32(info->attrs[DPLL_A_ID]);
2047 info->user_ptr[0] = dpll_device_get_by_id(id);
2048 if (!info->user_ptr[0]) {
2049 NL_SET_ERR_MSG(info->extack, "device not found");
2050 goto unlock;
2051 }
2052 return 0;
2053 unlock:
2054 mutex_unlock(&dpll_lock);
2055 return -ENODEV;
2056 }
2057
dpll_post_doit(const struct genl_split_ops * ops,struct sk_buff * skb,struct genl_info * info)2058 void dpll_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
2059 struct genl_info *info)
2060 {
2061 mutex_unlock(&dpll_lock);
2062 }
2063
2064 int
dpll_lock_doit(const struct genl_split_ops * ops,struct sk_buff * skb,struct genl_info * info)2065 dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
2066 struct genl_info *info)
2067 {
2068 mutex_lock(&dpll_lock);
2069
2070 return 0;
2071 }
2072
2073 void
dpll_unlock_doit(const struct genl_split_ops * ops,struct sk_buff * skb,struct genl_info * info)2074 dpll_unlock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
2075 struct genl_info *info)
2076 {
2077 mutex_unlock(&dpll_lock);
2078 }
2079
dpll_pin_pre_doit(const struct genl_split_ops * ops,struct sk_buff * skb,struct genl_info * info)2080 int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
2081 struct genl_info *info)
2082 {
2083 int ret;
2084
2085 mutex_lock(&dpll_lock);
2086 if (GENL_REQ_ATTR_CHECK(info, DPLL_A_PIN_ID)) {
2087 ret = -EINVAL;
2088 goto unlock_dev;
2089 }
2090 info->user_ptr[0] = xa_load(&dpll_pin_xa,
2091 nla_get_u32(info->attrs[DPLL_A_PIN_ID]));
2092 if (!info->user_ptr[0] ||
2093 !dpll_pin_available(info->user_ptr[0])) {
2094 NL_SET_ERR_MSG(info->extack, "pin not found");
2095 ret = -ENODEV;
2096 goto unlock_dev;
2097 }
2098
2099 return 0;
2100
2101 unlock_dev:
2102 mutex_unlock(&dpll_lock);
2103 return ret;
2104 }
2105
dpll_pin_post_doit(const struct genl_split_ops * ops,struct sk_buff * skb,struct genl_info * info)2106 void dpll_pin_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
2107 struct genl_info *info)
2108 {
2109 mutex_unlock(&dpll_lock);
2110 }
2111