msecs_to_jiffies(1));
 }
 
-static void pci_epf_test_linkup(struct pci_epf *epf)
+static int pci_epf_test_notifier(struct notifier_block *nb, unsigned long val,
+                                void *data)
 {
+       struct pci_epf *epf = container_of(nb, struct pci_epf, nb);
        struct pci_epf_test *epf_test = epf_get_drvdata(epf);
 
        queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
                           msecs_to_jiffies(1));
+
+       return NOTIFY_OK;
 }
 
 static void pci_epf_test_unbind(struct pci_epf *epf)
                }
        }
 
-       if (!linkup_notifier)
+       if (linkup_notifier) {
+               epf->nb.notifier_call = pci_epf_test_notifier;
+               pci_epc_register_notifier(epc, &epf->nb);
+       } else {
                queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
+       }
 
        return 0;
 }
 static struct pci_epf_ops ops = {
        .unbind = pci_epf_test_unbind,
        .bind   = pci_epf_test_bind,
-       .linkup = pci_epf_test_linkup,
 };
 
 static struct pci_epf_driver test_driver = {
 
  */
 void pci_epc_linkup(struct pci_epc *epc)
 {
-       unsigned long flags;
-       struct pci_epf *epf;
-
        if (!epc || IS_ERR(epc))
                return;
 
-       spin_lock_irqsave(&epc->lock, flags);
-       list_for_each_entry(epf, &epc->pci_epf, list)
-               pci_epf_linkup(epf);
-       spin_unlock_irqrestore(&epc->lock, flags);
+       atomic_notifier_call_chain(&epc->notifier, 0, NULL);
 }
 EXPORT_SYMBOL_GPL(pci_epc_linkup);
 
 
        spin_lock_init(&epc->lock);
        INIT_LIST_HEAD(&epc->pci_epf);
+       ATOMIC_INIT_NOTIFIER_HEAD(&epc->notifier);
 
        device_initialize(&epc->dev);
        epc->dev.class = pci_epc_class;
 
 static struct bus_type pci_epf_bus_type;
 static const struct device_type pci_epf_type;
 
-/**
- * pci_epf_linkup() - Notify the function driver that EPC device has
- *                   established a connection with the Root Complex.
- * @epf: the EPF device bound to the EPC device which has established
- *      the connection with the host
- *
- * Invoke to notify the function driver that EPC device has established
- * a connection with the Root Complex.
- */
-void pci_epf_linkup(struct pci_epf *epf)
-{
-       if (!epf->driver) {
-               dev_WARN(&epf->dev, "epf device not bound to driver\n");
-               return;
-       }
-
-       epf->driver->ops->linkup(epf);
-}
-EXPORT_SYMBOL_GPL(pci_epf_linkup);
-
 /**
  * pci_epf_unbind() - Notify the function driver that the binding between the
  *                   EPF device and EPC device has been lost
        if (!driver->ops)
                return -EINVAL;
 
-       if (!driver->ops->bind || !driver->ops->unbind || !driver->ops->linkup)
+       if (!driver->ops->bind || !driver->ops->unbind)
                return -EINVAL;
 
        driver->driver.bus = &pci_epf_bus_type;
 
  * @max_functions: max number of functions that can be configured in this EPC
  * @group: configfs group representing the PCI EPC device
  * @lock: spinlock to protect pci_epc ops
+ * @notifier: used to notify EPF of any EPC events (like linkup)
  */
 struct pci_epc {
        struct device                   dev;
        struct config_group             *group;
        /* spinlock to protect against concurrent access of EP controller */
        spinlock_t                      lock;
+       struct atomic_notifier_head     notifier;
 };
 
 /**
        return dev_get_drvdata(&epc->dev);
 }
 
+static inline int
+pci_epc_register_notifier(struct pci_epc *epc, struct notifier_block *nb)
+{
+       return atomic_notifier_chain_register(&epc->notifier, nb);
+}
+
 struct pci_epc *
 __devm_pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
                      struct module *owner);
 
  * @bind: ops to perform when a EPC device has been bound to EPF device
  * @unbind: ops to perform when a binding has been lost between a EPC device
  *         and EPF device
- * @linkup: ops to perform when the EPC device has established a connection with
- *         a host system
  */
 struct pci_epf_ops {
        int     (*bind)(struct pci_epf *epf);
        void    (*unbind)(struct pci_epf *epf);
-       void    (*linkup)(struct pci_epf *epf);
 };
 
 /**
  * @epc: the EPC device to which this EPF device is bound
  * @driver: the EPF driver to which this EPF device is bound
  * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
+ * @nb: notifier block to notify EPF of any EPC events (like linkup)
  */
 struct pci_epf {
        struct device           dev;
        struct pci_epc          *epc;
        struct pci_epf_driver   *driver;
        struct list_head        list;
+       struct notifier_block   nb;
 };
 
 #define to_pci_epf(epf_dev) container_of((epf_dev), struct pci_epf, dev)
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);
 int pci_epf_bind(struct pci_epf *epf);
 void pci_epf_unbind(struct pci_epf *epf);
-void pci_epf_linkup(struct pci_epf *epf);
 #endif /* __LINUX_PCI_EPF_H */