提交 c099c2a7 编写于 作者: P Pali Rohár 提交者: Lorenzo Pieralisi

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.orgSigned-off-by: NPali Rohár <pali@kernel.org>
Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
上级 2b6ee04c
...@@ -294,11 +294,25 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) ...@@ -294,11 +294,25 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
mvebu_writel(port, mask, PCIE_MASK_OFF); 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, 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), mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
PCIE_CONF_ADDR_OFF); PCIE_CONF_ADDR_OFF);
...@@ -314,18 +328,27 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port, ...@@ -314,18 +328,27 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
*val = readl_relaxed(conf_data); *val = readl_relaxed(conf_data);
break; break;
default: default:
*val = 0xffffffff;
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
} }
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port, static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
struct pci_bus *bus, int where, int size, u32 val)
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), mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
PCIE_CONF_ADDR_OFF); PCIE_CONF_ADDR_OFF);
...@@ -347,6 +370,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port, ...@@ -347,6 +370,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
return PCIBIOS_SUCCESSFUL; 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 * Remove windows, starting from the largest ones to the smallest
* ones. * ones.
...@@ -862,25 +890,12 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, ...@@ -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 *pcie = bus->sysdata;
struct mvebu_pcie_port *port; struct mvebu_pcie_port *port;
int ret;
port = mvebu_pcie_find_port(pcie, bus, devfn); port = mvebu_pcie_find_port(pcie, bus, devfn);
if (!port) if (!port)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
/* Access the emulated PCI-to-PCI bridge */ return pci_bridge_emul_conf_write(&port->bridge, where, size, val);
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;
} }
/* PCI configuration space read function */ /* PCI configuration space read function */
...@@ -889,25 +904,12 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -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 *pcie = bus->sysdata;
struct mvebu_pcie_port *port; struct mvebu_pcie_port *port;
int ret;
port = mvebu_pcie_find_port(pcie, bus, devfn); port = mvebu_pcie_find_port(pcie, bus, devfn);
if (!port) if (!port)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
/* Access the emulated PCI-to-PCI bridge */ return pci_bridge_emul_conf_read(&port->bridge, where, size, val);
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;
} }
static struct pci_ops mvebu_pcie_ops = { static struct pci_ops mvebu_pcie_ops = {
...@@ -1416,6 +1418,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev) ...@@ -1416,6 +1418,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
bridge->sysdata = pcie; bridge->sysdata = pcie;
bridge->ops = &mvebu_pcie_ops; bridge->ops = &mvebu_pcie_ops;
bridge->child_ops = &mvebu_pcie_child_ops;
bridge->align_resource = mvebu_pcie_align_resource; bridge->align_resource = mvebu_pcie_align_resource;
bridge->map_irq = mvebu_pcie_map_irq; bridge->map_irq = mvebu_pcie_map_irq;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册