Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dpll: Allow associating dpll pin with a firmware node

Extend the DPLL core to support associating a DPLL pin with a firmware
node. This association is required to allow other subsystems (such as
network drivers) to locate and request specific DPLL pins defined in
the Device Tree or ACPI.

* Add a .fwnode field to the struct dpll_pin
* Introduce dpll_pin_fwnode_set() helper to allow the provider driver
to associate a pin with a fwnode after the pin has been allocated
* Introduce fwnode_dpll_pin_find() helper to allow consumers to search
for a registered DPLL pin using its associated fwnode handle
* Ensure the fwnode reference is properly released in dpll_pin_put()

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
Link: https://patch.msgid.link/20260203174002.705176-2-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Ivan Vecera and committed by
Paolo Abeni
d0f4771e 0e6c95c9

+62
+49
drivers/dpll/dpll_core.c
··· 10 10 11 11 #include <linux/device.h> 12 12 #include <linux/err.h> 13 + #include <linux/property.h> 13 14 #include <linux/slab.h> 14 15 #include <linux/string.h> 15 16 ··· 596 595 xa_destroy(&pin->parent_refs); 597 596 xa_destroy(&pin->ref_sync_pins); 598 597 dpll_pin_prop_free(&pin->prop); 598 + fwnode_handle_put(pin->fwnode); 599 599 kfree_rcu(pin, rcu); 600 600 } 601 601 mutex_unlock(&dpll_lock); 602 602 } 603 603 EXPORT_SYMBOL_GPL(dpll_pin_put); 604 + 605 + /** 606 + * dpll_pin_fwnode_set - set dpll pin firmware node reference 607 + * @pin: pointer to a dpll pin 608 + * @fwnode: firmware node handle 609 + * 610 + * Set firmware node handle for the given dpll pin. 611 + */ 612 + void dpll_pin_fwnode_set(struct dpll_pin *pin, struct fwnode_handle *fwnode) 613 + { 614 + mutex_lock(&dpll_lock); 615 + fwnode_handle_put(pin->fwnode); /* Drop fwnode previously set */ 616 + pin->fwnode = fwnode_handle_get(fwnode); 617 + mutex_unlock(&dpll_lock); 618 + } 619 + EXPORT_SYMBOL_GPL(dpll_pin_fwnode_set); 620 + 621 + /** 622 + * fwnode_dpll_pin_find - find dpll pin by firmware node reference 623 + * @fwnode: reference to firmware node 624 + * 625 + * Get existing object of a pin that is associated with given firmware node 626 + * reference. 627 + * 628 + * Context: Acquires a lock (dpll_lock) 629 + * Return: 630 + * * valid dpll_pin pointer on success 631 + * * NULL when no such pin exists 632 + */ 633 + struct dpll_pin *fwnode_dpll_pin_find(struct fwnode_handle *fwnode) 634 + { 635 + struct dpll_pin *pin, *ret = NULL; 636 + unsigned long index; 637 + 638 + mutex_lock(&dpll_lock); 639 + xa_for_each(&dpll_pin_xa, index, pin) { 640 + if (pin->fwnode == fwnode) { 641 + ret = pin; 642 + refcount_inc(&ret->refcount); 643 + break; 644 + } 645 + } 646 + mutex_unlock(&dpll_lock); 647 + 648 + return ret; 649 + } 650 + EXPORT_SYMBOL_GPL(fwnode_dpll_pin_find); 604 651 605 652 static int 606 653 __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
+2
drivers/dpll/dpll_core.h
··· 42 42 * @pin_idx: index of a pin given by dev driver 43 43 * @clock_id: clock_id of creator 44 44 * @module: module of creator 45 + * @fwnode: optional reference to firmware node 45 46 * @dpll_refs: hold referencees to dplls pin was registered with 46 47 * @parent_refs: hold references to parent pins pin was registered with 47 48 * @ref_sync_pins: hold references to pins for Reference SYNC feature ··· 55 54 u32 pin_idx; 56 55 u64 clock_id; 57 56 struct module *module; 57 + struct fwnode_handle *fwnode; 58 58 struct xarray dpll_refs; 59 59 struct xarray parent_refs; 60 60 struct xarray ref_sync_pins;
+11
include/linux/dpll.h
··· 16 16 struct dpll_device; 17 17 struct dpll_pin; 18 18 struct dpll_pin_esync; 19 + struct fwnode_handle; 19 20 20 21 struct dpll_device_ops { 21 22 int (*mode_get)(const struct dpll_device *dpll, void *dpll_priv, ··· 179 178 size_t dpll_netdev_pin_handle_size(const struct net_device *dev); 180 179 int dpll_netdev_add_pin_handle(struct sk_buff *msg, 181 180 const struct net_device *dev); 181 + 182 + struct dpll_pin *fwnode_dpll_pin_find(struct fwnode_handle *fwnode); 182 183 #else 183 184 static inline void 184 185 dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) { } ··· 195 192 dpll_netdev_add_pin_handle(struct sk_buff *msg, const struct net_device *dev) 196 193 { 197 194 return 0; 195 + } 196 + 197 + static inline struct dpll_pin * 198 + fwnode_dpll_pin_find(struct fwnode_handle *fwnode) 199 + { 200 + return NULL; 198 201 } 199 202 #endif 200 203 ··· 226 217 const struct dpll_pin_ops *ops, void *priv); 227 218 228 219 void dpll_pin_put(struct dpll_pin *pin); 220 + 221 + void dpll_pin_fwnode_set(struct dpll_pin *pin, struct fwnode_handle *fwnode); 229 222 230 223 int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, 231 224 const struct dpll_pin_ops *ops, void *priv);