Commit c099c2a7 authored by Pali Rohár's avatar Pali Rohár Committed by Lorenzo Pieralisi
Browse files

PCI: mvebu: Use child_ops API

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: default avatarPali Rohár <pali@kernel.org>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
parent 2b6ee04c
Loading
Loading
Loading
Loading
+40 −37
Original line number Diff line number Diff line
@@ -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,
static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
						    struct pci_bus *bus,
				 u32 devfn, int where, int size, u32 *val)
						    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;