Skip to content

Commit 0f74d89

Browse files
committed
Merge branch 'pci/endpoint'
- Remove unused struct pci_epf_group.type_group (Christophe JAILLET) - Use cached epc_features instead of pci_epc_get_features() to avoid having to check for failure (potential NULL pointer dereference) (Manivannan Sadhasivam) - Drop pointless local msix_capable variable in pci_epf_test_alloc_space() (Manivannan Sadhasivam) - Rename struct pci_epc_event_ops.core_init to .epc_init, since "core" is no longer meaningful here (Manivannan Sadhasivam) - Rename pci_epc_bme_notify(), pci_epf_mhi_bme(), pci_epc_bme_notify() to spell out "bus_master_enable" instead of "bme" (Manivannan Sadhasivam) - Factor pci_epf_test_clear_bar() and pci_epf_test_free_space() out of pci_epf_test_unbind() so they can be reused elsewhere (Manivannan Sadhasivam) - Move DMA initialization to the pci_epf_mhi_epc_init() callback so endpoint drivers do this uniformly (Manivannan Sadhasivam) - Add endpoint testing for Link Down events (Manivannan Sadhasivam) - Add 'epc_deinit' event so endpoints that can be reset via PERST# (qcom, tegra194) can notify EPF drivers when this happens (Manivannan Sadhasivam) - Make pci_epc_class constant (Greg Kroah-Hartman) - Fix vpci_scan_bus() error checking to print error for failure (not success) and clean up after failure (Dan Carpenter) - Fix epf_ntb_epc_cleanup() error handling to clean up scratchpad BARs and clean up in mirror order of allocation (Dan Carpenter) - Add rk3588, which requires 64KB BAR alignment, to pci_endpoint_test (Niklas Cassel) - Use memcpy_toio()/memcpy_fromio() for endpoint BAR tests to improve performance (Niklas Cassel) - Set DMA mask to 48 bits always to simplify endpoint test, since there's there's no need to check for error or to fallback to 32 bits (Frank Li) - Suggest using programmable Vendor/Device ID (when supported) to use pci_endpoint_test without having to add new entries (Yoshihiro Shimoda) - Remove unused pci_endpoint_test_bar_{readl,writel}() (Jiapeng Chong) - Remove 'linkup' and add 'add_cfs' to the endpoint function driver 'ops' documentation to match the code (Alexander Stein) - * pci/endpoint: Documentation: PCI: pci-endpoint: Fix EPF ops list misc: pci_endpoint_test: Remove unused pci_endpoint_test_bar_{readl,writel} functions misc: pci_endpoint_test: Document policy about adding pci_device_id misc: pci_endpoint_test: Refactor dma_set_mask_and_coherent() logic misc: pci_endpoint_test: Use memcpy_toio()/memcpy_fromio() for BAR tests misc: pci_endpoint_test: Add support for Rockchip rk3588 PCI: endpoint: Fix error handling in epf_ntb_epc_cleanup() PCI: endpoint: Clean up error handling in vpci_scan_bus() PCI: endpoint: Make pci_epc_class struct constant PCI: endpoint: Introduce 'epc_deinit' event and notify the EPF drivers PCI: endpoint: pci-epf-test: Handle Link Down event PCI: endpoint: pci-epf-{mhi/test}: Move DMA initialization to EPC init callback PCI: endpoint: pci-epf-test: Refactor pci_epf_test_unbind() function PCI: endpoint: Rename BME to Bus Master Enable PCI: endpoint: Rename core_init() callback in 'struct pci_epc_event_ops' to epc_init() PCI: endpoint: pci-epf-test: Use 'msix_capable' flag directly in pci_epf_test_alloc_space() PCI: endpoint: pci-epf-test: Make use of cached 'epc_features' in pci_epf_test_core_init() PCI: endpoint: Remove unused field in struct pci_epf_group
2 parents 7095d21 + 96447ed commit 0f74d89

File tree

12 files changed

+254
-130
lines changed

12 files changed

+254
-130
lines changed

Documentation/PCI/endpoint/pci-endpoint.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ by the PCI endpoint function driver.
172172
* bind: ops to perform when a EPC device has been bound to EPF device
173173
* unbind: ops to perform when a binding has been lost between a EPC
174174
device and EPF device
175-
* linkup: ops to perform when the EPC device has established a
176-
connection with a host system
175+
* add_cfs: optional ops to create function specific configfs
176+
attributes
177177

