#include <linux/clocksource.h>
 #include <linux/highmem.h>
 #include <rdma/mlx5-abi.h>
+#include "lib/eq.h"
 #include "en.h"
 #include "clock.h"
 
        clock->pps_info.pin_caps[7] = MLX5_GET(mtpps_reg, out, cap_pin_7_mode);
 }
 
-void mlx5_pps_event(struct mlx5_core_dev *mdev,
-                   struct mlx5_eqe *eqe)
+static int mlx5_pps_event(struct notifier_block *nb,
+                         unsigned long type, void *data)
 {
-       struct mlx5_clock *clock = &mdev->clock;
+       struct mlx5_clock *clock = mlx5_nb_cof(nb, struct mlx5_clock, pps_nb);
+       struct mlx5_core_dev *mdev = clock->mdev;
        struct ptp_clock_event ptp_event;
-       struct timespec64 ts;
-       u64 nsec_now, nsec_delta;
        u64 cycles_now, cycles_delta;
+       u64 nsec_now, nsec_delta, ns;
+       struct mlx5_eqe *eqe = data;
        int pin = eqe->data.pps.pin;
-       s64 ns;
+       struct timespec64 ts;
        unsigned long flags;
 
        switch (clock->ptp_info.pin_config[pin].func) {
                } else {
                        ptp_event.type = PTP_CLOCK_EXTTS;
                }
+               /* TODOL clock->ptp can be NULL if ptp_clock_register failes */
                ptp_clock_event(clock->ptp, &ptp_event);
                break;
        case PTP_PF_PEROUT:
                write_sequnlock_irqrestore(&clock->lock, flags);
                break;
        default:
-               mlx5_core_err(mdev, " Unhandled event\n");
+               mlx5_core_err(mdev, " Unhandled clock PPS event, func %d\n",
+                             clock->ptp_info.pin_config[pin].func);
        }
+
+       return NOTIFY_OK;
 }
 
 void mlx5_init_clock(struct mlx5_core_dev *mdev)
                               PTR_ERR(clock->ptp));
                clock->ptp = NULL;
        }
+
+       MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT);
+       mlx5_eq_notifier_register(mdev, &clock->pps_nb);
 }
 
 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev)
        if (!MLX5_CAP_GEN(mdev, device_frequency_khz))
                return;
 
+       mlx5_eq_notifier_unregister(mdev, &clock->pps_nb);
        if (clock->ptp) {
                ptp_clock_unregister(clock->ptp);
                clock->ptp = NULL;
 
 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
 void mlx5_init_clock(struct mlx5_core_dev *mdev);
 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev);
-void mlx5_pps_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
 
 static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
 {
 #else
 static inline void mlx5_init_clock(struct mlx5_core_dev *mdev) {}
 static inline void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) {}
-static inline void mlx5_pps_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe) {}
-
 static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
 {
        return -1;
 
 #include <linux/mlx5/device.h>
 #include <linux/mlx5/doorbell.h>
 #include <linux/mlx5/srq.h>
+#include <linux/mlx5/eq.h>
 #include <linux/timecounter.h>
 #include <linux/ptp_clock_kernel.h>
 
 };
 
 struct mlx5_clock {
+       struct mlx5_core_dev      *mdev;
+       struct mlx5_nb             pps_nb;
        seqlock_t                  lock;
        struct cyclecounter        cycles;
        struct timecounter         tc;
        u32                        nominal_c_mult;
        unsigned long              overflow_period;
        struct delayed_work        overflow_work;
-       struct mlx5_core_dev      *mdev;
        struct ptp_clock          *ptp;
        struct ptp_clock_info      ptp_info;
        struct mlx5_pps            pps_info;