Skip to content

Commit efaf16d

Browse files
shradhatkwilczynski
authored andcommitted
PCI: dwc: Add helper to find the Vendor Specific Extended Capability (VSEC)
The new dw_pcie_find_vsec_capability() helper will be used within different DWC APIs to find the VSEC capabilities like PTM, RAS, etc. Co-developed-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Manivannan Sadhasivam <[email protected]> Signed-off-by: Shradha Todi <[email protected]> Reviewed-by: Fan Ni <[email protected]> Tested-by: Hrishikesh Deleep <[email protected]> Link: https://lore.kernel.org/r/[email protected] [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <[email protected]>
1 parent 5d2b978 commit efaf16d

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/gpio/consumer.h>
1717
#include <linux/ioport.h>
1818
#include <linux/of.h>
19+
#include <linux/pcie-dwc.h>
1920
#include <linux/platform_device.h>
2021
#include <linux/sizes.h>
2122
#include <linux/types.h>
@@ -283,6 +284,45 @@ u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
283284
}
284285
EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
285286

287+
static u16 __dw_pcie_find_vsec_capability(struct dw_pcie *pci, u16 vendor_id,
288+
u16 vsec_id)
289+
{
290+
u16 vsec = 0;
291+
u32 header;
292+
293+
if (vendor_id != dw_pcie_readw_dbi(pci, PCI_VENDOR_ID))
294+
return 0;
295+
296+
while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
297+
PCI_EXT_CAP_ID_VNDR))) {
298+
header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
299+
if (PCI_VNDR_HEADER_ID(header) == vsec_id)
300+
return vsec;
301+
}
302+
303+
return 0;
304+
}
305+
306+
static u16 dw_pcie_find_vsec_capability(struct dw_pcie *pci,
307+
const struct dwc_pcie_vsec_id *vsec_ids)
308+
{
309+
const struct dwc_pcie_vsec_id *vid;
310+
u16 vsec;
311+
u32 header;
312+
313+
for (vid = vsec_ids; vid->vendor_id; vid++) {
314+
vsec = __dw_pcie_find_vsec_capability(pci, vid->vendor_id,
315+
vid->vsec_id);
316+
if (vsec) {
317+
header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
318+
if (PCI_VNDR_HEADER_REV(header) == vid->vsec_rev)
319+
return vsec;
320+
}
321+
}
322+
323+
return 0;
324+
}
325+
286326
int dw_pcie_read(void __iomem *addr, int size, u32 *val)
287327
{
288328
if (!IS_ALIGNED((uintptr_t)addr, size)) {

0 commit comments

Comments
 (0)