@@ -534,10 +534,40 @@ void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn,
}
EXPORT_SYMBOL_GPL(dw_pcie_own_conf_map_bus);
+static int dw_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ struct pcie_port *pp = bus->sysdata;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ if (PCI_SLOT(devfn) > 0) {
+ *val = ~0U;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ *val = dw_pcie_read_dbi(pci, where, size);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int dw_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ struct pcie_port *pp = bus->sysdata;
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+
+ if (PCI_SLOT(devfn) > 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ dw_pcie_write_dbi(pci, where, size, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
static struct pci_ops dw_pcie_ops = {
.map_bus = dw_pcie_own_conf_map_bus,
- .read = pci_generic_config_read,
- .write = pci_generic_config_write,
+ .read = dw_pcie_rd_own_conf,
+ .write = dw_pcie_wr_own_conf,
};
void dw_pcie_setup_rc(struct pcie_port *pp)
Commit c2b0c098fbd1 ("PCI: dwc: Use generic config accessors") replaced the locally defined DW PCIe host controller config-space accessors with the generic methods pci_generic_config_read() and pci_generic_config_write(). It was intended that the corresponding bus-mapping callback returned a correct virtual address of the passed PCI config-space register. The problem of the proposed solution was that it didn't take into account the way the host config-space is accessed on the DW PCIe. Depending on the DW PCIe IP-core synthesize parameters different interfaces can be used to access the host and peripheral config/memory spaces. The former one can be accessed via the DBI interface, while the later ones is reached via the AHB/AXI application bus. In case if the DW PCIe controller is configured to have a dedicated DBI interface, the way it is mapped into the IO-memory turns to be platform-specific. For such setups the DWC PCIe driver provides a set of the callbacks dw_pcie_ops.{read_dbi,write_dbi} so the platforms glue-drivers would be able to take into account the DBI bus IO peculiarities. Since commit c2b0c098fbd1 ("PCI: dwc: Use generic config accessors") these methods haven't been utilized during the generic host initialization performed by the PCIe subsystem code. I don't really know how come there have been no problems spotted for the Histb/Exynos/Kirin PCIe controllers so far, but in our case with dword aligned IO requirement the generic config-space accessors can't be utilized for the host config-space. Thus in order to make sure the host config-space is properly accessed via the DBI bus let's get back the dw_pcie_rd_own_conf() and dw_pcie_wr_own_conf() methods. They are going to be just wrappers around the already defined dw_pcie_read_dbi()/dw_pcie_write_dbi() functions with proper arguments conversion. These methods perform the platform-specific config-space IO if the DBI accessors are specified, otherwise they call normal MMIO operations. Fixes: c2b0c098fbd1 ("PCI: dwc: Use generic config accessors") Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> --- .../pci/controller/dwc/pcie-designware-host.c | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-)