diff options
author | Vidya Sagar <vidyas@nvidia.com> | 2019-08-13 07:36:19 -0400 |
---|---|---|
committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2019-08-13 10:51:55 -0400 |
commit | 5b0841fa653f6c156500ecfe7e996837884363c4 (patch) | |
tree | 69a8f642514a9047c55a871eb8e54c8b300d379c | |
parent | 7a6854f6874ff416afa6552706a0011418f07888 (diff) |
PCI: dwc: Add extended configuration space capability search API
Add extended configuration space capability search API using struct
dw_pcie* pointer.
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
Acked-by: Thierry Reding <treding@nvidia.com>
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.c | 41 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.h | 1 |
2 files changed, 42 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 7818b4febb08..181449e342f1 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c | |||
@@ -53,6 +53,47 @@ u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap) | |||
53 | } | 53 | } |
54 | EXPORT_SYMBOL_GPL(dw_pcie_find_capability); | 54 | EXPORT_SYMBOL_GPL(dw_pcie_find_capability); |
55 | 55 | ||
56 | static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start, | ||
57 | u8 cap) | ||
58 | { | ||
59 | u32 header; | ||
60 | int ttl; | ||
61 | int pos = PCI_CFG_SPACE_SIZE; | ||
62 | |||
63 | /* minimum 8 bytes per capability */ | ||
64 | ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; | ||
65 | |||
66 | if (start) | ||
67 | pos = start; | ||
68 | |||
69 | header = dw_pcie_readl_dbi(pci, pos); | ||
70 | /* | ||
71 | * If we have no capabilities, this is indicated by cap ID, | ||
72 | * cap version and next pointer all being 0. | ||
73 | */ | ||
74 | if (header == 0) | ||
75 | return 0; | ||
76 | |||
77 | while (ttl-- > 0) { | ||
78 | if (PCI_EXT_CAP_ID(header) == cap && pos != start) | ||
79 | return pos; | ||
80 | |||
81 | pos = PCI_EXT_CAP_NEXT(header); | ||
82 | if (pos < PCI_CFG_SPACE_SIZE) | ||
83 | break; | ||
84 | |||
85 | header = dw_pcie_readl_dbi(pci, pos); | ||
86 | } | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap) | ||
92 | { | ||
93 | return dw_pcie_find_next_ext_capability(pci, 0, cap); | ||
94 | } | ||
95 | EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability); | ||
96 | |||
56 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) | 97 | int dw_pcie_read(void __iomem *addr, int size, u32 *val) |
57 | { | 98 | { |
58 | if (!IS_ALIGNED((uintptr_t)addr, size)) { | 99 | if (!IS_ALIGNED((uintptr_t)addr, size)) { |
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index d8c66a6827dc..11c223471416 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h | |||
@@ -252,6 +252,7 @@ struct dw_pcie { | |||
252 | container_of((endpoint), struct dw_pcie, ep) | 252 | container_of((endpoint), struct dw_pcie, ep) |
253 | 253 | ||
254 | u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap); | 254 | u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap); |
255 | u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap); | ||
255 | 256 | ||
256 | int dw_pcie_read(void __iomem *addr, int size, u32 *val); | 257 | int dw_pcie_read(void __iomem *addr, int size, u32 *val); |
257 | int dw_pcie_write(void __iomem *addr, int size, u32 val); | 258 | int dw_pcie_write(void __iomem *addr, int size, u32 val); |