PCI: mvebu: Use child_ops API
authorPali Rohár <pali@kernel.org>
Tue, 22 Feb 2022 15:50:26 +0000 (16:50 +0100)
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tue, 22 Feb 2022 16:04:20 +0000 (16:04 +0000)
Split struct pci_ops between ops and child_ops. Member ops is used for
accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
accessing real PCIe cards.

There is no need to mix these two struct pci_ops into one as PCI core code
already provides separate callbacks via bridge->ops and bridge->child_ops.

Link: https://lore.kernel.org/r/20220222155030.988-9-pali@kernel.org
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
drivers/pci/controller/pci-mvebu.c

index 1cf5c02..1ae7718 100644 (file)
@@ -294,11 +294,25 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
        mvebu_writel(port, mask, PCIE_MASK_OFF);
 }
 
-static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
-                                struct pci_bus *bus,
-                                u32 devfn, int where, int size, u32 *val)
+static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
+                                                   struct pci_bus *bus,
+                                                   int devfn);
+
+static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+                                   int size, u32 *val)
 {
-       void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
+       struct mvebu_pcie *pcie = bus->sysdata;
+       struct mvebu_pcie_port *port;
+       void __iomem *conf_data;
+
+       port = mvebu_pcie_find_port(pcie, bus, devfn);
+       if (!port)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       if (!mvebu_pcie_link_up(port))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       conf_data = port->base + PCIE_CONF_DATA_OFF;
 
        mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
                     PCIE_CONF_ADDR_OFF);
@@ -314,18 +328,27 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
                *val = readl_relaxed(conf_data);
                break;
        default:
-               *val = 0xffffffff;
                return PCIBIOS_BAD_REGISTER_NUMBER;
        }
 
        return PCIBIOS_SUCCESSFUL;
 }
 
-static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
-                                struct pci_bus *bus,
-                                u32 devfn, int where, int size, u32 val)
+static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
+                                   int where, int size, u32 val)
 {
-       void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
+       struct mvebu_pcie *pcie = bus->sysdata;
+       struct mvebu_pcie_port *port;
+       void __iomem *conf_data;
+
+       port = mvebu_pcie_find_port(pcie, bus, devfn);
+       if (!port)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       if (!mvebu_pcie_link_up(port))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       conf_data = port->base + PCIE_CONF_DATA_OFF;
 
        mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
                     PCIE_CONF_ADDR_OFF);
@@ -347,6 +370,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
        return PCIBIOS_SUCCESSFUL;
 }
 
+static struct pci_ops mvebu_pcie_child_ops = {
+       .read = mvebu_pcie_child_rd_conf,
+       .write = mvebu_pcie_child_wr_conf,
+};
+
 /*
  * Remove windows, starting from the largest ones to the smallest
  * ones.
@@ -862,25 +890,12 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 {
        struct mvebu_pcie *pcie = bus->sysdata;
        struct mvebu_pcie_port *port;
-       int ret;
 
        port = mvebu_pcie_find_port(pcie, bus, devfn);
        if (!port)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
-       /* Access the emulated PCI-to-PCI bridge */
-       if (bus->number == 0)
-               return pci_bridge_emul_conf_write(&port->bridge, where,
-                                                 size, val);
-
-       if (!mvebu_pcie_link_up(port))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       /* Access the real PCIe interface */
-       ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
-                                   where, size, val);
-
-       return ret;
+       return pci_bridge_emul_conf_write(&port->bridge, where, size, val);
 }
 
 /* PCI configuration space read function */
@@ -889,25 +904,12 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 {
        struct mvebu_pcie *pcie = bus->sysdata;
        struct mvebu_pcie_port *port;
-       int ret;
 
        port = mvebu_pcie_find_port(pcie, bus, devfn);
        if (!port)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
-       /* Access the emulated PCI-to-PCI bridge */
-       if (bus->number == 0)
-               return pci_bridge_emul_conf_read(&port->bridge, where,
-                                                size, val);
-
-       if (!mvebu_pcie_link_up(port))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       /* Access the real PCIe interface */
-       ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
-                                   where, size, val);
-
-       return ret;
+       return pci_bridge_emul_conf_read(&port->bridge, where, size, val);
 }
 
 static struct pci_ops mvebu_pcie_ops = {
@@ -1416,6 +1418,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 
        bridge->sysdata = pcie;
        bridge->ops = &mvebu_pcie_ops;
+       bridge->child_ops = &mvebu_pcie_child_ops;
        bridge->align_resource = mvebu_pcie_align_resource;
        bridge->map_irq = mvebu_pcie_map_irq;