1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * dpll_core.c - DPLL subsystem kernel-space interface implementation. 4 * 5 * Copyright (c) 2023 Meta Platforms, Inc. and affiliates 6 * Copyright (c) 2023 Intel Corporation. 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 11 #include <linux/device.h> 12 #include <linux/err.h> 13 #include <linux/slab.h> 14 #include <linux/string.h> 15 16 #include "dpll_core.h" 17 #include "dpll_netlink.h" 18 19 /* Mutex lock to protect DPLL subsystem devices and pins */ 20 DEFINE_MUTEX(dpll_lock); 21 22 DEFINE_XARRAY_FLAGS(dpll_device_xa, XA_FLAGS_ALLOC); 23 DEFINE_XARRAY_FLAGS(dpll_pin_xa, XA_FLAGS_ALLOC); 24 25 static u32 dpll_device_xa_id; 26 static u32 dpll_pin_xa_id; 27 28 #define ASSERT_DPLL_REGISTERED(d) \ 29 WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) 30 #define ASSERT_DPLL_NOT_REGISTERED(d) \ 31 WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) 32 #define ASSERT_PIN_REGISTERED(p) \ 33 WARN_ON_ONCE(!xa_get_mark(&dpll_pin_xa, (p)->id, DPLL_REGISTERED)) 34 35 struct dpll_device_registration { 36 struct list_head list; 37 const struct dpll_device_ops *ops; 38 void *priv; 39 }; 40 41 struct dpll_pin_registration { 42 struct list_head list; 43 const struct dpll_pin_ops *ops; 44 void *priv; 45 }; 46 47 struct dpll_device *dpll_device_get_by_id(int id) 48 { 49 if (xa_get_mark(&dpll_device_xa, id, DPLL_REGISTERED)) 50 return xa_load(&dpll_device_xa, id); 51 52 return NULL; 53 } 54 55 static struct dpll_pin_registration * 56 dpll_pin_registration_find(struct dpll_pin_ref *ref, 57 const struct dpll_pin_ops *ops, void *priv) 58 { 59 struct dpll_pin_registration *reg; 60 61 list_for_each_entry(reg, &ref->registration_list, list) { 62 if (reg->ops == ops && reg->priv == priv) 63 return reg; 64 } 65 return NULL; 66 } 67 68 static int 69 dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, 70 const struct dpll_pin_ops *ops, void *priv) 71 { 72 struct dpll_pin_registration *reg; 73 struct dpll_pin_ref *ref; 74 bool ref_exists = false; 75 unsigned long i; 76 int ret; 77 78 xa_for_each(xa_pins, i, ref) { 79 if (ref->pin != pin) 80 continue; 81 reg = dpll_pin_registration_find(ref, ops, priv); 82 if (reg) { 83 refcount_inc(&ref->refcount); 84 return 0; 85 } 86 ref_exists = true; 87 break; 88 } 89 90 if (!ref_exists) { 91 ref = kzalloc(sizeof(*ref), GFP_KERNEL); 92 if (!ref) 93 return -ENOMEM; 94 ref->pin = pin; 95 INIT_LIST_HEAD(&ref->registration_list); 96 ret = xa_insert(xa_pins, pin->pin_idx, ref, GFP_KERNEL); 97 if (ret) { 98 kfree(ref); 99 return ret; 100 } 101 refcount_set(&ref->refcount, 1); 102 } 103 104 reg = kzalloc(sizeof(*reg), GFP_KERNEL); 105 if (!reg) { 106 if (!ref_exists) { 107 xa_erase(xa_pins, pin->pin_idx); 108 kfree(ref); 109 } 110 return -ENOMEM; 111 } 112 reg->ops = ops; 113 reg->priv = priv; 114 if (ref_exists) 115 refcount_inc(&ref->refcount); 116 list_add_tail(®->list, &ref->registration_list); 117 118 return 0; 119 } 120 121 static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin, 122 const struct dpll_pin_ops *ops, void *priv) 123 { 124 struct dpll_pin_registration *reg; 125 struct dpll_pin_ref *ref; 126 unsigned long i; 127 128 xa_for_each(xa_pins, i, ref) { 129 if (ref->pin != pin) 130 continue; 131 reg = dpll_pin_registration_find(ref, ops, priv); 132 if (WARN_ON(!reg)) 133 return -EINVAL; 134 if (refcount_dec_and_test(&ref->refcount)) { 135 list_del(®->list); 136 kfree(reg); 137 xa_erase(xa_pins, i); 138 WARN_ON(!list_empty(&ref->registration_list)); 139 kfree(ref); 140 } 141 return 0; 142 } 143 144 return -EINVAL; 145 } 146 147 static int 148 dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, 149 const struct dpll_pin_ops *ops, void *priv) 150 { 151 struct dpll_pin_registration *reg; 152 struct dpll_pin_ref *ref; 153 bool ref_exists = false; 154 unsigned long i; 155 int ret; 156 157 xa_for_each(xa_dplls, i, ref) { 158 if (ref->dpll != dpll) 159 continue; 160 reg = dpll_pin_registration_find(ref, ops, priv); 161 if (reg) { 162 refcount_inc(&ref->refcount); 163 return 0; 164 } 165 ref_exists = true; 166 break; 167 } 168 169 if (!ref_exists) { 170 ref = kzalloc(sizeof(*ref), GFP_KERNEL); 171 if (!ref) 172 return -ENOMEM; 173 ref->dpll = dpll; 174 INIT_LIST_HEAD(&ref->registration_list); 175 ret = xa_insert(xa_dplls, dpll->id, ref, GFP_KERNEL); 176 if (ret) { 177 kfree(ref); 178 return ret; 179 } 180 refcount_set(&ref->refcount, 1); 181 } 182 183 reg = kzalloc(sizeof(*reg), GFP_KERNEL); 184 if (!reg) { 185 if (!ref_exists) { 186 xa_erase(xa_dplls, dpll->id); 187 kfree(ref); 188 } 189 return -ENOMEM; 190 } 191 reg->ops = ops; 192 reg->priv = priv; 193 if (ref_exists) 194 refcount_inc(&ref->refcount); 195 list_add_tail(®->list, &ref->registration_list); 196 197 return 0; 198 } 199 200 static void 201 dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll, 202 const struct dpll_pin_ops *ops, void *priv) 203 { 204 struct dpll_pin_registration *reg; 205 struct dpll_pin_ref *ref; 206 unsigned long i; 207 208 xa_for_each(xa_dplls, i, ref) { 209 if (ref->dpll != dpll) 210 continue; 211 reg = dpll_pin_registration_find(ref, ops, priv); 212 if (WARN_ON(!reg)) 213 return; 214 if (refcount_dec_and_test(&ref->refcount)) { 215 list_del(®->list); 216 kfree(reg); 217 xa_erase(xa_dplls, i); 218 WARN_ON(!list_empty(&ref->registration_list)); 219 kfree(ref); 220 } 221 return; 222 } 223 } 224 225 struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs) 226 { 227 struct dpll_pin_ref *ref; 228 unsigned long i = 0; 229 230 ref = xa_find(xa_refs, &i, ULONG_MAX, XA_PRESENT); 231 WARN_ON(!ref); 232 return ref; 233 } 234 235 static struct dpll_device * 236 dpll_device_alloc(const u64 clock_id, u32 device_idx, struct module *module) 237 { 238 struct dpll_device *dpll; 239 int ret; 240 241 dpll = kzalloc(sizeof(*dpll), GFP_KERNEL); 242 if (!dpll) 243 return ERR_PTR(-ENOMEM); 244 refcount_set(&dpll->refcount, 1); 245 INIT_LIST_HEAD(&dpll->registration_list); 246 dpll->device_idx = device_idx; 247 dpll->clock_id = clock_id; 248 dpll->module = module; 249 ret = xa_alloc_cyclic(&dpll_device_xa, &dpll->id, dpll, xa_limit_32b, 250 &dpll_device_xa_id, GFP_KERNEL); 251 if (ret < 0) { 252 kfree(dpll); 253 return ERR_PTR(ret); 254 } 255 xa_init_flags(&dpll->pin_refs, XA_FLAGS_ALLOC); 256 257 return dpll; 258 } 259 260 /** 261 * dpll_device_get - find existing or create new dpll device 262 * @clock_id: clock_id of creator 263 * @device_idx: idx given by device driver 264 * @module: reference to registering module 265 * 266 * Get existing object of a dpll device, unique for given arguments. 267 * Create new if doesn't exist yet. 268 * 269 * Context: Acquires a lock (dpll_lock) 270 * Return: 271 * * valid dpll_device struct pointer if succeeded 272 * * ERR_PTR(X) - error 273 */ 274 struct dpll_device * 275 dpll_device_get(u64 clock_id, u32 device_idx, struct module *module) 276 { 277 struct dpll_device *dpll, *ret = NULL; 278 unsigned long index; 279 280 mutex_lock(&dpll_lock); 281 xa_for_each(&dpll_device_xa, index, dpll) { 282 if (dpll->clock_id == clock_id && 283 dpll->device_idx == device_idx && 284 dpll->module == module) { 285 ret = dpll; 286 refcount_inc(&ret->refcount); 287 break; 288 } 289 } 290 if (!ret) 291 ret = dpll_device_alloc(clock_id, device_idx, module); 292 mutex_unlock(&dpll_lock); 293 294 return ret; 295 } 296 EXPORT_SYMBOL_GPL(dpll_device_get); 297 298 /** 299 * dpll_device_put - decrease the refcount and free memory if possible 300 * @dpll: dpll_device struct pointer 301 * 302 * Context: Acquires a lock (dpll_lock) 303 * Drop reference for a dpll device, if all references are gone, delete 304 * dpll device object. 305 */ 306 void dpll_device_put(struct dpll_device *dpll) 307 { 308 mutex_lock(&dpll_lock); 309 if (refcount_dec_and_test(&dpll->refcount)) { 310 ASSERT_DPLL_NOT_REGISTERED(dpll); 311 WARN_ON_ONCE(!xa_empty(&dpll->pin_refs)); 312 xa_destroy(&dpll->pin_refs); 313 xa_erase(&dpll_device_xa, dpll->id); 314 WARN_ON(!list_empty(&dpll->registration_list)); 315 kfree(dpll); 316 } 317 mutex_unlock(&dpll_lock); 318 } 319 EXPORT_SYMBOL_GPL(dpll_device_put); 320 321 static struct dpll_device_registration * 322 dpll_device_registration_find(struct dpll_device *dpll, 323 const struct dpll_device_ops *ops, void *priv) 324 { 325 struct dpll_device_registration *reg; 326 327 list_for_each_entry(reg, &dpll->registration_list, list) { 328 if (reg->ops == ops && reg->priv == priv) 329 return reg; 330 } 331 return NULL; 332 } 333 334 /** 335 * dpll_device_register - register the dpll device in the subsystem 336 * @dpll: pointer to a dpll 337 * @type: type of a dpll 338 * @ops: ops for a dpll device 339 * @priv: pointer to private information of owner 340 * 341 * Make dpll device available for user space. 342 * 343 * Context: Acquires a lock (dpll_lock) 344 * Return: 345 * * 0 on success 346 * * negative - error value 347 */ 348 int dpll_device_register(struct dpll_device *dpll, enum dpll_type type, 349 const struct dpll_device_ops *ops, void *priv) 350 { 351 struct dpll_device_registration *reg; 352 bool first_registration = false; 353 354 if (WARN_ON(!ops)) 355 return -EINVAL; 356 if (WARN_ON(!ops->mode_get)) 357 return -EINVAL; 358 if (WARN_ON(!ops->lock_status_get)) 359 return -EINVAL; 360 if (WARN_ON(type < DPLL_TYPE_PPS || type > DPLL_TYPE_MAX)) 361 return -EINVAL; 362 363 mutex_lock(&dpll_lock); 364 reg = dpll_device_registration_find(dpll, ops, priv); 365 if (reg) { 366 mutex_unlock(&dpll_lock); 367 return -EEXIST; 368 } 369 370 reg = kzalloc(sizeof(*reg), GFP_KERNEL); 371 if (!reg) { 372 mutex_unlock(&dpll_lock); 373 return -ENOMEM; 374 } 375 reg->ops = ops; 376 reg->priv = priv; 377 dpll->type = type; 378 first_registration = list_empty(&dpll->registration_list); 379 list_add_tail(®->list, &dpll->registration_list); 380 if (!first_registration) { 381 mutex_unlock(&dpll_lock); 382 return 0; 383 } 384 385 xa_set_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED); 386 dpll_device_create_ntf(dpll); 387 mutex_unlock(&dpll_lock); 388 389 return 0; 390 } 391 EXPORT_SYMBOL_GPL(dpll_device_register); 392 393 /** 394 * dpll_device_unregister - unregister dpll device 395 * @dpll: registered dpll pointer 396 * @ops: ops for a dpll device 397 * @priv: pointer to private information of owner 398 * 399 * Unregister device, make it unavailable for userspace. 400 * Note: It does not free the memory 401 * Context: Acquires a lock (dpll_lock) 402 */ 403 void dpll_device_unregister(struct dpll_device *dpll, 404 const struct dpll_device_ops *ops, void *priv) 405 { 406 struct dpll_device_registration *reg; 407 408 mutex_lock(&dpll_lock); 409 ASSERT_DPLL_REGISTERED(dpll); 410 dpll_device_delete_ntf(dpll); 411 reg = dpll_device_registration_find(dpll, ops, priv); 412 if (WARN_ON(!reg)) { 413 mutex_unlock(&dpll_lock); 414 return; 415 } 416 list_del(®->list); 417 kfree(reg); 418 419 if (!list_empty(&dpll->registration_list)) { 420 mutex_unlock(&dpll_lock); 421 return; 422 } 423 xa_clear_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED); 424 mutex_unlock(&dpll_lock); 425 } 426 EXPORT_SYMBOL_GPL(dpll_device_unregister); 427 428 static struct dpll_pin * 429 dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, 430 const struct dpll_pin_properties *prop) 431 { 432 struct dpll_pin *pin; 433 int ret; 434 435 pin = kzalloc(sizeof(*pin), GFP_KERNEL); 436 if (!pin) 437 return ERR_PTR(-ENOMEM); 438 pin->pin_idx = pin_idx; 439 pin->clock_id = clock_id; 440 pin->module = module; 441 if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX || 442 prop->type > DPLL_PIN_TYPE_MAX)) { 443 ret = -EINVAL; 444 goto err; 445 } 446 pin->prop = prop; 447 refcount_set(&pin->refcount, 1); 448 xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC); 449 xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC); 450 ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b, 451 &dpll_pin_xa_id, GFP_KERNEL); 452 if (ret) 453 goto err; 454 return pin; 455 err: 456 xa_destroy(&pin->dpll_refs); 457 xa_destroy(&pin->parent_refs); 458 kfree(pin); 459 return ERR_PTR(ret); 460 } 461 462 /** 463 * dpll_pin_get - find existing or create new dpll pin 464 * @clock_id: clock_id of creator 465 * @pin_idx: idx given by dev driver 466 * @module: reference to registering module 467 * @prop: dpll pin properties 468 * 469 * Get existing object of a pin (unique for given arguments) or create new 470 * if doesn't exist yet. 471 * 472 * Context: Acquires a lock (dpll_lock) 473 * Return: 474 * * valid allocated dpll_pin struct pointer if succeeded 475 * * ERR_PTR(X) - error 476 */ 477 struct dpll_pin * 478 dpll_pin_get(u64 clock_id, u32 pin_idx, struct module *module, 479 const struct dpll_pin_properties *prop) 480 { 481 struct dpll_pin *pos, *ret = NULL; 482 unsigned long i; 483 484 mutex_lock(&dpll_lock); 485 xa_for_each(&dpll_pin_xa, i, pos) { 486 if (pos->clock_id == clock_id && 487 pos->pin_idx == pin_idx && 488 pos->module == module) { 489 ret = pos; 490 refcount_inc(&ret->refcount); 491 break; 492 } 493 } 494 if (!ret) 495 ret = dpll_pin_alloc(clock_id, pin_idx, module, prop); 496 mutex_unlock(&dpll_lock); 497 498 return ret; 499 } 500 EXPORT_SYMBOL_GPL(dpll_pin_get); 501 502 /** 503 * dpll_pin_put - decrease the refcount and free memory if possible 504 * @pin: pointer to a pin to be put 505 * 506 * Drop reference for a pin, if all references are gone, delete pin object. 507 * 508 * Context: Acquires a lock (dpll_lock) 509 */ 510 void dpll_pin_put(struct dpll_pin *pin) 511 { 512 mutex_lock(&dpll_lock); 513 if (refcount_dec_and_test(&pin->refcount)) { 514 xa_destroy(&pin->dpll_refs); 515 xa_destroy(&pin->parent_refs); 516 xa_erase(&dpll_pin_xa, pin->id); 517 kfree(pin); 518 } 519 mutex_unlock(&dpll_lock); 520 } 521 EXPORT_SYMBOL_GPL(dpll_pin_put); 522 523 static int 524 __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 525 const struct dpll_pin_ops *ops, void *priv) 526 { 527 int ret; 528 529 ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv); 530 if (ret) 531 return ret; 532 ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv); 533 if (ret) 534 goto ref_pin_del; 535 xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 536 dpll_pin_create_ntf(pin); 537 538 return ret; 539 540 ref_pin_del: 541 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); 542 return ret; 543 } 544 545 /** 546 * dpll_pin_register - register the dpll pin in the subsystem 547 * @dpll: pointer to a dpll 548 * @pin: pointer to a dpll pin 549 * @ops: ops for a dpll pin ops 550 * @priv: pointer to private information of owner 551 * 552 * Context: Acquires a lock (dpll_lock) 553 * Return: 554 * * 0 on success 555 * * negative - error value 556 */ 557 int 558 dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 559 const struct dpll_pin_ops *ops, void *priv) 560 { 561 int ret; 562 563 if (WARN_ON(!ops) || 564 WARN_ON(!ops->state_on_dpll_get) || 565 WARN_ON(!ops->direction_get)) 566 return -EINVAL; 567 if (ASSERT_DPLL_REGISTERED(dpll)) 568 return -EINVAL; 569 570 mutex_lock(&dpll_lock); 571 if (WARN_ON(!(dpll->module == pin->module && 572 dpll->clock_id == pin->clock_id))) 573 ret = -EINVAL; 574 else 575 ret = __dpll_pin_register(dpll, pin, ops, priv); 576 mutex_unlock(&dpll_lock); 577 578 return ret; 579 } 580 EXPORT_SYMBOL_GPL(dpll_pin_register); 581 582 static void 583 __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 584 const struct dpll_pin_ops *ops, void *priv) 585 { 586 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); 587 dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv); 588 if (xa_empty(&pin->dpll_refs)) 589 xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 590 } 591 592 /** 593 * dpll_pin_unregister - unregister dpll pin from dpll device 594 * @dpll: registered dpll pointer 595 * @pin: pointer to a pin 596 * @ops: ops for a dpll pin 597 * @priv: pointer to private information of owner 598 * 599 * Note: It does not free the memory 600 * Context: Acquires a lock (dpll_lock) 601 */ 602 void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 603 const struct dpll_pin_ops *ops, void *priv) 604 { 605 if (WARN_ON(xa_empty(&dpll->pin_refs))) 606 return; 607 if (WARN_ON(!xa_empty(&pin->parent_refs))) 608 return; 609 610 mutex_lock(&dpll_lock); 611 dpll_pin_delete_ntf(pin); 612 __dpll_pin_unregister(dpll, pin, ops, priv); 613 mutex_unlock(&dpll_lock); 614 } 615 EXPORT_SYMBOL_GPL(dpll_pin_unregister); 616 617 /** 618 * dpll_pin_on_pin_register - register a pin with a parent pin 619 * @parent: pointer to a parent pin 620 * @pin: pointer to a pin 621 * @ops: ops for a dpll pin 622 * @priv: pointer to private information of owner 623 * 624 * Register a pin with a parent pin, create references between them and 625 * between newly registered pin and dplls connected with a parent pin. 626 * 627 * Context: Acquires a lock (dpll_lock) 628 * Return: 629 * * 0 on success 630 * * negative - error value 631 */ 632 int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, 633 const struct dpll_pin_ops *ops, void *priv) 634 { 635 struct dpll_pin_ref *ref; 636 unsigned long i, stop; 637 int ret; 638 639 if (WARN_ON(parent->prop->type != DPLL_PIN_TYPE_MUX)) 640 return -EINVAL; 641 642 if (WARN_ON(!ops) || 643 WARN_ON(!ops->state_on_pin_get) || 644 WARN_ON(!ops->direction_get)) 645 return -EINVAL; 646 if (ASSERT_PIN_REGISTERED(parent)) 647 return -EINVAL; 648 649 mutex_lock(&dpll_lock); 650 ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv); 651 if (ret) 652 goto unlock; 653 refcount_inc(&pin->refcount); 654 xa_for_each(&parent->dpll_refs, i, ref) { 655 ret = __dpll_pin_register(ref->dpll, pin, ops, priv); 656 if (ret) { 657 stop = i; 658 goto dpll_unregister; 659 } 660 dpll_pin_create_ntf(pin); 661 } 662 mutex_unlock(&dpll_lock); 663 664 return ret; 665 666 dpll_unregister: 667 xa_for_each(&parent->dpll_refs, i, ref) 668 if (i < stop) { 669 __dpll_pin_unregister(ref->dpll, pin, ops, priv); 670 dpll_pin_delete_ntf(pin); 671 } 672 refcount_dec(&pin->refcount); 673 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); 674 unlock: 675 mutex_unlock(&dpll_lock); 676 return ret; 677 } 678 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register); 679 680 /** 681 * dpll_pin_on_pin_unregister - unregister dpll pin from a parent pin 682 * @parent: pointer to a parent pin 683 * @pin: pointer to a pin 684 * @ops: ops for a dpll pin 685 * @priv: pointer to private information of owner 686 * 687 * Context: Acquires a lock (dpll_lock) 688 * Note: It does not free the memory 689 */ 690 void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, 691 const struct dpll_pin_ops *ops, void *priv) 692 { 693 struct dpll_pin_ref *ref; 694 unsigned long i; 695 696 mutex_lock(&dpll_lock); 697 dpll_pin_delete_ntf(pin); 698 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); 699 refcount_dec(&pin->refcount); 700 xa_for_each(&pin->dpll_refs, i, ref) 701 __dpll_pin_unregister(ref->dpll, pin, ops, priv); 702 mutex_unlock(&dpll_lock); 703 } 704 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); 705 706 static struct dpll_device_registration * 707 dpll_device_registration_first(struct dpll_device *dpll) 708 { 709 struct dpll_device_registration *reg; 710 711 reg = list_first_entry_or_null((struct list_head *)&dpll->registration_list, 712 struct dpll_device_registration, list); 713 WARN_ON(!reg); 714 return reg; 715 } 716 717 void *dpll_priv(struct dpll_device *dpll) 718 { 719 struct dpll_device_registration *reg; 720 721 reg = dpll_device_registration_first(dpll); 722 return reg->priv; 723 } 724 725 const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) 726 { 727 struct dpll_device_registration *reg; 728 729 reg = dpll_device_registration_first(dpll); 730 return reg->ops; 731 } 732 733 static struct dpll_pin_registration * 734 dpll_pin_registration_first(struct dpll_pin_ref *ref) 735 { 736 struct dpll_pin_registration *reg; 737 738 reg = list_first_entry_or_null(&ref->registration_list, 739 struct dpll_pin_registration, list); 740 WARN_ON(!reg); 741 return reg; 742 } 743 744 void *dpll_pin_on_dpll_priv(struct dpll_device *dpll, 745 struct dpll_pin *pin) 746 { 747 struct dpll_pin_registration *reg; 748 struct dpll_pin_ref *ref; 749 750 ref = xa_load(&dpll->pin_refs, pin->pin_idx); 751 if (!ref) 752 return NULL; 753 reg = dpll_pin_registration_first(ref); 754 return reg->priv; 755 } 756 757 void *dpll_pin_on_pin_priv(struct dpll_pin *parent, 758 struct dpll_pin *pin) 759 { 760 struct dpll_pin_registration *reg; 761 struct dpll_pin_ref *ref; 762 763 ref = xa_load(&pin->parent_refs, parent->pin_idx); 764 if (!ref) 765 return NULL; 766 reg = dpll_pin_registration_first(ref); 767 return reg->priv; 768 } 769 770 const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref) 771 { 772 struct dpll_pin_registration *reg; 773 774 reg = dpll_pin_registration_first(ref); 775 return reg->ops; 776 } 777 778 static int __init dpll_init(void) 779 { 780 int ret; 781 782 ret = genl_register_family(&dpll_nl_family); 783 if (ret) 784 goto error; 785 786 return 0; 787 788 error: 789 mutex_destroy(&dpll_lock); 790 return ret; 791 } 792 793 static void __exit dpll_exit(void) 794 { 795 genl_unregister_family(&dpll_nl_family); 796 mutex_destroy(&dpll_lock); 797 } 798 799 subsys_initcall(dpll_init); 800 module_exit(dpll_exit); 801