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 (prop->phase_gran && 641 nla_put_u32(msg, DPLL_A_PIN_PHASE_ADJUST_GRAN, 642 prop->phase_gran)) 643 return -EMSGSIZE; 644 if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MIN, 645 prop->phase_range.min)) 646 return -EMSGSIZE; 647 if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MAX, 648 prop->phase_range.max)) 649 return -EMSGSIZE; 650 ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack); 651 if (ret) 652 return ret; 653 ret = dpll_msg_add_ffo(msg, pin, ref, extack); 654 if (ret) 655 return ret; 656 ret = dpll_msg_add_pin_esync(msg, pin, ref, extack); 657 if (ret) 658 return ret; 659 if (!xa_empty(&pin->ref_sync_pins)) 660 ret = dpll_msg_add_pin_ref_sync(msg, pin, ref, extack); 661 if (ret) 662 return ret; 663 if (xa_empty(&pin->parent_refs)) 664 ret = dpll_msg_add_pin_dplls(msg, pin, extack); 665 else 666 ret = dpll_msg_add_pin_parents(msg, pin, ref, extack); 667 668 return ret; 669 } 670 671 static int 672 dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg, 673 struct netlink_ext_ack *extack) 674 { 675 int ret; 676 677 ret = dpll_msg_add_dev_handle(msg, dpll); 678 if (ret) 679 return ret; 680 if (nla_put_string(msg, DPLL_A_MODULE_NAME, module_name(dpll->module))) 681 return -EMSGSIZE; 682 if (nla_put_64bit(msg, DPLL_A_CLOCK_ID, sizeof(dpll->clock_id), 683 &dpll->clock_id, DPLL_A_PAD)) 684 return -EMSGSIZE; 685 ret = dpll_msg_add_temp(msg, dpll, extack); 686 if (ret) 687 return ret; 688 ret = dpll_msg_add_lock_status(msg, dpll, extack); 689 if (ret) 690 return ret; 691 ret = dpll_msg_add_clock_quality_level(msg, dpll, extack); 692 if (ret) 693 return ret; 694 ret = dpll_msg_add_mode(msg, dpll, extack); 695 if (ret) 696 return ret; 697 ret = dpll_msg_add_mode_supported(msg, dpll, extack); 698 if (ret) 699 return ret; 700 if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type)) 701 return -EMSGSIZE; 702 ret = dpll_msg_add_phase_offset_monitor(msg, dpll, extack); 703 if (ret) 704 return ret; 705 ret = dpll_msg_add_phase_offset_avg_factor(msg, dpll, extack); 706 if (ret) 707 return ret; 708 709 return 0; 710 } 711 712 static int 713 dpll_device_event_send(enum dpll_cmd event, struct dpll_device *dpll) 714 { 715 struct sk_buff *msg; 716 int ret = -ENOMEM; 717 void *hdr; 718 719 if (WARN_ON(!xa_get_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED))) 720 return -ENODEV; 721 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 722 if (!msg) 723 return -ENOMEM; 724 hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event); 725 if (!hdr) 726 goto err_free_msg; 727 ret = dpll_device_get_one(dpll, msg, NULL); 728 if (ret) 729 goto err_cancel_msg; 730 genlmsg_end(msg, hdr); 731 genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL); 732 733 return 0; 734 735 err_cancel_msg: 736 genlmsg_cancel(msg, hdr); 737 err_free_msg: 738 nlmsg_free(msg); 739 740 return ret; 741 } 742 743 int dpll_device_create_ntf(struct dpll_device *dpll) 744 { 745 return dpll_device_event_send(DPLL_CMD_DEVICE_CREATE_NTF, dpll); 746 } 747 748 int dpll_device_delete_ntf(struct dpll_device *dpll) 749 { 750 return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll); 751 } 752 753 static int 754 __dpll_device_change_ntf(struct dpll_device *dpll) 755 { 756 return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll); 757 } 758 759 /** 760 * dpll_device_change_ntf - notify that the dpll device has been changed 761 * @dpll: registered dpll pointer 762 * 763 * Context: acquires and holds a dpll_lock. 764 * Return: 0 if succeeds, error code otherwise. 765 */ 766 int dpll_device_change_ntf(struct dpll_device *dpll) 767 { 768 int ret; 769 770 mutex_lock(&dpll_lock); 771 ret = __dpll_device_change_ntf(dpll); 772 mutex_unlock(&dpll_lock); 773 774 return ret; 775 } 776 EXPORT_SYMBOL_GPL(dpll_device_change_ntf); 777 778 static int 779 dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin) 780 { 781 struct sk_buff *msg; 782 int ret = -ENOMEM; 783 void *hdr; 784 785 if (!dpll_pin_available(pin)) 786 return -ENODEV; 787 788 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 789 if (!msg) 790 return -ENOMEM; 791 792 hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event); 793 if (!hdr) 794 goto err_free_msg; 795 ret = dpll_cmd_pin_get_one(msg, pin, NULL); 796 if (ret) 797 goto err_cancel_msg; 798 genlmsg_end(msg, hdr); 799 genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL); 800 801 return 0; 802 803 err_cancel_msg: 804 genlmsg_cancel(msg, hdr); 805 err_free_msg: 806 nlmsg_free(msg); 807 808 return ret; 809 } 810 811 int dpll_pin_create_ntf(struct dpll_pin *pin) 812 { 813 return dpll_pin_event_send(DPLL_CMD_PIN_CREATE_NTF, pin); 814 } 815 816 int dpll_pin_delete_ntf(struct dpll_pin *pin) 817 { 818 return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin); 819 } 820 821 int __dpll_pin_change_ntf(struct dpll_pin *pin) 822 { 823 return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin); 824 } 825 826 /** 827 * dpll_pin_change_ntf - notify that the pin has been changed 828 * @pin: registered pin pointer 829 * 830 * Context: acquires and holds a dpll_lock. 831 * Return: 0 if succeeds, error code otherwise. 832 */ 833 int dpll_pin_change_ntf(struct dpll_pin *pin) 834 { 835 int ret; 836 837 mutex_lock(&dpll_lock); 838 ret = __dpll_pin_change_ntf(pin); 839 mutex_unlock(&dpll_lock); 840 841 return ret; 842 } 843 EXPORT_SYMBOL_GPL(dpll_pin_change_ntf); 844 845 static int 846 dpll_phase_offset_monitor_set(struct dpll_device *dpll, struct nlattr *a, 847 struct netlink_ext_ack *extack) 848 { 849 const struct dpll_device_ops *ops = dpll_device_ops(dpll); 850 enum dpll_feature_state state = nla_get_u32(a), old_state; 851 int ret; 852 853 if (!(ops->phase_offset_monitor_set && ops->phase_offset_monitor_get)) { 854 NL_SET_ERR_MSG_ATTR(extack, a, "dpll device not capable of phase offset monitor"); 855 return -EOPNOTSUPP; 856 } 857 ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll), &old_state, 858 extack); 859 if (ret) { 860 NL_SET_ERR_MSG(extack, "unable to get current state of phase offset monitor"); 861 return ret; 862 } 863 if (state == old_state) 864 return 0; 865 866 return ops->phase_offset_monitor_set(dpll, dpll_priv(dpll), state, 867 extack); 868 } 869 870 static int 871 dpll_phase_offset_avg_factor_set(struct dpll_device *dpll, struct nlattr *a, 872 struct netlink_ext_ack *extack) 873 { 874 const struct dpll_device_ops *ops = dpll_device_ops(dpll); 875 u32 factor = nla_get_u32(a); 876 877 if (!ops->phase_offset_avg_factor_set) { 878 NL_SET_ERR_MSG_ATTR(extack, a, 879 "device not capable of changing phase offset average factor"); 880 return -EOPNOTSUPP; 881 } 882 883 return ops->phase_offset_avg_factor_set(dpll, dpll_priv(dpll), factor, 884 extack); 885 } 886 887 static int 888 dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a, 889 struct netlink_ext_ack *extack) 890 { 891 u64 freq = nla_get_u64(a), old_freq; 892 struct dpll_pin_ref *ref, *failed; 893 const struct dpll_pin_ops *ops; 894 struct dpll_device *dpll; 895 unsigned long i; 896 int ret; 897 898 if (!dpll_pin_is_freq_supported(pin, freq)) { 899 NL_SET_ERR_MSG_ATTR(extack, a, "frequency is not supported by the device"); 900 return -EINVAL; 901 } 902 903 xa_for_each(&pin->dpll_refs, i, ref) { 904 ops = dpll_pin_ops(ref); 905 if (!ops->frequency_set || !ops->frequency_get) { 906 NL_SET_ERR_MSG(extack, "frequency set not supported by the device"); 907 return -EOPNOTSUPP; 908 } 909 } 910 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs); 911 ops = dpll_pin_ops(ref); 912 dpll = ref->dpll; 913 ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll, 914 dpll_priv(dpll), &old_freq, extack); 915 if (ret) { 916 NL_SET_ERR_MSG(extack, "unable to get old frequency value"); 917 return ret; 918 } 919 if (freq == old_freq) 920 return 0; 921 922 xa_for_each(&pin->dpll_refs, i, ref) { 923 ops = dpll_pin_ops(ref); 924 dpll = ref->dpll; 925 ret = ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 926 dpll, dpll_priv(dpll), freq, extack); 927 if (ret) { 928 failed = ref; 929 NL_SET_ERR_MSG_FMT(extack, "frequency set failed for dpll_id:%u", 930 dpll->id); 931 goto rollback; 932 } 933 } 934 __dpll_pin_change_ntf(pin); 935 936 return 0; 937 938 rollback: 939 xa_for_each(&pin->dpll_refs, i, ref) { 940 if (ref == failed) 941 break; 942 ops = dpll_pin_ops(ref); 943 dpll = ref->dpll; 944 if (ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 945 dpll, dpll_priv(dpll), old_freq, extack)) 946 NL_SET_ERR_MSG(extack, "set frequency rollback failed"); 947 } 948 return ret; 949 } 950 951 static int 952 dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a, 953 struct netlink_ext_ack *extack) 954 { 955 struct dpll_pin_ref *ref, *failed; 956 const struct dpll_pin_ops *ops; 957 struct dpll_pin_esync esync; 958 u64 freq = nla_get_u64(a); 959 struct dpll_device *dpll; 960 bool supported = false; 961 unsigned long i; 962 int ret; 963 964 xa_for_each(&pin->dpll_refs, i, ref) { 965 ops = dpll_pin_ops(ref); 966 if (!ops->esync_set || !ops->esync_get) { 967 NL_SET_ERR_MSG(extack, 968 "embedded sync feature is not supported by this device"); 969 return -EOPNOTSUPP; 970 } 971 } 972 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs); 973 ops = dpll_pin_ops(ref); 974 dpll = ref->dpll; 975 ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll, 976 dpll_priv(dpll), &esync, extack); 977 if (ret) { 978 NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value"); 979 return ret; 980 } 981 if (freq == esync.freq) 982 return 0; 983 for (i = 0; i < esync.range_num; i++) 984 if (freq <= esync.range[i].max && freq >= esync.range[i].min) 985 supported = true; 986 if (!supported) { 987 NL_SET_ERR_MSG_ATTR(extack, a, 988 "requested embedded sync frequency value is not supported by this device"); 989 return -EINVAL; 990 } 991 992 xa_for_each(&pin->dpll_refs, i, ref) { 993 void *pin_dpll_priv; 994 995 ops = dpll_pin_ops(ref); 996 dpll = ref->dpll; 997 pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin); 998 ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll), 999 freq, extack); 1000 if (ret) { 1001 failed = ref; 1002 NL_SET_ERR_MSG_FMT(extack, 1003 "embedded sync frequency set failed for dpll_id: %u", 1004 dpll->id); 1005 goto rollback; 1006 } 1007 } 1008 __dpll_pin_change_ntf(pin); 1009 1010 return 0; 1011 1012 rollback: 1013 xa_for_each(&pin->dpll_refs, i, ref) { 1014 void *pin_dpll_priv; 1015 1016 if (ref == failed) 1017 break; 1018 ops = dpll_pin_ops(ref); 1019 dpll = ref->dpll; 1020 pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin); 1021 if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll), 1022 esync.freq, extack)) 1023 NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed"); 1024 } 1025 return ret; 1026 } 1027 1028 static int 1029 dpll_pin_ref_sync_state_set(struct dpll_pin *pin, 1030 unsigned long ref_sync_pin_idx, 1031 const enum dpll_pin_state state, 1032 struct netlink_ext_ack *extack) 1033 1034 { 1035 struct dpll_pin_ref *ref, *failed; 1036 const struct dpll_pin_ops *ops; 1037 enum dpll_pin_state old_state; 1038 struct dpll_pin *ref_sync_pin; 1039 struct dpll_device *dpll; 1040 unsigned long i; 1041 int ret; 1042 1043 ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx, 1044 ULONG_MAX, XA_PRESENT); 1045 if (!ref_sync_pin) { 1046 NL_SET_ERR_MSG(extack, "reference sync pin not found"); 1047 return -EINVAL; 1048 } 1049 if (!dpll_pin_available(ref_sync_pin)) { 1050 NL_SET_ERR_MSG(extack, "reference sync pin not available"); 1051 return -EINVAL; 1052 } 1053 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs); 1054 ASSERT_NOT_NULL(ref); 1055 ops = dpll_pin_ops(ref); 1056 if (!ops->ref_sync_set || !ops->ref_sync_get) { 1057 NL_SET_ERR_MSG(extack, "reference sync not supported by this pin"); 1058 return -EOPNOTSUPP; 1059 } 1060 dpll = ref->dpll; 1061 ret = ops->ref_sync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), 1062 ref_sync_pin, 1063 dpll_pin_on_dpll_priv(dpll, ref_sync_pin), 1064 &old_state, extack); 1065 if (ret) { 1066 NL_SET_ERR_MSG(extack, "unable to get old reference sync state"); 1067 return ret; 1068 } 1069 if (state == old_state) 1070 return 0; 1071 xa_for_each(&pin->dpll_refs, i, ref) { 1072 ops = dpll_pin_ops(ref); 1073 dpll = ref->dpll; 1074 ret = ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 1075 ref_sync_pin, 1076 dpll_pin_on_dpll_priv(dpll, 1077 ref_sync_pin), 1078 state, extack); 1079 if (ret) { 1080 failed = ref; 1081 NL_SET_ERR_MSG_FMT(extack, "reference sync set failed for dpll_id:%u", 1082 dpll->id); 1083 goto rollback; 1084 } 1085 } 1086 __dpll_pin_change_ntf(pin); 1087 1088 return 0; 1089 1090 rollback: 1091 xa_for_each(&pin->dpll_refs, i, ref) { 1092 if (ref == failed) 1093 break; 1094 ops = dpll_pin_ops(ref); 1095 dpll = ref->dpll; 1096 if (ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 1097 ref_sync_pin, 1098 dpll_pin_on_dpll_priv(dpll, ref_sync_pin), 1099 old_state, extack)) 1100 NL_SET_ERR_MSG(extack, "set reference sync rollback failed"); 1101 } 1102 return ret; 1103 } 1104 1105 static int 1106 dpll_pin_ref_sync_set(struct dpll_pin *pin, struct nlattr *nest, 1107 struct netlink_ext_ack *extack) 1108 { 1109 struct nlattr *tb[DPLL_A_PIN_MAX + 1]; 1110 enum dpll_pin_state state; 1111 u32 sync_pin_id; 1112 1113 nla_parse_nested(tb, DPLL_A_PIN_MAX, nest, 1114 dpll_reference_sync_nl_policy, extack); 1115 if (!tb[DPLL_A_PIN_ID]) { 1116 NL_SET_ERR_MSG(extack, "sync pin id expected"); 1117 return -EINVAL; 1118 } 1119 sync_pin_id = nla_get_u32(tb[DPLL_A_PIN_ID]); 1120 1121 if (!tb[DPLL_A_PIN_STATE]) { 1122 NL_SET_ERR_MSG(extack, "sync pin state expected"); 1123 return -EINVAL; 1124 } 1125 state = nla_get_u32(tb[DPLL_A_PIN_STATE]); 1126 1127 return dpll_pin_ref_sync_state_set(pin, sync_pin_id, state, extack); 1128 } 1129 1130 static int 1131 dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx, 1132 enum dpll_pin_state state, 1133 struct netlink_ext_ack *extack) 1134 { 1135 struct dpll_pin_ref *parent_ref; 1136 const struct dpll_pin_ops *ops; 1137 struct dpll_pin_ref *dpll_ref; 1138 void *pin_priv, *parent_priv; 1139 struct dpll_pin *parent; 1140 unsigned long i; 1141 int ret; 1142 1143 if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & 1144 pin->prop.capabilities)) { 1145 NL_SET_ERR_MSG(extack, "state changing is not allowed"); 1146 return -EOPNOTSUPP; 1147 } 1148 parent = xa_load(&dpll_pin_xa, parent_idx); 1149 if (!parent) 1150 return -EINVAL; 1151 parent_ref = xa_load(&pin->parent_refs, parent->pin_idx); 1152 if (!parent_ref) 1153 return -EINVAL; 1154 xa_for_each(&parent->dpll_refs, i, dpll_ref) { 1155 ops = dpll_pin_ops(parent_ref); 1156 if (!ops->state_on_pin_set) 1157 return -EOPNOTSUPP; 1158 pin_priv = dpll_pin_on_pin_priv(parent, pin); 1159 parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, parent); 1160 ret = ops->state_on_pin_set(pin, pin_priv, parent, parent_priv, 1161 state, extack); 1162 if (ret) 1163 return ret; 1164 } 1165 __dpll_pin_change_ntf(pin); 1166 1167 return 0; 1168 } 1169 1170 static int 1171 dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, 1172 enum dpll_pin_state state, 1173 struct netlink_ext_ack *extack) 1174 { 1175 const struct dpll_pin_ops *ops; 1176 struct dpll_pin_ref *ref; 1177 int ret; 1178 1179 if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & 1180 pin->prop.capabilities)) { 1181 NL_SET_ERR_MSG(extack, "state changing is not allowed"); 1182 return -EOPNOTSUPP; 1183 } 1184 ref = xa_load(&pin->dpll_refs, dpll->id); 1185 ASSERT_NOT_NULL(ref); 1186 ops = dpll_pin_ops(ref); 1187 if (!ops->state_on_dpll_set) 1188 return -EOPNOTSUPP; 1189 ret = ops->state_on_dpll_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 1190 dpll, dpll_priv(dpll), state, extack); 1191 if (ret) 1192 return ret; 1193 __dpll_pin_change_ntf(pin); 1194 1195 return 0; 1196 } 1197 1198 static int 1199 dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin, 1200 u32 prio, struct netlink_ext_ack *extack) 1201 { 1202 const struct dpll_pin_ops *ops; 1203 struct dpll_pin_ref *ref; 1204 int ret; 1205 1206 if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE & 1207 pin->prop.capabilities)) { 1208 NL_SET_ERR_MSG(extack, "prio changing is not allowed"); 1209 return -EOPNOTSUPP; 1210 } 1211 ref = xa_load(&pin->dpll_refs, dpll->id); 1212 ASSERT_NOT_NULL(ref); 1213 ops = dpll_pin_ops(ref); 1214 if (!ops->prio_set) 1215 return -EOPNOTSUPP; 1216 ret = ops->prio_set(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll, 1217 dpll_priv(dpll), prio, extack); 1218 if (ret) 1219 return ret; 1220 __dpll_pin_change_ntf(pin); 1221 1222 return 0; 1223 } 1224 1225 static int 1226 dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll, 1227 enum dpll_pin_direction direction, 1228 struct netlink_ext_ack *extack) 1229 { 1230 const struct dpll_pin_ops *ops; 1231 struct dpll_pin_ref *ref; 1232 int ret; 1233 1234 if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE & 1235 pin->prop.capabilities)) { 1236 NL_SET_ERR_MSG(extack, "direction changing is not allowed"); 1237 return -EOPNOTSUPP; 1238 } 1239 ref = xa_load(&pin->dpll_refs, dpll->id); 1240 ASSERT_NOT_NULL(ref); 1241 ops = dpll_pin_ops(ref); 1242 if (!ops->direction_set) 1243 return -EOPNOTSUPP; 1244 ret = ops->direction_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 1245 dpll, dpll_priv(dpll), direction, extack); 1246 if (ret) 1247 return ret; 1248 __dpll_pin_change_ntf(pin); 1249 1250 return 0; 1251 } 1252 1253 static int 1254 dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr, 1255 struct netlink_ext_ack *extack) 1256 { 1257 struct dpll_pin_ref *ref, *failed; 1258 const struct dpll_pin_ops *ops; 1259 s32 phase_adj, old_phase_adj; 1260 struct dpll_device *dpll; 1261 unsigned long i; 1262 int ret; 1263 1264 phase_adj = nla_get_s32(phase_adj_attr); 1265 if (phase_adj > pin->prop.phase_range.max || 1266 phase_adj < pin->prop.phase_range.min) { 1267 NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr, 1268 "phase adjust value of out range"); 1269 return -EINVAL; 1270 } 1271 if (pin->prop.phase_gran && phase_adj % (s32)pin->prop.phase_gran) { 1272 NL_SET_ERR_MSG_ATTR_FMT(extack, phase_adj_attr, 1273 "phase adjust value not multiple of %u", 1274 pin->prop.phase_gran); 1275 return -EINVAL; 1276 } 1277 1278 xa_for_each(&pin->dpll_refs, i, ref) { 1279 ops = dpll_pin_ops(ref); 1280 if (!ops->phase_adjust_set || !ops->phase_adjust_get) { 1281 NL_SET_ERR_MSG(extack, "phase adjust not supported"); 1282 return -EOPNOTSUPP; 1283 } 1284 } 1285 ref = dpll_xa_ref_dpll_first(&pin->dpll_refs); 1286 ops = dpll_pin_ops(ref); 1287 dpll = ref->dpll; 1288 ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin), 1289 dpll, dpll_priv(dpll), &old_phase_adj, 1290 extack); 1291 if (ret) { 1292 NL_SET_ERR_MSG(extack, "unable to get old phase adjust value"); 1293 return ret; 1294 } 1295 if (phase_adj == old_phase_adj) 1296 return 0; 1297 1298 xa_for_each(&pin->dpll_refs, i, ref) { 1299 ops = dpll_pin_ops(ref); 1300 dpll = ref->dpll; 1301 ret = ops->phase_adjust_set(pin, 1302 dpll_pin_on_dpll_priv(dpll, pin), 1303 dpll, dpll_priv(dpll), phase_adj, 1304 extack); 1305 if (ret) { 1306 failed = ref; 1307 NL_SET_ERR_MSG_FMT(extack, 1308 "phase adjust set failed for dpll_id:%u", 1309 dpll->id); 1310 goto rollback; 1311 } 1312 } 1313 __dpll_pin_change_ntf(pin); 1314 1315 return 0; 1316 1317 rollback: 1318 xa_for_each(&pin->dpll_refs, i, ref) { 1319 if (ref == failed) 1320 break; 1321 ops = dpll_pin_ops(ref); 1322 dpll = ref->dpll; 1323 if (ops->phase_adjust_set(pin, dpll_pin_on_dpll_priv(dpll, pin), 1324 dpll, dpll_priv(dpll), old_phase_adj, 1325 extack)) 1326 NL_SET_ERR_MSG(extack, "set phase adjust rollback failed"); 1327 } 1328 return ret; 1329 } 1330 1331 static int 1332 dpll_pin_parent_device_set(struct dpll_pin *pin, struct nlattr *parent_nest, 1333 struct netlink_ext_ack *extack) 1334 { 1335 struct nlattr *tb[DPLL_A_PIN_MAX + 1]; 1336 enum dpll_pin_direction direction; 1337 enum dpll_pin_state state; 1338 struct dpll_pin_ref *ref; 1339 struct dpll_device *dpll; 1340 u32 pdpll_idx, prio; 1341 int ret; 1342 1343 nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest, 1344 dpll_pin_parent_device_nl_policy, extack); 1345 if (!tb[DPLL_A_PIN_PARENT_ID]) { 1346 NL_SET_ERR_MSG(extack, "device parent id expected"); 1347 return -EINVAL; 1348 } 1349 pdpll_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]); 1350 dpll = xa_load(&dpll_device_xa, pdpll_idx); 1351 if (!dpll) { 1352 NL_SET_ERR_MSG(extack, "parent device not found"); 1353 return -EINVAL; 1354 } 1355 ref = xa_load(&pin->dpll_refs, dpll->id); 1356 if (!ref) { 1357 NL_SET_ERR_MSG(extack, "pin not connected to given parent device"); 1358 return -EINVAL; 1359 } 1360 if (tb[DPLL_A_PIN_STATE]) { 1361 state = nla_get_u32(tb[DPLL_A_PIN_STATE]); 1362 ret = dpll_pin_state_set(dpll, pin, state, extack); 1363 if (ret) 1364 return ret; 1365 } 1366 if (tb[DPLL_A_PIN_PRIO]) { 1367 prio = nla_get_u32(tb[DPLL_A_PIN_PRIO]); 1368 ret = dpll_pin_prio_set(dpll, pin, prio, extack); 1369 if (ret) 1370 return ret; 1371 } 1372 if (tb[DPLL_A_PIN_DIRECTION]) { 1373 direction = nla_get_u32(tb[DPLL_A_PIN_DIRECTION]); 1374 ret = dpll_pin_direction_set(pin, dpll, direction, extack); 1375 if (ret) 1376 return ret; 1377 } 1378 return 0; 1379 } 1380 1381 static int 1382 dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest, 1383 struct netlink_ext_ack *extack) 1384 { 1385 struct nlattr *tb[DPLL_A_PIN_MAX + 1]; 1386 u32 ppin_idx; 1387 int ret; 1388 1389 nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest, 1390 dpll_pin_parent_pin_nl_policy, extack); 1391 if (!tb[DPLL_A_PIN_PARENT_ID]) { 1392 NL_SET_ERR_MSG(extack, "device parent id expected"); 1393 return -EINVAL; 1394 } 1395 ppin_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]); 1396 1397 if (tb[DPLL_A_PIN_STATE]) { 1398 enum dpll_pin_state state = nla_get_u32(tb[DPLL_A_PIN_STATE]); 1399 1400 ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack); 1401 if (ret) 1402 return ret; 1403 } 1404 1405 return 0; 1406 } 1407 1408 static int 1409 dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info) 1410 { 1411 struct nlattr *a; 1412 int rem, ret; 1413 1414 nla_for_each_attr(a, genlmsg_data(info->genlhdr), 1415 genlmsg_len(info->genlhdr), rem) { 1416 switch (nla_type(a)) { 1417 case DPLL_A_PIN_FREQUENCY: 1418 ret = dpll_pin_freq_set(pin, a, info->extack); 1419 if (ret) 1420 return ret; 1421 break; 1422 case DPLL_A_PIN_PHASE_ADJUST: 1423 ret = dpll_pin_phase_adj_set(pin, a, info->extack); 1424 if (ret) 1425 return ret; 1426 break; 1427 case DPLL_A_PIN_PARENT_DEVICE: 1428 ret = dpll_pin_parent_device_set(pin, a, info->extack); 1429 if (ret) 1430 return ret; 1431 break; 1432 case DPLL_A_PIN_PARENT_PIN: 1433 ret = dpll_pin_parent_pin_set(pin, a, info->extack); 1434 if (ret) 1435 return ret; 1436 break; 1437 case DPLL_A_PIN_ESYNC_FREQUENCY: 1438 ret = dpll_pin_esync_set(pin, a, info->extack); 1439 if (ret) 1440 return ret; 1441 break; 1442 case DPLL_A_PIN_REFERENCE_SYNC: 1443 ret = dpll_pin_ref_sync_set(pin, a, info->extack); 1444 if (ret) 1445 return ret; 1446 break; 1447 } 1448 } 1449 1450 return 0; 1451 } 1452 1453 static struct dpll_pin * 1454 dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr, 1455 enum dpll_pin_type type, struct nlattr *board_label, 1456 struct nlattr *panel_label, struct nlattr *package_label, 1457 struct netlink_ext_ack *extack) 1458 { 1459 bool board_match, panel_match, package_match; 1460 struct dpll_pin *pin_match = NULL, *pin; 1461 const struct dpll_pin_properties *prop; 1462 bool cid_match, mod_match, type_match; 1463 unsigned long i; 1464 1465 xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) { 1466 prop = &pin->prop; 1467 cid_match = clock_id ? pin->clock_id == clock_id : true; 1468 mod_match = mod_name_attr && module_name(pin->module) ? 1469 !nla_strcmp(mod_name_attr, 1470 module_name(pin->module)) : true; 1471 type_match = type ? prop->type == type : true; 1472 board_match = board_label ? (prop->board_label ? 1473 !nla_strcmp(board_label, prop->board_label) : false) : 1474 true; 1475 panel_match = panel_label ? (prop->panel_label ? 1476 !nla_strcmp(panel_label, prop->panel_label) : false) : 1477 true; 1478 package_match = package_label ? (prop->package_label ? 1479 !nla_strcmp(package_label, prop->package_label) : 1480 false) : true; 1481 if (cid_match && mod_match && type_match && board_match && 1482 panel_match && package_match) { 1483 if (pin_match) { 1484 NL_SET_ERR_MSG(extack, "multiple matches"); 1485 return ERR_PTR(-EINVAL); 1486 } 1487 pin_match = pin; 1488 } 1489 } 1490 if (!pin_match) { 1491 NL_SET_ERR_MSG(extack, "not found"); 1492 return ERR_PTR(-ENODEV); 1493 } 1494 return pin_match; 1495 } 1496 1497 static struct dpll_pin *dpll_pin_find_from_nlattr(struct genl_info *info) 1498 { 1499 struct nlattr *attr, *mod_name_attr = NULL, *board_label_attr = NULL, 1500 *panel_label_attr = NULL, *package_label_attr = NULL; 1501 enum dpll_pin_type type = 0; 1502 u64 clock_id = 0; 1503 int rem = 0; 1504 1505 nla_for_each_attr(attr, genlmsg_data(info->genlhdr), 1506 genlmsg_len(info->genlhdr), rem) { 1507 switch (nla_type(attr)) { 1508 case DPLL_A_PIN_CLOCK_ID: 1509 if (clock_id) 1510 goto duplicated_attr; 1511 clock_id = nla_get_u64(attr); 1512 break; 1513 case DPLL_A_PIN_MODULE_NAME: 1514 if (mod_name_attr) 1515 goto duplicated_attr; 1516 mod_name_attr = attr; 1517 break; 1518 case DPLL_A_PIN_TYPE: 1519 if (type) 1520 goto duplicated_attr; 1521 type = nla_get_u32(attr); 1522 break; 1523 case DPLL_A_PIN_BOARD_LABEL: 1524 if (board_label_attr) 1525 goto duplicated_attr; 1526 board_label_attr = attr; 1527 break; 1528 case DPLL_A_PIN_PANEL_LABEL: 1529 if (panel_label_attr) 1530 goto duplicated_attr; 1531 panel_label_attr = attr; 1532 break; 1533 case DPLL_A_PIN_PACKAGE_LABEL: 1534 if (package_label_attr) 1535 goto duplicated_attr; 1536 package_label_attr = attr; 1537 break; 1538 default: 1539 break; 1540 } 1541 } 1542 if (!(clock_id || mod_name_attr || board_label_attr || 1543 panel_label_attr || package_label_attr)) { 1544 NL_SET_ERR_MSG(info->extack, "missing attributes"); 1545 return ERR_PTR(-EINVAL); 1546 } 1547 return dpll_pin_find(clock_id, mod_name_attr, type, board_label_attr, 1548 panel_label_attr, package_label_attr, 1549 info->extack); 1550 duplicated_attr: 1551 NL_SET_ERR_MSG(info->extack, "duplicated attribute"); 1552 return ERR_PTR(-EINVAL); 1553 } 1554 1555 int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info) 1556 { 1557 struct dpll_pin *pin; 1558 struct sk_buff *msg; 1559 struct nlattr *hdr; 1560 int ret; 1561 1562 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1563 if (!msg) 1564 return -ENOMEM; 1565 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, 1566 DPLL_CMD_PIN_ID_GET); 1567 if (!hdr) { 1568 nlmsg_free(msg); 1569 return -EMSGSIZE; 1570 } 1571 pin = dpll_pin_find_from_nlattr(info); 1572 if (IS_ERR(pin)) { 1573 nlmsg_free(msg); 1574 return PTR_ERR(pin); 1575 } 1576 if (!dpll_pin_available(pin)) { 1577 nlmsg_free(msg); 1578 return -ENODEV; 1579 } 1580 ret = dpll_msg_add_pin_handle(msg, pin); 1581 if (ret) { 1582 nlmsg_free(msg); 1583 return ret; 1584 } 1585 genlmsg_end(msg, hdr); 1586 1587 return genlmsg_reply(msg, info); 1588 } 1589 1590 int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info) 1591 { 1592 struct dpll_pin *pin = info->user_ptr[0]; 1593 struct sk_buff *msg; 1594 struct nlattr *hdr; 1595 int ret; 1596 1597 if (!pin) 1598 return -ENODEV; 1599 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1600 if (!msg) 1601 return -ENOMEM; 1602 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, 1603 DPLL_CMD_PIN_GET); 1604 if (!hdr) { 1605 nlmsg_free(msg); 1606 return -EMSGSIZE; 1607 } 1608 ret = dpll_cmd_pin_get_one(msg, pin, info->extack); 1609 if (ret) { 1610 nlmsg_free(msg); 1611 return ret; 1612 } 1613 genlmsg_end(msg, hdr); 1614 1615 return genlmsg_reply(msg, info); 1616 } 1617 1618 int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 1619 { 1620 struct dpll_dump_ctx *ctx = dpll_dump_context(cb); 1621 struct dpll_pin *pin; 1622 struct nlattr *hdr; 1623 unsigned long i; 1624 int ret = 0; 1625 1626 mutex_lock(&dpll_lock); 1627 xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED, 1628 ctx->idx) { 1629 if (!dpll_pin_available(pin)) 1630 continue; 1631 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, 1632 cb->nlh->nlmsg_seq, 1633 &dpll_nl_family, NLM_F_MULTI, 1634 DPLL_CMD_PIN_GET); 1635 if (!hdr) { 1636 ret = -EMSGSIZE; 1637 break; 1638 } 1639 ret = dpll_cmd_pin_get_one(skb, pin, cb->extack); 1640 if (ret) { 1641 genlmsg_cancel(skb, hdr); 1642 break; 1643 } 1644 genlmsg_end(skb, hdr); 1645 } 1646 mutex_unlock(&dpll_lock); 1647 1648 if (ret == -EMSGSIZE) { 1649 ctx->idx = i; 1650 return skb->len; 1651 } 1652 return ret; 1653 } 1654 1655 int dpll_nl_pin_set_doit(struct sk_buff *skb, struct genl_info *info) 1656 { 1657 struct dpll_pin *pin = info->user_ptr[0]; 1658 1659 return dpll_pin_set_from_nlattr(pin, info); 1660 } 1661 1662 static struct dpll_device * 1663 dpll_device_find(u64 clock_id, struct nlattr *mod_name_attr, 1664 enum dpll_type type, struct netlink_ext_ack *extack) 1665 { 1666 struct dpll_device *dpll_match = NULL, *dpll; 1667 bool cid_match, mod_match, type_match; 1668 unsigned long i; 1669 1670 xa_for_each_marked(&dpll_device_xa, i, dpll, DPLL_REGISTERED) { 1671 cid_match = clock_id ? dpll->clock_id == clock_id : true; 1672 mod_match = mod_name_attr ? (module_name(dpll->module) ? 1673 !nla_strcmp(mod_name_attr, 1674 module_name(dpll->module)) : false) : true; 1675 type_match = type ? dpll->type == type : true; 1676 if (cid_match && mod_match && type_match) { 1677 if (dpll_match) { 1678 NL_SET_ERR_MSG(extack, "multiple matches"); 1679 return ERR_PTR(-EINVAL); 1680 } 1681 dpll_match = dpll; 1682 } 1683 } 1684 if (!dpll_match) { 1685 NL_SET_ERR_MSG(extack, "not found"); 1686 return ERR_PTR(-ENODEV); 1687 } 1688 1689 return dpll_match; 1690 } 1691 1692 static struct dpll_device * 1693 dpll_device_find_from_nlattr(struct genl_info *info) 1694 { 1695 struct nlattr *attr, *mod_name_attr = NULL; 1696 enum dpll_type type = 0; 1697 u64 clock_id = 0; 1698 int rem = 0; 1699 1700 nla_for_each_attr(attr, genlmsg_data(info->genlhdr), 1701 genlmsg_len(info->genlhdr), rem) { 1702 switch (nla_type(attr)) { 1703 case DPLL_A_CLOCK_ID: 1704 if (clock_id) 1705 goto duplicated_attr; 1706 clock_id = nla_get_u64(attr); 1707 break; 1708 case DPLL_A_MODULE_NAME: 1709 if (mod_name_attr) 1710 goto duplicated_attr; 1711 mod_name_attr = attr; 1712 break; 1713 case DPLL_A_TYPE: 1714 if (type) 1715 goto duplicated_attr; 1716 type = nla_get_u32(attr); 1717 break; 1718 default: 1719 break; 1720 } 1721 } 1722 if (!clock_id && !mod_name_attr && !type) { 1723 NL_SET_ERR_MSG(info->extack, "missing attributes"); 1724 return ERR_PTR(-EINVAL); 1725 } 1726 return dpll_device_find(clock_id, mod_name_attr, type, info->extack); 1727 duplicated_attr: 1728 NL_SET_ERR_MSG(info->extack, "duplicated attribute"); 1729 return ERR_PTR(-EINVAL); 1730 } 1731 1732 int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info) 1733 { 1734 struct dpll_device *dpll; 1735 struct sk_buff *msg; 1736 struct nlattr *hdr; 1737 int ret; 1738 1739 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1740 if (!msg) 1741 return -ENOMEM; 1742 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, 1743 DPLL_CMD_DEVICE_ID_GET); 1744 if (!hdr) { 1745 nlmsg_free(msg); 1746 return -EMSGSIZE; 1747 } 1748 1749 dpll = dpll_device_find_from_nlattr(info); 1750 if (IS_ERR(dpll)) { 1751 nlmsg_free(msg); 1752 return PTR_ERR(dpll); 1753 } 1754 ret = dpll_msg_add_dev_handle(msg, dpll); 1755 if (ret) { 1756 nlmsg_free(msg); 1757 return ret; 1758 } 1759 genlmsg_end(msg, hdr); 1760 1761 return genlmsg_reply(msg, info); 1762 } 1763 1764 int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info) 1765 { 1766 struct dpll_device *dpll = info->user_ptr[0]; 1767 struct sk_buff *msg; 1768 struct nlattr *hdr; 1769 int ret; 1770 1771 msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1772 if (!msg) 1773 return -ENOMEM; 1774 hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, 1775 DPLL_CMD_DEVICE_GET); 1776 if (!hdr) { 1777 nlmsg_free(msg); 1778 return -EMSGSIZE; 1779 } 1780 1781 ret = dpll_device_get_one(dpll, msg, info->extack); 1782 if (ret) { 1783 nlmsg_free(msg); 1784 return ret; 1785 } 1786 genlmsg_end(msg, hdr); 1787 1788 return genlmsg_reply(msg, info); 1789 } 1790 1791 static int 1792 dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info) 1793 { 1794 struct nlattr *a; 1795 int rem, ret; 1796 1797 nla_for_each_attr(a, genlmsg_data(info->genlhdr), 1798 genlmsg_len(info->genlhdr), rem) { 1799 switch (nla_type(a)) { 1800 case DPLL_A_PHASE_OFFSET_MONITOR: 1801 ret = dpll_phase_offset_monitor_set(dpll, a, 1802 info->extack); 1803 if (ret) 1804 return ret; 1805 break; 1806 case DPLL_A_PHASE_OFFSET_AVG_FACTOR: 1807 ret = dpll_phase_offset_avg_factor_set(dpll, a, 1808 info->extack); 1809 if (ret) 1810 return ret; 1811 break; 1812 } 1813 } 1814 1815 return 0; 1816 } 1817 1818 int dpll_nl_device_set_doit(struct sk_buff *skb, struct genl_info *info) 1819 { 1820 struct dpll_device *dpll = info->user_ptr[0]; 1821 1822 return dpll_set_from_nlattr(dpll, info); 1823 } 1824 1825 int dpll_nl_device_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 1826 { 1827 struct dpll_dump_ctx *ctx = dpll_dump_context(cb); 1828 struct dpll_device *dpll; 1829 struct nlattr *hdr; 1830 unsigned long i; 1831 int ret = 0; 1832 1833 mutex_lock(&dpll_lock); 1834 xa_for_each_marked_start(&dpll_device_xa, i, dpll, DPLL_REGISTERED, 1835 ctx->idx) { 1836 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, 1837 cb->nlh->nlmsg_seq, &dpll_nl_family, 1838 NLM_F_MULTI, DPLL_CMD_DEVICE_GET); 1839 if (!hdr) { 1840 ret = -EMSGSIZE; 1841 break; 1842 } 1843 ret = dpll_device_get_one(dpll, skb, cb->extack); 1844 if (ret) { 1845 genlmsg_cancel(skb, hdr); 1846 break; 1847 } 1848 genlmsg_end(skb, hdr); 1849 } 1850 mutex_unlock(&dpll_lock); 1851 1852 if (ret == -EMSGSIZE) { 1853 ctx->idx = i; 1854 return skb->len; 1855 } 1856 return ret; 1857 } 1858 1859 int dpll_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 1860 struct genl_info *info) 1861 { 1862 u32 id; 1863 1864 if (GENL_REQ_ATTR_CHECK(info, DPLL_A_ID)) 1865 return -EINVAL; 1866 1867 mutex_lock(&dpll_lock); 1868 id = nla_get_u32(info->attrs[DPLL_A_ID]); 1869 info->user_ptr[0] = dpll_device_get_by_id(id); 1870 if (!info->user_ptr[0]) { 1871 NL_SET_ERR_MSG(info->extack, "device not found"); 1872 goto unlock; 1873 } 1874 return 0; 1875 unlock: 1876 mutex_unlock(&dpll_lock); 1877 return -ENODEV; 1878 } 1879 1880 void dpll_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 1881 struct genl_info *info) 1882 { 1883 mutex_unlock(&dpll_lock); 1884 } 1885 1886 int 1887 dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 1888 struct genl_info *info) 1889 { 1890 mutex_lock(&dpll_lock); 1891 1892 return 0; 1893 } 1894 1895 void 1896 dpll_unlock_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 1897 struct genl_info *info) 1898 { 1899 mutex_unlock(&dpll_lock); 1900 } 1901 1902 int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 1903 struct genl_info *info) 1904 { 1905 int ret; 1906 1907 mutex_lock(&dpll_lock); 1908 if (GENL_REQ_ATTR_CHECK(info, DPLL_A_PIN_ID)) { 1909 ret = -EINVAL; 1910 goto unlock_dev; 1911 } 1912 info->user_ptr[0] = xa_load(&dpll_pin_xa, 1913 nla_get_u32(info->attrs[DPLL_A_PIN_ID])); 1914 if (!info->user_ptr[0] || 1915 !dpll_pin_available(info->user_ptr[0])) { 1916 NL_SET_ERR_MSG(info->extack, "pin not found"); 1917 ret = -ENODEV; 1918 goto unlock_dev; 1919 } 1920 1921 return 0; 1922 1923 unlock_dev: 1924 mutex_unlock(&dpll_lock); 1925 return ret; 1926 } 1927 1928 void dpll_pin_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb, 1929 struct genl_info *info) 1930 { 1931 mutex_unlock(&dpll_lock); 1932 } 1933