mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
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
This commit is contained in:
parent
4d909bf1a5
commit
8ffc9f234f
|
|
@ -213,83 +213,16 @@ void dw_pcie_version_detect(struct dw_pcie *pci)
|
|||
pci->type = ver;
|
||||
}
|
||||
|
||||
/*
|
||||
* These interfaces resemble the pci_find_*capability() interfaces, but these
|
||||
* are for configuring host controllers, which are bridges *to* PCI devices but
|
||||
* are not PCI devices themselves.
|
||||
*/
|
||||
static u8 __dw_pcie_find_next_cap(struct dw_pcie *pci, u8 cap_ptr,
|
||||
u8 cap)
|
||||
{
|
||||
u8 cap_id, next_cap_ptr;
|
||||
u16 reg;
|
||||
|
||||
if (!cap_ptr)
|
||||
return 0;
|
||||
|
||||
reg = dw_pcie_readw_dbi(pci, cap_ptr);
|
||||
cap_id = (reg & 0x00ff);
|
||||
|
||||
if (cap_id > PCI_CAP_ID_MAX)
|
||||
return 0;
|
||||
|
||||
if (cap_id == cap)
|
||||
return cap_ptr;
|
||||
|
||||
next_cap_ptr = (reg & 0xff00) >> 8;
|
||||
return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap);
|
||||
}
|
||||
|
||||
u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
|
||||
{
|
||||
u8 next_cap_ptr;
|
||||
u16 reg;
|
||||
|
||||
reg = dw_pcie_readw_dbi(pci, PCI_CAPABILITY_LIST);
|
||||
next_cap_ptr = (reg & 0x00ff);
|
||||
|
||||
return __dw_pcie_find_next_cap(pci, next_cap_ptr, cap);
|
||||
return PCI_FIND_NEXT_CAP(dw_pcie_read_cfg, PCI_CAPABILITY_LIST, cap,
|
||||
pci);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
|
||||
|
||||
static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
|
||||
u8 cap)
|
||||
{
|
||||
u32 header;
|
||||
int ttl;
|
||||
int pos = PCI_CFG_SPACE_SIZE;
|
||||
|
||||
/* minimum 8 bytes per capability */
|
||||
ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
|
||||
|
||||
if (start)
|
||||
pos = start;
|
||||
|
||||
header = dw_pcie_readl_dbi(pci, pos);
|
||||
/*
|
||||
* If we have no capabilities, this is indicated by cap ID,
|
||||
* cap version and next pointer all being 0.
|
||||
*/
|
||||
if (header == 0)
|
||||
return 0;
|
||||
|
||||
while (ttl-- > 0) {
|
||||
if (PCI_EXT_CAP_ID(header) == cap && pos != start)
|
||||
return pos;
|
||||
|
||||
pos = PCI_EXT_CAP_NEXT(header);
|
||||
if (pos < PCI_CFG_SPACE_SIZE)
|
||||
break;
|
||||
|
||||
header = dw_pcie_readl_dbi(pci, pos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap)
|
||||
{
|
||||
return dw_pcie_find_next_ext_capability(pci, 0, cap);
|
||||
return PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, 0, cap, pci);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dw_pcie_find_ext_capability);
|
||||
|
||||
|
|
@ -302,8 +235,8 @@ static u16 __dw_pcie_find_vsec_capability(struct dw_pcie *pci, u16 vendor_id,
|
|||
if (vendor_id != dw_pcie_readw_dbi(pci, PCI_VENDOR_ID))
|
||||
return 0;
|
||||
|
||||
while ((vsec = dw_pcie_find_next_ext_capability(pci, vsec,
|
||||
PCI_EXT_CAP_ID_VNDR))) {
|
||||
while ((vsec = PCI_FIND_NEXT_EXT_CAP(dw_pcie_read_cfg, vsec,
|
||||
PCI_EXT_CAP_ID_VNDR, pci))) {
|
||||
header = dw_pcie_readl_dbi(pci, vsec + PCI_VNDR_HEADER);
|
||||
if (PCI_VNDR_HEADER_ID(header) == vsec_id)
|
||||
return vsec;
|
||||
|
|
|
|||
|
|
@ -609,6 +609,27 @@ static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val)
|
|||
dw_pcie_write_dbi2(pci, reg, 0x4, val);
|
||||
}
|
||||
|
||||
static inline int dw_pcie_read_cfg_byte(struct dw_pcie *pci, int where,
|
||||
u8 *val)
|
||||
{
|
||||
*val = dw_pcie_readb_dbi(pci, where);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static inline int dw_pcie_read_cfg_word(struct dw_pcie *pci, int where,
|
||||
u16 *val)
|
||||
{
|
||||
*val = dw_pcie_readw_dbi(pci, where);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static inline int dw_pcie_read_cfg_dword(struct dw_pcie *pci, int where,
|
||||
u32 *val)
|
||||
{
|
||||
*val = dw_pcie_readl_dbi(pci, where);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static inline unsigned int dw_pcie_ep_get_dbi_offset(struct dw_pcie_ep *ep,
|
||||
u8 func_no)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user