@@ -826,20 +826,17 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
return 0;
}
+static const struct pci_epc_event_ops pci_epf_test_event_ops = {
+ .core_init = pci_epf_test_core_init,
+};
+
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);
- int ret;
switch (val) {
- case CORE_INIT:
- ret = pci_epf_test_core_init(epf);
- if (ret)
- return NOTIFY_BAD;
- break;
-
case LINK_UP:
queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
msecs_to_jiffies(1));
@@ -1010,6 +1007,8 @@ static int pci_epf_test_probe(struct pci_epf *epf)
INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);
+ epf->event_ops = &pci_epf_test_event_ops;
+
epf_set_drvdata(epf, epf_test);
return 0;
}
@@ -707,10 +707,19 @@ EXPORT_SYMBOL_GPL(pci_epc_linkup);
*/
void pci_epc_init_notify(struct pci_epc *epc)
{
+ struct pci_epf *epf;
+
if (!epc || IS_ERR(epc))
return;
- atomic_notifier_call_chain(&epc->notifier, CORE_INIT, NULL);
+ mutex_lock(&epc->list_lock);
+ list_for_each_entry(epf, &epc->pci_epf, list) {
+ mutex_lock(&epf->lock);
+ if (epf->event_ops && epf->event_ops->core_init)
+ epf->event_ops->core_init(epf);
+ mutex_unlock(&epf->lock);
+ }
+ mutex_unlock(&epc->list_lock);
}
EXPORT_SYMBOL_GPL(pci_epc_init_notify);
@@ -18,7 +18,6 @@ struct pci_epf;
enum pci_epc_interface_type;
enum pci_notify_event {
- CORE_INIT,
LINK_UP,
};
@@ -72,6 +71,14 @@ struct pci_epf_ops {
struct config_group *group);
};
+/**
+ * struct pci_epf_event_ops - Callbacks for capturing the EPC events
+ * @core_init: Callback for the EPC initialization complete event
+ */
+struct pci_epc_event_ops {
+ int (*core_init)(struct pci_epf *epf);
+};
+
/**
* struct pci_epf_driver - represents the PCI EPF driver
* @probe: ops to perform when a new EPF device has been bound to the EPF driver
@@ -139,6 +146,7 @@ struct pci_epf_bar {
* @is_vf: true - virtual function, false - physical function
* @vfunction_num_map: bitmap to manage virtual function number
* @pci_vepf: list of virtual endpoint functions associated with this function
+ * @event_ops: Callbacks for capturing the EPC events
*/
struct pci_epf {
struct device dev;
@@ -168,6 +176,7 @@ struct pci_epf {
unsigned int is_vf;
unsigned long vfunction_num_map;
struct list_head pci_vepf;
+ const struct pci_epc_event_ops *event_ops;
};
/**