Skip to content

Commit 8ffc9f2

Browse files
Hans Zhangbjorn-helgaas
authored andcommitted
PCI: dwc: Implement capability search using PCI core APIs
The PCI core now provides generic PCI_FIND_NEXT_CAP() and PCI_FIND_NEXT_EXT_CAP() macros to search for PCI capabilities, using config accessors we supply. Use them in the DWC driver to implement dw_pcie_find_capability() and dw_pcie_find_ext_capability() instead of duplicating the algorithm. Signed-off-by: Hans Zhang <18255117159@163.com> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://patch.msgid.link/20250813144529.303548-5-18255117159@163.com
1 parent 4d909bf commit 8ffc9f2

2 files changed

Lines changed: 26 additions & 72 deletions

File tree

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

Lines changed: 5 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -213,83 +213,16 @@ void dw_pcie_version_detect(struct dw_pcie *pci)
213213
pci->type = ver;
214214
}
215215

216-
/*
217-
* These interfaces resemble the pci_find_*capability() interfaces, but these
218-
* are for configuring host controllers, which are bridges *to* PCI devices but
219-
* are not PCI devices themselves.
220-
*/
221-
static u8 __dw_pcie_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
222-
u8 cap)
223-
{
224-
u8 cap_id, next_cap_ptr;
225-
u16 reg;
226-
227-
if (!cap_ptr)
228-
return 0;
229-
230-
reg = dw_pcie_readw_dbi(pci, cap_ptr);
231-
cap_id = (reg & 0x00ff);
232-
233-
if (cap_id > PCI_CAP_ID_MAX)
234-
return 0;
235-
236-
if (cap_id == cap)
237-
return cap_ptr;
238-
239-
next_cap_ptr = (reg & 0xff00) >> 8;
240-
return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap);
241-
}
242-
243216
u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
244217
{
245-
u8 next_cap_ptr;
246-
u16 reg;
247-
248-
reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
249-
next_cap_ptr = (reg & 0x00ff);
250-
251-
return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap);
218+
return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap,
219+
pci);
252220
}
253221
EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
254222

255-
static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
256-
u8 cap)
257-
{
258-
u32 header;
259-
int ttl;
260-
int pos = PCI_CFG_SPACE_SIZE;
261-
262-
/* minimum 8 bytes per capability */
263-
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
264-
265-
if (start)
266-
pos = start;
267-
268-
header = dw_pcie_readl_dbi(pci, pos);
269-
/*
270-
* If we have no capabilities, this is indicated by cap ID,
271-
* cap version and next pointer all being 0.
272-
*/
273-
if (header == 0)
274-
return 0;
275-
276-
while (ttl-- > 0) {
277-
if (PCI_EXT_CAP_ID(header) == cap && pos != start)
278-
return pos;
279-
280-
pos = PCI_EXT_CAP_NEXT(header);
281-
if (pos < PCI_CFG_SPACE_SIZE)
282-
break;
283-
284-
header = dw_pcie_readl_dbi(pci, pos);
285-
}
286-
287-
return 0;
288-
}
289-
290223
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
291224
{
292-
return dw_pcie_find_next_ext_capability(pci, 0, cap);
225+
return PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, 0, cap, pci);
293226
}
294227
EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
295228

@@ -302,8 +235,8 @@ static u16 __dw_pcie_find_vsec_capability(struct dw_pcie *pci, u16 vendor_id,
302235
if (vendor_id != dw_pcie_readw_dbi(pci, PCI_VENDOR_ID))
303236
return 0;
304237

305-
while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
306-
PCI_EXT_CAP_ID_VNDR))) {
238+
while ((vsec = PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, vsec,
239+
PCI_EXT_CAP_ID_VNDR, pci))) {
307240
header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
308241
if (PCI_VNDR_HEADER_ID(header) == vsec_id)
309242
return vsec;

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,27 @@ static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val)
609609
dw_pcie_write_dbi2(pci, reg, 0x4, val);
610610
}
611611

612+
static inline int dw_pcie_read_cfg_byte(struct dw_pcie *pci, int where,
613+
u8 *val)
614+
{
615+
*val = dw_pcie_readb_dbi(pci, where);
616+
return PCIBIOS_SUCCESSFUL;
617+
}
618+
619+
static inline int dw_pcie_read_cfg_word(struct dw_pcie *pci, int where,
620+
u16 *val)
621+
{
622+
*val = dw_pcie_readw_dbi(pci, where);
623+
return PCIBIOS_SUCCESSFUL;
624+
}
625+
626+
static inline int dw_pcie_read_cfg_dword(struct dw_pcie *pci, int where,
627+
u32 *val)
628+
{
629+
*val = dw_pcie_readl_dbi(pci, where);
630+
return PCIBIOS_SUCCESSFUL;
631+
}
632+
612633
static inline unsigned int dw_pcie_ep_get_dbi_offset(struct dw_pcie_ep *ep,
613634
u8 func_no)
614635
{

0 commit comments

Comments
 (0)