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 list_del(®->list); 135 kfree(reg); 136 if (refcount_dec_and_test(&ref->refcount)) { 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 list_del(®->list); 215 kfree(reg); 216 if (refcount_dec_and_test(&ref->refcount)) { 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 static void dpll_netdev_pin_assign(struct net_device *dev, struct dpll_pin *dpll_pin) 514 { 515 rtnl_lock(); 516 rcu_assign_pointer(dev->dpll_pin, dpll_pin); 517 rtnl_unlock(); 518 } 519 520 void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) 521 { 522 WARN_ON(!dpll_pin); 523 dpll_netdev_pin_assign(dev, dpll_pin); 524 } 525 EXPORT_SYMBOL(dpll_netdev_pin_set); 526 527 void dpll_netdev_pin_clear(struct net_device *dev) 528 { 529 dpll_netdev_pin_assign(dev, NULL); 530 } 531 EXPORT_SYMBOL(dpll_netdev_pin_clear); 532 533 /** 534 * dpll_pin_get - find existing or create new dpll pin 535 * @clock_id: clock_id of creator 536 * @pin_idx: idx given by dev driver 537 * @module: reference to registering module 538 * @prop: dpll pin properties 539 * 540 * Get existing object of a pin (unique for given arguments) or create new 541 * if doesn't exist yet. 542 * 543 * Context: Acquires a lock (dpll_lock) 544 * Return: 545 * * valid allocated dpll_pin struct pointer if succeeded 546 * * ERR_PTR(X) - error 547 */ 548 struct dpll_pin * 549 dpll_pin_get(u64 clock_id, u32 pin_idx, struct module *module, 550 const struct dpll_pin_properties *prop) 551 { 552 struct dpll_pin *pos, *ret = NULL; 553 unsigned long i; 554 555 mutex_lock(&dpll_lock); 556 xa_for_each(&dpll_pin_xa, i, pos) { 557 if (pos->clock_id == clock_id && 558 pos->pin_idx == pin_idx && 559 pos->module == module) { 560 ret = pos; 561 refcount_inc(&ret->refcount); 562 break; 563 } 564 } 565 if (!ret) 566 ret = dpll_pin_alloc(clock_id, pin_idx, module, prop); 567 mutex_unlock(&dpll_lock); 568 569 return ret; 570 } 571 EXPORT_SYMBOL_GPL(dpll_pin_get); 572 573 /** 574 * dpll_pin_put - decrease the refcount and free memory if possible 575 * @pin: pointer to a pin to be put 576 * 577 * Drop reference for a pin, if all references are gone, delete pin object. 578 * 579 * Context: Acquires a lock (dpll_lock) 580 */ 581 void dpll_pin_put(struct dpll_pin *pin) 582 { 583 mutex_lock(&dpll_lock); 584 if (refcount_dec_and_test(&pin->refcount)) { 585 xa_erase(&dpll_pin_xa, pin->id); 586 xa_destroy(&pin->dpll_refs); 587 xa_destroy(&pin->parent_refs); 588 dpll_pin_prop_free(&pin->prop); 589 kfree_rcu(pin, rcu); 590 } 591 mutex_unlock(&dpll_lock); 592 } 593 EXPORT_SYMBOL_GPL(dpll_pin_put); 594 595 static int 596 __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 597 const struct dpll_pin_ops *ops, void *priv) 598 { 599 int ret; 600 601 ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv); 602 if (ret) 603 return ret; 604 ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv); 605 if (ret) 606 goto ref_pin_del; 607 xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 608 dpll_pin_create_ntf(pin); 609 610 return ret; 611 612 ref_pin_del: 613 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); 614 return ret; 615 } 616 617 /** 618 * dpll_pin_register - register the dpll pin in the subsystem 619 * @dpll: pointer to a dpll 620 * @pin: pointer to a dpll pin 621 * @ops: ops for a dpll pin ops 622 * @priv: pointer to private information of owner 623 * 624 * Context: Acquires a lock (dpll_lock) 625 * Return: 626 * * 0 on success 627 * * negative - error value 628 */ 629 int 630 dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 631 const struct dpll_pin_ops *ops, void *priv) 632 { 633 int ret; 634 635 if (WARN_ON(!ops) || 636 WARN_ON(!ops->state_on_dpll_get) || 637 WARN_ON(!ops->direction_get)) 638 return -EINVAL; 639 640 mutex_lock(&dpll_lock); 641 if (WARN_ON(!(dpll->module == pin->module && 642 dpll->clock_id == pin->clock_id))) 643 ret = -EINVAL; 644 else 645 ret = __dpll_pin_register(dpll, pin, ops, priv); 646 mutex_unlock(&dpll_lock); 647 648 return ret; 649 } 650 EXPORT_SYMBOL_GPL(dpll_pin_register); 651 652 static void 653 __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 654 const struct dpll_pin_ops *ops, void *priv) 655 { 656 ASSERT_DPLL_PIN_REGISTERED(pin); 657 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv); 658 dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv); 659 if (xa_empty(&pin->dpll_refs)) 660 xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 661 } 662 663 /** 664 * dpll_pin_unregister - unregister dpll pin from dpll device 665 * @dpll: registered dpll pointer 666 * @pin: pointer to a pin 667 * @ops: ops for a dpll pin 668 * @priv: pointer to private information of owner 669 * 670 * Note: It does not free the memory 671 * Context: Acquires a lock (dpll_lock) 672 */ 673 void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 674 const struct dpll_pin_ops *ops, void *priv) 675 { 676 if (WARN_ON(xa_empty(&dpll->pin_refs))) 677 return; 678 if (WARN_ON(!xa_empty(&pin->parent_refs))) 679 return; 680 681 mutex_lock(&dpll_lock); 682 dpll_pin_delete_ntf(pin); 683 __dpll_pin_unregister(dpll, pin, ops, priv); 684 mutex_unlock(&dpll_lock); 685 } 686 EXPORT_SYMBOL_GPL(dpll_pin_unregister); 687 688 /** 689 * dpll_pin_on_pin_register - register a pin with a parent pin 690 * @parent: pointer to a parent pin 691 * @pin: pointer to a pin 692 * @ops: ops for a dpll pin 693 * @priv: pointer to private information of owner 694 * 695 * Register a pin with a parent pin, create references between them and 696 * between newly registered pin and dplls connected with a parent pin. 697 * 698 * Context: Acquires a lock (dpll_lock) 699 * Return: 700 * * 0 on success 701 * * negative - error value 702 */ 703 int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, 704 const struct dpll_pin_ops *ops, void *priv) 705 { 706 struct dpll_pin_ref *ref; 707 unsigned long i, stop; 708 int ret; 709 710 if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX)) 711 return -EINVAL; 712 713 if (WARN_ON(!ops) || 714 WARN_ON(!ops->state_on_pin_get) || 715 WARN_ON(!ops->direction_get)) 716 return -EINVAL; 717 718 mutex_lock(&dpll_lock); 719 ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv); 720 if (ret) 721 goto unlock; 722 refcount_inc(&pin->refcount); 723 xa_for_each(&parent->dpll_refs, i, ref) { 724 ret = __dpll_pin_register(ref->dpll, pin, ops, priv); 725 if (ret) { 726 stop = i; 727 goto dpll_unregister; 728 } 729 dpll_pin_create_ntf(pin); 730 } 731 mutex_unlock(&dpll_lock); 732 733 return ret; 734 735 dpll_unregister: 736 xa_for_each(&parent->dpll_refs, i, ref) 737 if (i < stop) { 738 __dpll_pin_unregister(ref->dpll, pin, ops, priv); 739 dpll_pin_delete_ntf(pin); 740 } 741 refcount_dec(&pin->refcount); 742 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); 743 unlock: 744 mutex_unlock(&dpll_lock); 745 return ret; 746 } 747 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register); 748 749 /** 750 * dpll_pin_on_pin_unregister - unregister dpll pin from a parent pin 751 * @parent: pointer to a parent pin 752 * @pin: pointer to a pin 753 * @ops: ops for a dpll pin 754 * @priv: pointer to private information of owner 755 * 756 * Context: Acquires a lock (dpll_lock) 757 * Note: It does not free the memory 758 */ 759 void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, 760 const struct dpll_pin_ops *ops, void *priv) 761 { 762 struct dpll_pin_ref *ref; 763 unsigned long i; 764 765 mutex_lock(&dpll_lock); 766 dpll_pin_delete_ntf(pin); 767 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv); 768 refcount_dec(&pin->refcount); 769 xa_for_each(&pin->dpll_refs, i, ref) 770 __dpll_pin_unregister(ref->dpll, pin, ops, priv); 771 mutex_unlock(&dpll_lock); 772 } 773 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); 774 775 static struct dpll_device_registration * 776 dpll_device_registration_first(struct dpll_device *dpll) 777 { 778 struct dpll_device_registration *reg; 779 780 reg = list_first_entry_or_null((struct list_head *)&dpll->registration_list, 781 struct dpll_device_registration, list); 782 WARN_ON(!reg); 783 return reg; 784 } 785 786 void *dpll_priv(struct dpll_device *dpll) 787 { 788 struct dpll_device_registration *reg; 789 790 reg = dpll_device_registration_first(dpll); 791 return reg->priv; 792 } 793 794 const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) 795 { 796 struct dpll_device_registration *reg; 797 798 reg = dpll_device_registration_first(dpll); 799 return reg->ops; 800 } 801 802 static struct dpll_pin_registration * 803 dpll_pin_registration_first(struct dpll_pin_ref *ref) 804 { 805 struct dpll_pin_registration *reg; 806 807 reg = list_first_entry_or_null(&ref->registration_list, 808 struct dpll_pin_registration, list); 809 WARN_ON(!reg); 810 return reg; 811 } 812 813 void *dpll_pin_on_dpll_priv(struct dpll_device *dpll, 814 struct dpll_pin *pin) 815 { 816 struct dpll_pin_registration *reg; 817 struct dpll_pin_ref *ref; 818 819 ref = xa_load(&dpll->pin_refs, pin->pin_idx); 820 if (!ref) 821 return NULL; 822 reg = dpll_pin_registration_first(ref); 823 return reg->priv; 824 } 825 826 void *dpll_pin_on_pin_priv(struct dpll_pin *parent, 827 struct dpll_pin *pin) 828 { 829 struct dpll_pin_registration *reg; 830 struct dpll_pin_ref *ref; 831 832 ref = xa_load(&pin->parent_refs, parent->pin_idx); 833 if (!ref) 834 return NULL; 835 reg = dpll_pin_registration_first(ref); 836 return reg->priv; 837 } 838 839 const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref) 840 { 841 struct dpll_pin_registration *reg; 842 843 reg = dpll_pin_registration_first(ref); 844 return reg->ops; 845 } 846 847 static int __init dpll_init(void) 848 { 849 int ret; 850 851 ret = genl_register_family(&dpll_nl_family); 852 if (ret) 853 goto error; 854 855 return 0; 856 857 error: 858 mutex_destroy(&dpll_lock); 859 return ret; 860 } 861 862 static void __exit dpll_exit(void) 863 { 864 genl_unregister_family(&dpll_nl_family); 865 mutex_destroy(&dpll_lock); 866 } 867 868 subsys_initcall(dpll_init); 869 module_exit(dpll_exit); 870