178178
The PCI Function driver can then register the PCI EPF driver by using
179179
pci_epf_register_driver().

drivers/misc/pci_endpoint_test.c

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <linux/crc32.h>
10+
#include <linux/cleanup.h>
1011
#include <linux/delay.h>
1112
#include <linux/fs.h>
1213
#include <linux/io.h>
@@ -84,6 +85,9 @@
8485
#define PCI_DEVICE_ID_RENESAS_R8A774E1 0x0025
8586
#define PCI_DEVICE_ID_RENESAS_R8A779F0 0x0031
8687

88+
#define PCI_VENDOR_ID_ROCKCHIP 0x1d87
89+
#define PCI_DEVICE_ID_ROCKCHIP_RK3588 0x3588
90+
8791
static DEFINE_IDA(pci_endpoint_test_ida);
8892

8993
#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
@@ -140,18 +144,6 @@ static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
140144
writel(value, test->base + offset);
141145
}
142146

143-
static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *test,
144-
int bar, int offset)
145-
{
146-
return readl(test->bar[bar] + offset);
147-
}
148-
149-
static inline void pci_endpoint_test_bar_writel(struct pci_endpoint_test *test,
150-
int bar, u32 offset, u32 value)
151-
{
152-
writel(value, test->bar[bar] + offset);
153-
}
154-
155147
static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
156148
{
157149
struct pci_endpoint_test *test = dev_id;
@@ -272,31 +264,60 @@ static const u32 bar_test_pattern[] = {
272264
0xA5A5A5A5,
273265
};
274266

267+
static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
268+
enum pci_barno barno, int offset,
269+
void *write_buf, void *read_buf,
270+
int size)
271+
{
272+
memset(write_buf, bar_test_pattern[barno], size);
273+
memcpy_toio(test->bar[barno] + offset, write_buf, size);
274+
275+
memcpy_fromio(read_buf, test->bar[barno] + offset, size);
276+
277+
return memcmp(write_buf, read_buf, size);
278+
}
279+
275280
static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
276281
enum pci_barno barno)
277282
{
278-
int j;
279-
u32 val;
280-
int size;
283+
int j, bar_size, buf_size, iters, remain;
284+
void *write_buf __free(kfree) = NULL;
285+
void *read_buf __free(kfree) = NULL;
281286
struct pci_dev *pdev = test->pdev;
282287

283288
if (!test->bar[barno])
284289
return false;
285290

286-
size = pci_resource_len(pdev, barno);
291+
bar_size = pci_resource_len(pdev, barno);
287292

288293
if (barno == test->test_reg_bar)
289-
size = 0x4;
294+
bar_size = 0x4;
295+
296+
/*
297+
* Allocate a buffer of max size 1MB, and reuse that buffer while
298+
* iterating over the whole BAR size (which might be much larger).
299+
*/
300+
buf_size = min(SZ_1M, bar_size);
290301

291-
for (j = 0; j < size; j += 4)
292-
pci_endpoint_test_bar_writel(test, barno, j,
293-
bar_test_pattern[barno]);
302+
write_buf = kmalloc(buf_size, GFP_KERNEL);
303+
if (!write_buf)
304+
return false;
294305

295-
for (j = 0; j < size; j += 4) {
296-
val = pci_endpoint_test_bar_readl(test, barno, j);
297-
if (val != bar_test_pattern[barno])
306+
read_buf = kmalloc(buf_size, GFP_KERNEL);
307+
if (!read_buf)
308+
return false;
309+
310+
iters = bar_size / buf_size;
311+
for (j = 0; j < iters; j++)
312+
if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * j,
313+
write_buf, read_buf, buf_size))
314+
return false;
315+
316+
remain = bar_size % buf_size;
317+
if (remain)
318+
if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * iters,
319+
write_buf, read_buf, remain))
298320
return false;
299-
}
300321

301322
return true;
302323
}
@@ -824,11 +845,7 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev,
824845
init_completion(&test->irq_raised);
825846
mutex_init(&test->mutex);
826847

