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_DPLL_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 void dpll_pin_prop_free(struct dpll_pin_properties *prop) 429 { 430 kfree(prop->package_label); 431 kfree(prop->panel_label); 432 kfree(prop->board_label); 433 kfree(prop->freq_supported); 434 } 435 436 static int dpll_pin_prop_dup(const struct dpll_pin_properties *src, 437 struct dpll_pin_properties *dst) 438 { 439 memcpy(dst, src, sizeof(*dst)); 440 if (src->freq_supported && src->freq_supported_num) { 441 size_t freq_size = src->freq_supported_num * 442 sizeof(*src->freq_supported); 443 dst->freq_supported = kmemdup(src->freq_supported, 444 freq_size, GFP_KERNEL); 445 if (!src->freq_supported) 446 return -ENOMEM; 447 } 448 if (src->board_label) { 449 dst->board_label = kstrdup(src->board_label, GFP_KERNEL); 450 if (!dst->board_label) 451 goto err_board_label; 452 } 453 if (src->panel_label) { 454 dst->panel_label = kstrdup(src->panel_label, GFP_KERNEL); 455 if (!dst->panel_label) 456 goto err_panel_label; 457 } 458 if (src->package_label) { 459 dst->package_label = kstrdup(src->package_label, GFP_KERNEL); 460 if (!dst->package_label) 461 goto err_package_label; 462 } 463 464 return 0; 465 466 err_package_label: 467 kfree(dst->panel_label); 468 err_panel_label: 469 kfree(dst->board_label); 470 err_board_label: 471 kfree(dst->freq_supported); 472 return -ENOMEM; 473 } 474 475 static struct dpll_pin * 476 dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, 477 const struct dpll_pin_properties *prop) 478 { 479 struct dpll_pin *pin; 480 int ret; 481 482 pin = kzalloc(sizeof(*pin), GFP_KERNEL); 483 if (!pin) 484 return ERR_PTR(-ENOMEM); 485 pin->pin_idx = pin_idx; 486 pin->clock_id = clock_id; 487 pin->module = module; 488 if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX || 489 prop->type > DPLL_PIN_TYPE_MAX)) { 490 ret = -EINVAL; 491 goto err_pin_prop; 492 } 493 ret = dpll_pin_prop_dup(prop, &pin->prop); 494 if (ret) 495 goto err_pin_prop; 496 refcount_set(&pin->refcount, 1); 497 xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC); 498 xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC); 499 ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b, 500 &dpll_pin_xa_id, GFP_KERNEL); 501 if (ret) 502 goto err_xa_alloc; 503 return pin; 504 err_xa_alloc: 505 xa_destroy(&pin->dpll_refs); 506 xa_destroy(&pin->parent_refs); 507 dpll_pin_prop_free(&pin->prop); 508 err_pin_prop: 509 kfree(pin); 510 return ERR_PTR(ret); 511 } 512 513 /** 514 * dpll_pin_get - find existing or create new dpll pin 515 * @clock_id: clock_id of creator 516 * @pin_idx: idx given by dev driver 517 * @module: reference to registering module 518 * @prop: dpll pin properties 519 * 520 * Get existing object of a pin (unique for given arguments) or create new 521 * if doesn't exist yet. 522 * 523 * Context: Acquires a lock (dpll_lock) 524 * Return: 525 * * valid allocated dpll_pin struct pointer if succeeded 526 * * ERR_PTR(X) - error 527 */ 528 struct dpll_pin * 529 dpll_pin_get(u64 clock_id, u32 pin_idx, struct module *module, 530 const struct dpll_pin_properties *prop) 531 { 532 struct dpll_pin *pos, *ret = NULL; 533 unsigned long i; 534 535 mutex_lock(&dpll_lock); 536 xa_for_each(&dpll_pin_xa, i, pos) { 537 if (pos->clock_id == clock_id && 538 pos->pin_idx == pin_idx && 539 pos->module == module) { 540 ret = pos; 541 refcount_inc(&ret->refcount); 542 break; 543 } 544 } 545 if (!ret) 546 ret = dpll_pin_alloc(clock_id, pin_idx, module, prop); 547 mutex_unlock(&dpll_lock); 548 549 return ret; 550 } 551 EXPORT_SYMBOL_GPL(dpll_pin_get); 552 553 /** 554 * dpll_pin_put - decrease the refcount and free memory if possible 555 * @pin: pointer to a pin to be put 556 * 557 * Drop reference for a pin, if all references are gone, delete pin object. 558 * 559 * Context: Acquires a lock (dpll_lock) 560 */ 561 void dpll_pin_put(struct dpll_pin *pin) 562 { 563 mutex_lock(&dpll_lock); 564 if (refcount_dec_and_test(&pin->refcount)) { 565 xa_erase(&dpll_pin_xa, pin->id); 566 xa_destroy(&pin->dpll_refs); 567 xa_destroy(&pin->parent_refs); 568 dpll_pin_prop_free(&pin->prop); 569 kfree(pin); 570 } 571 mutex_unlock(&dpll_lock); 572 } 573 EXPORT_SYMBOL_GPL(dpll_pin_put); 574 575 static int 576 __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 577 const struct dpll_pin_ops *ops, void *priv) 578 { 579 int ret; 580 581 ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv); 582 if (ret) 583 return ret; 584 ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv); 585 if (ret) 586 goto ref_pin_del; 587 xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 588 dpll_pin_create_ntf(pin); 589 590 return ret; 591 592 ref_pin_del: 593 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); 594 return ret; 595 } 596 597 /** 598 * dpll_pin_register - register the dpll pin in the subsystem 599 * @dpll: pointer to a dpll 600 * @pin: pointer to a dpll pin 601 * @ops: ops for a dpll pin ops 602 * @priv: pointer to private information of owner 603 * 604 * Context: Acquires a lock (dpll_lock) 605 * Return: 606 * * 0 on success 607 * * negative - error value 608 */ 609 int 610 dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 611 const struct dpll_pin_ops *ops, void *priv) 612 { 613 int ret; 614 615 if (WARN_ON(!ops) || 616 WARN_ON(!ops->state_on_dpll_get) || 617 WARN_ON(!ops->direction_get)) 618 return -EINVAL; 619 620 mutex_lock(&dpll_lock); 621 if (WARN_ON(!(dpll->module == pin->module && 622 dpll->clock_id == pin->clock_id))) 623 ret = -EINVAL; 624 else 625 ret = __dpll_pin_register(dpll, pin, ops, priv); 626 mutex_unlock(&dpll_lock); 627 628 return ret; 629 } 630 EXPORT_SYMBOL_GPL(dpll_pin_register); 631 632 static void 633 __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 634 const struct dpll_pin_ops *ops, void *priv) 635 { 636 ASSERT_DPLL_PIN_REGISTERED(pin); 637 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); 638 dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv); 639 if (xa_empty(&pin->dpll_refs)) 640 xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 641 } 642 643 /** 644 * dpll_pin_unregister - unregister dpll pin from dpll device 645 * @dpll: registered dpll pointer 646 * @pin: pointer to a pin 647 * @ops: ops for a dpll pin 648 * @priv: pointer to private information of owner 649 * 650 * Note: It does not free the memory 651 * Context: Acquires a lock (dpll_lock) 652 */ 653 void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 654 const struct dpll_pin_ops *ops, void *priv) 655 { 656 if (WARN_ON(xa_empty(&dpll->pin_refs))) 657 return; 658 if (WARN_ON(!xa_empty(&pin->parent_refs))) 659 return; 660 661 mutex_lock(&dpll_lock); 662 dpll_pin_delete_ntf(pin); 663 __dpll_pin_unregister(dpll, pin, ops, priv); 664 mutex_unlock(&dpll_lock); 665 } 666 EXPORT_SYMBOL_GPL(dpll_pin_unregister); 667 668 /** 669 * dpll_pin_on_pin_register - register a pin with a parent pin 670 * @parent: pointer to a parent pin 671 * @pin: pointer to a pin 672 * @ops: ops for a dpll pin 673 * @priv: pointer to private information of owner 674 * 675 * Register a pin with a parent pin, create references between them and 676 * between newly registered pin and dplls connected with a parent pin. 677 * 678 * Context: Acquires a lock (dpll_lock) 679 * Return: 680 * * 0 on success 681 * * negative - error value 682 */ 683 int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, 684 const struct dpll_pin_ops *ops, void *priv) 685 { 686 struct dpll_pin_ref *ref; 687 unsigned long i, stop; 688 int ret; 689 690 if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX)) 691 return -EINVAL; 692 693 if (WARN_ON(!ops) || 694 WARN_ON(!ops->state_on_pin_get) || 695 WARN_ON(!ops->direction_get)) 696 return -EINVAL; 697 698 mutex_lock(&dpll_lock); 699 ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv); 700 if (ret) 701 goto unlock; 702 refcount_inc(&pin->refcount); 703 xa_for_each(&parent->dpll_refs, i, ref) { 704 ret = __dpll_pin_register(ref->dpll, pin, ops, priv); 705 if (ret) { 706 stop = i; 707 goto dpll_unregister; 708 } 709 dpll_pin_create_ntf(pin); 710 } 711 mutex_unlock(&dpll_lock); 712 713 return ret; 714 715 dpll_unregister: 716 xa_for_each(&parent->dpll_refs, i, ref) 717 if (i < stop) { 718 __dpll_pin_unregister(ref->dpll, pin, ops, priv); 719 dpll_pin_delete_ntf(pin); 720 } 721 refcount_dec(&pin->refcount); 722 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); 723 unlock: 724 mutex_unlock(&dpll_lock); 725 return ret; 726 } 727 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register); 728 729 /** 730 * dpll_pin_on_pin_unregister - unregister dpll pin from a parent pin 731 * @parent: pointer to a parent pin 732 * @pin: pointer to a pin 733 * @ops: ops for a dpll pin 734 * @priv: pointer to private information of owner 735 * 736 * Context: Acquires a lock (dpll_lock) 737 * Note: It does not free the memory 738 */ 739 void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, 740 const struct dpll_pin_ops *ops, void *priv) 741 { 742 struct dpll_pin_ref *ref; 743 unsigned long i; 744 745 mutex_lock(&dpll_lock); 746 dpll_pin_delete_ntf(pin); 747 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); 748 refcount_dec(&pin->refcount); 749 xa_for_each(&pin->dpll_refs, i, ref) 750 __dpll_pin_unregister(ref->dpll, pin, ops, priv); 751 mutex_unlock(&dpll_lock); 752 } 753 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); 754 755 static struct dpll_device_registration * 756 dpll_device_registration_first(struct dpll_device *dpll) 757 { 758 struct dpll_device_registration *reg; 759 760 reg = list_first_entry_or_null((struct list_head *)&dpll->registration_list, 761 struct dpll_device_registration, list); 762 WARN_ON(!reg); 763 return reg; 764 } 765 766 void *dpll_priv(struct dpll_device *dpll) 767 { 768 struct dpll_device_registration *reg; 769 770 reg = dpll_device_registration_first(dpll); 771 return reg->priv; 772 } 773 774 const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) 775 { 776 struct dpll_device_registration *reg; 777 778 reg = dpll_device_registration_first(dpll); 779 return reg->ops; 780 } 781 782 static struct dpll_pin_registration * 783 dpll_pin_registration_first(struct dpll_pin_ref *ref) 784 { 785 struct dpll_pin_registration *reg; 786 787 reg = list_first_entry_or_null(&ref->registration_list, 788 struct dpll_pin_registration, list); 789 WARN_ON(!reg); 790 return reg; 791 } 792 793 void *dpll_pin_on_dpll_priv(struct dpll_device *dpll, 794 struct dpll_pin *pin) 795 { 796 struct dpll_pin_registration *reg; 797 struct dpll_pin_ref *ref; 798 799 ref = xa_load(&dpll->pin_refs, pin->pin_idx); 800 if (!ref) 801 return NULL; 802 reg = dpll_pin_registration_first(ref); 803 return reg->priv; 804 } 805 806 void *dpll_pin_on_pin_priv(struct dpll_pin *parent, 807 struct dpll_pin *pin) 808 { 809 struct dpll_pin_registration *reg; 810 struct dpll_pin_ref *ref; 811 812 ref = xa_load(&pin->parent_refs, parent->pin_idx); 813 if (!ref) 814 return NULL; 815 reg = dpll_pin_registration_first(ref); 816 return reg->priv; 817 } 818 819 const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref) 820 { 821 struct dpll_pin_registration *reg; 822 823 reg = dpll_pin_registration_first(ref); 824 return reg->ops; 825 } 826 827 static int __init dpll_init(void) 828 { 829 int ret; 830 831 ret = genl_register_family(&dpll_nl_family); 832 if (ret) 833 goto error; 834 835 return 0; 836 837 error: 838 mutex_destroy(&dpll_lock); 839 return ret; 840 } 841 842 static void __exit dpll_exit(void) 843 { 844 genl_unregister_family(&dpll_nl_family); 845 mutex_destroy(&dpll_lock); 846 } 847 848 subsys_initcall(dpll_init); 849 module_exit(dpll_exit); 850