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: Add notifier chain for dpll events

Currently, the DPLL subsystem reports events (creation, deletion, changes)
to userspace via Netlink. However, there is no mechanism for other kernel
components to be notified of these events directly.

Add a raw notifier chain to the DPLL core protected by dpll_lock. This
allows other kernel subsystems or drivers to register callbacks and
receive notifications when DPLL devices or pins are created, deleted,
or modified.

Define the following:
- Registration helpers: {,un}register_dpll_notifier()
- Event types: DPLL_DEVICE_CREATED, DPLL_PIN_CREATED, etc.
- Context structures: dpll_{device,pin}_notifier_info to pass relevant
data to the listeners.

The notification chain is invoked alongside the existing Netlink event
generation to ensure in-kernel listeners are kept in sync with the
subsystem state.

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

authored by

Petr Oros and committed by
Paolo Abeni
2be46758 e6dc7727

+96
+57
drivers/dpll/dpll_core.c
··· 23 23 DEFINE_XARRAY_FLAGS(dpll_device_xa, XA_FLAGS_ALLOC); 24 24 DEFINE_XARRAY_FLAGS(dpll_pin_xa, XA_FLAGS_ALLOC); 25 25 26 + static RAW_NOTIFIER_HEAD(dpll_notifier_chain); 27 + 26 28 static u32 dpll_device_xa_id; 27 29 static u32 dpll_pin_xa_id; 28 30 ··· 47 45 void *priv; 48 46 void *cookie; 49 47 }; 48 + 49 + static int call_dpll_notifiers(unsigned long action, void *info) 50 + { 51 + lockdep_assert_held(&dpll_lock); 52 + return raw_notifier_call_chain(&dpll_notifier_chain, action, info); 53 + } 54 + 55 + void dpll_device_notify(struct dpll_device *dpll, unsigned long action) 56 + { 57 + struct dpll_device_notifier_info info = { 58 + .dpll = dpll, 59 + .id = dpll->id, 60 + .idx = dpll->device_idx, 61 + .clock_id = dpll->clock_id, 62 + .type = dpll->type, 63 + }; 64 + 65 + call_dpll_notifiers(action, &info); 66 + } 67 + 68 + void dpll_pin_notify(struct dpll_pin *pin, unsigned long action) 69 + { 70 + struct dpll_pin_notifier_info info = { 71 + .pin = pin, 72 + .id = pin->id, 73 + .idx = pin->pin_idx, 74 + .clock_id = pin->clock_id, 75 + .fwnode = pin->fwnode, 76 + .prop = &pin->prop, 77 + }; 78 + 79 + call_dpll_notifiers(action, &info); 80 + } 50 81 51 82 struct dpll_device *dpll_device_get_by_id(int id) 52 83 { ··· 573 538 dpll_netdev_pin_assign(dev, NULL); 574 539 } 575 540 EXPORT_SYMBOL(dpll_netdev_pin_clear); 541 + 542 + int register_dpll_notifier(struct notifier_block *nb) 543 + { 544 + int ret; 545 + 546 + mutex_lock(&dpll_lock); 547 + ret = raw_notifier_chain_register(&dpll_notifier_chain, nb); 548 + mutex_unlock(&dpll_lock); 549 + return ret; 550 + } 551 + EXPORT_SYMBOL_GPL(register_dpll_notifier); 552 + 553 + int unregister_dpll_notifier(struct notifier_block *nb) 554 + { 555 + int ret; 556 + 557 + mutex_lock(&dpll_lock); 558 + ret = raw_notifier_chain_unregister(&dpll_notifier_chain, nb); 559 + mutex_unlock(&dpll_lock); 560 + return ret; 561 + } 562 + EXPORT_SYMBOL_GPL(unregister_dpll_notifier); 576 563 577 564 /** 578 565 * dpll_pin_get - find existing or create new dpll pin
+4
drivers/dpll/dpll_core.h
··· 91 91 extern struct xarray dpll_device_xa; 92 92 extern struct xarray dpll_pin_xa; 93 93 extern struct mutex dpll_lock; 94 + 95 + void dpll_device_notify(struct dpll_device *dpll, unsigned long action); 96 + void dpll_pin_notify(struct dpll_pin *pin, unsigned long action); 97 + 94 98 #endif
+6
drivers/dpll/dpll_netlink.c
··· 761 761 762 762 int dpll_device_create_ntf(struct dpll_device *dpll) 763 763 { 764 + dpll_device_notify(dpll, DPLL_DEVICE_CREATED); 764 765 return dpll_device_event_send(DPLL_CMD_DEVICE_CREATE_NTF, dpll); 765 766 } 766 767 767 768 int dpll_device_delete_ntf(struct dpll_device *dpll) 768 769 { 770 + dpll_device_notify(dpll, DPLL_DEVICE_DELETED); 769 771 return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll); 770 772 } 771 773 772 774 static int 773 775 __dpll_device_change_ntf(struct dpll_device *dpll) 774 776 { 777 + dpll_device_notify(dpll, DPLL_DEVICE_CHANGED); 775 778 return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll); 776 779 } 777 780 ··· 832 829 833 830 int dpll_pin_create_ntf(struct dpll_pin *pin) 834 831 { 832 + dpll_pin_notify(pin, DPLL_PIN_CREATED); 835 833 return dpll_pin_event_send(DPLL_CMD_PIN_CREATE_NTF, pin); 836 834 } 837 835 838 836 int dpll_pin_delete_ntf(struct dpll_pin *pin) 839 837 { 838 + dpll_pin_notify(pin, DPLL_PIN_DELETED); 840 839 return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin); 841 840 } 842 841 843 842 int __dpll_pin_change_ntf(struct dpll_pin *pin) 844 843 { 844 + dpll_pin_notify(pin, DPLL_PIN_CHANGED); 845 845 return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin); 846 846 } 847 847
+29
include/linux/dpll.h
··· 11 11 #include <linux/device.h> 12 12 #include <linux/netlink.h> 13 13 #include <linux/netdevice.h> 14 + #include <linux/notifier.h> 14 15 #include <linux/rtnetlink.h> 15 16 16 17 struct dpll_device; ··· 173 172 u32 phase_gran; 174 173 }; 175 174 175 + #define DPLL_DEVICE_CREATED 1 176 + #define DPLL_DEVICE_DELETED 2 177 + #define DPLL_DEVICE_CHANGED 3 178 + #define DPLL_PIN_CREATED 4 179 + #define DPLL_PIN_DELETED 5 180 + #define DPLL_PIN_CHANGED 6 181 + 182 + struct dpll_device_notifier_info { 183 + struct dpll_device *dpll; 184 + u32 id; 185 + u32 idx; 186 + u64 clock_id; 187 + enum dpll_type type; 188 + }; 189 + 190 + struct dpll_pin_notifier_info { 191 + struct dpll_pin *pin; 192 + u32 id; 193 + u32 idx; 194 + u64 clock_id; 195 + const struct fwnode_handle *fwnode; 196 + const struct dpll_pin_properties *prop; 197 + }; 198 + 176 199 #if IS_ENABLED(CONFIG_DPLL) 177 200 void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); 178 201 void dpll_netdev_pin_clear(struct net_device *dev); ··· 266 241 int dpll_device_change_ntf(struct dpll_device *dpll); 267 242 268 243 int dpll_pin_change_ntf(struct dpll_pin *pin); 244 + 245 + int register_dpll_notifier(struct notifier_block *nb); 246 + 247 + int unregister_dpll_notifier(struct notifier_block *nb); 269 248 270 249 #endif