summaryrefslogtreecommitdiff
path: root/drivers/pci/endpoint
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2023-02-22 22:47:28 +0300
committerBjorn Helgaas <bhelgaas@google.com>2023-02-22 22:47:28 +0300
commit33abd97c34ff233f21355d411bea6709f4d5ad75 (patch)
tree192c0ed67eb2da8162db9007cc39785dee3cfd73 /drivers/pci/endpoint
parent191b41018856da2bcd6f3f3ab0b2eb1c7a9f8585 (diff)
parentf5edd8715e2ea672e6119c3764041743761fb178 (diff)
downloadlinux-33abd97c34ff233f21355d411bea6709f4d5ad75.tar.xz
Merge branch 'pci/endpoint'
- Convert dra7xx to threaded IRQ handler (Manivannan Sadhasivam) - Move tegra194 dw_pcie_ep_linkup() to threaded IRQ handler (Manivannan Sadhasivam) - Add a separate lock for the endpoint pci_epf list to avoid deadlock while running callbacks (Manivannan Sadhasivam) - Use callbacks instead of notifier chains to signal events from EPC to EPF drivers (Manivannan Sadhasivam) - Use link_up() callback in place of LINK_UP notifier (Manivannan Sadhasivam) * pci/endpoint: PCI: endpoint: Use link_up() callback in place of LINK_UP notifier PCI: endpoint: Use callback mechanism for passing events from EPC to EPF PCI: endpoint: Use a separate lock for protecting epc->pci_epf list PCI: tegra194: Move dw_pcie_ep_linkup() to threaded IRQ handler PCI: dra7xx: Use threaded IRQ handler for "dra7xx-pcie-main" IRQ
Diffstat (limited to 'drivers/pci/endpoint')
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c38
-rw-r--r--drivers/pci/endpoint/pci-epc-core.c32
2 files changed, 37 insertions, 33 deletions
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 55283d2379a6..0f9d2ec822ac 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -826,33 +826,21 @@ static int pci_epf_test_core_init(struct pci_epf *epf)
return 0;
}
-static int pci_epf_test_notifier(struct notifier_block *nb, unsigned long val,
- void *data)
+static int pci_epf_test_link_up(struct pci_epf *epf)
{
- 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));
- break;
-
- default:
- dev_err(&epf->dev, "Invalid EPF test notifier event\n");
- return NOTIFY_BAD;
- }
+ queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
+ msecs_to_jiffies(1));
- return NOTIFY_OK;
+ return 0;
}
+static const struct pci_epc_event_ops pci_epf_test_event_ops = {
+ .core_init = pci_epf_test_core_init,
+ .link_up = pci_epf_test_link_up,
+};
+
static int pci_epf_test_alloc_space(struct pci_epf *epf)
{
struct pci_epf_test *epf_test = epf_get_drvdata(epf);
@@ -979,12 +967,8 @@ static int pci_epf_test_bind(struct pci_epf *epf)
if (ret)
epf_test->dma_supported = false;
- if (linkup_notifier || core_init_notifier) {
- epf->nb.notifier_call = pci_epf_test_notifier;
- pci_epc_register_notifier(epc, &epf->nb);
- } else {
+ if (!linkup_notifier && !core_init_notifier)
queue_work(kpcitest_workqueue, &epf_test->cmd_handler.work);
- }
return 0;
}
@@ -1010,6 +994,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;
}
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index dd750ad29485..9440d9811eea 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -613,7 +613,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
if (type == SECONDARY_INTERFACE && epf->sec_epc)
return -EBUSY;
- mutex_lock(&epc->lock);
+ mutex_lock(&epc->list_lock);
func_no = find_first_zero_bit(&epc->function_num_map,
BITS_PER_LONG);
if (func_no >= BITS_PER_LONG) {
@@ -640,7 +640,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf,
list_add_tail(list, &epc->pci_epf);
ret:
- mutex_unlock(&epc->lock);
+ mutex_unlock(&epc->list_lock);
return ret;
}
@@ -672,11 +672,11 @@ void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf,
list = &epf->sec_epc_list;
}
- mutex_lock(&epc->lock);
+ mutex_lock(&epc->list_lock);
clear_bit(func_no, &epc->function_num_map);
list_del(list);
epf->epc = NULL;
- mutex_unlock(&epc->lock);
+ mutex_unlock(&epc->list_lock);
}
EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
@@ -690,10 +690,19 @@ EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
*/
void pci_epc_linkup(struct pci_epc *epc)
{
+ struct pci_epf *epf;
+
if (!epc || IS_ERR(epc))
return;
- atomic_notifier_call_chain(&epc->notifier, LINK_UP, 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->link_up)
+ epf->event_ops->link_up(epf);
+ mutex_unlock(&epf->lock);
+ }
+ mutex_unlock(&epc->list_lock);
}
EXPORT_SYMBOL_GPL(pci_epc_linkup);
@@ -707,10 +716,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);
@@ -777,8 +795,8 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
}
mutex_init(&epc->lock);
+ mutex_init(&epc->list_lock);
INIT_LIST_HEAD(&epc->pci_epf);
- ATOMIC_INIT_NOTIFIER_HEAD(&epc->notifier);
device_initialize(&epc->dev);
epc->dev.class = pci_epc_class;