827-
if ((dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48)) != 0) &&
828-
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) {
829-
dev_err(dev, "Cannot set DMA mask\n");
830-
return -EINVAL;
831-
}
848+
dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
832849

833850
err = pci_enable_device(pdev);
834851
if (err) {
@@ -980,6 +997,15 @@ static const struct pci_endpoint_test_data j721e_data = {
980997
.irq_type = IRQ_TYPE_MSI,
981998
};
982999

1000+
static const struct pci_endpoint_test_data rk3588_data = {
1001+
.alignment = SZ_64K,
1002+
.irq_type = IRQ_TYPE_MSI,
1003+
};
1004+
1005+
/*
1006+
* If the controller's Vendor/Device ID are programmable, you may be able to
1007+
* use one of the existing entries for testing instead of adding a new one.
1008+
*/
9831009
static const struct pci_device_id pci_endpoint_test_tbl[] = {
9841010
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x),
9851011
.driver_data = (kernel_ulong_t)&default_data,
@@ -1017,6 +1043,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
10171043
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721S2),
10181044
.driver_data = (kernel_ulong_t)&j721e_data,
10191045
},
1046+
{ PCI_DEVICE(PCI_VENDOR_ID_ROCKCHIP, PCI_DEVICE_ID_ROCKCHIP_RK3588),
1047+
.driver_data = (kernel_ulong_t)&rk3588_data,
1048+
},
10201049
{ }
10211050
};
10221051
MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);

drivers/pci/controller/dwc/pcie-designware-ep.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,6 @@ void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep)
632632
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
633633

634634
dw_pcie_edma_remove(pci);
635-
ep->epc->init_complete = false;
636635
}
637636
EXPORT_SYMBOL_GPL(dw_pcie_ep_cleanup);
638637

drivers/pci/controller/dwc/pcie-qcom-ep.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ static void qcom_pcie_perst_assert(struct dw_pcie *pci)
507507
return;
508508
}
509509

510+
pci_epc_deinit_notify(pci->ep.epc);
510511
dw_pcie_ep_cleanup(&pci->ep);
511512
qcom_pcie_disable_resources(pcie_ep);
512513
pcie_ep->link_status = QCOM_PCIE_EP_LINK_DISABLED;
@@ -642,10 +643,10 @@ static irqreturn_t qcom_pcie_ep_global_irq_thread(int irq, void *data)
642643
pcie_ep->link_status = QCOM_PCIE_EP_LINK_DOWN;
643644
pci_epc_linkdown(pci->ep.epc);
644645
} else if (FIELD_GET(PARF_INT_ALL_BME, status)) {
645-
dev_dbg(dev, "Received BME event. Link is enabled!\n");
646+
dev_dbg(dev, "Received Bus Master Enable event\n");
646647
pcie_ep->link_status = QCOM_PCIE_EP_LINK_ENABLED;
647648
qcom_pcie_ep_icc_update(pcie_ep);
648-
pci_epc_bme_notify(pci->ep.epc);
649+
pci_epc_bus_master_enable_notify(pci->ep.epc);
649650
} else if (FIELD_GET(PARF_INT_ALL_PM_TURNOFF, status)) {
650651
dev_dbg(dev, "Received PM Turn-off event! Entering L23\n");
651652
val = readl_relaxed(pcie_ep->parf + PARF_PM_CTRL);

drivers/pci/controller/dwc/pcie-tegra194.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,7 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie)
17151715
if (ret)
17161716
dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret);
17171717

1718+
pci_epc_deinit_notify(pcie->pci.ep.epc);
17181719
dw_pcie_ep_cleanup(&pcie->pci.ep);
17191720

17201721
reset_control_assert(pcie->core_rst);

drivers/pci/endpoint/functions/pci-epf-mhi.c

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ static void pci_epf_mhi_dma_deinit(struct pci_epf_mhi *epf_mhi)
716716
epf_mhi->dma_chan_rx = NULL;
717717
}
718718

