From 462a088c474832b19ff2730de1e6bea66d399c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sat, 15 Oct 2022 23:01:29 +0200 Subject: Add Turris kernel (includes patches from OpenWrt) --- .../0031-PCI-mvebu-Use-child_ops-API.patch | 165 +++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 pkgs/patches-linux-5.15/0031-PCI-mvebu-Use-child_ops-API.patch (limited to 'pkgs/patches-linux-5.15/0031-PCI-mvebu-Use-child_ops-API.patch') diff --git a/pkgs/patches-linux-5.15/0031-PCI-mvebu-Use-child_ops-API.patch b/pkgs/patches-linux-5.15/0031-PCI-mvebu-Use-child_ops-API.patch new file mode 100644 index 0000000..41d7430 --- /dev/null +++ b/pkgs/patches-linux-5.15/0031-PCI-mvebu-Use-child_ops-API.patch @@ -0,0 +1,165 @@ +From a32d68b41dac1a1aeab94a2c8b2239534ac59c15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= +Date: Tue, 16 Nov 2021 10:43:17 +0100 +Subject: [PATCH 31/90] PCI: mvebu: Use child_ops API +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +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. + +Signed-off-by: Pali Rohár +--- + drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++-------------- + 1 file changed, 44 insertions(+), 38 deletions(-) + +diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c +index 9ea2f6a7c2b0..1e90ab888075 100644 +--- a/drivers/pci/controller/pci-mvebu.c ++++ b/drivers/pci/controller/pci-mvebu.c +@@ -294,11 +294,29 @@ 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) { ++ *val = 0xffffffff; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ ++ if (!mvebu_pcie_link_up(port)) { ++ *val = 0xffffffff; ++ 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); +@@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port, + 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 +375,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 +895,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,7 +909,6 @@ 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) { +@@ -897,21 +916,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, + 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)) { +- *val = 0xffffffff; +- 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 = { +@@ -1421,6 +1426,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; + +-- +2.34.1 + -- cgit v1.2.3