diff options
| author | Paolo Abeni <pabeni@redhat.com> | 2026-02-05 15:57:48 +0100 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-02-05 15:57:49 +0100 |
| commit | 651f71248a01231c54c5dc3bac4cec989dba1a6d (patch) | |
| tree | 6252815fc885ccc6d5cc9e3ecc7cd631a69d2fa5 /include/linux | |
| parent | 0e6c95c9882913ba88417f035f5a9f343afd5db0 (diff) | |
| parent | ad1df4f2d591e167bc64b8a7ce6328a2735e3d58 (diff) | |
Merge branch 'dpll-core-improvements-and-ice-e825-c-synce-support'
Ivan Vecera says:
====================
dpll: Core improvements and ice E825-C SyncE support
This series introduces Synchronous Ethernet (SyncE) support for the Intel
E825-C Ethernet controller. Unlike previous generations where DPLL
connections were implicitly assumed, the E825-C architecture relies
on the platform firmware (ACPI) to describe the physical connections
between the Ethernet controller and external DPLLs (such as the ZL3073x).
To accommodate this, the series extends the DPLL subsystem to support
firmware node (fwnode) associations, asynchronous discovery via notifiers,
and dynamic pin management. Additionally, a significant refactor of
the DPLL reference counting logic is included to ensure robustness and
debuggability.
DPLL Core Extensions:
* Firmware Node Association: Pins can now be associated with a struct
fwnode_handle after allocation via dpll_pin_fwnode_set(). This allows
drivers to link pin objects with their corresponding DT/ACPI nodes.
* Asynchronous Notifiers: A raw notifier chain is added to the DPLL core.
This allows the Ethernet driver to subscribe to events and react when
the platform DPLL driver registers the parent pins, resolving probe
ordering dependencies.
* Dynamic Indexing: Drivers can now request DPLL_PIN_IDX_UNSPEC to have
the core automatically allocate a unique pin index.
Reference Counting & Debugging:
* Refactor: The reference counting logic in the core is consolidated.
Internal list management helpers now automatically handle hold/put
operations, removing fragile open-coded logic in the registration paths.
* Reference Tracking: A new Kconfig option DPLL_REFCNT_TRACKER is added.
This allows developers to instrument and debug reference leaks by
recording stack traces for every get/put operation.
Driver Updates:
* zl3073x: Updated to associate pins with fwnode handles using the new
setter and support the 'mux' pin type.
* ice: Implements the E825-C specific hardware configuration for SyncE
(CGU registers). It utilizes the new notifier and fwnode APIs to
dynamically discover and attach to the platform DPLLs.
Patch Summary:
Patch 1: DPLL Core (fwnode association).
Patch 2: Driver zl3073x (Set fwnode).
Patch 3-4: DPLL Core (Notifiers and dynamic IDs).
Patch 5: Driver zl3073x (Mux type).
Patch 6: DPLL Core (Refcount refactor).
Patch 7-8: Refcount tracking infrastructure and driver updates.
Patch 9: Driver ice (E825-C SyncE logic).
====================
Link: https://patch.msgid.link/20260203174002.705176-1-ivecera@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/dpll.h | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/include/linux/dpll.h b/include/linux/dpll.h index c6d0248fa527..2ce295b46b8c 100644 --- a/include/linux/dpll.h +++ b/include/linux/dpll.h @@ -11,11 +11,14 @@ #include <linux/device.h> #include <linux/netlink.h> #include <linux/netdevice.h> +#include <linux/notifier.h> #include <linux/rtnetlink.h> struct dpll_device; struct dpll_pin; struct dpll_pin_esync; +struct fwnode_handle; +struct ref_tracker; struct dpll_device_ops { int (*mode_get)(const struct dpll_device *dpll, void *dpll_priv, @@ -171,6 +174,36 @@ struct dpll_pin_properties { u32 phase_gran; }; +#ifdef CONFIG_DPLL_REFCNT_TRACKER +typedef struct ref_tracker *dpll_tracker; +#else +typedef struct {} dpll_tracker; +#endif + +#define DPLL_DEVICE_CREATED 1 +#define DPLL_DEVICE_DELETED 2 +#define DPLL_DEVICE_CHANGED 3 +#define DPLL_PIN_CREATED 4 +#define DPLL_PIN_DELETED 5 +#define DPLL_PIN_CHANGED 6 + +struct dpll_device_notifier_info { + struct dpll_device *dpll; + u32 id; + u32 idx; + u64 clock_id; + enum dpll_type type; +}; + +struct dpll_pin_notifier_info { + struct dpll_pin *pin; + u32 id; + u32 idx; + u64 clock_id; + const struct fwnode_handle *fwnode; + const struct dpll_pin_properties *prop; +}; + #if IS_ENABLED(CONFIG_DPLL) void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); void dpll_netdev_pin_clear(struct net_device *dev); @@ -178,6 +211,9 @@ void dpll_netdev_pin_clear(struct net_device *dev); size_t dpll_netdev_pin_handle_size(const struct net_device *dev); int dpll_netdev_add_pin_handle(struct sk_buff *msg, const struct net_device *dev); + +struct dpll_pin *fwnode_dpll_pin_find(struct fwnode_handle *fwnode, + dpll_tracker *tracker); #else static inline void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) { } @@ -193,12 +229,19 @@ dpll_netdev_add_pin_handle(struct sk_buff *msg, const struct net_device *dev) { return 0; } + +static inline struct dpll_pin * +fwnode_dpll_pin_find(struct fwnode_handle *fwnode, dpll_tracker *tracker) +{ + return NULL; +} #endif struct dpll_device * -dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module); +dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module, + dpll_tracker *tracker); -void dpll_device_put(struct dpll_device *dpll); +void dpll_device_put(struct dpll_device *dpll, dpll_tracker *tracker); int dpll_device_register(struct dpll_device *dpll, enum dpll_type type, const struct dpll_device_ops *ops, void *priv); @@ -206,9 +249,11 @@ int dpll_device_register(struct dpll_device *dpll, enum dpll_type type, void dpll_device_unregister(struct dpll_device *dpll, const struct dpll_device_ops *ops, void *priv); +#define DPLL_PIN_IDX_UNSPEC U32_MAX + struct dpll_pin * dpll_pin_get(u64 clock_id, u32 dev_driver_id, struct module *module, - const struct dpll_pin_properties *prop); + const struct dpll_pin_properties *prop, dpll_tracker *tracker); int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, const struct dpll_pin_ops *ops, void *priv); @@ -216,7 +261,9 @@ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, const struct dpll_pin_ops *ops, void *priv); -void dpll_pin_put(struct dpll_pin *pin); +void dpll_pin_put(struct dpll_pin *pin, dpll_tracker *tracker); + +void dpll_pin_fwnode_set(struct dpll_pin *pin, struct fwnode_handle *fwnode); int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, const struct dpll_pin_ops *ops, void *priv); @@ -231,4 +278,8 @@ int dpll_device_change_ntf(struct dpll_device *dpll); int dpll_pin_change_ntf(struct dpll_pin *pin); +int register_dpll_notifier(struct notifier_block *nb); + +int unregister_dpll_notifier(struct notifier_block *nb); + #endif |
