]> www.infradead.org Git - users/hch/misc.git/commitdiff
PCI: dwc: Implement capability search using PCI core APIs
authorHans Zhang <18255117159@163.com>
Wed, 13 Aug 2025 14:45:27 +0000 (22:45 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 14 Aug 2025 20:20:54 +0000 (15:20 -0500)
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
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h

index 89aad5a08928cc29870ab258d33bee9ff8f83143..5fe0744d4235c37f58d892dd29f56d671783c7ad 100644 (file)
@@ -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;
index 00f52d472dcdd794013a865ad6c4c7cc251edb48..b5e7e18138a656853cc62fa785a7034055d4d1fb 100644 (file)
@@ -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)
 {