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