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