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/idr.h> 14 #include <linux/module.h> 15 #include <linux/property.h> 16 #include <linux/slab.h> 17 #include <linux/string.h> 18 19 #include "dpll_core.h" 20 #include "dpll_netlink.h" 21 22 /* Mutex lock to protect DPLL subsystem devices and pins */ 23 DEFINE_MUTEX(dpll_lock); 24 25 DEFINE_XARRAY_FLAGS(dpll_device_xa, XA_FLAGS_ALLOC); 26 DEFINE_XARRAY_FLAGS(dpll_pin_xa, XA_FLAGS_ALLOC); 27 28 static RAW_NOTIFIER_HEAD(dpll_notifier_chain); 29 static DEFINE_IDA(dpll_pin_idx_ida); 30 31 static u32 dpll_device_xa_id; 32 static u32 dpll_pin_xa_id; 33 34 #define ASSERT_DPLL_REGISTERED(d) \ 35 WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) 36 #define ASSERT_DPLL_NOT_REGISTERED(d) \ 37 WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED)) 38 #define ASSERT_DPLL_PIN_REGISTERED(p) \ 39 WARN_ON_ONCE(!xa_get_mark(&dpll_pin_xa, (p)->id, DPLL_REGISTERED)) 40 41 struct dpll_device_registration { 42 struct list_head list; 43 const struct dpll_device_ops *ops; 44 void *priv; 45 dpll_tracker tracker; 46 }; 47 48 struct dpll_pin_registration { 49 struct list_head list; 50 const struct dpll_pin_ops *ops; 51 void *priv; 52 void *cookie; 53 dpll_tracker tracker; 54 }; 55 56 static int call_dpll_notifiers(unsigned long action, void *info) 57 { 58 lockdep_assert_held(&dpll_lock); 59 return raw_notifier_call_chain(&dpll_notifier_chain, action, info); 60 } 61 62 void dpll_device_notify(struct dpll_device *dpll, unsigned long action) 63 { 64 struct dpll_device_notifier_info info = { 65 .dpll = dpll, 66 .id = dpll->id, 67 .idx = dpll->device_idx, 68 .clock_id = dpll->clock_id, 69 .type = dpll->type, 70 }; 71 72 call_dpll_notifiers(action, &info); 73 } 74 75 void dpll_pin_notify(struct dpll_pin *pin, unsigned long action) 76 { 77 struct dpll_pin_notifier_info info = { 78 .pin = pin, 79 .id = pin->id, 80 .idx = pin->pin_idx, 81 .clock_id = pin->clock_id, 82 .fwnode = pin->fwnode, 83 .prop = &pin->prop, 84 }; 85 86 call_dpll_notifiers(action, &info); 87 } 88 89 static void dpll_device_tracker_alloc(struct dpll_device *dpll, 90 dpll_tracker *tracker) 91 { 92 #ifdef CONFIG_DPLL_REFCNT_TRACKER 93 ref_tracker_alloc(&dpll->refcnt_tracker, tracker, GFP_KERNEL); 94 #endif 95 } 96 97 static void dpll_device_tracker_free(struct dpll_device *dpll, 98 dpll_tracker *tracker) 99 { 100 #ifdef CONFIG_DPLL_REFCNT_TRACKER 101 ref_tracker_free(&dpll->refcnt_tracker, tracker); 102 #endif 103 } 104 105 static void __dpll_device_hold(struct dpll_device *dpll, dpll_tracker *tracker) 106 { 107 dpll_device_tracker_alloc(dpll, tracker); 108 refcount_inc(&dpll->refcount); 109 } 110 111 static void __dpll_device_put(struct dpll_device *dpll, dpll_tracker *tracker) 112 { 113 dpll_device_tracker_free(dpll, tracker); 114 if (refcount_dec_and_test(&dpll->refcount)) { 115 ASSERT_DPLL_NOT_REGISTERED(dpll); 116 WARN_ON_ONCE(!xa_empty(&dpll->pin_refs)); 117 xa_destroy(&dpll->pin_refs); 118 xa_erase(&dpll_device_xa, dpll->id); 119 WARN_ON(!list_empty(&dpll->registration_list)); 120 ref_tracker_dir_exit(&dpll->refcnt_tracker); 121 kfree(dpll); 122 } 123 } 124 125 static void dpll_pin_tracker_alloc(struct dpll_pin *pin, dpll_tracker *tracker) 126 { 127 #ifdef CONFIG_DPLL_REFCNT_TRACKER 128 ref_tracker_alloc(&pin->refcnt_tracker, tracker, GFP_KERNEL); 129 #endif 130 } 131 132 static void dpll_pin_tracker_free(struct dpll_pin *pin, dpll_tracker *tracker) 133 { 134 #ifdef CONFIG_DPLL_REFCNT_TRACKER 135 ref_tracker_free(&pin->refcnt_tracker, tracker); 136 #endif 137 } 138 139 static void __dpll_pin_hold(struct dpll_pin *pin, dpll_tracker *tracker) 140 { 141 dpll_pin_tracker_alloc(pin, tracker); 142 refcount_inc(&pin->refcount); 143 } 144 145 static void dpll_pin_idx_free(u32 pin_idx); 146 static void dpll_pin_prop_free(struct dpll_pin_properties *prop); 147 148 static void __dpll_pin_put(struct dpll_pin *pin, dpll_tracker *tracker) 149 { 150 dpll_pin_tracker_free(pin, tracker); 151 if (refcount_dec_and_test(&pin->refcount)) { 152 xa_erase(&dpll_pin_xa, pin->id); 153 xa_destroy(&pin->dpll_refs); 154 xa_destroy(&pin->parent_refs); 155 xa_destroy(&pin->ref_sync_pins); 156 dpll_pin_prop_free(&pin->prop); 157 fwnode_handle_put(pin->fwnode); 158 dpll_pin_idx_free(pin->pin_idx); 159 ref_tracker_dir_exit(&pin->refcnt_tracker); 160 kfree_rcu(pin, rcu); 161 } 162 } 163 164 struct dpll_device *dpll_device_get_by_id(int id) 165 { 166 if (xa_get_mark(&dpll_device_xa, id, DPLL_REGISTERED)) 167 return xa_load(&dpll_device_xa, id); 168 169 return NULL; 170 } 171 172 static struct dpll_pin_registration * 173 dpll_pin_registration_find(struct dpll_pin_ref *ref, 174 const struct dpll_pin_ops *ops, void *priv, 175 void *cookie) 176 { 177 struct dpll_pin_registration *reg; 178 179 list_for_each_entry(reg, &ref->registration_list, list) { 180 if (reg->ops == ops && reg->priv == priv && 181 reg->cookie == cookie) 182 return reg; 183 } 184 return NULL; 185 } 186 187 static int 188 dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, 189 const struct dpll_pin_ops *ops, void *priv, 190 void *cookie) 191 { 192 struct dpll_pin_registration *reg; 193 struct dpll_pin_ref *ref; 194 bool ref_exists = false; 195 unsigned long i; 196 int ret; 197 198 xa_for_each(xa_pins, i, ref) { 199 if (ref->pin != pin) 200 continue; 201 reg = dpll_pin_registration_find(ref, ops, priv, cookie); 202 if (reg) 203 return -EEXIST; 204 ref_exists = true; 205 break; 206 } 207 208 if (!ref_exists) { 209 ref = kzalloc_obj(*ref); 210 if (!ref) 211 return -ENOMEM; 212 ref->pin = pin; 213 INIT_LIST_HEAD(&ref->registration_list); 214 ret = xa_insert(xa_pins, pin->pin_idx, ref, GFP_KERNEL); 215 if (ret) { 216 kfree(ref); 217 return ret; 218 } 219 refcount_set(&ref->refcount, 1); 220 } 221 222 reg = kzalloc_obj(*reg); 223 if (!reg) { 224 if (!ref_exists) { 225 xa_erase(xa_pins, pin->pin_idx); 226 kfree(ref); 227 } 228 return -ENOMEM; 229 } 230 reg->ops = ops; 231 reg->priv = priv; 232 reg->cookie = cookie; 233 __dpll_pin_hold(pin, ®->tracker); 234 if (ref_exists) 235 refcount_inc(&ref->refcount); 236 list_add_tail(®->list, &ref->registration_list); 237 238 return 0; 239 } 240 241 static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin, 242 const struct dpll_pin_ops *ops, void *priv, 243 void *cookie) 244 { 245 struct dpll_pin_registration *reg; 246 struct dpll_pin_ref *ref; 247 unsigned long i; 248 249 xa_for_each(xa_pins, i, ref) { 250 if (ref->pin != pin) 251 continue; 252 reg = dpll_pin_registration_find(ref, ops, priv, cookie); 253 if (WARN_ON(!reg)) 254 return -EINVAL; 255 list_del(®->list); 256 __dpll_pin_put(pin, ®->tracker); 257 kfree(reg); 258 if (refcount_dec_and_test(&ref->refcount)) { 259 xa_erase(xa_pins, i); 260 WARN_ON(!list_empty(&ref->registration_list)); 261 kfree(ref); 262 } 263 return 0; 264 } 265 266 return -EINVAL; 267 } 268 269 static int 270 dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, 271 const struct dpll_pin_ops *ops, void *priv, void *cookie) 272 { 273 struct dpll_pin_registration *reg; 274 struct dpll_pin_ref *ref; 275 bool ref_exists = false; 276 unsigned long i; 277 int ret; 278 279 xa_for_each(xa_dplls, i, ref) { 280 if (ref->dpll != dpll) 281 continue; 282 reg = dpll_pin_registration_find(ref, ops, priv, cookie); 283 if (reg) 284 return -EEXIST; 285 ref_exists = true; 286 break; 287 } 288 289 if (!ref_exists) { 290 ref = kzalloc_obj(*ref); 291 if (!ref) 292 return -ENOMEM; 293 ref->dpll = dpll; 294 INIT_LIST_HEAD(&ref->registration_list); 295 ret = xa_insert(xa_dplls, dpll->id, ref, GFP_KERNEL); 296 if (ret) { 297 kfree(ref); 298 return ret; 299 } 300 refcount_set(&ref->refcount, 1); 301 } 302 303 reg = kzalloc_obj(*reg); 304 if (!reg) { 305 if (!ref_exists) { 306 xa_erase(xa_dplls, dpll->id); 307 kfree(ref); 308 } 309 return -ENOMEM; 310 } 311 reg->ops = ops; 312 reg->priv = priv; 313 reg->cookie = cookie; 314 __dpll_device_hold(dpll, ®->tracker); 315 if (ref_exists) 316 refcount_inc(&ref->refcount); 317 list_add_tail(®->list, &ref->registration_list); 318 319 return 0; 320 } 321 322 static void 323 dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll, 324 const struct dpll_pin_ops *ops, void *priv, void *cookie) 325 { 326 struct dpll_pin_registration *reg; 327 struct dpll_pin_ref *ref; 328 unsigned long i; 329 330 xa_for_each(xa_dplls, i, ref) { 331 if (ref->dpll != dpll) 332 continue; 333 reg = dpll_pin_registration_find(ref, ops, priv, cookie); 334 if (WARN_ON(!reg)) 335 return; 336 list_del(®->list); 337 __dpll_device_put(dpll, ®->tracker); 338 kfree(reg); 339 if (refcount_dec_and_test(&ref->refcount)) { 340 xa_erase(xa_dplls, i); 341 WARN_ON(!list_empty(&ref->registration_list)); 342 kfree(ref); 343 } 344 return; 345 } 346 } 347 348 struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs) 349 { 350 struct dpll_pin_ref *ref; 351 unsigned long i = 0; 352 353 ref = xa_find(xa_refs, &i, ULONG_MAX, XA_PRESENT); 354 WARN_ON(!ref); 355 return ref; 356 } 357 358 static struct dpll_device * 359 dpll_device_alloc(const u64 clock_id, u32 device_idx, struct module *module) 360 { 361 struct dpll_device *dpll; 362 int ret; 363 364 dpll = kzalloc_obj(*dpll); 365 if (!dpll) 366 return ERR_PTR(-ENOMEM); 367 refcount_set(&dpll->refcount, 1); 368 INIT_LIST_HEAD(&dpll->registration_list); 369 dpll->device_idx = device_idx; 370 dpll->clock_id = clock_id; 371 dpll->module = module; 372 ret = xa_alloc_cyclic(&dpll_device_xa, &dpll->id, dpll, xa_limit_32b, 373 &dpll_device_xa_id, GFP_KERNEL); 374 if (ret < 0) { 375 kfree(dpll); 376 return ERR_PTR(ret); 377 } 378 xa_init_flags(&dpll->pin_refs, XA_FLAGS_ALLOC); 379 ref_tracker_dir_init(&dpll->refcnt_tracker, 128, "dpll_device"); 380 381 return dpll; 382 } 383 384 /** 385 * dpll_device_get - find existing or create new dpll device 386 * @clock_id: clock_id of creator 387 * @device_idx: idx given by device driver 388 * @module: reference to registering module 389 * @tracker: tracking object for the acquired reference 390 * 391 * Get existing object of a dpll device, unique for given arguments. 392 * Create new if doesn't exist yet. 393 * 394 * Context: Acquires a lock (dpll_lock) 395 * Return: 396 * * valid dpll_device struct pointer if succeeded 397 * * ERR_PTR(X) - error 398 */ 399 struct dpll_device * 400 dpll_device_get(u64 clock_id, u32 device_idx, struct module *module, 401 dpll_tracker *tracker) 402 { 403 struct dpll_device *dpll, *ret = NULL; 404 unsigned long index; 405 406 mutex_lock(&dpll_lock); 407 xa_for_each(&dpll_device_xa, index, dpll) { 408 if (dpll->clock_id == clock_id && 409 dpll->device_idx == device_idx && 410 dpll->module == module) { 411 __dpll_device_hold(dpll, tracker); 412 ret = dpll; 413 break; 414 } 415 } 416 if (!ret) { 417 ret = dpll_device_alloc(clock_id, device_idx, module); 418 if (!IS_ERR(ret)) 419 dpll_device_tracker_alloc(ret, tracker); 420 } 421 422 mutex_unlock(&dpll_lock); 423 424 return ret; 425 } 426 EXPORT_SYMBOL_GPL(dpll_device_get); 427 428 /** 429 * dpll_device_put - decrease the refcount and free memory if possible 430 * @dpll: dpll_device struct pointer 431 * @tracker: tracking object for the acquired reference 432 * 433 * Context: Acquires a lock (dpll_lock) 434 * Drop reference for a dpll device, if all references are gone, delete 435 * dpll device object. 436 */ 437 void dpll_device_put(struct dpll_device *dpll, dpll_tracker *tracker) 438 { 439 mutex_lock(&dpll_lock); 440 __dpll_device_put(dpll, tracker); 441 mutex_unlock(&dpll_lock); 442 } 443 EXPORT_SYMBOL_GPL(dpll_device_put); 444 445 static struct dpll_device_registration * 446 dpll_device_registration_find(struct dpll_device *dpll, 447 const struct dpll_device_ops *ops, void *priv) 448 { 449 struct dpll_device_registration *reg; 450 451 list_for_each_entry(reg, &dpll->registration_list, list) { 452 if (reg->ops == ops && reg->priv == priv) 453 return reg; 454 } 455 return NULL; 456 } 457 458 /** 459 * dpll_device_register - register the dpll device in the subsystem 460 * @dpll: pointer to a dpll 461 * @type: type of a dpll 462 * @ops: ops for a dpll device 463 * @priv: pointer to private information of owner 464 * 465 * Make dpll device available for user space. 466 * 467 * Context: Acquires a lock (dpll_lock) 468 * Return: 469 * * 0 on success 470 * * negative - error value 471 */ 472 int dpll_device_register(struct dpll_device *dpll, enum dpll_type type, 473 const struct dpll_device_ops *ops, void *priv) 474 { 475 struct dpll_device_registration *reg; 476 bool first_registration = false; 477 478 if (WARN_ON(!ops)) 479 return -EINVAL; 480 if (WARN_ON(!ops->mode_get)) 481 return -EINVAL; 482 if (WARN_ON(!ops->lock_status_get)) 483 return -EINVAL; 484 if (WARN_ON(type < DPLL_TYPE_PPS || type > DPLL_TYPE_MAX)) 485 return -EINVAL; 486 487 mutex_lock(&dpll_lock); 488 reg = dpll_device_registration_find(dpll, ops, priv); 489 if (reg) { 490 mutex_unlock(&dpll_lock); 491 return -EEXIST; 492 } 493 494 reg = kzalloc_obj(*reg); 495 if (!reg) { 496 mutex_unlock(&dpll_lock); 497 return -ENOMEM; 498 } 499 reg->ops = ops; 500 reg->priv = priv; 501 dpll->type = type; 502 __dpll_device_hold(dpll, ®->tracker); 503 first_registration = list_empty(&dpll->registration_list); 504 list_add_tail(®->list, &dpll->registration_list); 505 if (!first_registration) { 506 mutex_unlock(&dpll_lock); 507 return 0; 508 } 509 510 xa_set_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED); 511 dpll_device_create_ntf(dpll); 512 mutex_unlock(&dpll_lock); 513 514 return 0; 515 } 516 EXPORT_SYMBOL_GPL(dpll_device_register); 517 518 /** 519 * dpll_device_unregister - unregister dpll device 520 * @dpll: registered dpll pointer 521 * @ops: ops for a dpll device 522 * @priv: pointer to private information of owner 523 * 524 * Unregister device, make it unavailable for userspace. 525 * Note: It does not free the memory 526 * Context: Acquires a lock (dpll_lock) 527 */ 528 void dpll_device_unregister(struct dpll_device *dpll, 529 const struct dpll_device_ops *ops, void *priv) 530 { 531 struct dpll_device_registration *reg; 532 533 mutex_lock(&dpll_lock); 534 ASSERT_DPLL_REGISTERED(dpll); 535 dpll_device_delete_ntf(dpll); 536 reg = dpll_device_registration_find(dpll, ops, priv); 537 if (WARN_ON(!reg)) { 538 mutex_unlock(&dpll_lock); 539 return; 540 } 541 list_del(®->list); 542 __dpll_device_put(dpll, ®->tracker); 543 kfree(reg); 544 545 if (!list_empty(&dpll->registration_list)) { 546 mutex_unlock(&dpll_lock); 547 return; 548 } 549 xa_clear_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED); 550 mutex_unlock(&dpll_lock); 551 } 552 EXPORT_SYMBOL_GPL(dpll_device_unregister); 553 554 static int dpll_pin_idx_alloc(u32 *pin_idx) 555 { 556 int ret; 557 558 if (!pin_idx) 559 return -EINVAL; 560 561 /* Alloc unique number from IDA. Number belongs to <0, INT_MAX> range */ 562 ret = ida_alloc(&dpll_pin_idx_ida, GFP_KERNEL); 563 if (ret < 0) 564 return ret; 565 566 /* Map the value to dynamic pin index range <INT_MAX+1, U32_MAX> */ 567 *pin_idx = (u32)ret + INT_MAX + 1; 568 569 return 0; 570 } 571 572 static void dpll_pin_idx_free(u32 pin_idx) 573 { 574 if (pin_idx <= INT_MAX) 575 return; /* Not a dynamic pin index */ 576 577 /* Map the index value from dynamic pin index range to IDA range and 578 * free it. 579 */ 580 pin_idx -= (u32)INT_MAX + 1; 581 ida_free(&dpll_pin_idx_ida, pin_idx); 582 } 583 584 static void dpll_pin_prop_free(struct dpll_pin_properties *prop) 585 { 586 kfree(prop->package_label); 587 kfree(prop->panel_label); 588 kfree(prop->board_label); 589 kfree(prop->freq_supported); 590 } 591 592 static int dpll_pin_prop_dup(const struct dpll_pin_properties *src, 593 struct dpll_pin_properties *dst) 594 { 595 if (WARN_ON(src->freq_supported && !src->freq_supported_num)) 596 return -EINVAL; 597 598 memcpy(dst, src, sizeof(*dst)); 599 if (src->freq_supported) { 600 size_t freq_size = src->freq_supported_num * 601 sizeof(*src->freq_supported); 602 dst->freq_supported = kmemdup(src->freq_supported, 603 freq_size, GFP_KERNEL); 604 if (!dst->freq_supported) 605 return -ENOMEM; 606 } 607 if (src->board_label) { 608 dst->board_label = kstrdup(src->board_label, GFP_KERNEL); 609 if (!dst->board_label) 610 goto err_board_label; 611 } 612 if (src->panel_label) { 613 dst->panel_label = kstrdup(src->panel_label, GFP_KERNEL); 614 if (!dst->panel_label) 615 goto err_panel_label; 616 } 617 if (src->package_label) { 618 dst->package_label = kstrdup(src->package_label, GFP_KERNEL); 619 if (!dst->package_label) 620 goto err_package_label; 621 } 622 623 return 0; 624 625 err_package_label: 626 kfree(dst->panel_label); 627 err_panel_label: 628 kfree(dst->board_label); 629 err_board_label: 630 kfree(dst->freq_supported); 631 return -ENOMEM; 632 } 633 634 static struct dpll_pin * 635 dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, 636 const struct dpll_pin_properties *prop) 637 { 638 struct dpll_pin *pin; 639 int ret; 640 641 if (pin_idx == DPLL_PIN_IDX_UNSPEC) { 642 ret = dpll_pin_idx_alloc(&pin_idx); 643 if (ret) 644 return ERR_PTR(ret); 645 } else if (pin_idx > INT_MAX) { 646 return ERR_PTR(-EINVAL); 647 } 648 pin = kzalloc_obj(*pin); 649 if (!pin) { 650 ret = -ENOMEM; 651 goto err_pin_alloc; 652 } 653 pin->pin_idx = pin_idx; 654 pin->clock_id = clock_id; 655 pin->module = module; 656 strscpy(pin->module_name, module_name(module)); 657 if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX || 658 prop->type > DPLL_PIN_TYPE_MAX)) { 659 ret = -EINVAL; 660 goto err_pin_prop; 661 } 662 ret = dpll_pin_prop_dup(prop, &pin->prop); 663 if (ret) 664 goto err_pin_prop; 665 refcount_set(&pin->refcount, 1); 666 xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC); 667 xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC); 668 xa_init_flags(&pin->ref_sync_pins, XA_FLAGS_ALLOC); 669 ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b, 670 &dpll_pin_xa_id, GFP_KERNEL); 671 if (ret < 0) 672 goto err_xa_alloc; 673 ref_tracker_dir_init(&pin->refcnt_tracker, 128, "dpll_pin"); 674 return pin; 675 err_xa_alloc: 676 xa_destroy(&pin->dpll_refs); 677 xa_destroy(&pin->parent_refs); 678 xa_destroy(&pin->ref_sync_pins); 679 dpll_pin_prop_free(&pin->prop); 680 err_pin_prop: 681 kfree(pin); 682 err_pin_alloc: 683 dpll_pin_idx_free(pin_idx); 684 return ERR_PTR(ret); 685 } 686 687 static void dpll_netdev_pin_assign(struct net_device *dev, struct dpll_pin *dpll_pin) 688 { 689 rtnl_lock(); 690 rcu_assign_pointer(dev->dpll_pin, dpll_pin); 691 rtnl_unlock(); 692 } 693 694 void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) 695 { 696 WARN_ON(!dpll_pin); 697 dpll_netdev_pin_assign(dev, dpll_pin); 698 } 699 EXPORT_SYMBOL(dpll_netdev_pin_set); 700 701 void dpll_netdev_pin_clear(struct net_device *dev) 702 { 703 dpll_netdev_pin_assign(dev, NULL); 704 } 705 EXPORT_SYMBOL(dpll_netdev_pin_clear); 706 707 int register_dpll_notifier(struct notifier_block *nb) 708 { 709 int ret; 710 711 mutex_lock(&dpll_lock); 712 ret = raw_notifier_chain_register(&dpll_notifier_chain, nb); 713 mutex_unlock(&dpll_lock); 714 return ret; 715 } 716 EXPORT_SYMBOL_GPL(register_dpll_notifier); 717 718 int unregister_dpll_notifier(struct notifier_block *nb) 719 { 720 int ret; 721 722 mutex_lock(&dpll_lock); 723 ret = raw_notifier_chain_unregister(&dpll_notifier_chain, nb); 724 mutex_unlock(&dpll_lock); 725 return ret; 726 } 727 EXPORT_SYMBOL_GPL(unregister_dpll_notifier); 728 729 /** 730 * dpll_pin_get - find existing or create new dpll pin 731 * @clock_id: clock_id of creator 732 * @pin_idx: idx given by dev driver 733 * @module: reference to registering module 734 * @prop: dpll pin properties 735 * @tracker: tracking object for the acquired reference 736 * 737 * Get existing object of a pin (unique for given arguments) or create new 738 * if doesn't exist yet. 739 * 740 * Context: Acquires a lock (dpll_lock) 741 * Return: 742 * * valid allocated dpll_pin struct pointer if succeeded 743 * * ERR_PTR(X) - error 744 */ 745 struct dpll_pin * 746 dpll_pin_get(u64 clock_id, u32 pin_idx, struct module *module, 747 const struct dpll_pin_properties *prop, dpll_tracker *tracker) 748 { 749 struct dpll_pin *pos, *ret = NULL; 750 unsigned long i; 751 752 mutex_lock(&dpll_lock); 753 xa_for_each(&dpll_pin_xa, i, pos) { 754 if (pos->clock_id == clock_id && 755 pos->pin_idx == pin_idx && 756 pos->module == module) { 757 __dpll_pin_hold(pos, tracker); 758 ret = pos; 759 break; 760 } 761 } 762 if (!ret) { 763 ret = dpll_pin_alloc(clock_id, pin_idx, module, prop); 764 if (!IS_ERR(ret)) 765 dpll_pin_tracker_alloc(ret, tracker); 766 } 767 mutex_unlock(&dpll_lock); 768 769 return ret; 770 } 771 EXPORT_SYMBOL_GPL(dpll_pin_get); 772 773 /** 774 * dpll_pin_put - decrease the refcount and free memory if possible 775 * @pin: pointer to a pin to be put 776 * @tracker: tracking object for the acquired reference 777 * 778 * Drop reference for a pin, if all references are gone, delete pin object. 779 * 780 * Context: Acquires a lock (dpll_lock) 781 */ 782 void dpll_pin_put(struct dpll_pin *pin, dpll_tracker *tracker) 783 { 784 mutex_lock(&dpll_lock); 785 __dpll_pin_put(pin, tracker); 786 mutex_unlock(&dpll_lock); 787 } 788 EXPORT_SYMBOL_GPL(dpll_pin_put); 789 790 /** 791 * dpll_pin_fwnode_set - set dpll pin firmware node reference 792 * @pin: pointer to a dpll pin 793 * @fwnode: firmware node handle 794 * 795 * Set firmware node handle for the given dpll pin. 796 */ 797 void dpll_pin_fwnode_set(struct dpll_pin *pin, struct fwnode_handle *fwnode) 798 { 799 mutex_lock(&dpll_lock); 800 fwnode_handle_put(pin->fwnode); /* Drop fwnode previously set */ 801 pin->fwnode = fwnode_handle_get(fwnode); 802 mutex_unlock(&dpll_lock); 803 } 804 EXPORT_SYMBOL_GPL(dpll_pin_fwnode_set); 805 806 /** 807 * fwnode_dpll_pin_find - find dpll pin by firmware node reference 808 * @fwnode: reference to firmware node 809 * @tracker: tracking object for the acquired reference 810 * 811 * Get existing object of a pin that is associated with given firmware node 812 * reference. 813 * 814 * Context: Acquires a lock (dpll_lock) 815 * Return: 816 * * valid dpll_pin pointer on success 817 * * NULL when no such pin exists 818 */ 819 struct dpll_pin *fwnode_dpll_pin_find(struct fwnode_handle *fwnode, 820 dpll_tracker *tracker) 821 { 822 struct dpll_pin *pin, *ret = NULL; 823 unsigned long index; 824 825 mutex_lock(&dpll_lock); 826 xa_for_each(&dpll_pin_xa, index, pin) { 827 if (pin->fwnode == fwnode) { 828 __dpll_pin_hold(pin, tracker); 829 ret = pin; 830 break; 831 } 832 } 833 mutex_unlock(&dpll_lock); 834 835 return ret; 836 } 837 EXPORT_SYMBOL_GPL(fwnode_dpll_pin_find); 838 839 static int 840 __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 841 const struct dpll_pin_ops *ops, void *priv, void *cookie) 842 { 843 int ret; 844 845 ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv, cookie); 846 if (ret) 847 return ret; 848 ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv, cookie); 849 if (ret) 850 goto ref_pin_del; 851 xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 852 dpll_pin_create_ntf(pin); 853 854 return ret; 855 856 ref_pin_del: 857 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); 858 return ret; 859 } 860 861 /** 862 * dpll_pin_register - register the dpll pin in the subsystem 863 * @dpll: pointer to a dpll 864 * @pin: pointer to a dpll pin 865 * @ops: ops for a dpll pin ops 866 * @priv: pointer to private information of owner 867 * 868 * Context: Acquires a lock (dpll_lock) 869 * Return: 870 * * 0 on success 871 * * negative - error value 872 */ 873 int 874 dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, 875 const struct dpll_pin_ops *ops, void *priv) 876 { 877 int ret; 878 879 if (WARN_ON(!ops) || 880 WARN_ON(!ops->state_on_dpll_get) || 881 WARN_ON(!ops->direction_get) || 882 WARN_ON(ops->measured_freq_get && 883 (!dpll_device_ops(dpll)->freq_monitor_get || 884 !dpll_device_ops(dpll)->freq_monitor_set)) || 885 WARN_ON(ops->supported_ffo && !ops->ffo_get)) 886 return -EINVAL; 887 888 mutex_lock(&dpll_lock); 889 890 /* 891 * For pins identified via firmware (pin->fwnode), allow registration 892 * even if the pin's (module, clock_id) differs from the target DPLL. 893 * For non-fwnode pins, require a strict (module, clock_id) match. 894 */ 895 if (!pin->fwnode && 896 WARN_ON_ONCE(dpll->module != pin->module || 897 dpll->clock_id != pin->clock_id)) { 898 ret = -EINVAL; 899 goto out_unlock; 900 } 901 902 ret = __dpll_pin_register(dpll, pin, ops, priv, NULL); 903 out_unlock: 904 mutex_unlock(&dpll_lock); 905 906 return ret; 907 } 908 EXPORT_SYMBOL_GPL(dpll_pin_register); 909 910 static void dpll_pin_ref_sync_pair_del(u32 ref_sync_pin_id) 911 { 912 struct dpll_pin *pin, *ref_sync_pin; 913 unsigned long i; 914 915 xa_for_each(&dpll_pin_xa, i, pin) { 916 ref_sync_pin = xa_load(&pin->ref_sync_pins, ref_sync_pin_id); 917 if (ref_sync_pin) { 918 xa_erase(&pin->ref_sync_pins, ref_sync_pin_id); 919 __dpll_pin_change_ntf(pin); 920 } 921 } 922 } 923 924 static void 925 __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 926 const struct dpll_pin_ops *ops, void *priv, void *cookie) 927 { 928 ASSERT_DPLL_PIN_REGISTERED(pin); 929 dpll_pin_ref_sync_pair_del(pin->id); 930 dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); 931 dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv, cookie); 932 if (xa_empty(&pin->dpll_refs)) 933 xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); 934 } 935 936 /** 937 * dpll_pin_unregister - unregister dpll pin from dpll device 938 * @dpll: registered dpll pointer 939 * @pin: pointer to a pin 940 * @ops: ops for a dpll pin 941 * @priv: pointer to private information of owner 942 * 943 * Note: It does not free the memory 944 * Context: Acquires a lock (dpll_lock) 945 */ 946 void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, 947 const struct dpll_pin_ops *ops, void *priv) 948 { 949 if (WARN_ON(xa_empty(&dpll->pin_refs))) 950 return; 951 if (WARN_ON(!xa_empty(&pin->parent_refs))) 952 return; 953 954 mutex_lock(&dpll_lock); 955 dpll_pin_delete_ntf(pin); 956 __dpll_pin_unregister(dpll, pin, ops, priv, NULL); 957 mutex_unlock(&dpll_lock); 958 } 959 EXPORT_SYMBOL_GPL(dpll_pin_unregister); 960 961 /** 962 * dpll_pin_on_pin_register - register a pin with a parent pin 963 * @parent: pointer to a parent pin 964 * @pin: pointer to a pin 965 * @ops: ops for a dpll pin 966 * @priv: pointer to private information of owner 967 * 968 * Register a pin with a parent pin, create references between them and 969 * between newly registered pin and dplls connected with a parent pin. 970 * 971 * Context: Acquires a lock (dpll_lock) 972 * Return: 973 * * 0 on success 974 * * negative - error value 975 */ 976 int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, 977 const struct dpll_pin_ops *ops, void *priv) 978 { 979 struct dpll_pin_ref *ref; 980 unsigned long i, stop; 981 int ret; 982 983 if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX)) 984 return -EINVAL; 985 986 if (WARN_ON(!ops) || 987 WARN_ON(!ops->state_on_pin_get) || 988 WARN_ON(!ops->direction_get)) 989 return -EINVAL; 990 991 mutex_lock(&dpll_lock); 992 ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv, pin); 993 if (ret) 994 goto unlock; 995 xa_for_each(&parent->dpll_refs, i, ref) { 996 ret = __dpll_pin_register(ref->dpll, pin, ops, priv, parent); 997 if (ret) { 998 stop = i; 999 goto dpll_unregister; 1000 } 1001 dpll_pin_create_ntf(pin); 1002 } 1003 mutex_unlock(&dpll_lock); 1004 1005 return ret; 1006 1007 dpll_unregister: 1008 xa_for_each(&parent->dpll_refs, i, ref) 1009 if (i < stop) { 1010 __dpll_pin_unregister(ref->dpll, pin, ops, priv, 1011 parent); 1012 dpll_pin_delete_ntf(pin); 1013 } 1014 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); 1015 unlock: 1016 mutex_unlock(&dpll_lock); 1017 return ret; 1018 } 1019 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register); 1020 1021 /** 1022 * dpll_pin_on_pin_unregister - unregister dpll pin from a parent pin 1023 * @parent: pointer to a parent pin 1024 * @pin: pointer to a pin 1025 * @ops: ops for a dpll pin 1026 * @priv: pointer to private information of owner 1027 * 1028 * Context: Acquires a lock (dpll_lock) 1029 * Note: It does not free the memory 1030 */ 1031 void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, 1032 const struct dpll_pin_ops *ops, void *priv) 1033 { 1034 struct dpll_pin_registration *reg; 1035 struct dpll_pin_ref *ref; 1036 unsigned long i; 1037 1038 mutex_lock(&dpll_lock); 1039 dpll_pin_delete_ntf(pin); 1040 dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); 1041 xa_for_each(&pin->dpll_refs, i, ref) { 1042 reg = dpll_pin_registration_find(ref, ops, priv, parent); 1043 if (!reg) 1044 continue; 1045 __dpll_pin_unregister(ref->dpll, pin, ops, priv, parent); 1046 } 1047 mutex_unlock(&dpll_lock); 1048 } 1049 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); 1050 1051 /** 1052 * dpll_pin_ref_sync_pair_add - create a reference sync signal pin pair 1053 * @pin: pin which produces the base frequency 1054 * @ref_sync_pin: pin which produces the sync signal 1055 * 1056 * Once pins are paired, the user-space configuration of reference sync pair 1057 * is possible. 1058 * Context: Acquires a lock (dpll_lock) 1059 * Return: 1060 * * 0 on success 1061 * * negative - error value 1062 */ 1063 int dpll_pin_ref_sync_pair_add(struct dpll_pin *pin, 1064 struct dpll_pin *ref_sync_pin) 1065 { 1066 int ret; 1067 1068 mutex_lock(&dpll_lock); 1069 ret = xa_insert(&pin->ref_sync_pins, ref_sync_pin->id, 1070 ref_sync_pin, GFP_KERNEL); 1071 __dpll_pin_change_ntf(pin); 1072 mutex_unlock(&dpll_lock); 1073 1074 return ret; 1075 } 1076 EXPORT_SYMBOL_GPL(dpll_pin_ref_sync_pair_add); 1077 1078 static struct dpll_device_registration * 1079 dpll_device_registration_first(struct dpll_device *dpll) 1080 { 1081 struct dpll_device_registration *reg; 1082 1083 reg = list_first_entry_or_null((struct list_head *)&dpll->registration_list, 1084 struct dpll_device_registration, list); 1085 WARN_ON(!reg); 1086 return reg; 1087 } 1088 1089 void *dpll_priv(struct dpll_device *dpll) 1090 { 1091 struct dpll_device_registration *reg; 1092 1093 reg = dpll_device_registration_first(dpll); 1094 return reg->priv; 1095 } 1096 1097 const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll) 1098 { 1099 struct dpll_device_registration *reg; 1100 1101 reg = dpll_device_registration_first(dpll); 1102 return reg->ops; 1103 } 1104 1105 static struct dpll_pin_registration * 1106 dpll_pin_registration_first(struct dpll_pin_ref *ref) 1107 { 1108 struct dpll_pin_registration *reg; 1109 1110 reg = list_first_entry_or_null(&ref->registration_list, 1111 struct dpll_pin_registration, list); 1112 WARN_ON(!reg); 1113 return reg; 1114 } 1115 1116 void *dpll_pin_on_dpll_priv(struct dpll_device *dpll, 1117 struct dpll_pin *pin) 1118 { 1119 struct dpll_pin_registration *reg; 1120 struct dpll_pin_ref *ref; 1121 1122 ref = xa_load(&dpll->pin_refs, pin->pin_idx); 1123 if (!ref) 1124 return NULL; 1125 reg = dpll_pin_registration_first(ref); 1126 return reg->priv; 1127 } 1128 1129 void *dpll_pin_on_pin_priv(struct dpll_pin *parent, 1130 struct dpll_pin *pin) 1131 { 1132 struct dpll_pin_registration *reg; 1133 struct dpll_pin_ref *ref; 1134 1135 ref = xa_load(&pin->parent_refs, parent->pin_idx); 1136 if (!ref) 1137 return NULL; 1138 reg = dpll_pin_registration_first(ref); 1139 return reg->priv; 1140 } 1141 1142 const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref) 1143 { 1144 struct dpll_pin_registration *reg; 1145 1146 reg = dpll_pin_registration_first(ref); 1147 return reg->ops; 1148 } 1149 1150 static int __init dpll_init(void) 1151 { 1152 int ret; 1153 1154 ret = genl_register_family(&dpll_nl_family); 1155 if (ret) 1156 goto error; 1157 1158 return 0; 1159 1160 error: 1161 mutex_destroy(&dpll_lock); 1162 return ret; 1163 } 1164 1165 static void __exit dpll_exit(void) 1166 { 1167 genl_unregister_family(&dpll_nl_family); 1168 mutex_destroy(&dpll_lock); 1169 } 1170 1171 subsys_initcall(dpll_init); 1172 module_exit(dpll_exit); 1173