719-
static int pci_epf_mhi_core_init(struct pci_epf *epf)
719+
static int pci_epf_mhi_epc_init(struct pci_epf *epf)
720720
{
721721
struct pci_epf_mhi *epf_mhi = epf_get_drvdata(epf);
722722
const struct pci_epf_mhi_ep_info *info = epf_mhi->info;
@@ -753,9 +753,35 @@ static int pci_epf_mhi_core_init(struct pci_epf *epf)
753753
if (!epf_mhi->epc_features)
754754
return -ENODATA;
755755

756+
if (info->flags & MHI_EPF_USE_DMA) {
757+
ret = pci_epf_mhi_dma_init(epf_mhi);
758+
if (ret) {
759+
dev_err(dev, "Failed to initialize DMA: %d\n", ret);
760+
return ret;
761+
}
762+
}
763+
756764
return 0;
757765
}
758766

767+
static void pci_epf_mhi_epc_deinit(struct pci_epf *epf)
768+
{
769+
struct pci_epf_mhi *epf_mhi = epf_get_drvdata(epf);
770+
const struct pci_epf_mhi_ep_info *info = epf_mhi->info;
771+
struct pci_epf_bar *epf_bar = &epf->bar[info->bar_num];
772+
struct mhi_ep_cntrl *mhi_cntrl = &epf_mhi->mhi_cntrl;
773+
struct pci_epc *epc = epf->epc;
774+
775+
if (mhi_cntrl->mhi_dev) {
776+
mhi_ep_power_down(mhi_cntrl);
777+
if (info->flags & MHI_EPF_USE_DMA)
778+
pci_epf_mhi_dma_deinit(epf_mhi);
779+
mhi_ep_unregister_controller(mhi_cntrl);
780+
}
781+
782+
pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no, epf_bar);
783+
}
784+
759785
static int pci_epf_mhi_link_up(struct pci_epf *epf)
760786
{
761787
struct pci_epf_mhi *epf_mhi = epf_get_drvdata(epf);
@@ -765,14 +791,6 @@ static int pci_epf_mhi_link_up(struct pci_epf *epf)
765791
struct device *dev = &epf->dev;
766792
int ret;
767793

768-
if (info->flags & MHI_EPF_USE_DMA) {
769-
ret = pci_epf_mhi_dma_init(epf_mhi);
770-
if (ret) {
771-
dev_err(dev, "Failed to initialize DMA: %d\n", ret);
772-
return ret;
773-
}
774-
}
775-
776794
mhi_cntrl->mmio = epf_mhi->mmio;
777795
mhi_cntrl->irq = epf_mhi->irq;
778796
mhi_cntrl->mru = info->mru;
@@ -819,7 +837,7 @@ static int pci_epf_mhi_link_down(struct pci_epf *epf)
819837
return 0;
820838
}
821839

822-
static int pci_epf_mhi_bme(struct pci_epf *epf)
840+
static int pci_epf_mhi_bus_master_enable(struct pci_epf *epf)
823841
{
824842
struct pci_epf_mhi *epf_mhi = epf_get_drvdata(epf);
825843
const struct pci_epf_mhi_ep_info *info = epf_mhi->info;
@@ -882,8 +900,8 @@ static void pci_epf_mhi_unbind(struct pci_epf *epf)
882900

883901
/*
884902
* Forcefully power down the MHI EP stack. Only way to bring the MHI EP
885-
* stack back to working state after successive bind is by getting BME
886-
* from host.
903+
* stack back to working state after successive bind is by getting Bus
904+
* Master Enable event from host.
887905
*/
888906
if (mhi_cntrl->mhi_dev) {
889907
mhi_ep_power_down(mhi_cntrl);
@@ -897,10 +915,11 @@ static void pci_epf_mhi_unbind(struct pci_epf *epf)
897915
}
898916

899917
static const struct pci_epc_event_ops pci_epf_mhi_event_ops = {
900-
.core_init = pci_epf_mhi_core_init,
918+
.epc_init = pci_epf_mhi_epc_init,
919+
.epc_deinit = pci_epf_mhi_epc_deinit,
901920
.link_up = pci_epf_mhi_link_up,
902921
.link_down = pci_epf_mhi_link_down,
903-
.bme = pci_epf_mhi_bme,
922+
.bus_master_enable = pci_epf_mhi_bus_master_enable,
904923
};
905924

906925
static int pci_epf_mhi_probe(struct pci_epf *epf,

0 commit comments

Comments
 (0)