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