PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Subsystems (12)
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
v1 -> v2
- Split pci_fixup_irqs() removal in several patches
- Embedded pci_register_host_bridge() in pci_scan_root_bus_bridge()
- Refactored iproc, faraday and xilinx-nwl host bridges in preparation for irq fixup removal
- Converted all DT PCI host bridge drivers to pci_scan_root_bus_bridge()
- Dropped RFC tag
- Added devm_pci_alloc_host_bridge() interface
- Rebased against v4.12-rc3
v1: http://marc.info/?l=linux-pci&m=149320545522205&w=2
Current pci_fixup_irqs() usage on ARM/ARM64 host controller drivers is flawed in that pci_fixup_irqs() allocates IRQs for all PCI devices present in a system; those PCI devices possibly belong to different PCI bus trees (and possibly rooted at different host bridges) and may well be enabled (ie probed and bound to a driver) by the time pci_fixup_irqs() is called when probing a given host bridge driver.
Furthermore, current kernel code relying on pci_fixup_irqs() to assign legacy PCI IRQs to devices does not work at all for hotplugged devices in that the code carrying out the IRQ fixup is called at host bridge driver probe time, which just cannot take into account devices hotplugged after system has booted.
By leveraging Matthew Minter's patch series (and its purpose):
http://lkml.kernel.org/r/1445576642-29624-2-git-send-email-matt at masarand.com
this series[1] adds IRQs mapping and swizzling primitives to the struct pci_host_bridge which allows IRQs to be allocated for for a device at probe time with host bridge specific functions, fixing the aforementioned limitations.
Current series remove pci_fixup_irqs() usage on ARM/ARM64; removal can be extended to other architectures provided the IRQs map/swizzle functions are set-up properly in the respective host bridges set-up/probe paths.
Tested on kvmtool with PCI host generic.
[1] git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git pci/pci-fixup-irqs-removal-v2
Lorenzo Pieralisi (37):
PCI: xilinx-nwl: Remove nwl_pcie_enable_msi() unused bus parameter
drivers: pci: host: iproc: Convert link check to raw PCI config
accessors
drivers: pci: host: ftpci100: convert IRQ masking to raw PCI config
accessors
PCI: Initialize bridge release function at bridge allocation
PCI: Add pci_free_host_bridge interface
PCI: Add devm_pci_alloc_host_bridge() interface
drivers: pci: host: ftpci100: Fix host bridge memory leakage
drivers: pci: host: tegra: Fix host bridge memory leakage
PCI: Introduce pci_scan_root_bus_bridge()
PCI: Make pci_register_host_bridge() PCI core internal
ARM: PCI: bios32: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: designware: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: aardvark: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: rcar: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: iproc: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: versatile: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: altera: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: xilinx: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: xgene: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: host-common: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: rockchip: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: xilinx-nwl: Convert PCI scan API to pci_scan_root_bus_bridge()
PCI: Remove pci_scan_root_bus_msi()
ARM: PCI: Remove pci_fixup_irqs() call for bios32 host controllers
PCI: tegra: Drop pci_fixup_irqs()
PCI: xilinx: Drop pci_fixup_irqs()
PCI: rcar: Drop pci_fixup_irqs()
PCI: iproc: Drop pci_fixup_irqs()
PCI: designware-host: Drop pci_fixup_irqs()
PCI: ftpci100: Drop pci_fixup_irqs()
PCI: host-common: Drop pci_fixup_irqs()
PCI: versatile: Drop pci_fixup_irqs()
PCI: altera: Drop pci_fixup_irqs()
PCI: xgene: Move to struct pci_host_bridge IRQ mapping functions
PCI: rockchip: Move to struct pci_host_bridge IRQ mapping functions
PCI: xilinx-nwl: Move to struct pci_host_bridge IRQ mapping functions
ARM64: PCI: Drop DT IRQ allocation from pcibios_alloc_irq()
Matthew Minter (5):
PCI: Build setup-irq.o on all arches
PCI: Add IRQ mapping function pointers to pci_host_bridge struct
PCI: Add pci_assign_irq() function and have pci_fixup_irqs() use it OF/PCI: Update of_irq_parse_and_map_pci() comment
PCI: Add a call to pci_assign_irq() in pci_device_probe()
Documentation/driver-model/devres.txt | 1 + arch/arm/include/asm/mach/pci.h | 3 +- arch/arm/kernel/bios32.c | 43 +++++++---- arch/arm/mach-dove/pcie.c | 33 +++++--- arch/arm/mach-iop13xx/pci.c | 31 +++++--- arch/arm/mach-iop13xx/pci.h | 3 +- arch/arm/mach-mv78xx0/pcie.c | 8 +- arch/arm/mach-orion5x/common.h | 3 +- arch/arm/mach-orion5x/pci.c | 39 ++++++---- arch/arm64/kernel/pci.c | 10 +-- drivers/of/of_pci_irq.c | 3 +- drivers/pci/Makefile | 17 +---- drivers/pci/dwc/pcie-designware-host.c | 43 ++++++----- drivers/pci/host/pci-aardvark.c | 21 +++-- drivers/pci/host/pci-ftpci100.c | 50 +++++++----- drivers/pci/host/pci-host-common.c | 27 +++++-- drivers/pci/host/pci-tegra.c | 9 +-- drivers/pci/host/pci-versatile.c | 22 +++++- drivers/pci/host/pci-xgene.c | 23 ++++-- drivers/pci/host/pcie-altera.c | 24 ++++-- drivers/pci/host/pcie-iproc-bcma.c | 7 +- drivers/pci/host/pcie-iproc-platform.c | 7 +- drivers/pci/host/pcie-iproc.c | 135 +++++++++++++++++++++++---------- drivers/pci/host/pcie-rcar.c | 40 ++++++---- drivers/pci/host/pcie-rockchip.c | 24 ++++-- drivers/pci/host/pcie-xilinx-nwl.c | 34 ++++++--- drivers/pci/host/pcie-xilinx.c | 34 +++++---- drivers/pci/pci-driver.c | 2 + drivers/pci/probe.c | 105 ++++++++++++++++++------- drivers/pci/setup-irq.c | 45 ++++++++--- include/linux/pci.h | 12 +-- 31 files changed, 565 insertions(+), 293 deletions(-)
Signature · 1 line
2.10.0
PATCH v2 1/42 PCI: xilinx-nwl: Remove nwl_pcie_enable_msi() unused bus parameter
nwl_pcie_enable_msi() second parameter (ie bus) is unused and creates a fake dependency on the struct pci_bus that just does not exist.
Remove it.
--- drivers/pci/host/pcie-xilinx-nwl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/host/pcie-xilinx-nwl.c +2 -2
@@ -530,7 +530,7 @@ static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie)return 0 ; } -static int nwl_pcie_enable_msi (struct nwl_pcie *pcie,struct pci_bus *bus) +static int nwl_pcie_enable_msi (struct nwl_pcie *pcie) {struct device *dev = pcie->dev;struct platform_device *pdev =to_platform_device (dev);
@@ -838,7 +838,7 @@ static int nwl_pcie_probe(struct platform_device *pdev) }if (IS_ENABLED (CONFIG_PCI_MSI )) { - err =nwl_pcie_enable_msi (pcie, bus); + err =nwl_pcie_enable_msi (pcie);if (err <0 ) {dev_err (dev,"failed to enable MSI support: %d\n" , err); goto error;
Signature · 1 line
2.10.0
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
In reply to Lorenzo PieralisiCurrent iproc driver host bridge controller driver requires struct pci_bus to be created in order to carry out PCI link checks with standard PCI config space accessors.
This struct pci_bus dependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).
Add PCI raw config space accessors to PCIe iproc driver and remove the fictitious struct pci_bus dependency.
--- drivers/pci/host/pcie-iproc.c | 94 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-)
drivers/pci/host/pcie-iproc.c +74 -20
@@ -452,14 +452,13 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,* Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ -static void __iomem *iproc_pcie_map_cfg_bus (struct pci_bus *bus, +static void __iomem *iproc_pcie_map_cfg_bus (struct iproc_pcie *pcie, +int busno,unsigned int devfn,int where) { -struct iproc_pcie *pcie =iproc_data (bus);unsigned slot =PCI_SLOT (devfn);unsigned fn =PCI_FUNC (devfn); -unsigned busno = bus->number;u32 val;u16 offset;
@@ -499,6 +498,58 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,return (pcie->base + offset); } +static void __iomem *iproc_pcie_bus_map_cfg_bus (struct pci_bus *bus, +unsigned int devfn, +int where) +{ +return iproc_pcie_map_cfg_bus (iproc_data (bus), bus->number, devfn, + where); +} + +static int iproc_pci_raw_config_read32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 *val) +{ +void __iomem *addr; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) { + *val = ~0 ; +return PCIBIOS_DEVICE_NOT_FOUND ; + } + + *val =readl (addr); + +if (size <=2 ) + *val = (*val >> (8 * (where &3 ))) & ((1 << (size *8 )) -1 ); + +return PCIBIOS_SUCCESSFUL ; +} + +static int iproc_pci_raw_config_write32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 val) +{ +void __iomem *addr; +u32 mask, tmp; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +if (size ==4 ) { +writel (val, addr); +return PCIBIOS_SUCCESSFUL ; + } + + mask = ~(((1 << (size *8 )) -1 ) << ((where &0x3 ) *8 )); + tmp =readl (addr) & mask; + tmp |= val << ((where &0x3 ) *8 ); +writel (tmp, addr); + +return PCIBIOS_SUCCESSFUL ; +} +static int iproc_pcie_config_read32 (struct pci_bus *bus,unsigned int devfn,int where,int size,u32 *val) {
@@ -524,7 +575,7 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, }static struct pci_ops iproc_pcie_ops = { - .map_bus = iproc_pcie_map_cfg_bus, + .map_bus = iproc_pcie_bus_map_cfg_bus, .read = iproc_pcie_config_read32, .write = iproc_pcie_config_write32, };
@@ -556,12 +607,11 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)msleep (100 ); } -static int iproc_pcie_check_link (struct iproc_pcie *pcie,struct pci_bus *bus) +static int iproc_pcie_check_link (struct iproc_pcie *pcie) {struct device *dev = pcie->dev; -u8 hdr_type; -u32 link_ctrl, class, val; -u16 pos =PCI_EXP_CAP , link_status; +u32 hdr_type, link_ctrl, link_status, class, val; +u16 pos =PCI_EXP_CAP ;bool link_is_active = false;/*
@@ -578,7 +628,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) }/* make sure we are not in EP mode */ -pci_bus_read_config_byte (bus,0 ,PCI_HEADER_TYPE , &hdr_type); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_HEADER_TYPE ,1 , &hdr_type);if ((hdr_type &0x7f ) !=PCI_HEADER_TYPE_BRIDGE ) {dev_err (dev,"in EP mode, hdr=%#02x\n" , hdr_type);return -EFAULT ;
@@ -588,13 +638,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c#define PCI_CLASS_BRIDGE_MASK 0xffff00#define PCI_CLASS_BRIDGE_SHIFT 8 -pci_bus_read_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , &class); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , &class); class &= ~PCI_CLASS_BRIDGE_MASK ; class |= (PCI_CLASS_BRIDGE_PCI <<PCI_CLASS_BRIDGE_SHIFT ); -pci_bus_write_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , class); +iproc_pci_raw_config_write32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , class);/* check link status to see if link is active */ -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , &link_status); +iproc_pci_raw_config_read32 (pcie,0 , pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true;
@@ -603,20 +656,21 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_TARGET_LINK_SPEED_MASK 0xf#define PCI_TARGET_LINK_SPEED_GEN2 0x2#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -pci_bus_read_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 ,4 , &link_ctrl);if ((link_ctrl &PCI_TARGET_LINK_SPEED_MASK ) ==PCI_TARGET_LINK_SPEED_GEN2 ) { link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK ; link_ctrl |=PCI_TARGET_LINK_SPEED_GEN1 ; -pci_bus_write_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , - link_ctrl); +iproc_pci_raw_config_write32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 , +4 , link_ctrl);msleep (100 ); -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , - &link_status); +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true; }
@@ -1260,7 +1314,7 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) } pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie, bus); + ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); goto err_rm_root_bus;
Signature · 1 line
2.10.0
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
Thanks,
Ray
Quoted 191 lines · Lorenzo Pieralisi
Current iproc driver host bridge controller driver requires struct
pci_busto be created in order to carry out PCI link checks with standard PCI config space accessors.This struct
pci_busdependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).Add PCI raw config space accessors to PCIe iproc driver and remove the fictitious struct
pci_busdependency.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Scott Branden <[email protected]>Cc Ray Jui <[email protected]>Cc Jon Mason <[email protected]>--- drivers/pci/host/pcie-iproc.c | 94 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-)drivers/pci/host/pcie-iproc.c +74
-20@@ -452,14 +452,13 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,* Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ -static void __iomem *iproc_pcie_map_cfg_bus (struct pci_bus *bus, +static void __iomem *iproc_pcie_map_cfg_bus (struct iproc_pcie *pcie, +int busno,unsigned int devfn,int where) { -struct iproc_pcie *pcie =iproc_data (bus);unsigned slot =PCI_SLOT (devfn);unsigned fn =PCI_FUNC (devfn); -unsigned busno = bus->number;u32 val;u16 offset;@@ -499,6 +498,58 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,return (pcie->base + offset); } +static void __iomem *iproc_pcie_bus_map_cfg_bus (struct pci_bus *bus, +unsigned int devfn, +int where) +{ +return iproc_pcie_map_cfg_bus (iproc_data (bus), bus->number, devfn, + where); +} + +static int iproc_pci_raw_config_read32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 *val) +{ +void __iomem *addr; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) { + *val = ~0 ; +return PCIBIOS_DEVICE_NOT_FOUND ; + } + + *val =readl (addr); + +if (size <=2 ) + *val = (*val >> (8 * (where &3 ))) & ((1 << (size *8 )) -1 ); + +return PCIBIOS_SUCCESSFUL ; +} + +static int iproc_pci_raw_config_write32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 val) +{ +void __iomem *addr; +u32 mask, tmp; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +if (size ==4 ) { +writel (val, addr); +return PCIBIOS_SUCCESSFUL ; + } + + mask = ~(((1 << (size *8 )) -1 ) << ((where &0x3 ) *8 )); + tmp =readl (addr) & mask; + tmp |= val << ((where &0x3 ) *8 ); +writel (tmp, addr); + +return PCIBIOS_SUCCESSFUL ; +} +static int iproc_pcie_config_read32 (struct pci_bus *bus,unsigned int devfn,int where,int size,u32 *val) {@@ -524,7 +575,7 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, }static struct pci_ops iproc_pcie_ops = { - .map_bus = iproc_pcie_map_cfg_bus, + .map_bus = iproc_pcie_bus_map_cfg_bus, .read = iproc_pcie_config_read32, .write = iproc_pcie_config_write32, };@@ -556,12 +607,11 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)msleep (100 ); } -static int iproc_pcie_check_link (struct iproc_pcie *pcie,struct pci_bus *bus) +static int iproc_pcie_check_link (struct iproc_pcie *pcie) {struct device *dev = pcie->dev; -u8 hdr_type; -u32 link_ctrl, class, val; -u16 pos =PCI_EXP_CAP , link_status; +u32 hdr_type, link_ctrl, link_status, class, val; +u16 pos =PCI_EXP_CAP ;bool link_is_active = false;/* @@ -578,7 +628,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) }/* make sure we are not in EP mode */ -pci_bus_read_config_byte (bus,0 ,PCI_HEADER_TYPE , &hdr_type); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_HEADER_TYPE ,1 , &hdr_type);if ((hdr_type &0x7f ) !=PCI_HEADER_TYPE_BRIDGE ) {dev_err (dev,"in EP mode, hdr=%#02x\n" , hdr_type);return -EFAULT ;@@ -588,13 +638,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c#define PCI_CLASS_BRIDGE_MASK 0xffff00#define PCI_CLASS_BRIDGE_SHIFT 8 -pci_bus_read_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , &class); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , &class); class &= ~PCI_CLASS_BRIDGE_MASK ; class |= (PCI_CLASS_BRIDGE_PCI <<PCI_CLASS_BRIDGE_SHIFT ); -pci_bus_write_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , class); +iproc_pci_raw_config_write32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , class);/* check link status to see if link is active */ -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , &link_status); +iproc_pci_raw_config_read32 (pcie,0 , pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true;@@ -603,20 +656,21 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_TARGET_LINK_SPEED_MASK 0xf#define PCI_TARGET_LINK_SPEED_GEN2 0x2#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -pci_bus_read_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 ,4 , &link_ctrl);if ((link_ctrl &PCI_TARGET_LINK_SPEED_MASK ) ==PCI_TARGET_LINK_SPEED_GEN2 ) { link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK ; link_ctrl |=PCI_TARGET_LINK_SPEED_GEN1 ; -pci_bus_write_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , - link_ctrl); +iproc_pci_raw_config_write32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 , +4 , link_ctrl);msleep (100 ); -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , - &link_status); +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true; }@@ -1260,7 +1314,7 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) } pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie, bus); + ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); goto err_rm_root_bus;
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.git pci/pci-fixup-irqs-removal-v2
Thanks for testing it, please let me know.
Thank you !
Lorenzo
Quoted 189 lines
Thanks,
Ray
Quoted 181 lines · Lorenzo Pieralisi
Current iproc driver host bridge controller driver requires struct
pci_busto be created in order to carry out PCI link checks with standard PCI config space accessors.This struct
pci_busdependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).Add PCI raw config space accessors to PCIe iproc driver and remove the fictitious struct
pci_busdependency.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Scott Branden <[email protected]>Cc Ray Jui <[email protected]>Cc Jon Mason <[email protected]>--- drivers/pci/host/pcie-iproc.c | 94 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-)drivers/pci/host/pcie-iproc.c +74
-20@@ -452,14 +452,13 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,* Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ -static void __iomem *iproc_pcie_map_cfg_bus (struct pci_bus *bus, +static void __iomem *iproc_pcie_map_cfg_bus (struct iproc_pcie *pcie, +int busno,unsigned int devfn,int where) { -struct iproc_pcie *pcie =iproc_data (bus);unsigned slot =PCI_SLOT (devfn);unsigned fn =PCI_FUNC (devfn); -unsigned busno = bus->number;u32 val;u16 offset;@@ -499,6 +498,58 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,return (pcie->base + offset); } +static void __iomem *iproc_pcie_bus_map_cfg_bus (struct pci_bus *bus, +unsigned int devfn, +int where) +{ +return iproc_pcie_map_cfg_bus (iproc_data (bus), bus->number, devfn, + where); +} + +static int iproc_pci_raw_config_read32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 *val) +{ +void __iomem *addr; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) { + *val = ~0 ; +return PCIBIOS_DEVICE_NOT_FOUND ; + } + + *val =readl (addr); + +if (size <=2 ) + *val = (*val >> (8 * (where &3 ))) & ((1 << (size *8 )) -1 ); + +return PCIBIOS_SUCCESSFUL ; +} + +static int iproc_pci_raw_config_write32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 val) +{ +void __iomem *addr; +u32 mask, tmp; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +if (size ==4 ) { +writel (val, addr); +return PCIBIOS_SUCCESSFUL ; + } + + mask = ~(((1 << (size *8 )) -1 ) << ((where &0x3 ) *8 )); + tmp =readl (addr) & mask; + tmp |= val << ((where &0x3 ) *8 ); +writel (tmp, addr); + +return PCIBIOS_SUCCESSFUL ; +} +static int iproc_pcie_config_read32 (struct pci_bus *bus,unsigned int devfn,int where,int size,u32 *val) {@@ -524,7 +575,7 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, }static struct pci_ops iproc_pcie_ops = { - .map_bus = iproc_pcie_map_cfg_bus, + .map_bus = iproc_pcie_bus_map_cfg_bus, .read = iproc_pcie_config_read32, .write = iproc_pcie_config_write32, };@@ -556,12 +607,11 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)msleep (100 ); } -static int iproc_pcie_check_link (struct iproc_pcie *pcie,struct pci_bus *bus) +static int iproc_pcie_check_link (struct iproc_pcie *pcie) {struct device *dev = pcie->dev; -u8 hdr_type; -u32 link_ctrl, class, val; -u16 pos =PCI_EXP_CAP , link_status; +u32 hdr_type, link_ctrl, link_status, class, val; +u16 pos =PCI_EXP_CAP ;bool link_is_active = false;/* @@ -578,7 +628,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) }/* make sure we are not in EP mode */ -pci_bus_read_config_byte (bus,0 ,PCI_HEADER_TYPE , &hdr_type); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_HEADER_TYPE ,1 , &hdr_type);if ((hdr_type &0x7f ) !=PCI_HEADER_TYPE_BRIDGE ) {dev_err (dev,"in EP mode, hdr=%#02x\n" , hdr_type);return -EFAULT ;@@ -588,13 +638,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c#define PCI_CLASS_BRIDGE_MASK 0xffff00#define PCI_CLASS_BRIDGE_SHIFT 8 -pci_bus_read_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , &class); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , &class); class &= ~PCI_CLASS_BRIDGE_MASK ; class |= (PCI_CLASS_BRIDGE_PCI <<PCI_CLASS_BRIDGE_SHIFT ); -pci_bus_write_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , class); +iproc_pci_raw_config_write32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , class);/* check link status to see if link is active */ -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , &link_status); +iproc_pci_raw_config_read32 (pcie,0 , pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true;@@ -603,20 +656,21 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_TARGET_LINK_SPEED_MASK 0xf#define PCI_TARGET_LINK_SPEED_GEN2 0x2#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -pci_bus_read_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 ,4 , &link_ctrl);if ((link_ctrl &PCI_TARGET_LINK_SPEED_MASK ) ==PCI_TARGET_LINK_SPEED_GEN2 ) { link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK ; link_ctrl |=PCI_TARGET_LINK_SPEED_GEN1 ; -pci_bus_write_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , - link_ctrl); +iproc_pci_raw_config_write32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 , +4 , link_ctrl);msleep (100 ); -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , - &link_status); +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true; }@@ -1260,7 +1314,7 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) } pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie, bus); + ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); goto err_rm_root_bus;
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 12 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 9 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
Quoted 5 lines
Quoted 1 line
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Hi Bjorn,
please help to review following changes, to avoid merge conflicts since Lorenzo's changes in iproc driver is touching basic config APIs.
[PATCH v3 1/2] PCI: iproc: Retry request when CRS returned from EP [PATCH v3 2/2] PCI: iproc: add device shutdown for PCI RC
Regards,
Oza.
Quoted 200 lines
Thanks for testing it, please let me know.
Thank you !
LorenzoQuoted 180 lines
Thanks,
Ray
Quoted 173 lines · Lorenzo Pieralisi
Current iproc driver host bridge controller driver requires struct
pci_busto be created in order to carry out PCI link checks with standard PCI config space accessors.This struct
pci_busdependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).Add PCI raw config space accessors to PCIe iproc driver and remove the fictitious struct
pci_busdependency.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Scott Branden <[email protected]>Cc Ray Jui <[email protected]>Cc Jon Mason <[email protected]>--- drivers/pci/host/pcie-iproc.c | 94 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-)drivers/pci/host/pcie-iproc.c +73
-19@@ -452,14 +452,13 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,* Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ -static void __iomem *iproc_pcie_map_cfg_bus (struct pci_bus *bus, +static void __iomem *iproc_pcie_map_cfg_bus (struct iproc_pcie *pcie, +int busno,unsigned int devfn,int where) { -struct iproc_pcie *pcie =iproc_data (bus);unsigned slot =PCI_SLOT (devfn);unsigned fn =PCI_FUNC (devfn); -unsigned busno = bus->number;u32 val;u16 offset;@@ -499,6 +498,58 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,return (pcie->base + offset); } +static void __iomem *iproc_pcie_bus_map_cfg_bus (struct pci_bus *bus, +unsigned int devfn, +int where) +{ +return iproc_pcie_map_cfg_bus (iproc_data (bus), bus->number, devfn, + where); +} + +static int iproc_pci_raw_config_read32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 *val) +{ +void __iomem *addr; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) { + *val = ~0 ; +return PCIBIOS_DEVICE_NOT_FOUND ; + } + + *val =readl (addr); + +if (size <=2 ) + *val = (*val >> (8 * (where &3 ))) & ((1 << (size *8 )) -1 ); + +return PCIBIOS_SUCCESSFUL ; +} + +static int iproc_pci_raw_config_write32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 val) +{ +void __iomem *addr; +u32 mask, tmp; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +if (size ==4 ) { +writel (val, addr); +return PCIBIOS_SUCCESSFUL ; + } + + mask = ~(((1 << (size *8 )) -1 ) << ((where &0x3 ) *8 )); + tmp =readl (addr) & mask; + tmp |= val << ((where &0x3 ) *8 ); +writel (tmp, addr); + +return PCIBIOS_SUCCESSFUL ; +} +static int iproc_pcie_config_read32 (struct pci_bus *bus,unsigned int devfn,int where,int size,u32 *val) {@@ -524,7 +575,7 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, }static struct pci_ops iproc_pcie_ops = { - .map_bus = iproc_pcie_map_cfg_bus, + .map_bus = iproc_pcie_bus_map_cfg_bus, .read = iproc_pcie_config_read32, .write = iproc_pcie_config_write32, };@@ -556,12 +607,11 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)msleep (100 ); } -static int iproc_pcie_check_link (struct iproc_pcie *pcie,struct pci_bus *bus) +static int iproc_pcie_check_link (struct iproc_pcie *pcie) {struct device *dev = pcie->dev; -u8 hdr_type; -u32 link_ctrl, class, val; -u16 pos =PCI_EXP_CAP , link_status; +u32 hdr_type, link_ctrl, link_status, class, val; +u16 pos =PCI_EXP_CAP ;bool link_is_active = false;/* @@ -578,7 +628,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) }/* make sure we are not in EP mode */ -pci_bus_read_config_byte (bus,0 ,PCI_HEADER_TYPE , &hdr_type); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_HEADER_TYPE ,1 , &hdr_type);if ((hdr_type &0x7f ) !=PCI_HEADER_TYPE_BRIDGE ) {dev_err (dev,"in EP mode, hdr=%#02x\n" , hdr_type);return -EFAULT ;@@ -588,13 +638,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c#define PCI_CLASS_BRIDGE_MASK 0xffff00#define PCI_CLASS_BRIDGE_SHIFT 8 -pci_bus_read_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , &class); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , &class); class &= ~PCI_CLASS_BRIDGE_MASK ; class |= (PCI_CLASS_BRIDGE_PCI <<PCI_CLASS_BRIDGE_SHIFT ); -pci_bus_write_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , class); +iproc_pci_raw_config_write32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , class);/* check link status to see if link is active */ -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , &link_status); +iproc_pci_raw_config_read32 (pcie,0 , pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true;@@ -603,20 +656,21 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_TARGET_LINK_SPEED_MASK 0xf#define PCI_TARGET_LINK_SPEED_GEN2 0x2#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -pci_bus_read_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 ,4 , &link_ctrl);if ((link_ctrl &PCI_TARGET_LINK_SPEED_MASK ) ==PCI_TARGET_LINK_SPEED_GEN2 ) { link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK ; link_ctrl |=PCI_TARGET_LINK_SPEED_GEN1 ; -pci_bus_write_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , - link_ctrl); +iproc_pci_raw_config_write32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 , +4 , link_ctrl);msleep (100 ); -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , - &link_status); +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true; }Quoted 9 lines
drivers/pci/host/pcie-iproc.c int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) · line 1319
Quoted 8 lines
drivers/pci/host/pcie-iproc.c +1
-1@@ -1260,7 +1314,7 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) } pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie, bus); + ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); goto err_rm_root_bus;_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 16 lines · Oza Oza
Quoted 14 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
Quoted 8 lines
Quoted 3 lines
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
Thanks a lot,
Lorenzo
Quoted 213 lines
Hi Bjorn,
please help to review following changes, to avoid merge conflicts since Lorenzo's changes in iproc driver is touching basic config APIs.
[PATCH v3 1/2] PCI: iproc: Retry request when CRS returned from EP [PATCH v3 2/2] PCI: iproc: add device shutdown for PCI RC
Regards,
Oza.Quoted 200 lines
Thanks for testing it, please let me know.
Thank you !
LorenzoQuoted 180 lines
Thanks,
Ray
Quoted 173 lines · Lorenzo Pieralisi
Current iproc driver host bridge controller driver requires struct
pci_busto be created in order to carry out PCI link checks with standard PCI config space accessors.This struct
pci_busdependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).Add PCI raw config space accessors to PCIe iproc driver and remove the fictitious struct
pci_busdependency.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Scott Branden <[email protected]>Cc Ray Jui <[email protected]>Cc Jon Mason <[email protected]>--- drivers/pci/host/pcie-iproc.c | 94 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-)drivers/pci/host/pcie-iproc.c +73
-19@@ -452,14 +452,13 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,* Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ -static void __iomem *iproc_pcie_map_cfg_bus (struct pci_bus *bus, +static void __iomem *iproc_pcie_map_cfg_bus (struct iproc_pcie *pcie, +int busno,unsigned int devfn,int where) { -struct iproc_pcie *pcie =iproc_data (bus);unsigned slot =PCI_SLOT (devfn);unsigned fn =PCI_FUNC (devfn); -unsigned busno = bus->number;u32 val;u16 offset;@@ -499,6 +498,58 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,return (pcie->base + offset); } +static void __iomem *iproc_pcie_bus_map_cfg_bus (struct pci_bus *bus, +unsigned int devfn, +int where) +{ +return iproc_pcie_map_cfg_bus (iproc_data (bus), bus->number, devfn, + where); +} + +static int iproc_pci_raw_config_read32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 *val) +{ +void __iomem *addr; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) { + *val = ~0 ; +return PCIBIOS_DEVICE_NOT_FOUND ; + } + + *val =readl (addr); + +if (size <=2 ) + *val = (*val >> (8 * (where &3 ))) & ((1 << (size *8 )) -1 ); + +return PCIBIOS_SUCCESSFUL ; +} + +static int iproc_pci_raw_config_write32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 val) +{ +void __iomem *addr; +u32 mask, tmp; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +if (size ==4 ) { +writel (val, addr); +return PCIBIOS_SUCCESSFUL ; + } + + mask = ~(((1 << (size *8 )) -1 ) << ((where &0x3 ) *8 )); + tmp =readl (addr) & mask; + tmp |= val << ((where &0x3 ) *8 ); +writel (tmp, addr); + +return PCIBIOS_SUCCESSFUL ; +} +static int iproc_pcie_config_read32 (struct pci_bus *bus,unsigned int devfn,int where,int size,u32 *val) {@@ -524,7 +575,7 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, }static struct pci_ops iproc_pcie_ops = { - .map_bus = iproc_pcie_map_cfg_bus, + .map_bus = iproc_pcie_bus_map_cfg_bus, .read = iproc_pcie_config_read32, .write = iproc_pcie_config_write32, };@@ -556,12 +607,11 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)msleep (100 ); } -static int iproc_pcie_check_link (struct iproc_pcie *pcie,struct pci_bus *bus) +static int iproc_pcie_check_link (struct iproc_pcie *pcie) {struct device *dev = pcie->dev; -u8 hdr_type; -u32 link_ctrl, class, val; -u16 pos =PCI_EXP_CAP , link_status; +u32 hdr_type, link_ctrl, link_status, class, val; +u16 pos =PCI_EXP_CAP ;bool link_is_active = false;/* @@ -578,7 +628,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) }/* make sure we are not in EP mode */ -pci_bus_read_config_byte (bus,0 ,PCI_HEADER_TYPE , &hdr_type); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_HEADER_TYPE ,1 , &hdr_type);if ((hdr_type &0x7f ) !=PCI_HEADER_TYPE_BRIDGE ) {dev_err (dev,"in EP mode, hdr=%#02x\n" , hdr_type);return -EFAULT ;@@ -588,13 +638,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c#define PCI_CLASS_BRIDGE_MASK 0xffff00#define PCI_CLASS_BRIDGE_SHIFT 8 -pci_bus_read_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , &class); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , &class); class &= ~PCI_CLASS_BRIDGE_MASK ; class |= (PCI_CLASS_BRIDGE_PCI <<PCI_CLASS_BRIDGE_SHIFT ); -pci_bus_write_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , class); +iproc_pci_raw_config_write32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , class);/* check link status to see if link is active */ -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , &link_status); +iproc_pci_raw_config_read32 (pcie,0 , pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true;@@ -603,20 +656,21 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_TARGET_LINK_SPEED_MASK 0xf#define PCI_TARGET_LINK_SPEED_GEN2 0x2#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -pci_bus_read_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 ,4 , &link_ctrl);if ((link_ctrl &PCI_TARGET_LINK_SPEED_MASK ) ==PCI_TARGET_LINK_SPEED_GEN2 ) { link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK ; link_ctrl |=PCI_TARGET_LINK_SPEED_GEN1 ; -pci_bus_write_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , - link_ctrl); +iproc_pci_raw_config_write32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 , +4 , link_ctrl);msleep (100 ); -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , - &link_status); +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true; }Quoted 9 lines
drivers/pci/host/pcie-iproc.c int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) · line 1319
Quoted 8 lines
drivers/pci/host/pcie-iproc.c +1
-1@@ -1260,7 +1314,7 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) } pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie, bus); + ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); goto err_rm_root_bus;_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2
Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat /proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1
after applying series:
root at bcm958742k:~# dmesg | grep nvme
[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22
here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified: arch/arm/include/asm/mach/pci.h
modified: arch/arm/kernel/bios32.c
modified: arch/arm/mach-dove/pcie.c
modified: arch/arm/mach-iop13xx/pci.c
modified: arch/arm/mach-iop13xx/pci.h
modified: arch/arm/mach-mv78xx0/pcie.c
modified: arch/arm/mach-orion5x/common.h
modified: arch/arm/mach-orion5x/pci.c
modified: arch/arm64/kernel/pci.c
modified: drivers/of/of_pci_irq.c
modified: drivers/pci/Makefile
modified: drivers/pci/host/pci-aardvark.c
modified: drivers/pci/host/pci-ftpci100.c
modified: drivers/pci/host/pci-host-common.c
modified: drivers/pci/host/pci-tegra.c
modified: drivers/pci/host/pci-versatile.c
modified: drivers/pci/host/pci-xgene.c
modified: drivers/pci/host/pcie-altera.c
modified: drivers/pci/host/pcie-iproc-bcma.c
modified: drivers/pci/host/pcie-iproc-platform.c
modified: drivers/pci/host/pcie-iproc.c
modified: drivers/pci/host/pcie-iproc.h
modified: drivers/pci/host/pcie-rcar.c
modified: drivers/pci/host/pcie-rockchip.c
modified: drivers/pci/host/pcie-xilinx-nwl.c
modified: drivers/pci/host/pcie-xilinx.c
modified: drivers/pci/pci-driver.c
modified: drivers/pci/probe.c
modified: drivers/pci/setup-irq.c
modified: include/linux/pci.hQuoted 216 lines
Thanks a lot,
LorenzoQuoted 213 lines
Hi Bjorn,
please help to review following changes, to avoid merge conflicts since Lorenzo's changes in iproc driver is touching basic config APIs.
[PATCH v3 1/2] PCI: iproc: Retry request when CRS returned from EP [PATCH v3 2/2] PCI: iproc: add device shutdown for PCI RC
Regards,
Oza.Quoted 200 lines
Thanks for testing it, please let me know.
Thank you !
LorenzoQuoted 180 lines
Thanks,
Ray
Quoted 173 lines · Lorenzo Pieralisi
Current iproc driver host bridge controller driver requires struct
pci_busto be created in order to carry out PCI link checks with standard PCI config space accessors.This struct
pci_busdependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).Add PCI raw config space accessors to PCIe iproc driver and remove the fictitious struct
pci_busdependency.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Scott Branden <[email protected]>Cc Ray Jui <[email protected]>Cc Jon Mason <[email protected]>--- drivers/pci/host/pcie-iproc.c | 94 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 20 deletions(-)drivers/pci/host/pcie-iproc.c +73
-19@@ -452,14 +452,13 @@ static inline void iproc_pcie_apb_err_disable(struct pci_bus *bus,* Note access to the configuration registers are protected at the higher layer * by 'pci_lock' in drivers/pci/access.c */ -static void __iomem *iproc_pcie_map_cfg_bus (struct pci_bus *bus, +static void __iomem *iproc_pcie_map_cfg_bus (struct iproc_pcie *pcie, +int busno,unsigned int devfn,int where) { -struct iproc_pcie *pcie =iproc_data (bus);unsigned slot =PCI_SLOT (devfn);unsigned fn =PCI_FUNC (devfn); -unsigned busno = bus->number;u32 val;u16 offset;@@ -499,6 +498,58 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,return (pcie->base + offset); } +static void __iomem *iproc_pcie_bus_map_cfg_bus (struct pci_bus *bus, +unsigned int devfn, +int where) +{ +return iproc_pcie_map_cfg_bus (iproc_data (bus), bus->number, devfn, + where); +} + +static int iproc_pci_raw_config_read32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 *val) +{ +void __iomem *addr; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) { + *val = ~0 ; +return PCIBIOS_DEVICE_NOT_FOUND ; + } + + *val =readl (addr); + +if (size <=2 ) + *val = (*val >> (8 * (where &3 ))) & ((1 << (size *8 )) -1 ); + +return PCIBIOS_SUCCESSFUL ; +} + +static int iproc_pci_raw_config_write32 (struct iproc_pcie *pcie, +unsigned int devfn,int where, +int size,u32 val) +{ +void __iomem *addr; +u32 mask, tmp; + + addr =iproc_pcie_map_cfg_bus (pcie,0 , devfn, where & ~0x3 ); +if (!addr) +return PCIBIOS_DEVICE_NOT_FOUND ; + +if (size ==4 ) { +writel (val, addr); +return PCIBIOS_SUCCESSFUL ; + } + + mask = ~(((1 << (size *8 )) -1 ) << ((where &0x3 ) *8 )); + tmp =readl (addr) & mask; + tmp |= val << ((where &0x3 ) *8 ); +writel (tmp, addr); + +return PCIBIOS_SUCCESSFUL ; +} +static int iproc_pcie_config_read32 (struct pci_bus *bus,unsigned int devfn,int where,int size,u32 *val) {@@ -524,7 +575,7 @@ static int iproc_pcie_config_write32(struct pci_bus *bus, unsigned int devfn, }static struct pci_ops iproc_pcie_ops = { - .map_bus = iproc_pcie_map_cfg_bus, + .map_bus = iproc_pcie_bus_map_cfg_bus, .read = iproc_pcie_config_read32, .write = iproc_pcie_config_write32, };@@ -556,12 +607,11 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)msleep (100 ); } -static int iproc_pcie_check_link (struct iproc_pcie *pcie,struct pci_bus *bus) +static int iproc_pcie_check_link (struct iproc_pcie *pcie) {struct device *dev = pcie->dev; -u8 hdr_type; -u32 link_ctrl, class, val; -u16 pos =PCI_EXP_CAP , link_status; +u32 hdr_type, link_ctrl, link_status, class, val; +u16 pos =PCI_EXP_CAP ;bool link_is_active = false;/* @@ -578,7 +628,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus) }/* make sure we are not in EP mode */ -pci_bus_read_config_byte (bus,0 ,PCI_HEADER_TYPE , &hdr_type); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_HEADER_TYPE ,1 , &hdr_type);if ((hdr_type &0x7f ) !=PCI_HEADER_TYPE_BRIDGE ) {dev_err (dev,"in EP mode, hdr=%#02x\n" , hdr_type);return -EFAULT ;@@ -588,13 +638,16 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c#define PCI_CLASS_BRIDGE_MASK 0xffff00#define PCI_CLASS_BRIDGE_SHIFT 8 -pci_bus_read_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , &class); +iproc_pci_raw_config_read32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , &class); class &= ~PCI_CLASS_BRIDGE_MASK ; class |= (PCI_CLASS_BRIDGE_PCI <<PCI_CLASS_BRIDGE_SHIFT ); -pci_bus_write_config_dword (bus,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , class); +iproc_pci_raw_config_write32 (pcie,0 ,PCI_BRIDGE_CTRL_REG_OFFSET , +4 , class);/* check link status to see if link is active */ -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , &link_status); +iproc_pci_raw_config_read32 (pcie,0 , pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true;@@ -603,20 +656,21 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)#define PCI_TARGET_LINK_SPEED_MASK 0xf#define PCI_TARGET_LINK_SPEED_GEN2 0x2#define PCI_TARGET_LINK_SPEED_GEN1 0x1 -pci_bus_read_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 ,4 , &link_ctrl);if ((link_ctrl &PCI_TARGET_LINK_SPEED_MASK ) ==PCI_TARGET_LINK_SPEED_GEN2 ) { link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK ; link_ctrl |=PCI_TARGET_LINK_SPEED_GEN1 ; -pci_bus_write_config_dword (bus,0 , - pos +PCI_EXP_LNKCTL2 , - link_ctrl); +iproc_pci_raw_config_write32 (pcie,0 , + pos +PCI_EXP_LNKCTL2 , +4 , link_ctrl);msleep (100 ); -pci_bus_read_config_word (bus,0 , pos +PCI_EXP_LNKSTA , - &link_status); +iproc_pci_raw_config_read32 (pcie,0 , + pos +PCI_EXP_LNKSTA , +2 , &link_status);if (link_status &PCI_EXP_LNKSTA_NLW ) link_is_active = true; }Quoted 9 lines
drivers/pci/host/pcie-iproc.c int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) · line 1319
Quoted 8 lines
drivers/pci/host/pcie-iproc.c +1
-1@@ -1260,7 +1314,7 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) } pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie, bus); + ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); goto err_rm_root_bus;_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.h
Quoted 9 lines
modified: drivers/pci/host/pcie-rcar.c
modified: drivers/pci/host/pcie-rockchip.c
modified: drivers/pci/host/pcie-xilinx-nwl.c
modified: drivers/pci/host/pcie-xilinx.c
modified: drivers/pci/pci-driver.c
modified: drivers/pci/probe.c
modified: drivers/pci/setup-irq.c
modified: include/linux/pci.hDid you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 86 lines · Ray Jui
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.hQuoted 9 lines
modified: drivers/pci/host/pcie-rcar.c modified: drivers/pci/host/pcie-rockchip.c modified: drivers/pci/host/pcie-xilinx-nwl.c modified: drivers/pci/host/pcie-xilinx.c modified: drivers/pci/pci-driver.c modified: drivers/pci/probe.c modified: drivers/pci/setup-irq.c modified: include/linux/pci.h
Quoted 8 lines
Did you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
Hi Ray,
yes irqdomain was missing, and with that legacy IRQ are fine now. please mainline those changes.
Hi Lorenzo,
Legacy IRQ is working fine as well wiht your patches.
cat /proc/interrupts
122: 160 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1
NVMe data transfer is also fine.
Regards,
Oza.
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Hi Oza/Lorenzo,
Quoted 104 lines · Oza Oza
Quoted 86 lines · Ray Jui
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.hQuoted 9 lines
modified: drivers/pci/host/pcie-rcar.c modified: drivers/pci/host/pcie-rockchip.c modified: drivers/pci/host/pcie-xilinx-nwl.c modified: drivers/pci/host/pcie-xilinx.c modified: drivers/pci/pci-driver.c modified: drivers/pci/probe.c modified: drivers/pci/setup-irq.c modified: include/linux/pci.hQuoted 8 lines
Did you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
Hi Ray,
yes irqdomain was missing, and with that legacy IRQ are fine now. please mainline those changes.Hi Lorenzo,
Legacy IRQ is working fine as well wiht your patches.
Quoted 9 lines
cat
/proc/interrupts
122: 160 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1NVMe data transfer is also fine.
Regards,
Oza.
Okay, so I take this as Lorenzo's changes on iProc PCIe driver have been sanity tested for link detection and legacy interrupt support. No regression is seen. Thanks, Oza.
I'll send out the INTx irqdomain support patch when I have time.
Ray
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 113 lines · Ray Jui
Hi Oza/Lorenzo,
Quoted 110 lines · Oza Oza
Quoted 86 lines · Ray Jui
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.hQuoted 9 lines
modified: drivers/pci/host/pcie-rcar.c modified: drivers/pci/host/pcie-rockchip.c modified: drivers/pci/host/pcie-xilinx-nwl.c modified: drivers/pci/host/pcie-xilinx.c modified: drivers/pci/pci-driver.c modified: drivers/pci/probe.c modified: drivers/pci/setup-irq.c modified: include/linux/pci.hQuoted 8 lines
Did you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
Hi Ray,
yes irqdomain was missing, and with that legacy IRQ are fine now. please mainline those changes.Hi Lorenzo,
Legacy IRQ is working fine as well wiht your patches.
cat
/proc/interrupts
122: 160 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1NVMe data transfer is also fine.
Quoted 7 lines
Quoted 3 lines
Regards,
Oza.Okay, so I take this as Lorenzo's changes on iProc PCIe driver have been sanity tested for link detection and legacy interrupt support. No regression is seen. Thanks, Oza.
Yes, that's how I take it too, I did not understand what was triggering the first regression reported - my series should work on top of mainline if the current code works and should not depend on any other patch being merged - please make sure that's the case to prevent unwanted regressions in case other patches do not make it into the mainline.
Thank you very much for your help in testing it.
Lorenzo
Quoted 8 lines
I'll send out the INTx irqdomain support patch when I have time.
Ray
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 122 lines · Lorenzo Pieralisi
Quoted 113 lines · Ray Jui
Hi Oza/Lorenzo,
Quoted 110 lines · Oza Oza
Quoted 86 lines · Ray Jui
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.hQuoted 9 lines
modified: drivers/pci/host/pcie-rcar.c modified: drivers/pci/host/pcie-rockchip.c modified: drivers/pci/host/pcie-xilinx-nwl.c modified: drivers/pci/host/pcie-xilinx.c modified: drivers/pci/pci-driver.c modified: drivers/pci/probe.c modified: drivers/pci/setup-irq.c modified: include/linux/pci.hQuoted 8 lines
Did you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
Hi Ray,
yes irqdomain was missing, and with that legacy IRQ are fine now. please mainline those changes.Hi Lorenzo,
Legacy IRQ is working fine as well wiht your patches.
cat
/proc/interrupts
122: 160 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1NVMe data transfer is also fine.
Quoted 7 lines
Quoted 3 lines
Regards,
Oza.Okay, so I take this as Lorenzo's changes on iProc PCIe driver have been sanity tested for link detection and legacy interrupt support. No regression is seen. Thanks, Oza.
Quoted 7 lines
Yes, that's how I take it too, I did not understand what was triggering the first regression reported - my series should work on top of mainline if the current code works and should not depend on any other patch being merged - please make sure that's the case to prevent unwanted regressions in case other patches do not make it into the mainline.
Thank you very much for your help in testing it.
Hi Lorenzo,
I have ported and tested my inbound memory patches on top of your patches and that work fine as well.
This is mainly to do with IOVA reservations.
Regards,
Oza.
Quoted 11 lines
Lorenzo
Quoted 8 lines
I'll send out the INTx irqdomain support patch when I have time.
Ray
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 133 lines · Oza Oza
Quoted 122 lines · Lorenzo Pieralisi
Quoted 113 lines · Ray Jui
Hi Oza/Lorenzo,
Quoted 110 lines · Oza Oza
Quoted 86 lines · Ray Jui
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.hQuoted 9 lines
modified: drivers/pci/host/pcie-rcar.c modified: drivers/pci/host/pcie-rockchip.c modified: drivers/pci/host/pcie-xilinx-nwl.c modified: drivers/pci/host/pcie-xilinx.c modified: drivers/pci/pci-driver.c modified: drivers/pci/probe.c modified: drivers/pci/setup-irq.c modified: include/linux/pci.hQuoted 8 lines
Did you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
Hi Ray,
yes irqdomain was missing, and with that legacy IRQ are fine now. please mainline those changes.Hi Lorenzo,
Legacy IRQ is working fine as well wiht your patches.
cat
/proc/interrupts
122: 160 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1NVMe data transfer is also fine.
Quoted 7 lines
Quoted 3 lines
Regards,
Oza.Okay, so I take this as Lorenzo's changes on iProc PCIe driver have been sanity tested for link detection and legacy interrupt support. No regression is seen. Thanks, Oza.
Quoted 7 lines
Yes, that's how I take it too, I did not understand what was triggering the first regression reported - my series should work on top of mainline if the current code works and should not depend on any other patch being merged - please make sure that's the case to prevent unwanted regressions in case other patches do not make it into the mainline.
Thank you very much for your help in testing it.
Quoted 20 lines
Hi Lorenzo,
I have ported and tested my inbound memory patches on top of your patches and that work fine as well.
This is mainly to do with IOVA reservations.Regards,
Oza.Quoted 11 lines
Lorenzo
Quoted 8 lines
I'll send out the INTx irqdomain support patch when I have time.
Ray
Hi Bjorn,
I have made v8 for inbound memory patches as you suggested, on top of Lorenzo's patches.
but I can not post them since Lorenzo's patches have not made in.
Also gentle reminder to review following series
[PATCH v5 1/2] PCI: iproc: Retry request when CRS returned from EP
because that also conflict with Lorenzo's changes.
Regards,
Oza.
PATCH v2 2/42 drivers: pci: host: iproc: Convert link check to raw PCI config accessors
Quoted 155 lines · Oza Oza
Quoted 133 lines · Oza Oza
Quoted 122 lines · Lorenzo Pieralisi
Quoted 113 lines · Ray Jui
Hi Oza/Lorenzo,
Quoted 110 lines · Oza Oza
Quoted 86 lines · Ray Jui
Quoted 73 lines · Oza Oza
Quoted 21 lines · Lorenzo Pieralisi
Quoted 20 lines · Oza Oza
Quoted 17 lines · Lorenzo Pieralisi
[dropped rock-chips maintainers, email bounces]
Quoted 10 lines · Ray Jui
Hi Lorenzo,
Thanks, I'll try my best to find time to test this along 15/42 and 33/42 patches. Hopefully I can get to that some time next week.
I have not yet reviewed these patches in details. Do they have dependency on other patches to the generic framework code you changed?
If so, is there a repo I can pull them?
I added it in the cover letter but anyway here it is:
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Quoted 8 lines
Quoted 4 lines
Hi Lorenzo,
I picked up your changes, and tested on iproc based SOC, and ran basic fio data transfer.. and it looks okay.
Thank you. If you could also check it is all OK from a legacy IRQ allocation (ie same as before applying series) I'd be grateful.
I disabled msi and it should default to legacy IRQ, looks like there is a problem, if I missed any change !
before applying series: cat
/proc/interrupts
377: 168 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1after applying series:
root at bcm958742k:~# dmesg | grep nvme[ 3.855466] nvme 0000:01:00.0: assign irq: got 0 [ 3.855469] nvme 0000:01:00.0: assigning IRQ 00 [ 3.855515] nvme nvme0: pci function 0000:01:00.0 [ 4.270850] nvme 0000:01:00.0: enabling device (0000 -> 0002) [ 4.276787] nvme 0000:01:00.0: enabling bus mastering [ 4.276817] nvme nvme0: Removing after probe failure status: -22here is my git status of your series, let me know if I am missing any change with respect to legacy IRQ ?
modified:
arch/arm/include/asm/mach/pci.hmodified: arch/arm/kernel/bios32.c modified: arch/arm/mach-dove/pcie.c modified: arch/arm/mach-iop13xx/pci.c modified: arch/arm/mach-iop13xx/pci.h modified: arch/arm/mach-mv78xx0/pcie.c modified: arch/arm/mach-orion5x/common.h modified: arch/arm/mach-orion5x/pci.c modified: arch/arm64/kernel/pci.c modified: drivers/of/of_pci_irq.c modified: drivers/pci/Makefile modified: drivers/pci/host/pci-aardvark.c modified: drivers/pci/host/pci-ftpci100.c modified: drivers/pci/host/pci-host-common.c modified: drivers/pci/host/pci-tegra.c modified: drivers/pci/host/pci-versatile.c modified: drivers/pci/host/pci-xgene.c modified: drivers/pci/host/pcie-altera.c modified: drivers/pci/host/pcie-iproc-bcma.c modified: drivers/pci/host/pcie-iproc-platform.c modified: drivers/pci/host/pcie-iproc.c modified: drivers/pci/host/pcie-iproc.hQuoted 9 lines
modified: drivers/pci/host/pcie-rcar.c modified: drivers/pci/host/pcie-rockchip.c modified: drivers/pci/host/pcie-xilinx-nwl.c modified: drivers/pci/host/pcie-xilinx.c modified: drivers/pci/pci-driver.c modified: drivers/pci/probe.c modified: drivers/pci/setup-irq.c modified: include/linux/pci.hQuoted 8 lines
Did you test with or without my change in bcm/master to emulate legacy interrupt through dummy IRQ domain?
Thanks,
Ray
Hi Ray,
yes irqdomain was missing, and with that legacy IRQ are fine now. please mainline those changes.Hi Lorenzo,
Legacy IRQ is working fine as well wiht your patches.
cat
/proc/interrupts
122: 160 0 0 0 0 0
0 0 dummy 1 Edge nvme0q0, nvme0q1NVMe data transfer is also fine.
Quoted 7 lines
Quoted 3 lines
Regards,
Oza.Okay, so I take this as Lorenzo's changes on iProc PCIe driver have been sanity tested for link detection and legacy interrupt support. No regression is seen. Thanks, Oza.
Quoted 7 lines
Yes, that's how I take it too, I did not understand what was triggering the first regression reported - my series should work on top of mainline if the current code works and should not depend on any other patch being merged - please make sure that's the case to prevent unwanted regressions in case other patches do not make it into the mainline.
Thank you very much for your help in testing it.
Quoted 20 lines
Hi Lorenzo,
I have ported and tested my inbound memory patches on top of your patches and that work fine as well.
This is mainly to do with IOVA reservations.Regards,
Oza.Quoted 11 lines
Lorenzo
Quoted 8 lines
I'll send out the INTx irqdomain support patch when I have time.
Ray
Quoted 5 lines
Hi Bjorn,
I have made v8 for inbound memory patches as you suggested, on top of Lorenzo's patches.
but I can not post them since Lorenzo's patches have not made in.
It depends on what kernel you are pulling. If you pulled v4.13-rc1 this series would be there.
Lorenzo
PATCH v2 3/42 drivers: pci: host: ftpci100: convert IRQ masking to raw PCI config accessors
In reply to Lorenzo PieralisiCurrent ftpci100 driver host bridge controller driver requires struct pci_bus to be created in order to mask and clear IRQs using standard PCI bus config accessors.
This struct pci_bus dependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).
Add PCI raw config space accessors to PCIe ftpci100 driver and remove the fictitious struct pci_bus dependency.
--- drivers/pci/host/pci-ftpci100.c | 44 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-)
drivers/pci/host/pci-ftpci100.c +26 -18
@@ -204,17 +204,13 @@ static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,return PCIBIOS_SUCCESSFUL ; } -static int faraday_pci_write_config (struct pci_bus *bus,unsigned int fn, -int config,int size,u32 value) +static int faraday_raw_pci_write_config (struct faraday_pci *p,int bus_number, +unsigned int fn,int config,int size, +u32 value) { -struct faraday_pci *p = bus->sysdata;int ret =PCIBIOS_SUCCESSFUL ; -dev_dbg (&bus->dev, -"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n" , -PCI_SLOT (fn),PCI_FUNC (fn), config, size, value); - - writel(PCI_CONF_BUS(bus->number) | + writel(PCI_CONF_BUS(bus_number) | PCI_CONF_DEVICE(PCI_SLOT(fn)) | PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_WHERE(config) |
@@ -238,6 +234,19 @@ static int faraday_pci_write_config(struct pci_bus *bus, unsigned int fn,return ret; } +static int faraday_pci_write_config (struct pci_bus *bus,unsigned int fn, +int config,int size,u32 value) +{ +struct faraday_pci *p = bus->sysdata; + +dev_dbg (&bus->dev, +"[write] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n" , +PCI_SLOT (fn),PCI_FUNC (fn), config, size, value); + +return faraday_raw_pci_write_config (p, bus->number, fn, config, size, + value); +} +static struct pci_ops faraday_pci_ops = { .read = faraday_pci_read_config, .write = faraday_pci_write_config,
@@ -496,17 +505,8 @@ static int faraday_pci_probe(struct platform_device *pdev) val |=PCI_COMMAND_MEMORY ; val |=PCI_COMMAND_MASTER ;writel (val, p->base +PCI_CTRL ); - -list_splice_init (&res, &host->windows); - ret =pci_register_host_bridge (host); -if (ret) { -dev_err (dev,"failed to register host: %d\n" , ret); -return ret; - } - p->bus = host->bus; -/* Mask and clear all interrupts */ -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 +2 ,2 ,0xF000 ); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 +2 ,2 ,0xF000 );if (variant->cascaded_irq) { ret =faraday_pci_setup_cascaded_irq (p);if (ret) {
@@ -519,6 +519,14 @@ static int faraday_pci_probe(struct platform_device *pdev)if (ret)return ret; +list_splice_init (&res, &host->windows); + ret =pci_register_host_bridge (host); +if (ret) { +dev_err (dev,"failed to register host: %d\n" , ret); +return ret; + } + p->bus = host->bus; +pci_scan_child_bus (p->bus);pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);pci_bus_assign_resources (p->bus);
Signature · 1 line
2.10.0
PATCH v2 3/42 drivers: pci: host: ftpci100: convert IRQ masking to raw PCI config accessors
Quoted 8 lines · Lorenzo Pieralisi
Current ftpci100 driver host bridge controller driver requires struct
pci_busto be created in order to mask and clear IRQs using standard PCI bus config accessors.This struct
pci_busdependency is fictitious and burdens the driver with unneeded constraints (eg to use separate APIs to create and scan the root bus).
Quoted 6 lines
Add PCI raw config space accessors to PCIe ftpci100 driver and remove the fictitious struct
pci_busdependency.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Bjorn Helgaas <[email protected]>Cc Linus Walleij <[email protected]>
This makes all kind of sense so:
I'm hoping to be able to pull in your branch on my board tree and actually test it too. The semantic change is a bit scary.
Yours,
Linus Walleij
PATCH v2 4/42 PCI: Initialize bridge release function at bridge allocation
In reply to Lorenzo PieralisiThe introduction of pci_register_host_bridge() kernel interface allows PCI host controller drivers to create the struct pci_host_bridge object, initialize it and register it with the kernel so that its corresponding PCI bus can be scanned and its devices probed.
The host bridge device release function pci_release_host_bridge_dev is a static function common for all struct pci_host_bridge allocated objects, so in its current form cannot be used by PCI host bridge controllers drivers to initialize the allocated struct pci_host_bridge, which leaves struct pci_host_bridge devices release function uninitialized.
Since pci_release_host_bridge_dev is a function common to all PCI host bridge objects, initialize it in pci_alloc_host_bridge() (ie common host bridge allocation interface) so that all struct pci_host_bridge objects have their release function initialized by default at allocation time, removing the need for exporting the common pci_release_host_bridge_dev function to other compilation units.
--- drivers/pci/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/probe.c +1 -1
@@ -531,6 +531,7 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv)return NULL ;INIT_LIST_HEAD (&bridge->windows); + bridge->dev.release = pci_release_host_bridge_dev;return bridge; }
@@ -2310,7 +2311,6 @@ static struct pci_bus *pci_create_root_bus_msi(struct device *parent,return NULL ; bridge->dev.parent = parent; - bridge->dev.release = pci_release_host_bridge_dev;list_splice_init (resources, &bridge->windows); bridge->sysdata = sysdata;
Signature · 1 line
2.10.0
PATCH v2 5/42 PCI: Add pci_free_host_bridge interface
In reply to Lorenzo PieralisiCommit a52d1443bba1 ("PCI: Export host bridge registration interface") exported the pci_alloc_host_bridge() interface so that PCI host controllers drivers can make use of it.
Introduce pci_alloc_host_bridge() kernel counterpart to free the host bridge data structures, pci_free_host_bridge(), export it and update kernel functions releasing host bridge objects allocated memory to make use of it.
--- drivers/pci/probe.c | 12 +++++++++--- include/linux/pci.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-)
drivers/pci/probe.c +9 -3
@@ -517,9 +517,7 @@ static void pci_release_host_bridge_dev(struct device *dev)if (bridge->release_fn) bridge->release_fn (bridge); -pci_free_resource_list (&bridge->windows); - -kfree (bridge); +pci_free_host_bridge (bridge); }struct pci_host_bridge *pci_alloc_host_bridge (size_t priv)
@@ -537,6 +535,14 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) }EXPORT_SYMBOL (pci_alloc_host_bridge); +void pci_free_host_bridge (struct pci_host_bridge *bridge) +{ +pci_free_resource_list (&bridge->windows); + +kfree (bridge); +} +EXPORT_SYMBOL (pci_free_host_bridge); +static const unsigned char pcix_bus_speed[] = {PCI_SPEED_UNKNOWN ,/* 0 */ PCI_SPEED_66MHz_PCIX,/* 1 */
include/linux/pci.h +1 -0
@@ -463,6 +463,7 @@ static inline struct pci_host_bridge *pci_host_bridge_from_priv(void *priv) }struct pci_host_bridge *pci_alloc_host_bridge (size_t priv); +void pci_free_host_bridge (struct pci_host_bridge *bridge);int pci_register_host_bridge (struct pci_host_bridge *bridge);struct pci_host_bridge *pci_find_host_bridge (struct pci_bus *bus);
Signature · 1 line
2.10.0
PATCH v2 6/42 PCI: Add devm_pci_alloc_host_bridge() interface
In reply to Lorenzo Pieralisistruct pci_host_bridge can be allocated by PCI host bridge drivers which usually allocate and map memory through devm managed interfaces.
Add a devm version for the pci_alloc_host_bridge() interface to simplify PCI host controller drivers porting and simplify the drivers failures paths.
--- Documentation/driver-model/devres.txt | 1 + drivers/pci/probe.c | 24 ++++++++++++++++++++++-- include/linux/pci.h | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-)
Documentation/driver-model/devres.txt +1 -0
@@ -342,6 +342,7 @@ PER-CPU MEM devm_free_percpu() PCI + devm_pci_alloc_host_bridge() : managed PCI host bridge allocation devm_pci_remap_cfgspace() : ioremap PCI configuration space devm_pci_remap_cfg_resource() : ioremap PCI configuration space resource pcim_enable_device() : after success, all PCI ops become managed
drivers/pci/probe.c +22 -2
@@ -510,14 +510,18 @@ static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)return b; } -static void pci_release_host_bridge_dev (struct device *dev) +static void devm_pci_release_host_bridge_dev (struct device *dev) {struct pci_host_bridge *bridge =to_pci_host_bridge (dev);if (bridge->release_fn) bridge->release_fn (bridge); +} -pci_free_host_bridge (bridge); +static void pci_release_host_bridge_dev (struct device *dev) +{ +devm_pci_release_host_bridge_dev (dev); +pci_free_host_bridge (to_pci_host_bridge (dev)); }struct pci_host_bridge *pci_alloc_host_bridge (size_t priv)
@@ -535,6 +539,22 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) }EXPORT_SYMBOL (pci_alloc_host_bridge); +struct pci_host_bridge *devm_pci_alloc_host_bridge (struct device *dev, +size_t priv) +{ +struct pci_host_bridge *bridge; + + bridge =devm_kzalloc (dev,sizeof (*bridge) + priv,GFP_KERNEL ); +if (!bridge) +return NULL ; + +INIT_LIST_HEAD (&bridge->windows); + bridge->dev.release = devm_pci_release_host_bridge_dev; + +return bridge; +} +EXPORT_SYMBOL (devm_pci_alloc_host_bridge); +void pci_free_host_bridge (struct pci_host_bridge *bridge) {pci_free_resource_list (&bridge->windows);
include/linux/pci.h +2 -0
@@ -463,6 +463,8 @@ static inline struct pci_host_bridge *pci_host_bridge_from_priv(void *priv) }struct pci_host_bridge *pci_alloc_host_bridge (size_t priv); +struct pci_host_bridge *devm_pci_alloc_host_bridge (struct device *dev, +size_t priv);void pci_free_host_bridge (struct pci_host_bridge *bridge);int pci_register_host_bridge (struct pci_host_bridge *bridge);struct pci_host_bridge *pci_find_host_bridge (struct pci_bus *bus);
Signature · 1 line
2.10.0
PATCH v2 7/42 drivers: pci: host: ftpci100: Fix host bridge memory leakage
In reply to Lorenzo PieralisiWhen probing the PCI host controller driver, if an error condition is trigger the probe function code does not free memory allocated for the struct pci_host_bridge resulting in memory leakage.
Move the struct pci_host_bridge allocation over to the respective devm interface to fix the issue.
--- drivers/pci/host/pci-ftpci100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/host/pci-ftpci100.c +1 -1
@@ -441,7 +441,7 @@ static int faraday_pci_probe(struct platform_device *pdev)u32 val;LIST_HEAD (res); - host =pci_alloc_host_bridge (sizeof (*p)); + host =devm_pci_alloc_host_bridge (dev,sizeof (*p));if (!host)return -ENOMEM ;
Signature · 1 line
2.10.0
PATCH v2 7/42 drivers: pci: host: ftpci100: Fix host bridge memory leakage
Quoted 10 lines · Lorenzo Pieralisi
When probing the PCI host controller driver, if an error condition is trigger the probe function code does not free memory allocated for the struct
pci_host_bridgeresulting in memory leakage.Move the struct
pci_host_bridgeallocation over to the respective devm interface to fix the issue.Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Arnd Bergmann <[email protected]>Cc Bjorn Helgaas <[email protected]>
Yours,
Linus Walleij
PATCH v2 8/42 drivers: pci: host: tegra: Fix host bridge memory leakage
In reply to Lorenzo PieralisiWhen probing the PCI host controller driver, if an error condition is triggered the probe function code does not free memory allocated for the struct pci_host_bridge resulting in memory leakage.
Move the struct pci_host_bridge allocation over to the respective devm interface to fix the issue.
--- drivers/pci/host/pci-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/host/pci-tegra.c +1 -1
@@ -2238,7 +2238,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)struct pci_bus *child;int err; - host =pci_alloc_host_bridge (sizeof (*pcie)); + host =devm_pci_alloc_host_bridge (dev,sizeof (*pcie));if (!host)return -ENOMEM ;
Signature · 1 line
2.10.0
PATCH v2 9/42 PCI: Introduce pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiCurrent pci_scan_root_bus() interface is made up of two main code paths:
- pci_create_root_bus()
- pci_scan_child_bus()
pci_create_root_bus() is a wrapper function that allows to create a struct pci_host_bridge structure, initialize it with the passed parameters and register it with the kernel.
As the struct pci_host_bridge require additional struct members, pci_create_root_bus() parameters list has grown in time, making it unwieldy to add further parameters to it in case the struct pci_host_bridge gains more members fields to augment its functionality.
Since PCI core code provides functions to allocate struct pci_host_bridge, instead of forcing the pci_create_root_bus() interface to add new parameters to cater for new struct pci_host_bridge functionality, it is more suitable to add an interface in PCI core code to scan a PCI bus straight from a struct pci_host_bridge created and customized by each specific PCI host controller driver.
Add a pci_scan_root_bus_bridge() function to allow PCI host controller drivers to create and initialize struct pci_host_bridge and scan the resulting bus.
--- drivers/pci/probe.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 40 insertions(+)
drivers/pci/probe.c +39 -0
@@ -2426,6 +2426,45 @@ void pci_bus_release_busn_res(struct pci_bus *b) res, ret ? "can not be" : "is"); } +int pci_scan_root_bus_bridge (struct pci_host_bridge *bridge) +{ +struct resource_entry *window; +bool found = false; +struct pci_bus *b; +int max, bus, ret; + +if (!bridge) +return -EINVAL ; + +resource_list_for_each_entry (window, &bridge->windows) +if (window->res->flags &IORESOURCE_BUS ) { + found = true; +break ; + } + + ret =pci_register_host_bridge (bridge); +if (ret <0 ) +return ret; + + b = bridge->bus; + bus = bridge->busnr; + +if (!found) { +dev_info (&b->dev, +"No busn resource found for root bus, will use [bus %02x-ff]\n" , + bus); +pci_bus_insert_busn_res (b, bus,255 ); + } + + max =pci_scan_child_bus (b); + +if (!found) +pci_bus_update_busn_res_end (b, max); + +return 0 ; +} +EXPORT_SYMBOL (pci_scan_root_bus_bridge); +struct pci_bus *pci_scan_root_bus_msi (struct device *parent,int bus,struct pci_ops *ops,void *sysdata,struct list_head *resources,struct msi_controller *msi)
include/linux/pci.h +1 -0
@@ -862,6 +862,7 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,struct pci_bus *pci_scan_root_bus (struct device *parent,int bus,struct pci_ops *ops,void *sysdata,struct list_head *resources); +int pci_scan_root_bus_bridge (struct pci_host_bridge *bridge);struct pci_bus *pci_add_new_bus (struct pci_bus *parent,struct pci_dev *dev,int busnr);void pcie_update_link_speed (struct pci_bus *bus,u16 link_status);
Signature · 1 line
2.10.0
PATCH v2 10/42 PCI: Make pci_register_host_bridge() PCI core internal
In reply to Lorenzo PieralisiWith the introduction of pci_scan_root_bus_bridge() there is no need to export pci_register_host_bridge() to other kernel subsystems other than the PCI compilation unit that needs it.
Make pci_register_host_bridge() static to its compilation unit and convert the existing drivers usage over to pci_scan_root_bus_bridge().
--- drivers/pci/host/pci-ftpci100.c | 5 ++--- drivers/pci/host/pci-tegra.c | 4 +--- drivers/pci/probe.c | 3 +-- include/linux/pci.h | 1 - 4 files changed, 4 insertions(+), 9 deletions(-)
drivers/pci/host/pci-ftpci100.c +2 -3
@@ -520,14 +520,13 @@ static int faraday_pci_probe(struct platform_device *pdev)return ret;list_splice_init (&res, &host->windows); - ret =pci_register_host_bridge (host); + ret =pci_scan_root_bus_bridge (host);if (ret) { -dev_err (dev,"failed to register host: %d\n" , ret); +dev_err (dev,"failed to scan host: %d\n" , ret);return ret; } p->bus = host->bus; -pci_scan_child_bus (p->bus);pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);pci_bus_assign_resources (p->bus);pci_bus_add_devices (p->bus);
drivers/pci/host/pci-tegra.c +1 -3
@@ -2285,14 +2285,12 @@ static int tegra_pcie_probe(struct platform_device *pdev) host->dev.parent = &pdev->dev; host->ops = &tegra_pcie_ops; - err =pci_register_host_bridge (host); + err =pci_scan_root_bus_bridge (host);if (err <0 ) {dev_err (dev,"failed to register host: %d\n" , err); goto disable_msi; } -pci_scan_child_bus (host->bus); -pci_fixup_irqs (pci_common_swizzle, tegra_pcie_map_irq);pci_bus_size_bridges (host->bus);pci_bus_assign_resources (host->bus);
drivers/pci/probe.c +1 -2
@@ -746,7 +746,7 @@ static void pci_set_bus_msi_domain(struct pci_bus *bus)dev_set_msi_domain (&bus->dev, d); } -int pci_register_host_bridge (struct pci_host_bridge *bridge) +static int pci_register_host_bridge (struct pci_host_bridge *bridge) {struct device *parent = bridge->dev.parent;struct resource_entry *window, *n;
@@ -861,7 +861,6 @@ int pci_register_host_bridge(struct pci_host_bridge *bridge)kfree (bus);return err; } -EXPORT_SYMBOL (pci_register_host_bridge);static struct pci_bus *pci_alloc_child_bus (struct pci_bus *parent,struct pci_dev *bridge,int busnr)
include/linux/pci.h +0 -1
@@ -466,7 +466,6 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv);struct pci_host_bridge *devm_pci_alloc_host_bridge (struct device *dev,size_t priv);void pci_free_host_bridge (struct pci_host_bridge *bridge); -int pci_register_host_bridge (struct pci_host_bridge *bridge);struct pci_host_bridge *pci_find_host_bridge (struct pci_bus *bus); void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
Signature · 1 line
2.10.0
PATCH v2 11/42 ARM: PCI: bios32: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert ARM bios32 code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- arch/arm/include/asm/mach/pci.h | 3 ++- arch/arm/kernel/bios32.c | 39 +++++++++++++++++++++++++-------------- arch/arm/mach-dove/pcie.c | 17 ++++++++++++----- arch/arm/mach-iop13xx/pci.c | 29 ++++++++++++++++++----------- arch/arm/mach-iop13xx/pci.h | 3 ++- arch/arm/mach-mv78xx0/pcie.c | 8 +++----- arch/arm/mach-orion5x/common.h | 3 ++- arch/arm/mach-orion5x/pci.c | 25 +++++++++++++++++-------- 8 files changed, 81 insertions(+), 46 deletions(-)
arch/arm/include/asm/mach/pci.h +2 -1
@@ -16,6 +16,7 @@struct pci_sys_data ;struct pci_ops ;struct pci_bus ; +struct pci_host_bridge ;struct device ;struct hw_pci {
@@ -25,7 +26,7 @@ struct hw_pci { unsigned int io_optional:1;void **private_data;int (*setup)(int nr,struct pci_sys_data *); -struct pci_bus *(*scan)(int nr,struct pci_sys_data *); +int (*scan)(int nr,struct pci_host_bridge *);void (*preinit)(void );void (*postinit)(void );u8 (*swizzle)(struct pci_dev *dev,u8 *pin);
arch/arm/kernel/bios32.c +25 -14
@@ -458,10 +458,14 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,int nr, busnr;for (nr = busnr =0 ; nr < hw->nr_controllers; nr++) { - sys =kzalloc (sizeof (struct pci_sys_data ),GFP_KERNEL ); -if (WARN (!sys,"PCI: unable to allocate sys data!" )) +struct pci_host_bridge *bridge; + + bridge =pci_alloc_host_bridge (sizeof (struct pci_sys_data )); +if (WARN (!bridge,"PCI: unable to allocate bridge!" ))break ; + sys =pci_host_bridge_priv (bridge); + sys->busnr = busnr; sys->swizzle = hw->swizzle; sys->map_irq = hw->map_irq;
@@ -473,7 +477,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ret = hw->setup (nr, sys);if (ret >0 ) { -struct pci_host_bridge *host_bridge; ret =pcibios_init_resource (nr, sys, hw->io_optional);if (ret) {
@@ -482,25 +485,33 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, }if (hw->scan) - sys->bus = hw->scan (nr, sys); -else - sys->bus =pci_scan_root_bus_msi (parent, - sys->busnr, hw->ops, sys, - &sys->resources, hw->msi_ctrl); + ret = hw->scan (nr, bridge); +else { +list_splice_init (&sys->resources, + &bridge->windows); + bridge->dev.parent = parent; + bridge->sysdata = sys; + bridge->busnr = sys->busnr; + bridge->ops = hw->ops; + bridge->msi = hw->msi_ctrl; + bridge->align_resource = + hw->align_resource; + + ret =pci_scan_root_bus_bridge (bridge); + } -if (WARN (!sys->bus,"PCI: unable to scan bus!" )) { -kfree (sys); +if (WARN (ret <0 ,"PCI: unable to scan bus!" )) { +pci_free_host_bridge (bridge);break ; } + sys->bus = bridge->bus; + busnr = sys->bus->busn_res.end +1 ;list_add (&sys->node, head); - - host_bridge =pci_find_host_bridge (sys->bus); - host_bridge->align_resource = hw->align_resource; }else { -kfree (sys); +pci_free_host_bridge (bridge);if (ret <0 )break ; }
arch/arm/mach-dove/pcie.c +12 -5
@@ -152,16 +152,23 @@ static void rc_pci_fixup(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_MARVELL ,PCI_ANY_ID , rc_pci_fixup); -static struct pci_bus __init * -dove_pcie_scan_bus (int nr,struct pci_sys_data *sys) +static int __init +dove_pcie_scan_bus (int nr,struct pci_host_bridge *bridge) { +struct pci_sys_data *sys =pci_host_bridge_priv (bridge); +if (nr >= num_pcie_ports) {BUG (); -return NULL ; +return -EINVAL ; } -return pci_scan_root_bus (NULL , sys->busnr, &pcie_ops, sys, - &sys->resources); +list_splice_init (&sys->resources, &bridge->windows); + bridge->dev.parent =NULL ; + bridge->sysdata = sys; + bridge->busnr = sys->busnr; + bridge->ops = &pcie_ops; + +return pci_scan_root_bus_bridge (bridge); }static int __init dove_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin)
arch/arm/mach-iop13xx/pci.c +18 -11
@@ -504,10 +504,10 @@ iop13xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)/* Scan an IOP13XX PCI bus. nr selects which ATU we use. */ -struct pci_bus *iop13xx_scan_bus (int nr,struct pci_sys_data *sys) +int iop13xx_scan_bus (int nr,struct pci_host_bridge *bridge) { -int which_atu; -struct pci_bus *bus =NULL ; +int which_atu, ret; +struct pci_sys_data *sys =pci_host_bridge_priv (bridge);switch (init_atu) {case IOP13XX_INIT_ATU_ATUX :
@@ -525,9 +525,14 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys)if (!which_atu) {BUG (); -return NULL ; +return -ENODEV ; } +list_splice_init (&sys->resources, &bridge->windows); + bridge->dev.parent =NULL ; + bridge->sysdata = sys; + bridge->busnr = sys->busnr; +switch (which_atu) {case IOP13XX_INIT_ATU_ATUX : if (time_after_eq(jiffies + msecs_to_jiffies(1000),
@@ -535,18 +540,20 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys)while (time_before (jiffies, atux_trhfa_timeout))udelay (100 ); - bus = pci_bus_atux =pci_scan_root_bus (NULL , sys->busnr, - &iop13xx_atux_ops, - sys, &sys->resources); + bridge->ops = &iop13xx_atux_ops; + ret =pci_scan_root_bus_bridge (bridge); +if (!ret) + pci_bus_atux = bridge->bus;break ;case IOP13XX_INIT_ATU_ATUE : - bus = pci_bus_atue =pci_scan_root_bus (NULL , sys->busnr, - &iop13xx_atue_ops, - sys, &sys->resources); + bridge->ops = &iop13xx_atue_ops; + ret =pci_scan_root_bus_bridge (bridge); +if (!ret) + pci_bus_atue = bridge->bus;break ; } -return bus; +return ret; }/* This function is called from iop13xx_pci_init() after assigning valid
arch/arm/mach-iop13xx/pci.h +2 -1
@@ -11,9 +11,10 @@ extern size_t iop13xx_atue_mem_size;extern size_t iop13xx_atux_mem_size;struct pci_sys_data ; +struct pci_host_bridge ;struct hw_pci ;int iop13xx_pci_setup (int nr,struct pci_sys_data *sys); -struct pci_bus *iop13xx_scan_bus (int nr,struct pci_sys_data *); +int iop13xx_scan_bus (int nr,struct pci_host_bridge *bridge);void iop13xx_atu_select (struct hw_pci *plat_pci);void iop13xx_pci_init (void );void iop13xx_map_pci_memory (void );
arch/arm/mach-mv78xx0/pcie.c +3 -5
@@ -194,16 +194,14 @@ static void rc_pci_fixup(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_MARVELL ,PCI_ANY_ID , rc_pci_fixup); -static struct pci_bus __init * -mv78xx0_pcie_scan_bus (int nr,struct pci_sys_data *sys) +static int __init mv78xx0_pcie_scan_bus (int nr,struct pci_host_bridge *bridge) {if (nr >= num_pcie_ports) {BUG (); -return NULL ; +return -EINVAL ; } -return pci_scan_root_bus (NULL , sys->busnr, &pcie_ops, sys, - &sys->resources); +return pci_scan_root_bus_bridge (bridge); } static int __init mv78xx0_pcie_map_irq(const struct pci_dev *dev, u8 slot,
arch/arm/mach-orion5x/common.h +2 -1
@@ -54,6 +54,7 @@ void orion5x_restart(enum reboot_mode, const char *);* PCIe/PCI functions. */ struct pci_bus ; +struct pci_host_bridge ;struct pci_sys_data ;struct pci_dev ;
@@ -61,7 +62,7 @@ void orion5x_pcie_id(u32 *dev, u32 *rev);void orion5x_pci_disable (void );void orion5x_pci_set_cardbus_mode (void );int orion5x_pci_sys_setup (int nr,struct pci_sys_data *sys); -struct pci_bus *orion5x_pci_sys_scan_bus (int nr,struct pci_sys_data *sys); +int orion5x_pci_sys_scan_bus (int nr,struct pci_host_bridge *bridge);int orion5x_pci_map_irq (const struct pci_dev *dev,u8 slot,u8 pin);struct tag ;
arch/arm/mach-orion5x/pci.c +17 -8
@@ -555,18 +555,27 @@ int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)return 0 ; } -struct pci_bus __init *orion5x_pci_sys_scan_bus (int nr,struct pci_sys_data *sys) +int __init orion5x_pci_sys_scan_bus (int nr,struct pci_host_bridge *bridge) { -if (nr ==0 ) -return pci_scan_root_bus (NULL , sys->busnr, &pcie_ops, sys, - &sys->resources); +struct pci_sys_data *sys =pci_host_bridge_priv (bridge); -if (nr ==1 && !orion5x_pci_disabled) -return pci_scan_root_bus (NULL , sys->busnr, &pci_ops, sys, - &sys->resources); +list_splice_init (&sys->resources, &bridge->windows); + bridge->dev.parent =NULL ; + bridge->sysdata = sys; + bridge->busnr = sys->busnr; + +if (nr ==0 ) { + bridge->ops = &pcie_ops; +return pci_scan_root_bus_bridge (bridge); + } + +if (nr ==1 && !orion5x_pci_disabled) { + bridge->ops = &pci_ops; +return pci_scan_root_bus_bridge (bridge); + }BUG (); -return NULL ; +return -ENODEV ; }int __init orion5x_pci_map_irq (const struct pci_dev *dev,u8 slot,u8 pin)
Signature · 1 line
2.10.0
PATCH v2 12/42 PCI: designware: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI designware host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/dwc/pcie-designware-host.c | 36 +++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-)
drivers/pci/dwc/pcie-designware-host.c +22 -14
@@ -280,9 +280,9 @@ int dw_pcie_host_init(struct pcie_port *pp)struct device_node *np = dev->of_node;struct platform_device *pdev =to_platform_device (dev);struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;struct resource *cfg_res;int i, ret; -LIST_HEAD (res);struct resource_entry *win, *tmp; cfg_res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"config" );
@@ -295,16 +295,21 @@ int dw_pcie_host_init(struct pcie_port *pp)dev_err (dev,"missing *config* reg space\n" ); } - ret =of_pci_get_host_bridge_resources (np,0 ,0xff , &res, &pp->io_base); + bridge =pci_alloc_host_bridge (0 ); +if (!bridge) +return -ENOMEM ; + + ret =of_pci_get_host_bridge_resources (np,0 ,0xff , + &bridge->windows, &pp->io_base);if (ret)return ret; - ret =devm_request_pci_bus_resources (dev, &res); + ret =devm_request_pci_bus_resources (dev, &bridge->windows);if (ret) goto error;/* Get the I/O and memory ranges from DT */ -resource_list_for_each_entry_safe (win, tmp, &res) { +resource_list_for_each_entry_safe (win, tmp, &bridge->windows) {switch (resource_type (win->res)) {case IORESOURCE_IO : ret =pci_remap_iospace (win->res, pp->io_base);
@@ -400,19 +405,22 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->ops->host_init (pp); pp->root_bus_nr = pp->busn->start; + + bridge->dev.parent = dev; + bridge->sysdata = pp; + bridge->busnr = pp->root_bus_nr; + bridge->ops = &dw_pcie_ops;if (IS_ENABLED (CONFIG_PCI_MSI )) { - bus =pci_scan_root_bus_msi (dev, pp->root_bus_nr, - &dw_pcie_ops, pp, &res, - &dw_pcie_msi_chip); + bridge->msi = &dw_pcie_msi_chip; dw_pcie_msi_chip.dev = dev; - }else - bus =pci_scan_root_bus (dev, pp->root_bus_nr, &dw_pcie_ops, - pp, &res); -if (!bus) { - ret = -ENOMEM ; - goto error; } + ret =pci_scan_root_bus_bridge (bridge); +if (ret) + goto error; + + bus = bridge->bus; +if (pp->ops->scan_bus) pp->ops->scan_bus (pp);
@@ -431,7 +439,7 @@ int dw_pcie_host_init(struct pcie_port *pp)return 0 ; error: -pci_free_resource_list (&res); +pci_free_host_bridge (bridge);return ret; }
Signature · 1 line
2.10.0
PATCH v2 13/42 PCI: aardvark: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI aardvark host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pci-aardvark.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
drivers/pci/host/pci-aardvark.c +15 -6
@@ -886,12 +886,14 @@ static int advk_pcie_probe(struct platform_device *pdev)struct advk_pcie *pcie;struct resource *res;struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;int ret, irq; - pcie =devm_kzalloc (dev,sizeof (struct advk_pcie ),GFP_KERNEL ); -if (!pcie) + bridge =devm_pci_alloc_host_bridge (dev,sizeof (struct advk_pcie )); +if (!bridge)return -ENOMEM ; + pcie =pci_host_bridge_priv (bridge); pcie->pdev = pdev; res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );
@@ -929,14 +931,21 @@ static int advk_pcie_probe(struct platform_device *pdev)return ret; } - bus =pci_scan_root_bus (dev,0 , &advk_pcie_ops, - pcie, &pcie->resources); -if (!bus) { +list_splice_init (&pcie->resources, &bridge->windows); + bridge->dev.parent = dev; + bridge->sysdata = pcie; + bridge->busnr =0 ; + bridge->ops = &advk_pcie_ops; + + ret =pci_scan_root_bus_bridge (bridge); +if (ret <0 ) {advk_pcie_remove_msi_irq_domain (pcie);advk_pcie_remove_irq_domain (pcie); -return -ENOMEM ; +return ret; } + bus = bridge->bus; +pci_bus_assign_resources (bus);list_for_each_entry (child, &bus->children, node)
Signature · 1 line
2.10.0
PATCH v2 14/42 PCI: rcar: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI rcar host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pcie-rcar.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
drivers/pci/host/pcie-rcar.c +24 -14
@@ -450,28 +450,32 @@ static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)static int rcar_pcie_enable (struct rcar_pcie *pcie) {struct device *dev = pcie->dev; +struct pci_host_bridge *bridge =pci_host_bridge_from_priv (pcie);struct pci_bus *bus, *child; -LIST_HEAD (res); +int ret;/* Try setting 5 GT/s link speed */ rcar_pcie_force_speedup (pcie); -rcar_pcie_setup (&res, pcie); +rcar_pcie_setup (&bridge->windows, pcie);pci_add_flags (PCI_REASSIGN_ALL_RSRC |PCI_REASSIGN_ALL_BUS ); + bridge->dev.parent = dev; + bridge->sysdata = pcie; + bridge->busnr = pcie->root_bus_nr; + bridge->ops = &rcar_pcie_ops;if (IS_ENABLED (CONFIG_PCI_MSI )) - bus =pci_scan_root_bus_msi (dev, pcie->root_bus_nr, - &rcar_pcie_ops, pcie, &res, &pcie->msi.chip); -else - bus =pci_scan_root_bus (dev, pcie->root_bus_nr, - &rcar_pcie_ops, pcie, &res); + bridge->msi = &pcie->msi.chip; -if (!bus) { -dev_err (dev,"Scanning rootbus failed" ); -return -ENODEV ; + ret =pci_scan_root_bus_bridge (bridge); +if (ret <0 ) { +kfree (bridge); +return ret; } + bus = bridge->bus; +pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);pci_bus_size_bridges (bus);
@@ -1127,11 +1131,14 @@ static int rcar_pcie_probe(struct platform_device *pdev)unsigned int data;int err;int (*hw_init_fn)(struct rcar_pcie *); +struct pci_host_bridge *bridge; - pcie =devm_kzalloc (dev,sizeof (*pcie),GFP_KERNEL ); -if (!pcie) + bridge =pci_alloc_host_bridge (sizeof (*pcie)); +if (!bridge)return -ENOMEM ; + pcie =pci_host_bridge_priv (bridge); + pcie->dev = dev;INIT_LIST_HEAD (&pcie->resources);
@@ -1141,12 +1148,12 @@ static int rcar_pcie_probe(struct platform_device *pdev) err =rcar_pcie_get_resources (pcie);if (err <0 ) {dev_err (dev,"failed to request resources: %d\n" , err); -return err; + goto err_free_bridge; } err =rcar_pcie_parse_map_dma_ranges (pcie, dev->of_node);if (err) -return err; + goto err_free_bridge;pm_runtime_enable (dev); err =pm_runtime_get_sync (dev);
@@ -1183,6 +1190,9 @@ static int rcar_pcie_probe(struct platform_device *pdev)return 0 ; +err_free_bridge: +pci_free_host_bridge (bridge); + err_pm_put:pm_runtime_put (dev);
Signature · 1 line
2.10.0
PATCH v2 15/42 PCI: iproc: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI iproc host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pcie-iproc-bcma.c | 7 +++++-- drivers/pci/host/pcie-iproc-platform.c | 7 +++++-- drivers/pci/host/pcie-iproc.c | 38 ++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 22 deletions(-)
drivers/pci/host/pcie-iproc-bcma.c +5 -2
@@ -45,12 +45,15 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)struct device *dev = &bdev->dev;struct iproc_pcie *pcie;LIST_HEAD (resources); +struct pci_host_bridge *bridge;int ret; - pcie =devm_kzalloc (dev,sizeof (*pcie),GFP_KERNEL ); -if (!pcie) + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*pcie)); +if (!bridge)return -ENOMEM ; + pcie =pci_host_bridge_priv (bridge); + pcie->dev = dev; pcie->type =IPROC_PCIE_PAXB_BCMA ;
drivers/pci/host/pcie-iproc-platform.c +5 -2
@@ -52,12 +52,15 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)struct resource reg;resource_size_t iobase =0 ;LIST_HEAD (resources); +struct pci_host_bridge *bridge;int ret; - pcie =devm_kzalloc (dev,sizeof (*pcie),GFP_KERNEL ); -if (!pcie) + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*pcie)); +if (!bridge)return -ENOMEM ; + pcie =pci_host_bridge_priv (bridge); + pcie->dev = dev; pcie->type = (enum iproc_pcie_type )of_device_get_match_data (dev);
drivers/pci/host/pcie-iproc.c +20 -18
@@ -1259,7 +1259,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)struct device *dev;int ret;void *sysdata; -struct pci_bus *bus, *child; +struct pci_bus *child; +struct pci_host_bridge *host =pci_host_bridge_from_priv (pcie); dev = pcie->dev;
@@ -1306,18 +1307,10 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) sysdata = pcie;#endif - bus =pci_create_root_bus (dev,0 , &iproc_pcie_ops, sysdata, res); -if (!bus) { -dev_err (dev,"unable to create PCI root bus\n" ); - ret = -ENOMEM ; - goto err_power_off_phy; - } - pcie->root_bus = bus; - ret =iproc_pcie_check_link (pcie);if (ret) {dev_err (dev,"no PCIe EP device detected\n" ); - goto err_rm_root_bus; + goto err_power_off_phy; }iproc_pcie_enable (pcie);
@@ -1326,23 +1319,32 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)if (iproc_pcie_msi_enable (pcie))dev_info (dev,"not using iProc MSI\n" ); -pci_scan_child_bus (bus); -pci_assign_unassigned_bus_resources (bus); +list_splice_init (res, &host->windows); + host->busnr =0 ; + host->dev.parent = dev; + host->ops = &iproc_pcie_ops; + host->sysdata = sysdata; + + ret =pci_scan_root_bus_bridge (host); +if (ret <0 ) { +dev_err (dev,"failed to scan host: %d\n" , ret); + goto err_power_off_phy; + }if (pcie->map_irq)pci_fixup_irqs (pci_common_swizzle, pcie->map_irq); -list_for_each_entry (child, &bus->children, node) +pci_assign_unassigned_bus_resources (host->bus); + + pcie->root_bus = host->bus; + +list_for_each_entry (child, &host->bus->children, node)pcie_bus_configure_settings (child); -pci_bus_add_devices (bus); +pci_bus_add_devices (host->bus);return 0 ; -err_rm_root_bus: -pci_stop_root_bus (bus); -pci_remove_root_bus (bus); - err_power_off_phy:phy_power_off (pcie->phy); err_exit_phy:
Signature · 1 line
2.10.0
PATCH v2 16/42 PCI: versatile: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI versatile host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pci-versatile.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
drivers/pci/host/pci-versatile.c +17 -3
@@ -125,8 +125,13 @@ static int versatile_pci_probe(struct platform_device *pdev)u32 val;void __iomem *local_pci_cfg_base;struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;LIST_HEAD (pci_res); + bridge =devm_pci_alloc_host_bridge (dev,0 ); +if (!bridge) +return -ENOMEM ; + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); versatile_pci_base =devm_ioremap_resource (&pdev->dev, res);if (IS_ERR (versatile_pci_base))
@@ -199,11 +204,20 @@ static int versatile_pci_probe(struct platform_device *pdev)pci_add_flags (PCI_ENABLE_PROC_DOMAINS );pci_add_flags (PCI_REASSIGN_ALL_BUS |PCI_REASSIGN_ALL_RSRC ); - bus =pci_scan_root_bus (&pdev->dev,0 , &pci_versatile_ops,NULL , &pci_res); -if (!bus) -return -ENOMEM ; +list_splice_init (&pci_res, &bridge->windows); + bridge->dev.parent = &pdev->dev; + bridge->sysdata =NULL ; + bridge->busnr =0 ; + bridge->ops = &pci_versatile_ops; + + ret =pci_scan_root_bus_bridge (bridge); +if (ret <0 ) +return ret; + + bus = bridge->bus;pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +pci_assign_unassigned_bus_resources (bus);list_for_each_entry (child, &bus->children, node)pcie_bus_configure_settings (child);
Signature · 1 line
2.10.0
PATCH v2 17/42 PCI: altera: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI altera host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pcie-altera.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/pci/host/pcie-altera.c +16 -6
@@ -579,12 +579,14 @@ static int altera_pcie_probe(struct platform_device *pdev)struct altera_pcie *pcie;struct pci_bus *bus;struct pci_bus *child; +struct pci_host_bridge *bridge;int ret; - pcie =devm_kzalloc (dev,sizeof (*pcie),GFP_KERNEL ); -if (!pcie) + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*pcie)); +if (!bridge)return -ENOMEM ; + pcie =pci_host_bridge_priv (bridge); pcie->pdev = pdev; ret =altera_pcie_parse_dt (pcie);
@@ -613,12 +615,20 @@ static int altera_pcie_probe(struct platform_device *pdev)cra_writel (pcie,P2A_INT_ENA_ALL ,P2A_INT_ENABLE );altera_pcie_host_init (pcie); - bus =pci_scan_root_bus (dev, pcie->root_bus_nr, &altera_pcie_ops, - pcie, &pcie->resources); -if (!bus) -return -ENOMEM ; +list_splice_init (&pcie->resources, &bridge->windows); + bridge->dev.parent = dev; + bridge->sysdata = pcie; + bridge->busnr = pcie->root_bus_nr; + bridge->ops = &altera_pcie_ops; + + ret =pci_scan_root_bus_bridge (bridge); +if (ret <0 ) +return ret; + + bus = bridge->bus;pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); +pci_assign_unassigned_bus_resources (bus);/* Configure PCI Express setting. */
Signature · 1 line
2.10.0
PATCH v2 18/42 PCI: xilinx: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI xilinx host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pcie-xilinx.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
drivers/pci/host/pcie-xilinx.c +19 -10
@@ -633,6 +633,7 @@ static int xilinx_pcie_probe(struct platform_device *pdev)struct device *dev = &pdev->dev;struct xilinx_pcie_port *port;struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;int err;resource_size_t iobase =0 ;LIST_HEAD (res);
@@ -640,9 +641,11 @@ static int xilinx_pcie_probe(struct platform_device *pdev)if (!dev->of_node)return -ENODEV ; - port =devm_kzalloc (dev,sizeof (*port),GFP_KERNEL ); -if (!port) -return -ENOMEM ; + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*port)); +if (!bridge) +return -ENODEV ; + + port =pci_host_bridge_priv (bridge); port->dev = dev;
@@ -671,17 +674,23 @@ static int xilinx_pcie_probe(struct platform_device *pdev)if (err) goto error; - bus =pci_create_root_bus (dev,0 , &xilinx_pcie_ops, port, &res); -if (!bus) { - err = -ENOMEM ; - goto error; - } + +list_splice_init (&res, &bridge->windows); + bridge->dev.parent = dev; + bridge->sysdata = port; + bridge->busnr =0 ; + bridge->ops = &xilinx_pcie_ops;#ifdef CONFIG_PCI_MSI xilinx_pcie_msi_chip.dev = dev; - bus->msi = &xilinx_pcie_msi_chip; + bridge->msi = &xilinx_pcie_msi_chip;#endif -pci_scan_child_bus (bus); + err =pci_scan_root_bus_bridge (bridge); +if (err <0 ) + goto error; + + bus = bridge->bus; +pci_assign_unassigned_bus_resources (bus);#ifndef CONFIG_MICROBLAZE pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);
Signature · 1 line
2.10.0
PATCH v2 19/42 PCI: xgene: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI xgene host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pci-xgene.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
drivers/pci/host/pci-xgene.c +15 -6
@@ -636,13 +636,16 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)struct xgene_pcie_port *port;resource_size_t iobase =0 ;struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;int ret;LIST_HEAD (res); - port =devm_kzalloc (dev,sizeof (*port),GFP_KERNEL ); -if (!port) + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*port)); +if (!bridge)return -ENOMEM ; + port =pci_host_bridge_priv (bridge); + port->node =of_node_get (dn); port->dev = dev;
@@ -670,11 +673,17 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)if (ret) goto error; - bus =pci_create_root_bus (dev,0 , &xgene_pcie_ops, port, &res); -if (!bus) { - ret = -ENOMEM ; +list_splice_init (&res, &bridge->windows); + bridge->dev.parent = dev; + bridge->sysdata = port; + bridge->busnr =0 ; + bridge->ops = &xgene_pcie_ops; + + ret =pci_scan_root_bus_bridge (bridge); +if (ret <0 ) goto error; - } + + bus = bridge->bus;pci_scan_child_bus (bus);pci_assign_unassigned_bus_resources (bus);
Signature · 1 line
2.10.0
PATCH v2 20/42 PCI: host-common: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI host-common code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pci-host-common.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
drivers/pci/host/pci-host-common.c +18 -5
@@ -117,8 +117,14 @@ int pci_host_common_probe(struct platform_device *pdev,struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;struct pci_config_window *cfg;struct list_head resources; +int ret; + + bridge =devm_pci_alloc_host_bridge (dev,0 ); +if (!bridge) +return -ENOMEM ; type =of_get_property (np,"device_type" ,NULL );if (!type ||strcmp (type,"pci" )) {
@@ -138,13 +144,20 @@ int pci_host_common_probe(struct platform_device *pdev,if (!pci_has_flag (PCI_PROBE_ONLY ))pci_add_flags (PCI_REASSIGN_ALL_RSRC |PCI_REASSIGN_ALL_BUS ); - bus =pci_scan_root_bus (dev, cfg->busr.start, &ops->pci_ops, cfg, - &resources); -if (!bus) { -dev_err (dev,"Scanning rootbus failed" ); -return -ENODEV ; +list_splice_init (&resources, &bridge->windows); + bridge->dev.parent = dev; + bridge->sysdata = cfg; + bridge->busnr = cfg->busr.start; + bridge->ops = &ops->pci_ops; + + ret =pci_scan_root_bus_bridge (bridge); +if (ret <0 ) { +dev_err (dev,"Scanning root bridge failed" ); +return ret; } + bus = bridge->bus; +#ifdef CONFIG_ARM pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);#endif
Signature · 1 line
2.10.0
PATCH v2 21/42 PCI: rockchip: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI rockchip host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pcie-rockchip.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/pci/host/pcie-rockchip.c +16 -6
@@ -1284,6 +1284,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)struct rockchip_pcie *rockchip;struct device *dev = &pdev->dev;struct pci_bus *bus, *child; +struct pci_host_bridge *bridge;struct resource_entry *win;resource_size_t io_base;struct resource *mem;
@@ -1295,10 +1296,12 @@ static int rockchip_pcie_probe(struct platform_device *pdev)if (!dev->of_node)return -ENODEV ; - rockchip =devm_kzalloc (dev,sizeof (*rockchip),GFP_KERNEL ); -if (!rockchip) + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*rockchip)); +if (!bridge)return -ENOMEM ; + rockchip =pci_host_bridge_priv (bridge); +platform_set_drvdata (pdev, rockchip); rockchip->dev = dev;
@@ -1396,11 +1399,18 @@ static int rockchip_pcie_probe(struct platform_device *pdev) goto err_free_res; } - bus =pci_scan_root_bus (&pdev->dev,0 , &rockchip_pcie_ops, rockchip, &res); -if (!bus) { - err = -ENOMEM ; +list_splice_init (&res, &bridge->windows); + bridge->dev.parent = &pdev->dev; + bridge->sysdata = rockchip; + bridge->busnr =0 ; + bridge->ops = &rockchip_pcie_ops; + + err =pci_scan_root_bus_bridge (bridge); +if (!err) goto err_free_res; - } + + bus = bridge->bus; + rockchip->root_bus = bus;pci_bus_size_bridges (bus);
Signature · 1 line
2.10.0
PATCH v2 22/42 PCI: xilinx-nwl: Convert PCI scan API to pci_scan_root_bus_bridge()
In reply to Lorenzo PieralisiThe introduction of pci_scan_root_bus_bridge() provides a PCI core API to scan a PCI root bus backed by an already initialized struct pci_host_bridge object, which simplifies the bus scan interface and makes the PCI scan root bus interface easier to generalize as members are added to the struct pci_host_bridge.
Convert PCI xilinx-nwl host code to pci_scan_root_bus_bridge() to improve the PCI root bus scanning interface.
--- drivers/pci/host/pcie-xilinx-nwl.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-)
drivers/pci/host/pcie-xilinx-nwl.c +18 -10
@@ -791,13 +791,16 @@ static int nwl_pcie_probe(struct platform_device *pdev)struct nwl_pcie *pcie;struct pci_bus *bus;struct pci_bus *child; +struct pci_host_bridge *bridge;int err;resource_size_t iobase =0 ;LIST_HEAD (res); - pcie =devm_kzalloc (dev,sizeof (*pcie),GFP_KERNEL ); -if (!pcie) -return -ENOMEM ; + bridge =devm_pci_alloc_host_bridge (dev,sizeof (*pcie)); +if (!bridge) +return -ENODEV ; + + pcie =pci_host_bridge_priv (bridge); pcie->dev = dev; pcie->ecam_value =NWL_ECAM_VALUE_DEFAULT ;
@@ -830,12 +833,11 @@ static int nwl_pcie_probe(struct platform_device *pdev) goto error; } - bus =pci_create_root_bus (dev, pcie->root_busno, - &nwl_pcie_ops, pcie, &res); -if (!bus) { - err = -ENOMEM ; - goto error; - } +list_splice_init (&res, &bridge->windows); + bridge->dev.parent = dev; + bridge->sysdata = pcie; + bridge->busnr = pcie->root_busno; + bridge->ops = &nwl_pcie_ops;if (IS_ENABLED (CONFIG_PCI_MSI )) { err =nwl_pcie_enable_msi (pcie);
@@ -844,7 +846,13 @@ static int nwl_pcie_probe(struct platform_device *pdev) goto error; } } -pci_scan_child_bus (bus); + + err =pci_scan_root_bus_bridge (bridge); +if (err) + goto error; + + bus = bridge->bus; +pci_assign_unassigned_bus_resources (bus);list_for_each_entry (child, &bus->children, node)pcie_bus_configure_settings (child);
Signature · 1 line
2.10.0
PATCH v2 23/42 PCI: Remove pci_scan_root_bus_msi()
In reply to Lorenzo PieralisiThe pci_scan_root_bus_bridge() function allows passing a parameterized struct pci_host_bridge and scanning the resulting PCI bus; since the struct msi_controller is part of the struct pci_host_bridge and the struct pci_host_bridge can now be passed to pci_scan_root_bus_bridge() explicitly, there is no need for a scan interface with a MSI controller parameter.
With all PCI host controller drivers and platform code relying on pci_scan_root_bus_msi() converted over to pci_scan_root_bus_bridge() the pci_scan_root_bus_msi() becomes obsolete and can be removed.
--- drivers/pci/probe.c | 27 +++++---------------------- include/linux/pci.h | 4 ---- 2 files changed, 5 insertions(+), 26 deletions(-)
drivers/pci/probe.c +5 -22
@@ -2324,9 +2324,8 @@ void __weak pcibios_remove_bus(struct pci_bus *bus) { } -static struct pci_bus *pci_create_root_bus_msi (struct device *parent, -int bus,struct pci_ops *ops,void *sysdata, -struct list_head *resources,struct msi_controller *msi) +struct pci_bus *pci_create_root_bus (struct device *parent,int bus, +struct pci_ops *ops,void *sysdata,struct list_head *resources) {int error;struct pci_host_bridge *bridge;
@@ -2341,7 +2340,6 @@ static struct pci_bus *pci_create_root_bus_msi(struct device *parent, bridge->sysdata = sysdata; bridge->busnr = bus; bridge->ops = ops; - bridge->msi = msi; error =pci_register_host_bridge (bridge);if (error <0 )
@@ -2353,13 +2351,6 @@ static struct pci_bus *pci_create_root_bus_msi(struct device *parent,kfree (bridge);return NULL ; } - -struct pci_bus *pci_create_root_bus (struct device *parent,int bus, -struct pci_ops *ops,void *sysdata,struct list_head *resources) -{ -return pci_create_root_bus_msi (parent, bus, ops, sysdata, resources, -NULL ); -}EXPORT_SYMBOL_GPL (pci_create_root_bus);int pci_bus_insert_busn_res (struct pci_bus *b,int bus,int bus_max)
@@ -2464,9 +2455,8 @@ int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge) }EXPORT_SYMBOL (pci_scan_root_bus_bridge); -struct pci_bus *pci_scan_root_bus_msi (struct device *parent,int bus, -struct pci_ops *ops,void *sysdata, -struct list_head *resources,struct msi_controller *msi) +struct pci_bus *pci_scan_root_bus (struct device *parent,int bus, +struct pci_ops *ops,void *sysdata,struct list_head *resources) {struct resource_entry *window;bool found = false;
@@ -2479,7 +2469,7 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,break ; } - b =pci_create_root_bus_msi (parent, bus, ops, sysdata, resources, msi); + b =pci_create_root_bus (parent, bus, ops, sysdata, resources);if (!b)return NULL ;
@@ -2497,13 +2487,6 @@ struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,return b; } - -struct pci_bus *pci_scan_root_bus (struct device *parent,int bus, -struct pci_ops *ops,void *sysdata,struct list_head *resources) -{ -return pci_scan_root_bus_msi (parent, bus, ops, sysdata, resources, -NULL ); -}EXPORT_SYMBOL (pci_scan_root_bus); struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
include/linux/pci.h +0 -4
@@ -854,10 +854,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,int pci_bus_insert_busn_res (struct pci_bus *b,int bus,int busmax);int pci_bus_update_busn_res_end (struct pci_bus *b,int busmax);void pci_bus_release_busn_res (struct pci_bus *b); -struct pci_bus *pci_scan_root_bus_msi (struct device *parent,int bus, -struct pci_ops *ops,void *sysdata, -struct list_head *resources, -struct msi_controller *msi);struct pci_bus *pci_scan_root_bus (struct device *parent,int bus,struct pci_ops *ops,void *sysdata,struct list_head *resources);
Signature · 1 line
2.10.0
PATCH v2 24/42 PCI: Build setup-irq.o on all arches
In reply to Lorenzo PieralisiFrom: Matthew Minter <[email protected]>
The functions included in setup-irq.o currently apply only to a selection of architectures which share common IRQ assignment code. However this code needs to be generalised for all arches to allow deferred IRQ assignment. So the first step is to build it on all architectures.
--- drivers/pci/Makefile | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-)
drivers/pci/Makefile +2 -15
@@ -4,7 +4,8 @@ obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ - irq.o vpd.o setup-bus.o vc.o mmap.o + irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o + obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o
@@ -29,20 +30,6 @@ obj-$(CONFIG_PCI_ATS) += ats.o obj-$(CONFIG_PCI_IOV) += iov.o # -# Some architectures use the generic PCI setup functions -# -obj-$(CONFIG_ALPHA) += setup-irq.o -obj-$(CONFIG_ARC) += setup-irq.o -obj-$(CONFIG_ARM) += setup-irq.o -obj-$(CONFIG_ARM64) += setup-irq.o -obj-$(CONFIG_UNICORE32) += setup-irq.o -obj-$(CONFIG_SUPERH) += setup-irq.o -obj-$(CONFIG_MIPS) += setup-irq.o -obj-$(CONFIG_TILE) += setup-irq.o -obj-$(CONFIG_SPARC_LEON) += setup-irq.o -obj-$(CONFIG_M68K) += setup-irq.o - -# # ACPI Related PCI FW Functions # ACPI _DSM provided firmware instance and string name #
Signature · 1 line
2.10.0
PATCH v2 25/42 PCI: Add IRQ mapping function pointers to pci_host_bridge struct
In reply to Lorenzo PieralisiFrom: Matthew Minter <[email protected]>
In order to defer IRQ assignment arches must be able to register functions to map and swizzle interrupts. These registered functions are stored in the pci_host_bridge struct.
--- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/pci.h +2 -0
@@ -437,6 +437,8 @@ struct pci_host_bridge {void *sysdata;int busnr;struct list_head windows;/* resource_entry */ +u8 (*swizzle_irq)(struct pci_dev *,u8 *);/* platform irq swizzler */ +int (*map_irq)(const struct pci_dev *,u8 ,u8 );void (*release_fn)(struct pci_host_bridge *);void *release_data;struct msi_controller *msi;
Signature · 1 line
2.10.0
PATCH v2 26/42 PCI: Add pci_assign_irq() function and have pci_fixup_irqs() use it
In reply to Lorenzo PieralisiFrom: Matthew Minter <[email protected]>
Here we delete the static pdev_fixup_irq() function which is currently what pci_fixup_irqs() uses to actually assign the irqs and replace it with the pci_assign_irq() function which changes the interface and makes use of the new function pointers stored in the host bridge structure.
Eventually this will allow pci_fixup_irqs() to be removed entirely and the new deferred assignment code path will call pci_assign_irq directly. However to ensure current users continue to work a new implementation of pci_fixup_irqs() is introduced which simply wraps the functionality of pci_assign_irq().
--- drivers/pci/setup-irq.c | 45 +++++++++++++++++++++++++++++++++++---------- include/linux/pci.h | 1 + 2 files changed, 36 insertions(+), 10 deletions(-)
drivers/pci/setup-irq.c +35 -10
@@ -15,6 +15,7 @@#include <linux/errno.h> #include <linux/ioport.h> #include <linux/cache.h> +#include "pci.h" void __weak pcibios_update_irq (struct pci_dev *dev,int irq) {
@@ -22,12 +23,17 @@ void __weak pcibios_update_irq(struct pci_dev *dev, int irq)pci_write_config_byte (dev,PCI_INTERRUPT_LINE , irq); } -static void pdev_fixup_irq (struct pci_dev *dev, -u8 (*swizzle)(struct pci_dev *,u8 *), -int (*map_irq)(const struct pci_dev *,u8 ,u8 )) +void pci_assign_irq (struct pci_dev *dev) { -u8 pin, slot; +u8 pin; +u8 slot =-1 ;int irq =0 ; +struct pci_host_bridge *hbrg =pci_find_host_bridge (dev->bus); + +if (!(hbrg->map_irq)) { +dev_dbg (&dev->dev,"runtime irq mapping not provided by arch\n" ); +return ; + }/* If this device is not on the primary bus, we need to figure out which interrupt pin it will come in on. We know which slot it
@@ -40,17 +46,22 @@ static void pdev_fixup_irq(struct pci_dev *dev,if (pin >4 ) pin =1 ; -if (pin !=0 ) { +if (pin) {/* Follow the chain of bridges, swizzling as we go. */ - slot = (*swizzle)(dev, &pin); +if (hbrg->swizzle_irq) + slot = (*(hbrg->swizzle_irq))(dev, &pin); - irq = (*map_irq)(dev, slot, pin); +/* +* If a swizzling function is not used map_irq must +* ignore slot +*/ + irq = (*(hbrg->map_irq))(dev, slot, pin);if (irq ==-1 ) irq =0 ; } dev->irq = irq; -dev_dbg (&dev->dev,"fixup irq: got %d\n" , dev->irq); +dev_dbg (&dev->dev,"assign irq: got %d\n" , dev->irq);/* Always tell the device, so the driver knows what is the real IRQ to use; the device does not use it. */
@@ -60,9 +71,23 @@ static void pdev_fixup_irq(struct pci_dev *dev,void pci_fixup_irqs (u8 (*swizzle)(struct pci_dev *,u8 *),int (*map_irq)(const struct pci_dev *,u8 ,u8 )) { +/* +* Implement pci_fixup_irqs() through pci_assign_irq(). +* This code should be remove eventually, it is a wrapper +* around pci_assign_irq() interface to keep current +* pci_fixup_irqs() behaviour unchanged on architecture +* code still relying on its interface. +*/ struct pci_dev *dev =NULL ; +struct pci_host_bridge *hbrg =NULL ; -for_each_pci_dev (dev) -pdev_fixup_irq (dev, swizzle, map_irq); +for_each_pci_dev (dev) { + hbrg =pci_find_host_bridge (dev->bus); + hbrg->swizzle_irq = swizzle; + hbrg->map_irq = map_irq; +pci_assign_irq (dev); + hbrg->swizzle_irq =NULL ; + hbrg->map_irq =NULL ; + } }EXPORT_SYMBOL_GPL (pci_fixup_irqs);
include/linux/pci.h +1 -0
@@ -1152,6 +1152,7 @@ void pdev_enable_device(struct pci_dev *);int pci_enable_resources (struct pci_dev *,int mask);void pci_fixup_irqs (u8 (*)(struct pci_dev *,u8 *),int (*)(const struct pci_dev *,u8 ,u8 )); +void pci_assign_irq (struct pci_dev *dev);struct resource *pci_find_resource (struct pci_dev *dev,struct resource *res);#define HAVE_PCI_REQ_REGIONS 2int __must_check pci_request_regions (struct pci_dev *,const char *);
Signature · 1 line
2.10.0
PATCH v2 27/42 OF/PCI: Update of_irq_parse_and_map_pci() comment
In reply to Lorenzo PieralisiFrom: Matthew Minter <[email protected]>
With the introduction of struct pci_host_bridge.(*map_irq) function pointer add another direct usage of of_irq_parse_and_map_pci().
Update the function comment to reflect this behaviour.
--- drivers/of/of_pci_irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/of/of_pci_irq.c +2 -1
@@ -113,7 +113,8 @@ EXPORT_SYMBOL_GPL(of_irq_parse_pci);* @pin: PCI irq pin number; passed when used as map_irq callback. Unused * * @slot and @pin are unused, but included in the function so that this -* function can be used directly as the map_irq callback to pci_fixup_irqs(). +* function can be used directly as the map_irq callback to +* pci_assign_irq() and struct pci_host_bridge.map_irq pointer */ int of_irq_parse_and_map_pci (const struct pci_dev *dev,u8 slot,u8 pin) {
Signature · 1 line
2.10.0
PATCH v2 28/42 PCI: Add a call to pci_assign_irq() in pci_device_probe()
In reply to Lorenzo PieralisiFrom: Matthew Minter <[email protected]>
The pci_assign_irq() function allows assignment of an irq to devices during device enable time rather than only at boot. Therefore call it in the pci_device_probe() function during the enable device code path so this assignment can be performed.
This patch will do nothing on arches which do not set the irq mapping function pointers and is therefore currently a nop, however as support for these function pointers is added to arch specific code this will cause irq assignment to migrate to device enable time allowing the new code paths to be used.
--- drivers/pci/pci-driver.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/pci-driver.c +2 -0
@@ -412,6 +412,8 @@ static int pci_device_probe(struct device *dev)struct pci_dev *pci_dev =to_pci_dev (dev);struct pci_driver *drv =to_pci_driver (dev->driver); +pci_assign_irq (pci_dev); + error =pcibios_alloc_irq (pci_dev);if (error <0 )return error;
Signature · 1 line
2.10.0
PATCH v2 29/42 ARM: PCI: Remove pci_fixup_irqs() call for bios32 host controllers
In reply to Lorenzo PieralisiLegacy PCI host controllers (ie host controllers that set-up the PCI bus through the ARM pci_common_init() API) are currently relying on pci_fixup_irqs() to assign legacy PCI irqs to devices. This is not ideal in that pci_fixup_irqs() assign IRQs for all PCI devices present in a given system some of which may well be enabled by the time pci_fixup_irqs() is called (ie a system with multiple host controllers). With the introduction of struct pci_host_bridge.(*map_irq) pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented through pci_assign_irq() that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.
The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devices
Remove pci_fixup_irqs() call from bios32 code and rely on pci_assign_irq() to carry out the IRQ mapping at device probe time.
The map_irq() and swizzle_irq() struct pci_host_bridge callbacks are set-up in the struct pci_host_bridge created in the bios32 pcibios_init_hw() function and mach-* code paths (for PCI mach implementations that require a specific struct hw_pci.(*scan) function callback).
--- arch/arm/kernel/bios32.c | 4 ++-- arch/arm/mach-dove/pcie.c | 18 ++++++++++-------- arch/arm/mach-iop13xx/pci.c | 2 ++ arch/arm/mach-orion5x/pci.c | 28 +++++++++++++++------------- 4 files changed, 29 insertions(+), 23 deletions(-)
arch/arm/kernel/bios32.c +2 -2
@@ -494,6 +494,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, bridge->busnr = sys->busnr; bridge->ops = hw->ops; bridge->msi = hw->msi_ctrl; + bridge->map_irq = pcibios_map_irq; + bridge->swizzle_irq = pcibios_swizzle; bridge->align_resource = hw->align_resource;
@@ -530,8 +532,6 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)if (hw->postinit) hw->postinit (); -pci_fixup_irqs (pcibios_swizzle, pcibios_map_irq); -list_for_each_entry (sys, &head, node) {struct pci_bus *bus = sys->bus;
arch/arm/mach-dove/pcie.c +10 -8
@@ -152,6 +152,14 @@ static void rc_pci_fixup(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_MARVELL ,PCI_ANY_ID , rc_pci_fixup); +static int __init dove_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) +{ +struct pci_sys_data *sys = dev->sysdata; +struct pcie_port *pp = sys->private_data; + +return pp->index ?IRQ_DOVE_PCIE1 :IRQ_DOVE_PCIE0 ; +} +static int __init dove_pcie_scan_bus (int nr,struct pci_host_bridge *bridge) {
@@ -167,18 +175,12 @@ dove_pcie_scan_bus(int nr, struct pci_host_bridge *bridge) bridge->sysdata = sys; bridge->busnr = sys->busnr; bridge->ops = &pcie_ops; + bridge->map_irq = dove_pcie_map_irq; + bridge->swizzle_irq = pci_common_swizzle;return pci_scan_root_bus_bridge (bridge); } -static int __init dove_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pci_sys_data *sys = dev->sysdata; -struct pcie_port *pp = sys->private_data; - -return pp->index ?IRQ_DOVE_PCIE1 :IRQ_DOVE_PCIE0 ; -} -static struct hw_pci dove_pci__initdata = { .nr_controllers =2 , .setup = dove_pcie_setup,
arch/arm/mach-iop13xx/pci.c +2 -0
@@ -532,6 +532,7 @@ int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge) bridge->dev.parent =NULL ; bridge->sysdata = sys; bridge->busnr = sys->busnr; + bridge->swizzle_irq = pci_common_swizzle;switch (which_atu) {case IOP13XX_INIT_ATU_ATUX :
@@ -547,6 +548,7 @@ int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge)break ;case IOP13XX_INIT_ATU_ATUE : bridge->ops = &iop13xx_atue_ops; + bridge->map_irq = iop13xx_pcie_map_irq; ret =pci_scan_root_bus_bridge (bridge);if (!ret) pci_bus_atue = bridge->bus;
arch/arm/mach-orion5x/pci.c +15 -13
@@ -555,6 +555,19 @@ int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)return 0 ; } +int __init orion5x_pci_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) +{ +int bus = dev->bus->number; + +/* +* PCIe endpoint? +*/ +if (orion5x_pci_disabled || bus <orion5x_pci_local_bus_nr ()) +return IRQ_ORION5X_PCIE0_INT ; + +return -1 ; +} +int __init orion5x_pci_sys_scan_bus (int nr,struct pci_host_bridge *bridge) {struct pci_sys_data *sys =pci_host_bridge_priv (bridge);
@@ -563,6 +576,8 @@ int __init orion5x_pci_sys_scan_bus(int nr, struct pci_host_bridge *bridge) bridge->dev.parent =NULL ; bridge->sysdata = sys; bridge->busnr = sys->busnr; + bridge->map_irq = orion5x_pci_map_irq; + bridge->swizzle_irq = pci_common_swizzle;if (nr ==0 ) { bridge->ops = &pcie_ops;
@@ -577,16 +592,3 @@ int __init orion5x_pci_sys_scan_bus(int nr, struct pci_host_bridge *bridge)BUG ();return -ENODEV ; } - -int __init orion5x_pci_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -int bus = dev->bus->number; - -/* -* PCIe endpoint? -*/ -if (orion5x_pci_disabled || bus <orion5x_pci_local_bus_nr ()) -return IRQ_ORION5X_PCIE0_INT ; - -return -1 ; -}
Signature · 1 line
2.10.0
PATCH v2 29/42 ARM: PCI: Remove pci_fixup_irqs() call for bios32 host controllers
Hi Bjorn,
Quoted 32 lines · Lorenzo Pieralisi
Legacy PCI host controllers (ie host controllers that set-up the PCI bus through the ARM
pci_common_init()API) are currently relying onpci_fixup_irqs()to assign legacy PCI irqs to devices. This is not ideal in thatpci_fixup_irqs()assign IRQs for all PCI devices present in a given system some of which may well be enabled by the timepci_fixup_irqs()is called (ie a system with multiple host controllers). With the introduction of struct pci_host_bridge.(*map_irq) pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented throughpci_assign_irq()that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devicesRemove
pci_fixup_irqs()call from bios32 code and rely onpci_assign_irq()to carry out the IRQ mapping at device probe time.The
map_irq()andswizzle_irq()structpci_host_bridgecallbacks are set-up in the structpci_host_bridgecreated in the bios32pcibios_init_hw()function and mach-* code paths (for PCI mach implementations that require a specific struct hw_pci.(*scan) function callback).Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Jason Cooper <[email protected]>Cc Bjorn Helgaas <[email protected]>Cc Russell King <[email protected]>Cc Andrew Lunn <[email protected]>
Quoted 6 lines
--- arch/arm/kernel/bios32.c | 4 ++-- arch/arm/mach-dove/pcie.c | 18 ++++++++++-------- arch/arm/mach-iop13xx/pci.c | 2 ++ arch/arm/mach-orion5x/pci.c | 28 +++++++++++++++------------- 4 files changed, 29 insertions(+), 23 deletions(-)
As I mentioned to you, this patch is incomplete and needs an upgrade (ie I misread how Orion and the gazillions board file that go with it to map irqs - apologies but it is very hard to untangle).
I am inlining below an incremental patch to be folded in commit:
feaec00e757a ("ARM/PCI: Remove pci_fixup_irqs() call for bios32 host controllers")
in your pci/irq-fixups branch, or if you prefer I can send you the resulting squashed-in patch to replace this one, as you prefer.
I understand timing is tight I am doing all I can to fix this series up and make 4.13.
Please let me know how I can help, thank you !
Lorenzo
-- >8 --
arch/arm/kernel/bios32.c +3 -2
@@ -484,6 +484,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,break ; } + bridge->map_irq = pcibios_map_irq; + bridge->swizzle_irq = pcibios_swizzle; +if (hw->scan) ret = hw->scan (nr, bridge);else {
@@ -494,8 +497,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, bridge->busnr = sys->busnr; bridge->ops = hw->ops; bridge->msi = hw->msi_ctrl; - bridge->map_irq = pcibios_map_irq; - bridge->swizzle_irq = pcibios_swizzle; bridge->align_resource = hw->align_resource;
arch/arm/mach-dove/pcie.c +8 -10
@@ -152,14 +152,6 @@ static void rc_pci_fixup(struct pci_dev *dev) }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_MARVELL ,PCI_ANY_ID , rc_pci_fixup); -static int __init dove_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -struct pci_sys_data *sys = dev->sysdata; -struct pcie_port *pp = sys->private_data; - -return pp->index ?IRQ_DOVE_PCIE1 :IRQ_DOVE_PCIE0 ; -} -static int __init dove_pcie_scan_bus (int nr,struct pci_host_bridge *bridge) {
@@ -175,12 +167,18 @@ dove_pcie_scan_bus(int nr, struct pci_host_bridge *bridge) bridge->sysdata = sys; bridge->busnr = sys->busnr; bridge->ops = &pcie_ops; - bridge->map_irq = dove_pcie_map_irq; - bridge->swizzle_irq = pci_common_swizzle;return pci_scan_root_bus_bridge (bridge); } +static int __init dove_pcie_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) +{ +struct pci_sys_data *sys = dev->sysdata; +struct pcie_port *pp = sys->private_data; + +return pp->index ?IRQ_DOVE_PCIE1 :IRQ_DOVE_PCIE0 ; +} +static struct hw_pci dove_pci__initdata = { .nr_controllers =2 , .setup = dove_pcie_setup,
arch/arm/mach-iop13xx/pci.c +0 -2
@@ -532,7 +532,6 @@ int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge) bridge->dev.parent =NULL ; bridge->sysdata = sys; bridge->busnr = sys->busnr; - bridge->swizzle_irq = pci_common_swizzle;switch (which_atu) {case IOP13XX_INIT_ATU_ATUX :
@@ -548,7 +547,6 @@ int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge)break ;case IOP13XX_INIT_ATU_ATUE : bridge->ops = &iop13xx_atue_ops; - bridge->map_irq = iop13xx_pcie_map_irq; ret =pci_scan_root_bus_bridge (bridge);if (!ret) pci_bus_atue = bridge->bus;
arch/arm/mach-orion5x/pci.c +13 -15
@@ -555,19 +555,6 @@ int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)return 0 ; } -int __init orion5x_pci_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) -{ -int bus = dev->bus->number; - -/* -* PCIe endpoint? -*/ -if (orion5x_pci_disabled || bus <orion5x_pci_local_bus_nr ()) -return IRQ_ORION5X_PCIE0_INT ; - -return -1 ; -} -int __init orion5x_pci_sys_scan_bus (int nr,struct pci_host_bridge *bridge) {struct pci_sys_data *sys =pci_host_bridge_priv (bridge);
@@ -576,8 +563,6 @@ int __init orion5x_pci_sys_scan_bus(int nr, struct pci_host_bridge *bridge) bridge->dev.parent =NULL ; bridge->sysdata = sys; bridge->busnr = sys->busnr; - bridge->map_irq = orion5x_pci_map_irq; - bridge->swizzle_irq = pci_common_swizzle;if (nr ==0 ) { bridge->ops = &pcie_ops;
@@ -592,3 +577,16 @@ int __init orion5x_pci_sys_scan_bus(int nr, struct pci_host_bridge *bridge)BUG ();return -ENODEV ; } + +int __init orion5x_pci_map_irq (const struct pci_dev *dev,u8 slot,u8 pin) +{ +int bus = dev->bus->number; + +/* +* PCIe endpoint? +*/ +if (orion5x_pci_disabled || bus <orion5x_pci_local_bus_nr ()) +return IRQ_ORION5X_PCIE0_INT ; + +return -1 ; +}
Signature · 1 line
2.10.0
PATCH v2 29/42 ARM: PCI: Remove pci_fixup_irqs() call for bios32 host controllers
Quoted 46 lines · Lorenzo Pieralisi
Hi Bjorn,
Quoted 32 lines · Lorenzo Pieralisi
Legacy PCI host controllers (ie host controllers that set-up the PCI bus through the ARM
pci_common_init()API) are currently relying onpci_fixup_irqs()to assign legacy PCI irqs to devices. This is not ideal in thatpci_fixup_irqs()assign IRQs for all PCI devices present in a given system some of which may well be enabled by the timepci_fixup_irqs()is called (ie a system with multiple host controllers). With the introduction of struct pci_host_bridge.(*map_irq) pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented throughpci_assign_irq()that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devicesRemove
pci_fixup_irqs()call from bios32 code and rely onpci_assign_irq()to carry out the IRQ mapping at device probe time.The
map_irq()andswizzle_irq()structpci_host_bridgecallbacks are set-up in the structpci_host_bridgecreated in the bios32pcibios_init_hw()function and mach-* code paths (for PCI mach implementations that require a specific struct hw_pci.(*scan) function callback).Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Jason Cooper <[email protected]>Cc Bjorn Helgaas <[email protected]>Cc Russell King <[email protected]>Cc Andrew Lunn <[email protected]>Quoted 6 lines
--- arch/arm/kernel/bios32.c | 4 ++-- arch/arm/mach-dove/pcie.c | 18 ++++++++++-------- arch/arm/mach-iop13xx/pci.c | 2 ++ arch/arm/mach-orion5x/pci.c | 28 +++++++++++++++------------- 4 files changed, 29 insertions(+), 23 deletions(-)As I mentioned to you, this patch is incomplete and needs an upgrade (ie I misread how Orion and the gazillions board file that go with it to map irqs - apologies but it is very hard to untangle).
Quoted 7 lines
I am inlining below an incremental patch to be folded in commit:
feaec00e757a("ARM/PCI: Removepci_fixup_irqs()call for bios32 host controllers")in your pci/irq-fixups branch, or if you prefer I can send you the resulting squashed-in patch to replace this one, as you prefer.
Thanks, I folded this into pci/irq-fixups. The resulting patch is merely this:
commit 16508469c0f3198a63923aaec08efa1c63f5fbcc
Author: Lorenzo Pieralisi <[email protected]> Date: Wed Jun 28 15:14:04 2017 -0500
ARM/PCI: Remove pci_fixup_irqs() call for bios32 host controllers
Legacy PCI host controllers (ie host controllers that set-up the PCI bus through the ARM pci_common_init() API) are currently relying on pci_fixup_irqs() to assign legacy PCI irqs to devices. This is not ideal in that pci_fixup_irqs() assigns IRQs for all PCI devices present in a given system some of which may well be enabled by the time pci_fixup_irqs() is called (ie a system with multiple host controllers). With the introduction of struct pci_host_bridge.(*map_irq) pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented through pci_assign_irq() that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.
The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devices
Remove pci_fixup_irqs() call from bios32 code and rely on pci_assign_irq() to carry out the IRQ mapping at device probe time.
The map_irq() and swizzle_irq() struct pci_host_bridge callbacks are set-up in the struct pci_host_bridge created in the bios32 pcibios_init_hw() function and mach-* code paths (for PCI mach implementations that require a specific struct hw_pci.(*scan) function callback).
[bhelgaas: folded in fixes from Lorenzo:
http://lkml.kernel.org/r/20170701140629.GC8977 at red-moon]
arch/arm/kernel/bios32.c +3 -2
@@ -484,6 +484,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,break ; } + bridge->map_irq = pcibios_map_irq; + bridge->swizzle_irq = pcibios_swizzle; +if (hw->scan) ret = hw->scan (nr, bridge);else {
@@ -530,8 +533,6 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)if (hw->postinit) hw->postinit (); -pci_fixup_irqs (pcibios_swizzle, pcibios_map_irq); -list_for_each_entry (sys, &head, node) {struct pci_bus *bus = sys->bus;
PATCH v2 29/42 ARM: PCI: Remove pci_fixup_irqs() call for bios32 host controllers
Quoted 49 lines · Bjorn Helgaas
Quoted 48 lines · Lorenzo Pieralisi
Hi Bjorn,
Quoted 32 lines · Lorenzo Pieralisi
Legacy PCI host controllers (ie host controllers that set-up the PCI bus through the ARM
pci_common_init()API) are currently relying onpci_fixup_irqs()to assign legacy PCI irqs to devices. This is not ideal in thatpci_fixup_irqs()assign IRQs for all PCI devices present in a given system some of which may well be enabled by the timepci_fixup_irqs()is called (ie a system with multiple host controllers). With the introduction of struct pci_host_bridge.(*map_irq) pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented throughpci_assign_irq()that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devicesRemove
pci_fixup_irqs()call from bios32 code and rely onpci_assign_irq()to carry out the IRQ mapping at device probe time.The
map_irq()andswizzle_irq()structpci_host_bridgecallbacks are set-up in the structpci_host_bridgecreated in the bios32pcibios_init_hw()function and mach-* code paths (for PCI mach implementations that require a specific struct hw_pci.(*scan) function callback).Signed-off-by Lorenzo Pieralisi <[email protected]>Cc Jason Cooper <[email protected]>Cc Bjorn Helgaas <[email protected]>Cc Russell King <[email protected]>Cc Andrew Lunn <[email protected]>Quoted 6 lines
--- arch/arm/kernel/bios32.c | 4 ++-- arch/arm/mach-dove/pcie.c | 18 ++++++++++-------- arch/arm/mach-iop13xx/pci.c | 2 ++ arch/arm/mach-orion5x/pci.c | 28 +++++++++++++++------------- 4 files changed, 29 insertions(+), 23 deletions(-)As I mentioned to you, this patch is incomplete and needs an upgrade (ie I misread how Orion and the gazillions board file that go with it to map irqs - apologies but it is very hard to untangle).
I am inlining below an incremental patch to be folded in commit:
Quoted 8 lines
Quoted 5 lines
feaec00e757a("ARM/PCI: Removepci_fixup_irqs()call for bios32 host controllers")in your pci/irq-fixups branch, or if you prefer I can send you the resulting squashed-in patch to replace this one, as you prefer.
Thanks, I folded this into pci/irq-fixups. The resulting patch is merely this:
Yes that's what I expected, we remove pci_fixup_irqs() and add the hooks into the host bridge structure that should cover all host bridges initialized via pci_common_init_dev().
Thanks !
Lorenzo
Quoted 61 lines
commit
16508469c0f3198a63923aaec08efa1c63f5fbccAuthor: Lorenzo Pieralisi <[email protected]> Date: Wed Jun 28 15:14:04 2017 -0500ARM/PCI: Remove
pci_fixup_irqs()call for bios32 host controllersLegacy PCI host controllers (ie host controllers that set-up the PCI bus through the ARM
pci_common_init()API) are currently relying onpci_fixup_irqs()to assign legacy PCI irqs to devices. This is not ideal in thatpci_fixup_irqs()assigns IRQs for all PCI devices present in a given system some of which may well be enabled by the timepci_fixup_irqs()is called (ie a system with multiple host controllers). With the introduction of struct pci_host_bridge.(*map_irq) pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented throughpci_assign_irq()that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devicesRemove
pci_fixup_irqs()call from bios32 code and rely onpci_assign_irq()to carry out the IRQ mapping at device probe time.The
map_irq()andswizzle_irq()structpci_host_bridgecallbacks are set-up in the structpci_host_bridgecreated in the bios32pcibios_init_hw()function and mach-* code paths (for PCI mach implementations that require a specific struct hw_pci.(*scan) function callback).Signed-off-by Lorenzo Pieralisi <[email protected]>[bhelgaas: folded in fixes from Lorenzo:
http://lkml.kernel.org/r/20170701140629.GC8977 at red-moon]Signed-off-by Bjorn Helgaas <[email protected]>Cc Jason Cooper <[email protected]>Cc Russell King <[email protected]>Cc Andrew Lunn <[email protected]>arch/arm/kernel/bios32.c +3
-2@@ -484,6 +484,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,break ; } + bridge->map_irq = pcibios_map_irq; + bridge->swizzle_irq = pcibios_swizzle; +if (hw->scan) ret = hw->scan (nr, bridge);else {@@ -530,8 +533,6 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)if (hw->postinit) hw->postinit (); -pci_fixup_irqs (pcibios_swizzle, pcibios_map_irq); -list_for_each_entry (sys, &head, node) {struct pci_bus *bus = sys->bus;
PATCH v2 30/42 PCI: tegra: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation
Drop pci_fixup_irqs() usage from PCI tegra host bridge driver.
--- drivers/pci/host/pci-tegra.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pci/host/pci-tegra.c +2 -1
@@ -2284,6 +2284,8 @@ static int tegra_pcie_probe(struct platform_device *pdev) host->busnr = pcie->busn.start; host->dev.parent = &pdev->dev; host->ops = &tegra_pcie_ops; + host->map_irq = tegra_pcie_map_irq; + host->swizzle_irq = pci_common_swizzle; err =pci_scan_root_bus_bridge (host);if (err <0 ) {
@@ -2291,7 +2293,6 @@ static int tegra_pcie_probe(struct platform_device *pdev) goto disable_msi; } -pci_fixup_irqs (pci_common_swizzle, tegra_pcie_map_irq);pci_bus_size_bridges (host->bus);pci_bus_assign_resources (host->bus);
Signature · 1 line
2.10.0
PATCH v2 31/42 PCI: xilinx: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI xilinx host bridge driver.
--- drivers/pci/host/pcie-xilinx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/pci/host/pcie-xilinx.c +2 -3
@@ -680,6 +680,8 @@ static int xilinx_pcie_probe(struct platform_device *pdev) bridge->sysdata = port; bridge->busnr =0 ; bridge->ops = &xilinx_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle;#ifdef CONFIG_PCI_MSI xilinx_pcie_msi_chip.dev = dev;
@@ -692,9 +694,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev) bus = bridge->bus;pci_assign_unassigned_bus_resources (bus); -#ifndef CONFIG_MICROBLAZE -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); -#endif list_for_each_entry (child, &bus->children, node)pcie_bus_configure_settings (child);pci_bus_add_devices (bus);
Signature · 1 line
2.10.0
PATCH v2 32/42 PCI: rcar: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI rcar host bridge driver.
--- drivers/pci/host/pcie-rcar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/host/pcie-rcar.c +2 -2
@@ -465,6 +465,8 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie) bridge->sysdata = pcie; bridge->busnr = pcie->root_bus_nr; bridge->ops = &rcar_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle;if (IS_ENABLED (CONFIG_PCI_MSI )) bridge->msi = &pcie->msi.chip;
@@ -476,8 +478,6 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie) bus = bridge->bus; -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); -pci_bus_size_bridges (bus);pci_bus_assign_resources (bus);
Signature · 1 line
2.10.0
PATCH v2 33/42 PCI: iproc: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI iproc host bridge driver.
--- drivers/pci/host/pcie-iproc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/pci/host/pcie-iproc.c +2 -3
@@ -1324,6 +1324,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) host->dev.parent = dev; host->ops = &iproc_pcie_ops; host->sysdata = sysdata; + host->map_irq = pcie->map_irq; + host->swizzle_irq = pci_common_swizzle; ret =pci_scan_root_bus_bridge (host);if (ret <0 ) {
@@ -1331,9 +1333,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) goto err_power_off_phy; } -if (pcie->map_irq) -pci_fixup_irqs (pci_common_swizzle, pcie->map_irq); -pci_assign_unassigned_bus_resources (host->bus); pcie->root_bus = host->bus;
Signature · 1 line
2.10.0
PATCH v2 34/42 PCI: designware-host: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI designware host bridge driver.
--- drivers/pci/dwc/pcie-designware-host.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/pci/dwc/pcie-designware-host.c +2 -5
@@ -410,6 +410,8 @@ int dw_pcie_host_init(struct pcie_port *pp) bridge->sysdata = pp; bridge->busnr = pp->root_bus_nr; bridge->ops = &dw_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle;if (IS_ENABLED (CONFIG_PCI_MSI )) { bridge->msi = &dw_pcie_msi_chip; dw_pcie_msi_chip.dev = dev;
@@ -424,11 +426,6 @@ int dw_pcie_host_init(struct pcie_port *pp)if (pp->ops->scan_bus) pp->ops->scan_bus (pp); -#ifdef CONFIG_ARM -/* support old dtbs that incorrectly describe IRQs */ -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); -#endif -pci_bus_size_bridges (bus);pci_bus_assign_resources (bus);
Signature · 1 line
2.10.0
PATCH v2 35/42 PCI: ftpci100: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI ftpci100 host bridge driver.
--- drivers/pci/host/pci-ftpci100.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/pci/host/pci-ftpci100.c +2 -1
@@ -449,6 +449,8 @@ static int faraday_pci_probe(struct platform_device *pdev) host->ops = &faraday_pci_ops; host->busnr =0 ; host->msi =NULL ; + host->map_irq = of_irq_parse_and_map_pci; + host->swizzle_irq = pci_common_swizzle; p =pci_host_bridge_priv (host); host->sysdata = p; p->dev = dev;
@@ -527,7 +529,6 @@ static int faraday_pci_probe(struct platform_device *pdev) } p->bus = host->bus; -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci);pci_bus_assign_resources (p->bus);pci_bus_add_devices (p->bus);pci_free_resource_list (&res);
Signature · 1 line
2.10.0
PATCH v2 36/42 PCI: host-common: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI host-common bridge driver.
--- drivers/pci/host/pci-host-common.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/pci/host/pci-host-common.c +2 -4
@@ -149,6 +149,8 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->sysdata = cfg; bridge->busnr = cfg->busr.start; bridge->ops = &ops->pci_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle; ret =pci_scan_root_bus_bridge (bridge);if (ret <0 ) {
@@ -158,10 +160,6 @@ int pci_host_common_probe(struct platform_device *pdev, bus = bridge->bus; -#ifdef CONFIG_ARM -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); -#endif -/* * We insert PCI resources into the iomem_resource and * ioport_resource trees in either pci_bus_claim_resources()
Signature · 1 line
2.10.0
PATCH v2 37/42 PCI: versatile: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI versatile host bridge driver.
--- drivers/pci/host/pci-versatile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/host/pci-versatile.c +2 -2
@@ -209,6 +209,8 @@ static int versatile_pci_probe(struct platform_device *pdev) bridge->sysdata =NULL ; bridge->busnr =0 ; bridge->ops = &pci_versatile_ops; + host->map_irq = of_irq_parse_and_map_pci; + host->swizzle_irq = pci_common_swizzle; ret =pci_scan_root_bus_bridge (bridge);if (ret <0 )
@@ -216,8 +218,6 @@ static int versatile_pci_probe(struct platform_device *pdev) bus = bridge->bus; -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); -pci_assign_unassigned_bus_resources (bus);list_for_each_entry (child, &bus->children, node)pcie_bus_configure_settings (child);
Signature · 1 line
2.10.0
PATCH v2 38/42 PCI: altera: Drop pci_fixup_irqs()
In reply to Lorenzo PieralisiSince, through struct pci_host_bridge.map/swizzle_irq hooks, IRQs are now allocated in the pci_assign_irq() callback automatically, PCI host bridge drivers can stop relying on pci_fixup_irqs() for IRQ allocation.
Drop pci_fixup_irqs() usage from PCI altera host bridge driver.
--- drivers/pci/host/pcie-altera.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/host/pcie-altera.c +2 -2
@@ -620,6 +620,8 @@ static int altera_pcie_probe(struct platform_device *pdev) bridge->sysdata = pcie; bridge->busnr = pcie->root_bus_nr; bridge->ops = &altera_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle; ret =pci_scan_root_bus_bridge (bridge);if (ret <0 )
@@ -627,8 +629,6 @@ static int altera_pcie_probe(struct platform_device *pdev) bus = bridge->bus; -pci_fixup_irqs (pci_common_swizzle, of_irq_parse_and_map_pci); -pci_assign_unassigned_bus_resources (bus);/* Configure PCI Express setting. */
Signature · 1 line
2.10.0
PATCH v2 39/42 PCI: xgene: Move to struct pci_host_bridge IRQ mapping functions
In reply to Lorenzo Pieralisistruct pci_host_bridge gained hooks to map/swizzle IRQs, so that the IRQ mapping can be done automatically by PCI core code through the pci_assign_irq() function instead of resorting to per-arch specific implementation callbacks to carry out the same task which force PCI host bridge drivers implementation to implement per-arch kludges to carry out a task that is inherently architecture agnostic.
Add map/swizzle IRQs hooks to the xgene PCI host driver to move the IRQ allocation into core code and stop relying on arch specific callbacks.
--- drivers/pci/host/pci-xgene.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/host/pci-xgene.c +2 -0
@@ -678,6 +678,8 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev) bridge->sysdata = port; bridge->busnr =0 ; bridge->ops = &xgene_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle; ret =pci_scan_root_bus_bridge (bridge);if (ret <0 )
Signature · 1 line
2.10.0
PATCH v2 40/42 PCI: rockchip: Move to struct pci_host_bridge IRQ mapping functions
In reply to Lorenzo Pieralisistruct pci_host_bridge gained hooks to map/swizzle IRQs, so that the IRQ mapping can be done automatically by PCI core code through the pci_assign_irq() function instead of resorting to per-arch specific implementation callbacks to carry out the same task which force PCI host bridge drivers implementation to implement per-arch kludges to carry out a task that is inherently architecture agnostic.
Add map/swizzle IRQs hooks to the rockchip PCI host driver to move the IRQ allocation into core code and stop relying on arch specific callbacks.
--- drivers/pci/host/pcie-rockchip.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/host/pcie-rockchip.c +2 -0
@@ -1404,6 +1404,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev) bridge->sysdata = rockchip; bridge->busnr =0 ; bridge->ops = &rockchip_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle; err =pci_scan_root_bus_bridge (bridge);if (!err)
Signature · 1 line
2.10.0
PATCH v2 41/42 PCI: xilinx-nwl: Move to struct pci_host_bridge IRQ mapping functions
In reply to Lorenzo Pieralisistruct pci_host_bridge gained hooks to map/swizzle IRQs, so that the IRQ mapping can be done automatically by PCI core code through the pci_assign_irq() function instead of resorting to per-arch specific implementation callbacks to carry out the same task which force PCI host bridge drivers implementation to implement per-arch kludges to carry out a task that is inherently architecture agnostic.
Add map/swizzle IRQs hooks to the xilinx-nwl PCI host driver to move the IRQ allocation into core code and stop relying on arch specific callbacks.
--- drivers/pci/host/pcie-xilinx-nwl.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/host/pcie-xilinx-nwl.c +2 -0
@@ -838,6 +838,8 @@ static int nwl_pcie_probe(struct platform_device *pdev) bridge->sysdata = pcie; bridge->busnr = pcie->root_busno; bridge->ops = &nwl_pcie_ops; + bridge->map_irq = of_irq_parse_and_map_pci; + bridge->swizzle_irq = pci_common_swizzle;if (IS_ENABLED (CONFIG_PCI_MSI )) { err =nwl_pcie_enable_msi (pcie);
Signature · 1 line
2.10.0
PATCH v2 42/42 ARM64: PCI: Drop DT IRQ allocation from pcibios_alloc_irq()
In reply to Lorenzo PieralisiWith the introduction of struct pci_host_bridge.map_irq pointer it is possible to assign IRQs for all devices originating from a PCI host bridge at probe time; this is implemented through pci_assign_irq() that relies on the struct pci_host_bridge.map_irq pointer to map IRQ for a given device.
The benefits this brings are twofold:
- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devices
With all DT based PCI host bridges converted to the struct pci_host_bridge.{map/swizzle}_irq hooks mechanism the DT IRQ allocation in ARM64 pcibios_alloc_irq() is now redundant and can be removed.
--- arch/arm64/kernel/pci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
arch/arm64/kernel/pci.c +4 -6
@@ -39,20 +39,18 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,return res->start; } +#ifdef CONFIG_ACPI /* * Try to assign the IRQ number when probing a new device */ int pcibios_alloc_irq (struct pci_dev *dev) { -if (acpi_disabled) - dev->irq =of_irq_parse_and_map_pci (dev,0 ,0 ); -#ifdef CONFIG_ACPI - else - return acpi_pci_irq_enable(dev); -#endif +if (!acpi_disabled) +acpi_pci_irq_enable (dev);return 0 ; } +#endif /* * raw_pci_read/write - Platform-specific PCI config space access.
Signature · 1 line
2.10.0
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
In reply to Lorenzo PieralisiQuoted 10 lines · Lorenzo Pieralisi
v1 -> v2
- Split
pci_fixup_irqs()removal in several patches
- Embeddedpci_register_host_bridge()inpci_scan_root_bus_bridge()
- Refactored iproc, faraday and xilinx-nwl host bridges in preparation for irq fixup removal
- Converted all DT PCI host bridge drivers topci_scan_root_bus_bridge()
- Dropped RFC tag
- Addeddevm_pci_alloc_host_bridge()interface
- Rebased against v4.12-rc3
For the arm64 and the host-common bits:
Will
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Quoted 12 lines · Will Deacon
Quoted 10 lines · Lorenzo Pieralisi
v1 -> v2
- Split
pci_fixup_irqs()removal in several patches
- Embeddedpci_register_host_bridge()inpci_scan_root_bus_bridge()
- Refactored iproc, faraday and xilinx-nwl host bridges in preparation for irq fixup removal
- Converted all DT PCI host bridge drivers topci_scan_root_bus_bridge()
- Dropped RFC tag
- Addeddevm_pci_alloc_host_bridge()interface
- Rebased against v4.12-rc3
Quoted 3 lines
For the arm64 and the host-common bits:
Acked-by Will Deacon <[email protected]>
Thank you !
Lorenzo
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
In reply to Lorenzo PieralisiHi Lorenzo,
I tested the patchset on X-Gene boards. It works fine with e1000e.
Best regards,
Khuong Dinh
Quoted 128 lines · Lorenzo Pieralisi
v1 -> v2
- Split
pci_fixup_irqs()removal in several patches
- Embeddedpci_register_host_bridge()inpci_scan_root_bus_bridge()
- Refactored iproc, faraday and xilinx-nwl host bridges in preparation for irq fixup removal
- Converted all DT PCI host bridge drivers topci_scan_root_bus_bridge()
- Dropped RFC tag
- Addeddevm_pci_alloc_host_bridge()interface
- Rebased against v4.12-rc3v1: http://marc.info/?l=linux-pci&m=149320545522205&w=2
Current
pci_fixup_irqs()usage on ARM/ARM64 host controller drivers is flawed in thatpci_fixup_irqs()allocates IRQs for all PCI devices present in a system; those PCI devices possibly belong to different PCI bus trees (and possibly rooted at different host bridges) and may well be enabled (ie probed and bound to a driver) by the timepci_fixup_irqs()is called when probing a given host bridge driver.Furthermore, current kernel code relying on
pci_fixup_irqs()to assign legacy PCI IRQs to devices does not work at all for hotplugged devices in that the code carrying out the IRQ fixup is called at host bridge driver probe time, which just cannot take into account devices hotplugged after system has booted.By leveraging Matthew Minter's patch series (and its purpose):
http://lkml.kernel.org/r/1445576642-29624-2-git-send-email-matt at masarand.com
this series[1] adds IRQs mapping and swizzling primitives to the struct
pci_host_bridgewhich allows IRQs to be allocated for for a device at probe time with host bridge specific functions, fixing the aforementioned limitations.Current series remove
pci_fixup_irqs()usage on ARM/ARM64; removal can be extended to other architectures provided the IRQs map/swizzle functions are set-up properly in the respective host bridges set-up/probe paths.Tested on kvmtool with PCI host generic.
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Lorenzo Pieralisi (37):
PCI: xilinx-nwl: Removenwl_pcie_enable_msi()unused bus parameter
drivers: pci: host: iproc: Convert link check to raw PCI config
accessors
drivers: pci: host: ftpci100: convert IRQ masking to raw PCI config
accessors
PCI: Initialize bridge release function at bridge allocation
PCI: Addpci_free_host_bridgeinterface
PCI: Adddevm_pci_alloc_host_bridge()interface
drivers: pci: host: ftpci100: Fix host bridge memory leakage
drivers: pci: host: tegra: Fix host bridge memory leakage
PCI: Introducepci_scan_root_bus_bridge()
PCI: Makepci_register_host_bridge()PCI core internal
ARM: PCI: bios32: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: designware: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: aardvark: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: rcar: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: iproc: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: versatile: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: altera: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xilinx: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xgene: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: host-common: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: rockchip: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xilinx-nwl: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: Removepci_scan_root_bus_msi()
ARM: PCI: Removepci_fixup_irqs()call for bios32 host controllers
PCI: tegra: Droppci_fixup_irqs()
PCI: xilinx: Droppci_fixup_irqs()
PCI: rcar: Droppci_fixup_irqs()
PCI: iproc: Droppci_fixup_irqs()
PCI: designware-host: Droppci_fixup_irqs()
PCI: ftpci100: Droppci_fixup_irqs()
PCI: host-common: Droppci_fixup_irqs()
PCI: versatile: Droppci_fixup_irqs()
PCI: altera: Droppci_fixup_irqs()
PCI: xgene: Move to structpci_host_bridgeIRQ mapping functions
PCI: rockchip: Move to structpci_host_bridgeIRQ mapping functions
PCI: xilinx-nwl: Move to structpci_host_bridgeIRQ mapping functions
ARM64: PCI: Drop DT IRQ allocation frompcibios_alloc_irq()Matthew Minter (5):
PCI: Build setup-irq.o on all arches
PCI: Add IRQ mapping function pointers topci_host_bridgestruct
PCI: Addpci_assign_irq()function and havepci_fixup_irqs()use it OF/PCI: Updateof_irq_parse_and_map_pci()comment
PCI: Add a call topci_assign_irq()inpci_device_probe()Documentation/driver-model/devres.txt | 1 + arch/arm/include/asm/mach/pci.h | 3 +- arch/arm/kernel/bios32.c | 43 +++++++---- arch/arm/mach-dove/pcie.c | 33 +++++--- arch/arm/mach-iop13xx/pci.c | 31 +++++--- arch/arm/mach-iop13xx/pci.h | 3 +- arch/arm/mach-mv78xx0/pcie.c | 8 +- arch/arm/mach-orion5x/common.h | 3 +- arch/arm/mach-orion5x/pci.c | 39 ++++++---- arch/arm64/kernel/pci.c | 10 +-- drivers/of/of_pci_irq.c | 3 +- drivers/pci/Makefile | 17 +---- drivers/pci/dwc/pcie-designware-host.c | 43 ++++++----- drivers/pci/host/pci-aardvark.c | 21 +++-- drivers/pci/host/pci-ftpci100.c | 50 +++++++----- drivers/pci/host/pci-host-common.c | 27 +++++-- drivers/pci/host/pci-tegra.c | 9 +-- drivers/pci/host/pci-versatile.c | 22 +++++- drivers/pci/host/pci-xgene.c | 23 ++++-- drivers/pci/host/pcie-altera.c | 24 ++++-- drivers/pci/host/pcie-iproc-bcma.c | 7 +- drivers/pci/host/pcie-iproc-platform.c | 7 +- drivers/pci/host/pcie-iproc.c | 135 +++++++++++++++++++++++---------- drivers/pci/host/pcie-rcar.c | 40 ++++++---- drivers/pci/host/pcie-rockchip.c | 24 ++++-- drivers/pci/host/pcie-xilinx-nwl.c | 34 ++++++--- drivers/pci/host/pcie-xilinx.c | 34 +++++---- drivers/pci/pci-driver.c | 2 + drivers/pci/probe.c | 105 ++++++++++++++++++------- drivers/pci/setup-irq.c | 45 ++++++++--- include/linux/pci.h | 12 +-- 31 files changed, 565 insertions(+), 293 deletions(-)--
2.10.0
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
In reply to Lorenzo PieralisiQuoted 116 lines · Lorenzo Pieralisi
v1 -> v2
- Split
pci_fixup_irqs()removal in several patches
- Embeddedpci_register_host_bridge()inpci_scan_root_bus_bridge()
- Refactored iproc, faraday and xilinx-nwl host bridges in preparation for irq fixup removal
- Converted all DT PCI host bridge drivers topci_scan_root_bus_bridge()
- Dropped RFC tag
- Addeddevm_pci_alloc_host_bridge()interface
- Rebased against v4.12-rc3v1: http://marc.info/?l=linux-pci&m=149320545522205&w=2
Current
pci_fixup_irqs()usage on ARM/ARM64 host controller drivers is flawed in thatpci_fixup_irqs()allocates IRQs for all PCI devices present in a system; those PCI devices possibly belong to different PCI bus trees (and possibly rooted at different host bridges) and may well be enabled (ie probed and bound to a driver) by the timepci_fixup_irqs()is called when probing a given host bridge driver.Furthermore, current kernel code relying on
pci_fixup_irqs()to assign legacy PCI IRQs to devices does not work at all for hotplugged devices in that the code carrying out the IRQ fixup is called at host bridge driver probe time, which just cannot take into account devices hotplugged after system has booted.By leveraging Matthew Minter's patch series (and its purpose):
http://lkml.kernel.org/r/1445576642-29624-2-git-send-email-matt at masarand.com
this series[1] adds IRQs mapping and swizzling primitives to the struct
pci_host_bridgewhich allows IRQs to be allocated for for a device at probe time with host bridge specific functions, fixing the aforementioned limitations.Current series remove
pci_fixup_irqs()usage on ARM/ARM64; removal can be extended to other architectures provided the IRQs map/swizzle functions are set-up properly in the respective host bridges set-up/probe paths.Tested on kvmtool with PCI host generic.
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Lorenzo Pieralisi (37):
PCI: xilinx-nwl: Removenwl_pcie_enable_msi()unused bus parameter
drivers: pci: host: iproc: Convert link check to raw PCI config
accessors
drivers: pci: host: ftpci100: convert IRQ masking to raw PCI config
accessors
PCI: Initialize bridge release function at bridge allocation
PCI: Addpci_free_host_bridgeinterface
PCI: Adddevm_pci_alloc_host_bridge()interface
drivers: pci: host: ftpci100: Fix host bridge memory leakage
drivers: pci: host: tegra: Fix host bridge memory leakage
PCI: Introducepci_scan_root_bus_bridge()
PCI: Makepci_register_host_bridge()PCI core internal
ARM: PCI: bios32: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: designware: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: aardvark: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: rcar: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: iproc: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: versatile: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: altera: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xilinx: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xgene: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: host-common: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: rockchip: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xilinx-nwl: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: Removepci_scan_root_bus_msi()
ARM: PCI: Removepci_fixup_irqs()call for bios32 host controllers
PCI: tegra: Droppci_fixup_irqs()
PCI: xilinx: Droppci_fixup_irqs()
PCI: rcar: Droppci_fixup_irqs()
PCI: iproc: Droppci_fixup_irqs()
PCI: designware-host: Droppci_fixup_irqs()
PCI: ftpci100: Droppci_fixup_irqs()
PCI: host-common: Droppci_fixup_irqs()
PCI: versatile: Droppci_fixup_irqs()
PCI: altera: Droppci_fixup_irqs()
PCI: xgene: Move to structpci_host_bridgeIRQ mapping functions
PCI: rockchip: Move to structpci_host_bridgeIRQ mapping functions
PCI: xilinx-nwl: Move to structpci_host_bridgeIRQ mapping functions
ARM64: PCI: Drop DT IRQ allocation frompcibios_alloc_irq()Matthew Minter (5):
PCI: Build setup-irq.o on all arches
PCI: Add IRQ mapping function pointers topci_host_bridgestruct
PCI: Addpci_assign_irq()function and havepci_fixup_irqs()use it OF/PCI: Updateof_irq_parse_and_map_pci()comment
PCI: Add a call topci_assign_irq()inpci_device_probe()Documentation/driver-model/devres.txt | 1 + arch/arm/include/asm/mach/pci.h | 3 +- arch/arm/kernel/bios32.c | 43 +++++++---- arch/arm/mach-dove/pcie.c | 33 +++++--- arch/arm/mach-iop13xx/pci.c | 31 +++++--- arch/arm/mach-iop13xx/pci.h | 3 +- arch/arm/mach-mv78xx0/pcie.c | 8 +- arch/arm/mach-orion5x/common.h | 3 +- arch/arm/mach-orion5x/pci.c | 39 ++++++---- arch/arm64/kernel/pci.c | 10 +-- drivers/of/of_pci_irq.c | 3 +- drivers/pci/Makefile | 17 +---- drivers/pci/dwc/pcie-designware-host.c | 43 ++++++----- drivers/pci/host/pci-aardvark.c | 21 +++-- drivers/pci/host/pci-ftpci100.c | 50 +++++++----- drivers/pci/host/pci-host-common.c | 27 +++++-- drivers/pci/host/pci-tegra.c | 9 +-- drivers/pci/host/pci-versatile.c | 22 +++++- drivers/pci/host/pci-xgene.c | 23 ++++-- drivers/pci/host/pcie-altera.c | 24 ++++-- drivers/pci/host/pcie-iproc-bcma.c | 7 +- drivers/pci/host/pcie-iproc-platform.c | 7 +- drivers/pci/host/pcie-iproc.c | 135 +++++++++++++++++++++++---------- drivers/pci/host/pcie-rcar.c | 40 ++++++----
Quoted 8 lines
drivers/pci/host/pcie-rockchip.c | 24 ++++-- drivers/pci/host/pcie-xilinx-nwl.c | 34 ++++++--- drivers/pci/host/pcie-xilinx.c | 34 +++++---- drivers/pci/pci-driver.c | 2 + drivers/pci/probe.c | 105 ++++++++++++++++++------- drivers/pci/setup-irq.c | 45 ++++++++--- include/linux/pci.h | 12 +-- 31 files changed, 565 insertions(+), 293 deletions(-)
This is awesome! I put these on pci/enumeration with the acks received so far. I hope we can merge these for v4.13, so please take a look at your drivers and test if possible.
Bjorn
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Quoted 126 lines · Bjorn Helgaas
Quoted 116 lines · Lorenzo Pieralisi
v1 -> v2
- Split
pci_fixup_irqs()removal in several patches
- Embeddedpci_register_host_bridge()inpci_scan_root_bus_bridge()
- Refactored iproc, faraday and xilinx-nwl host bridges in preparation for irq fixup removal
- Converted all DT PCI host bridge drivers topci_scan_root_bus_bridge()
- Dropped RFC tag
- Addeddevm_pci_alloc_host_bridge()interface
- Rebased against v4.12-rc3v1: http://marc.info/?l=linux-pci&m=149320545522205&w=2
Current
pci_fixup_irqs()usage on ARM/ARM64 host controller drivers is flawed in thatpci_fixup_irqs()allocates IRQs for all PCI devices present in a system; those PCI devices possibly belong to different PCI bus trees (and possibly rooted at different host bridges) and may well be enabled (ie probed and bound to a driver) by the timepci_fixup_irqs()is called when probing a given host bridge driver.Furthermore, current kernel code relying on
pci_fixup_irqs()to assign legacy PCI IRQs to devices does not work at all for hotplugged devices in that the code carrying out the IRQ fixup is called at host bridge driver probe time, which just cannot take into account devices hotplugged after system has booted.By leveraging Matthew Minter's patch series (and its purpose):
http://lkml.kernel.org/r/1445576642-29624-2-git-send-email-matt at masarand.com
this series[1] adds IRQs mapping and swizzling primitives to the struct
pci_host_bridgewhich allows IRQs to be allocated for for a device at probe time with host bridge specific functions, fixing the aforementioned limitations.Current series remove
pci_fixup_irqs()usage on ARM/ARM64; removal can be extended to other architectures provided the IRQs map/swizzle functions are set-up properly in the respective host bridges set-up/probe paths.Tested on kvmtool with PCI host generic.
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2Lorenzo Pieralisi (37):
PCI: xilinx-nwl: Removenwl_pcie_enable_msi()unused bus parameter
drivers: pci: host: iproc: Convert link check to raw PCI config
accessors
drivers: pci: host: ftpci100: convert IRQ masking to raw PCI config
accessors
PCI: Initialize bridge release function at bridge allocation
PCI: Addpci_free_host_bridgeinterface
PCI: Adddevm_pci_alloc_host_bridge()interface
drivers: pci: host: ftpci100: Fix host bridge memory leakage
drivers: pci: host: tegra: Fix host bridge memory leakage
PCI: Introducepci_scan_root_bus_bridge()
PCI: Makepci_register_host_bridge()PCI core internal
ARM: PCI: bios32: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: designware: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: aardvark: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: rcar: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: iproc: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: versatile: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: altera: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xilinx: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xgene: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: host-common: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: rockchip: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: xilinx-nwl: Convert PCI scan API topci_scan_root_bus_bridge()
PCI: Removepci_scan_root_bus_msi()
ARM: PCI: Removepci_fixup_irqs()call for bios32 host controllers
PCI: tegra: Droppci_fixup_irqs()
PCI: xilinx: Droppci_fixup_irqs()
PCI: rcar: Droppci_fixup_irqs()
PCI: iproc: Droppci_fixup_irqs()
PCI: designware-host: Droppci_fixup_irqs()
PCI: ftpci100: Droppci_fixup_irqs()
PCI: host-common: Droppci_fixup_irqs()
PCI: versatile: Droppci_fixup_irqs()
PCI: altera: Droppci_fixup_irqs()
PCI: xgene: Move to structpci_host_bridgeIRQ mapping functions
PCI: rockchip: Move to structpci_host_bridgeIRQ mapping functions
PCI: xilinx-nwl: Move to structpci_host_bridgeIRQ mapping functions
ARM64: PCI: Drop DT IRQ allocation frompcibios_alloc_irq()Matthew Minter (5):
PCI: Build setup-irq.o on all arches
PCI: Add IRQ mapping function pointers topci_host_bridgestruct
PCI: Addpci_assign_irq()function and havepci_fixup_irqs()use it OF/PCI: Updateof_irq_parse_and_map_pci()comment
PCI: Add a call topci_assign_irq()inpci_device_probe()Documentation/driver-model/devres.txt | 1 + arch/arm/include/asm/mach/pci.h | 3 +- arch/arm/kernel/bios32.c | 43 +++++++---- arch/arm/mach-dove/pcie.c | 33 +++++--- arch/arm/mach-iop13xx/pci.c | 31 +++++--- arch/arm/mach-iop13xx/pci.h | 3 +- arch/arm/mach-mv78xx0/pcie.c | 8 +- arch/arm/mach-orion5x/common.h | 3 +- arch/arm/mach-orion5x/pci.c | 39 ++++++---- arch/arm64/kernel/pci.c | 10 +-- drivers/of/of_pci_irq.c | 3 +- drivers/pci/Makefile | 17 +---- drivers/pci/dwc/pcie-designware-host.c | 43 ++++++----- drivers/pci/host/pci-aardvark.c | 21 +++-- drivers/pci/host/pci-ftpci100.c | 50 +++++++----- drivers/pci/host/pci-host-common.c | 27 +++++-- drivers/pci/host/pci-tegra.c | 9 +-- drivers/pci/host/pci-versatile.c | 22 +++++- drivers/pci/host/pci-xgene.c | 23 ++++-- drivers/pci/host/pcie-altera.c | 24 ++++-- drivers/pci/host/pcie-iproc-bcma.c | 7 +- drivers/pci/host/pcie-iproc-platform.c | 7 +- drivers/pci/host/pcie-iproc.c | 135 +++++++++++++++++++++++---------- drivers/pci/host/pcie-rcar.c | 40 ++++++----Quoted 8 lines
drivers/pci/host/pcie-rockchip.c | 24 ++++-- drivers/pci/host/pcie-xilinx-nwl.c | 34 ++++++--- drivers/pci/host/pcie-xilinx.c | 34 +++++---- drivers/pci/pci-driver.c | 2 + drivers/pci/probe.c | 105 ++++++++++++++++++------- drivers/pci/setup-irq.c | 45 ++++++++--- include/linux/pci.h | 12 +-- 31 files changed, 565 insertions(+), 293 deletions(-)
Quoted 3 lines
This is awesome! I put these on pci/enumeration with the acks received so far. I hope we can merge these for v4.13, so please take a look at your drivers and test if possible.
Thank you very much Bjorn. Yes it would help me a lot if CC'ed people can help me test it (and also Matt's patch [PATCH 26] reworked pci_fixup_irqs() on top of struct pci_host_bridge hooks so even if they should not be affected all arches other than ARM/ARM64 should be tested too - I have not extended the CC list since it is huge already).
Thanks !
Lorenzo
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
In reply to Lorenzo PieralisiOn Thu, Jun 8, 2017 at 4:13 PM, Lorenzo Pieralisi
<[email protected]> wrote:
I pulled this into the Gemini tree:
Quoted 1 line
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2
And then this happens:
OF: PCI: host bridge /soc/pci at 50000000 ranges:
OF: PCI: IO 0x50000000..0x500fffff -> 0x00000000
OF: PCI: MEM 0x58000000..0x5fffffff -> 0x58000000
Unable to handle kernel NULL pointer dereference at virtual address 00000070 pgd = c0004000 [00000070] *pgd=00000000 Internal error: Oops: 17 [#1] PREEMPT ARM CPU: 0 PID: 254 Comm: kworker/0:1 Not tainted 4.12.0-rc3+ #888 Hardware name: Gemini (Device Tree) Workqueue: events deferred_probe_work_func task: c38c3a40 task.stack: c390a000 PC is at faraday_pci_probe+0x274/0x65c LR is at __irq_put_desc_unlock+0x18/0x70 pc : [<c0232648>] lr : [<c004be48>] psr: 80000013
sp : c390bdf0 ip : c3424274 fp : c3ac2ee0
r10: c3f77718 r9 : c3ad49b0 r8 : c3907800
r7 : 00000004 r6 : c390be18 r5 : c3907810 r4 : c3ad4810 r3 : 00000000 r2 : 00000000 r1 : 00000001 r0 : c3ac2de0
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 0000397f Table: 03a9c000 DAC: 00000053 Process kworker/0:1 (pid: 254, stack limit = 0xc390a190)
Stack: (0xc390bdf0 to 0xc390c000)
bde0: c0534a60 c3ad49b0 00000003 c024cb68
be00: 00000001 20000013 00000000 50000000 00000007 000020dd c3ae2680 c3ae2740
be20: c07c861f c0134328 00000000 c3ad5fa0 c3910a50 c3910a50 00000001 00000000
be40: 00000000 c01344ec c3910a50 c3910a50 00000001 00000000 c3910a50 c39d76e0
be60: c3ad5fa0 c05f6f58 c3910a50 c3907810 c3907810 c07cba88 fffffdfb 00000003
be80: 00000000 c07c5040 c386e420 c02bbbe0 c3907810 c081c6c4 00000000 c07cba88
bea0: 00000003 c02ba9dc 00000000 c390bee0 c02bab30 00000001 c07bf660 00000000
bec0: c07c5040 c02b93dc c382829c c39886f4 c3907810 c3907844 c3907810 c02ba674
bee0: c3907810 00000001 c390bf0c c3907810 c07d3a80 c3907810 c07d38e4 c02b961c
bf00: c3907810 c07d38d0 c07d38d0 c02ba210 c07d38ec c386e420 00000000 c3f6b100
bf20: c07bf660 c002dac0 00000008 c07bf660 c07bf660 c386e438 c390a000 c07bf674
bf40: 00000008 c07bf660 c07c5040 c002e044 c390a000 00000001 00000000 00000000
bf60: c3901518 c3901500 ffffe000 c38e2700 00000000 c3901518 c386e420 c002ddb4
bf80: c3839ee4 c00335ec c390a000 c38e2700 c003350c 00000000 00000000 00000000
bfa0: 00000000 00000000 00000000 c000a270 00000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff [<c0232648>] (faraday_pci_probe) from [<c02bbbe0>] (platform_drv_probe+0x50/0xb4)
[<c02bbbe0>] (platform_drv_probe) from [<c02ba9dc>] (driver_probe_device+0x248/0x2dc)
[<c02ba9dc>] (driver_probe_device) from [<c02b93dc>] (bus_for_each_drv+0x68/0x98)
[<c02b93dc>] (bus_for_each_drv) from [<c02ba674>] (__device_attach+0xa8/0x110) [<c02ba674>] (__device_attach) from [<c02b961c>] (bus_probe_device+0x88/0x90) [<c02b961c>] (bus_probe_device) from [<c02ba210>] (deferred_probe_work_func+0x54/0x80)
[<c02ba210>] (deferred_probe_work_func) from [<c002dac0>] (process_one_work+0x13c/0x430)
[<c002dac0>] (process_one_work) from [<c002e044>] (worker_thread+0x290/0x5f4) [<c002e044>] (worker_thread) from [<c00335ec>] (kthread+0xe0/0x120) [<c00335ec>] (kthread) from [<c000a270>] (ret_from_fork+0x14/0x24)
Code: e59401b0 e3700a01 8a00001d e59421ac (e5d23070) ---[ end trace 1e313b1ea11e101c ]---
I'm trying to figure out what is causing it.
Yours,
Linus Walleij
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Quoted 6 lines · Linus Walleij
On Thu, Jun 8, 2017 at 4:13 PM, Lorenzo Pieralisi
<[email protected]> wrote:I pulled this into the Gemini tree:
Quoted 1 line
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2
Thank you Linus for helping me out.
Quoted 5 lines
And then this happens:
OF: PCI: host bridge /soc/pci at 50000000 ranges:
OF: PCI: IO 0x50000000..0x500fffff ->0x00000000
OF: PCI: MEM 0x58000000..0x5fffffff ->0x58000000
Quoted 11 lines
Unable to handle kernel NULL pointer dereference at virtual address 00000070 pgd = c0004000 [00000070] *pgd=00000000 Internal error: Oops: 17 [#1] PREEMPT ARM CPU: 0 PID: 254 Comm: kworker/0:1 Not tainted 4.12.0-rc3+ #888 Hardware name: Gemini (Device Tree) Workqueue: events deferred_probe_work_func task: c38c3a40 task.stack: c390a000 PC is at faraday_pci_probe+0x274/0x65c LR is at __irq_put_desc_unlock+0x18/0x70 pc : [<c0232648>] lr : [<c004be48>] psr: 80000013
I think I see what it is. faraday_pci_irq_handler() relies on struct faraday_pci->bus to access config space and with this series it can't be set till pci_scan_root_bus_bridge() returns.
If that's the case we will have to update the config accessors in faraday_pci_irq_handler() to raw ones (ie ones that do not depend on the struct pci_bus), code is already there, patch coming, sorry about this but it is extremely complicated for me to untangle these drivers inner workings.
Thanks,
Lorenzo
Quoted 47 lines
sp :
c390bdf0ip :c3424274fp :c3ac2ee0
r10:c3f77718r9 :c3ad49b0r8 :c3907800
r7 : 00000004 r6 :c390be18r5 :c3907810r4 :c3ad4810r3 : 00000000 r2 : 00000000 r1 : 00000001 r0 :c3ac2de0
Flags: Nzcv IRQs on FIQs on ModeSVC_32ISA ARM Segment none
Control:0000397fTable:03a9c000DAC: 00000053 Process kworker/0:1 (pid: 254, stack limit =0xc390a190)Stack: (0xc390bdf0 to 0xc390c000)bde0:
c0534a60c3ad49b000000003c024cb68
be00: 00000001 20000013 00000000 50000000 00000007000020ddc3ae2680c3ae2740
be20:c07c861fc013432800000000c3ad5fa0c3910a50c3910a5000000001 00000000
be40: 00000000c01344ecc3910a50c3910a5000000001 00000000c3910a50c39d76e0
be60:c3ad5fa0c05f6f58c3910a50c3907810c3907810c07cba88fffffdfb 00000003
be80: 00000000c07c5040c386e420c02bbbe0c3907810c081c6c400000000c07cba88
bea0: 00000003c02ba9dc00000000c390bee0c02bab3000000001c07bf66000000000
bec0:c07c5040c02b93dcc382829cc39886f4c3907810c3907844c3907810c02ba674
bee0:c390781000000001c390bf0cc3907810c07d3a80c3907810c07d38e4c02b961c
bf00:c3907810c07d38d0c07d38d0c02ba210c07d38ecc386e42000000000c3f6b100
bf20:c07bf660c002dac000000008c07bf660c07bf660c386e438c390a000c07bf674
bf40: 00000008c07bf660c07c5040c002e044c390a00000000001 00000000 00000000
bf60:c3901518c3901500ffffe000c38e270000000000c3901518c386e420c002ddb4
bf80:c3839ee4c00335ecc390a000c38e2700c003350c00000000 00000000 00000000
bfa0: 00000000 00000000 00000000c000a27000000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff [<c0232648>] (faraday_pci_probe) from [<c02bbbe0>] (platform_drv_probe+0x50/0xb4)
[<c02bbbe0>] (platform_drv_probe) from [<c02ba9dc>] (driver_probe_device+0x248/0x2dc)
[<c02ba9dc>] (driver_probe_device) from [<c02b93dc>] (bus_for_each_drv+0x68/0x98)
[<c02b93dc>] (bus_for_each_drv) from [<c02ba674>] (__device_attach+0xa8/0x110) [<c02ba674>] (__device_attach) from [<c02b961c>] (bus_probe_device+0x88/0x90) [<c02b961c>] (bus_probe_device) from [<c02ba210>] (deferred_probe_work_func+0x54/0x80)
[<c02ba210>] (deferred_probe_work_func) from [<c002dac0>] (process_one_work+0x13c/0x430)
[<c002dac0>] (process_one_work) from [<c002e044>] (worker_thread+0x290/0x5f4) [<c002e044>] (worker_thread) from [<c00335ec>] (kthread+0xe0/0x120) [<c00335ec>] (kthread) from [<c000a270>] (ret_from_fork+0x14/0x24)Code: e59401b0 e3700a01 8a00001d e59421ac (e5d23070) ---[ end trace 1e313b1ea11e101c ]---I'm trying to figure out what is causing it.
Yours,
Linus Walleij
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
In reply to Linus WalleijQuoted 62 lines · Linus Walleij
On Thu, Jun 8, 2017 at 4:13 PM, Lorenzo Pieralisi
<[email protected]> wrote:I pulled this into the Gemini tree:
Quoted 1 line
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2And then this happens:
OF: PCI: host bridge /soc/pci at 50000000 ranges:
OF: PCI: IO 0x50000000..0x500fffff ->0x00000000
OF: PCI: MEM 0x58000000..0x5fffffff ->0x58000000Unable to handle kernel NULL pointer dereference at virtual address 00000070 pgd = c0004000 [00000070] *pgd=00000000 Internal error: Oops: 17 [#1] PREEMPT ARM CPU: 0 PID: 254 Comm: kworker/0:1 Not tainted 4.12.0-rc3+ #888 Hardware name: Gemini (Device Tree) Workqueue: events deferred_probe_work_func task: c38c3a40 task.stack: c390a000 PC is at faraday_pci_probe+0x274/0x65c LR is at __irq_put_desc_unlock+0x18/0x70 pc : [<c0232648>] lr : [<c004be48>] psr: 80000013sp :
c390bdf0ip :c3424274fp :c3ac2ee0
r10:c3f77718r9 :c3ad49b0r8 :c3907800
r7 : 00000004 r6 :c390be18r5 :c3907810r4 :c3ad4810r3 : 00000000 r2 : 00000000 r1 : 00000001 r0 :c3ac2de0
Flags: Nzcv IRQs on FIQs on ModeSVC_32ISA ARM Segment none
Control:0000397fTable:03a9c000DAC: 00000053 Process kworker/0:1 (pid: 254, stack limit =0xc390a190)Stack: (0xc390bdf0 to 0xc390c000)bde0:
c0534a60c3ad49b000000003c024cb68
be00: 00000001 20000013 00000000 50000000 00000007000020ddc3ae2680c3ae2740
be20:c07c861fc013432800000000c3ad5fa0c3910a50c3910a5000000001 00000000
be40: 00000000c01344ecc3910a50c3910a5000000001 00000000c3910a50c39d76e0
be60:c3ad5fa0c05f6f58c3910a50c3907810c3907810c07cba88fffffdfb 00000003
be80: 00000000c07c5040c386e420c02bbbe0c3907810c081c6c400000000c07cba88
bea0: 00000003c02ba9dc00000000c390bee0c02bab3000000001c07bf66000000000
bec0:c07c5040c02b93dcc382829cc39886f4c3907810c3907844c3907810c02ba674
bee0:c390781000000001c390bf0cc3907810c07d3a80c3907810c07d38e4c02b961c
bf00:c3907810c07d38d0c07d38d0c02ba210c07d38ecc386e42000000000c3f6b100
bf20:c07bf660c002dac000000008c07bf660c07bf660c386e438c390a000c07bf674
bf40: 00000008c07bf660c07c5040c002e044c390a00000000001 00000000 00000000
bf60:c3901518c3901500ffffe000c38e270000000000c3901518c386e420c002ddb4
bf80:c3839ee4c00335ecc390a000c38e2700c003350c00000000 00000000 00000000
bfa0: 00000000 00000000 00000000c000a27000000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff [<c0232648>] (faraday_pci_probe) from [<c02bbbe0>] (platform_drv_probe+0x50/0xb4)
[<c02bbbe0>] (platform_drv_probe) from [<c02ba9dc>] (driver_probe_device+0x248/0x2dc)
[<c02ba9dc>] (driver_probe_device) from [<c02b93dc>] (bus_for_each_drv+0x68/0x98)
[<c02b93dc>] (bus_for_each_drv) from [<c02ba674>] (__device_attach+0xa8/0x110) [<c02ba674>] (__device_attach) from [<c02b961c>] (bus_probe_device+0x88/0x90) [<c02b961c>] (bus_probe_device) from [<c02ba210>] (deferred_probe_work_func+0x54/0x80)
[<c02ba210>] (deferred_probe_work_func) from [<c002dac0>] (process_one_work+0x13c/0x430)
[<c002dac0>] (process_one_work) from [<c002e044>] (worker_thread+0x290/0x5f4) [<c002e044>] (worker_thread) from [<c00335ec>] (kthread+0xe0/0x120) [<c00335ec>] (kthread) from [<c000a270>] (ret_from_fork+0x14/0x24)
Quoted 4 lines
Code: e59401b0 e3700a01 8a00001d e59421ac (e5d23070) ---[ end trace 1e313b1ea11e101c ]---I'm trying to figure out what is causing it.
Mind trying this patch please on top of my branch (compile tested, that's all I can do)
-- >8 --
drivers/pci/host/pci-ftpci100.c +20 -13
@@ -178,12 +178,11 @@ static int faraday_res_to_memcfg(resource_size_t mem_base,return 0 ; } -static int faraday_pci_read_config (struct pci_bus *bus,unsigned int fn, -int config,int size,u32 *value) +static int faraday_raw_pci_read_config (struct faraday_pci *p,int bus_number, +unsigned int fn,int config,int size, +u32 *value) { -struct faraday_pci *p = bus->sysdata; - - writel(PCI_CONF_BUS(bus->number) | + writel(PCI_CONF_BUS(bus_number) | PCI_CONF_DEVICE(PCI_SLOT(fn)) | PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_WHERE(config) |
@@ -197,11 +196,19 @@ static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,else if (size ==2 ) *value = (*value >> (8 * (config &3 ))) &0xFFFF ; +return PCIBIOS_SUCCESSFUL ; +} + +static int faraday_pci_read_config (struct pci_bus *bus,unsigned int fn, +int config,int size,u32 *value) +{ +struct faraday_pci *p = bus->sysdata; +dev_dbg (&bus->dev,"[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n" ,PCI_SLOT (fn),PCI_FUNC (fn), config, size, *value); -return PCIBIOS_SUCCESSFUL ; +return faraday_raw_pci_read_config (p, bus->number, fn, config, size, value); } static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number,
@@ -257,10 +264,10 @@ static void faraday_pci_ack_irq(struct irq_data *d)struct faraday_pci *p =irq_data_get_irq_chip_data (d);unsigned int reg; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); reg &= ~(0xF <<PCI_CTRL2_INTSTS_SHIFT ); reg |=BIT (irqd_to_hwirq (d) +PCI_CTRL2_INTSTS_SHIFT ); -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , reg); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , reg); }static void faraday_pci_mask_irq (struct irq_data *d)
@@ -268,10 +275,10 @@ static void faraday_pci_mask_irq(struct irq_data *d)struct faraday_pci *p =irq_data_get_irq_chip_data (d);unsigned int reg; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); reg &= ~((0xF <<PCI_CTRL2_INTSTS_SHIFT ) |BIT (irqd_to_hwirq (d) +PCI_CTRL2_INTMASK_SHIFT )); -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , reg); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , reg); }static void faraday_pci_unmask_irq (struct irq_data *d)
@@ -279,10 +286,10 @@ static void faraday_pci_unmask_irq(struct irq_data *d)struct faraday_pci *p =irq_data_get_irq_chip_data (d);unsigned int reg; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); reg &= ~(0xF <<PCI_CTRL2_INTSTS_SHIFT ); reg |=BIT (irqd_to_hwirq (d) +PCI_CTRL2_INTMASK_SHIFT ); -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , reg); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , reg); }static void faraday_pci_irq_handler (struct irq_desc *desc)
@@ -291,7 +298,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc)struct irq_chip *irqchip =irq_desc_get_chip (desc);unsigned int irq_stat, reg, i; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); irq_stat = reg >>PCI_CTRL2_INTSTS_SHIFT ;chained_irq_enter (irqchip, desc);
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Quoted 66 lines · Lorenzo Pieralisi
Quoted 65 lines · Linus Walleij
On Thu, Jun 8, 2017 at 4:13 PM, Lorenzo Pieralisi
<[email protected]> wrote:I pulled this into the Gemini tree:
Quoted 1 line
[1]
git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/linux.gitpci/pci-fixup-irqs-removal-v2And then this happens:
OF: PCI: host bridge /soc/pci at 50000000 ranges:
OF: PCI: IO 0x50000000..0x500fffff ->0x00000000
OF: PCI: MEM 0x58000000..0x5fffffff ->0x58000000Unable to handle kernel NULL pointer dereference at virtual address 00000070 pgd = c0004000 [00000070] *pgd=00000000 Internal error: Oops: 17 [#1] PREEMPT ARM CPU: 0 PID: 254 Comm: kworker/0:1 Not tainted 4.12.0-rc3+ #888 Hardware name: Gemini (Device Tree) Workqueue: events deferred_probe_work_func task: c38c3a40 task.stack: c390a000 PC is at faraday_pci_probe+0x274/0x65c LR is at __irq_put_desc_unlock+0x18/0x70 pc : [<c0232648>] lr : [<c004be48>] psr: 80000013sp :
c390bdf0ip :c3424274fp :c3ac2ee0
r10:c3f77718r9 :c3ad49b0r8 :c3907800
r7 : 00000004 r6 :c390be18r5 :c3907810r4 :c3ad4810r3 : 00000000 r2 : 00000000 r1 : 00000001 r0 :c3ac2de0
Flags: Nzcv IRQs on FIQs on ModeSVC_32ISA ARM Segment none
Control:0000397fTable:03a9c000DAC: 00000053 Process kworker/0:1 (pid: 254, stack limit =0xc390a190)Stack: (0xc390bdf0 to 0xc390c000)bde0:
c0534a60c3ad49b000000003c024cb68
be00: 00000001 20000013 00000000 50000000 00000007000020ddc3ae2680c3ae2740
be20:c07c861fc013432800000000c3ad5fa0c3910a50c3910a5000000001 00000000
be40: 00000000c01344ecc3910a50c3910a5000000001 00000000c3910a50c39d76e0
be60:c3ad5fa0c05f6f58c3910a50c3907810c3907810c07cba88fffffdfb 00000003
be80: 00000000c07c5040c386e420c02bbbe0c3907810c081c6c400000000c07cba88
bea0: 00000003c02ba9dc00000000c390bee0c02bab3000000001c07bf66000000000
bec0:c07c5040c02b93dcc382829cc39886f4c3907810c3907844c3907810c02ba674
bee0:c390781000000001c390bf0cc3907810c07d3a80c3907810c07d38e4c02b961c
bf00:c3907810c07d38d0c07d38d0c02ba210c07d38ecc386e42000000000c3f6b100
bf20:c07bf660c002dac000000008c07bf660c07bf660c386e438c390a000c07bf674
bf40: 00000008c07bf660c07c5040c002e044c390a00000000001 00000000 00000000
bf60:c3901518c3901500ffffe000c38e270000000000c3901518c386e420c002ddb4
bf80:c3839ee4c00335ecc390a000c38e2700c003350c00000000 00000000 00000000
bfa0: 00000000 00000000 00000000c000a27000000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff [<c0232648>] (faraday_pci_probe) from [<c02bbbe0>] (platform_drv_probe+0x50/0xb4)
[<c02bbbe0>] (platform_drv_probe) from [<c02ba9dc>] (driver_probe_device+0x248/0x2dc)
[<c02ba9dc>] (driver_probe_device) from [<c02b93dc>] (bus_for_each_drv+0x68/0x98)
[<c02b93dc>] (bus_for_each_drv) from [<c02ba674>] (__device_attach+0xa8/0x110) [<c02ba674>] (__device_attach) from [<c02b961c>] (bus_probe_device+0x88/0x90) [<c02b961c>] (bus_probe_device) from [<c02ba210>] (deferred_probe_work_func+0x54/0x80)
[<c02ba210>] (deferred_probe_work_func) from [<c002dac0>] (process_one_work+0x13c/0x430)
[<c002dac0>] (process_one_work) from [<c002e044>] (worker_thread+0x290/0x5f4) [<c002e044>] (worker_thread) from [<c00335ec>] (kthread+0xe0/0x120) [<c00335ec>] (kthread) from [<c000a270>] (ret_from_fork+0x14/0x24)Code: e59401b0 e3700a01 8a00001d e59421ac (e5d23070) ---[ end trace 1e313b1ea11e101c ]---
Quoted 4 lines
Quoted 1 line
I'm trying to figure out what is causing it.
Mind trying this patch please on top of my branch (compile tested, that's all I can do)
Sorry I miss yet another usage of struct pci_bus before bus is scanned in faraday_pci_parse_map_dma_ranges(), all these config accessors want is to access bus number 0 and writei/read some config values in there, please confirm.
Updated patch here:
-- >8 --
Subject: [PATCH] drivers: pci: host: ftpci100: Remove pre-scan bus dependency
Remove leftover pci_bus dependencies from the probe path.
--- drivers/pci/host/pci-ftpci100.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-)
drivers/pci/host/pci-ftpci100.c +22 -15
@@ -178,12 +178,11 @@ static int faraday_res_to_memcfg(resource_size_t mem_base,return 0 ; } -static int faraday_pci_read_config (struct pci_bus *bus,unsigned int fn, -int config,int size,u32 *value) +static int faraday_raw_pci_read_config (struct faraday_pci *p,int bus_number, +unsigned int fn,int config,int size, +u32 *value) { -struct faraday_pci *p = bus->sysdata; - - writel(PCI_CONF_BUS(bus->number) | + writel(PCI_CONF_BUS(bus_number) | PCI_CONF_DEVICE(PCI_SLOT(fn)) | PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_WHERE(config) |
@@ -197,11 +196,19 @@ static int faraday_pci_read_config(struct pci_bus *bus, unsigned int fn,else if (size ==2 ) *value = (*value >> (8 * (config &3 ))) &0xFFFF ; +return PCIBIOS_SUCCESSFUL ; +} + +static int faraday_pci_read_config (struct pci_bus *bus,unsigned int fn, +int config,int size,u32 *value) +{ +struct faraday_pci *p = bus->sysdata; +dev_dbg (&bus->dev,"[read] slt: %.2d, fnc: %d, cnf: 0x%.2X, val (%d bytes): 0x%.8X\n" ,PCI_SLOT (fn),PCI_FUNC (fn), config, size, *value); -return PCIBIOS_SUCCESSFUL ; +return faraday_raw_pci_read_config (p, bus->number, fn, config, size, value); } static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number,
@@ -257,10 +264,10 @@ static void faraday_pci_ack_irq(struct irq_data *d)struct faraday_pci *p =irq_data_get_irq_chip_data (d);unsigned int reg; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); reg &= ~(0xF <<PCI_CTRL2_INTSTS_SHIFT ); reg |=BIT (irqd_to_hwirq (d) +PCI_CTRL2_INTSTS_SHIFT ); -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , reg); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , reg); }static void faraday_pci_mask_irq (struct irq_data *d)
@@ -268,10 +275,10 @@ static void faraday_pci_mask_irq(struct irq_data *d)struct faraday_pci *p =irq_data_get_irq_chip_data (d);unsigned int reg; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); reg &= ~((0xF <<PCI_CTRL2_INTSTS_SHIFT ) |BIT (irqd_to_hwirq (d) +PCI_CTRL2_INTMASK_SHIFT )); -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , reg); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , reg); }static void faraday_pci_unmask_irq (struct irq_data *d)
@@ -279,10 +286,10 @@ static void faraday_pci_unmask_irq(struct irq_data *d)struct faraday_pci *p =irq_data_get_irq_chip_data (d);unsigned int reg; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); reg &= ~(0xF <<PCI_CTRL2_INTSTS_SHIFT ); reg |=BIT (irqd_to_hwirq (d) +PCI_CTRL2_INTMASK_SHIFT ); -faraday_pci_write_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , reg); +faraday_raw_pci_write_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , reg); }static void faraday_pci_irq_handler (struct irq_desc *desc)
@@ -291,7 +298,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc)struct irq_chip *irqchip =irq_desc_get_chip (desc);unsigned int irq_stat, reg, i; -faraday_pci_read_config (p->bus,0 ,FARADAY_PCI_CTRL2 ,4 , ®); +faraday_raw_pci_read_config (p,0 ,0 ,FARADAY_PCI_CTRL2 ,4 , ®); irq_stat = reg >>PCI_CTRL2_INTSTS_SHIFT ;chained_irq_enter (irqchip, desc);
@@ -412,8 +419,8 @@ static int faraday_pci_parse_map_dma_ranges(struct faraday_pci *p,dev_info (dev,"DMA MEM%d BASE: 0x%016llx -> 0x%016llx config %08x\n" , i +1 , range.pci_addr, end, val);if (i <=2 ) { -faraday_pci_write_config (p->bus,0 , confreg[i], -4 , val); +faraday_raw_pci_write_config (p,0 ,0 , confreg[i], +4 , val); }else {dev_err (dev,"ignore extraneous dma-range %d\n" , i);break ;
Signature · 1 line
2.10.0
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Quoted 10 lines · Lorenzo Pieralisi
Quoted 4 lines
Quoted 1 line
I'm trying to figure out what is causing it.
Mind trying this patch please on top of my branch (compile tested, that's all I can do)
Sorry I miss yet another usage of struct
pci_busbefore bus is scanned infaraday_pci_parse_map_dma_ranges(), all these config accessors want is to access bus number 0 and writei/read some config values in there, please confirm.
Quoted 8 lines
Updated patch here:
-- >8 --
Subject: [PATCH] drivers: pci: host: ftpci100: Remove pre-scan bus dependencyRemove leftover
pci_busdependencies from the probe path.Signed-off-by Lorenzo Pieralisi <[email protected]>
Hm I tried this but sort of the same problem:
OF: PCI: host bridge /soc/pci at 50000000 ranges:
OF: PCI: IO 0x50000000..0x500fffff -> 0x00000000
OF: PCI: MEM 0x58000000..0x5fffffff -> 0x58000000
Unable to handle kernel NULL pointer dereference at virtual address 00000070 pgd = c0004000 [00000070] *pgd=00000000 Internal error: Oops: 17 [#1] PREEMPT ARM CPU: 0 PID: 254 Comm: kworker/0:1 Not tainted 4.12.0-rc3+ #894 Hardware name: Gemini (Device Tree) Workqueue: events deferred_probe_work_func task: c387f2c0 task.stack: c387c000 PC is at faraday_pci_probe+0x274/0x650 LR is at __irq_put_desc_unlock+0x18/0x70 pc : [<c02324e8>] lr : [<c004be48>] psr: 80000013
sp : c387ddf0 ip : c3424274 fp : c3ac0ee0
r10: c3f77718 r9 : c3ae09b0 r8 : c3906800
r7 : 00000004 r6 : c387de18 r5 : c3906810 r4 : c3ae0810 r3 : 00000000 r2 : 00000000 r1 : 00000001 r0 : c3ac0de0
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 0000397f Table: 03ab8000 DAC: 00000053 Process kworker/0:1 (pid: 254, stack limit = 0xc387c190)
Stack: (0xc387ddf0 to 0xc387e000)
dde0: c0534a60 c3ae09b0 00000003 c024ca90
de00: 00000001 20000013 00000000 50000000 00000007 000020dd c3ae25c0 c3ae2700
de20: c07c861f c0134328 00000000 c3ae1fa0 c3913a50 c3913a50 00000001 00000000
de40: 00000000 c01344ec c3913a50 c3913a50 00000001 00000000 c3913a50 c39c16e0
de60: c3ae1fa0 c05f6f48 c3913a50 c3906810 c3906810 c07cba88 fffffdfb 00000003
de80: 00000000 c07c5040 c3916420 c02bbb08 c3906810 c081c6c4 00000000 c07cba88
dea0: 00000003 c02ba904 00000000 c387dee0 c02baa58 00000001 c07bf660 00000000
dec0: c07c5040 c02b9304 c382829c c39886f4 c3906810 c3906844 c3906810 c02ba59c
dee0: c3906810 00000001 c387df0c c3906810 c07d3a80 c3906810 c07d38e4 c02b9544
df00: c3906810 c07d38d0 c07d38d0 c02ba138 c07d38ec c3916420 00000000 c3f6b100
df20: c07bf660 c002dac0 00000008 c07bf660 c07bf660 c3916438 c387c000 c07bf674
df40: 00000008 c07bf660 c07c5040 c002e044 c387c000 00000001 00000000 00000000
df60: c39397d8 c39397c0 ffffe000 c38c4740 00000000 c39397d8 c3916420 c002ddb4
df80: c3839ee4 c00335ec c387c000 c38c4740 c003350c 00000000 00000000 00000000
dfa0: 00000000 00000000 00000000 c000a270 00000000 00000000 00000000 00000000
dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00030400 00080000 [<c02324e8>] (faraday_pci_probe) from [<c02bbb08>] (platform_drv_probe+0x50/0xb4)
[<c02bbb08>] (platform_drv_probe) from [<c02ba904>] (driver_probe_device+0x248/0x2dc)
[<c02ba904>] (driver_probe_device) from [<c02b9304>] (bus_for_each_drv+0x68/0x98)
[<c02b9304>] (bus_for_each_drv) from [<c02ba59c>] (__device_attach+0xa8/0x110) [<c02ba59c>] (__device_attach) from [<c02b9544>] (bus_probe_device+0x88/0x90) [<c02b9544>] (bus_probe_device) from [<c02ba138>] (deferred_probe_work_func+0x54/0x80)
[<c02ba138>] (deferred_probe_work_func) from [<c002dac0>] (process_one_work+0x13c/0x430)
[<c002dac0>] (process_one_work) from [<c002e044>] (worker_thread+0x290/0x5f4) [<c002e044>] (worker_thread) from [<c00335ec>] (kthread+0xe0/0x120) [<c00335ec>] (kthread) from [<c000a270>] (ret_from_fork+0x14/0x24)
Code: e59401b0 e3700a01 8a00001d e59421ac (e5d23070) ---[ end trace 538dce2df8d99ba7 ]---
I will try to figure it out, just a bit short on time right now...
Yours,
Linus Walleij
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
In reply to Lorenzo PieralisiQuoted 6 lines · Lorenzo Pieralisi
Sorry I miss yet another usage of struct
pci_busbefore bus is scanned infaraday_pci_parse_map_dma_ranges(), all these config accessors want is to access bus number 0 and writei/read some config values in there, please confirm.Updated patch here:
I fixed it. This was needed:
drivers/pci/host/pci-ftpci100.c +10 -6
@@ -450,6 +450,8 @@ static int faraday_pci_probe(struct platform_device *pdev)struct resource *io;struct pci_host_bridge *host;struct clk *clk; +unsigned char max_bus_speed = PCI_SPEED_33MHz; +unsigned char cur_bus_speed = PCI_SPEED_33MHz;int ret;u32 val;LIST_HEAD (res);
@@ -553,27 +555,27 @@ static int faraday_pci_probe(struct platform_device *pdev)unsigned long rate;u32 val; -faraday_pci_read_config (p->bus,0 , -FARADAY_PCI_STATUS_CMD ,4 , &val); +faraday_raw_pci_read_config (p,0 ,0 , +FARADAY_PCI_STATUS_CMD ,4 , &val); rate =clk_get_rate (p->bus_clk);if ((rate ==33000000 ) && (val &PCI_STATUS_66MHZ_CAPABLE )) {dev_info (dev,"33MHz bus is 66MHz capable\n" ); - p->bus->max_bus_speed = PCI_SPEED_66MHz; + max_bus_speed = PCI_SPEED_66MHz; ret =clk_set_rate (p->bus_clk,66000000 );if (ret)dev_err (dev,"failed to set bus clock\n" ); }else {dev_info (dev,"33MHz only bus\n" ); - p->bus->max_bus_speed = PCI_SPEED_33MHz; + max_bus_speed = PCI_SPEED_33MHz; }/* Bumping the clock may fail so read back the rate */ rate =clk_get_rate (p->bus_clk);if (rate ==33000000 ) - p->bus->cur_bus_speed = PCI_SPEED_33MHz; + cur_bus_speed = PCI_SPEED_33MHz;if (rate ==66000000 ) - p->bus->cur_bus_speed = PCI_SPEED_66MHz; + cur_bus_speed = PCI_SPEED_66MHz; } ret =faraday_pci_parse_map_dma_ranges (p, dev->of_node);
@@ -587,6 +589,8 @@ static int faraday_pci_probe(struct platform_device *pdev)return ret; } p->bus = host->bus; + p->bus->max_bus_speed = max_bus_speed; + p->bus->cur_bus_speed = cur_bus_speed;pci_bus_assign_resources (p->bus);pci_bus_add_devices (p->bus);
I'll send a modified and tested version of your patch.
Yours,
Linus Walleij
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Hi Linus,
Quoted 16 lines · Linus Walleij
Quoted 6 lines · Lorenzo Pieralisi
Sorry I miss yet another usage of struct
pci_busbefore bus is scanned infaraday_pci_parse_map_dma_ranges(), all these config accessors want is to access bus number 0 and writei/read some config values in there, please confirm.Updated patch here:
I fixed it. This was needed:
drivers/pci/host/pci-ftpci100.c +0
-0
drivers/pci/host/pci-ftpci100.c static int faraday_pci_probe(struct platform_device *pdev) · line 454
Quoted 5 lines
drivers/pci/host/pci-ftpci100.c +2
-0@@ -450,6 +450,8 @@ static int faraday_pci_probe(struct platform_device *pdev)struct resource *io;struct pci_host_bridge *host;struct clk *clk; +unsigned char max_bus_speed = PCI_SPEED_33MHz; +unsigned char cur_bus_speed = PCI_SPEED_33MHz;
I could not fix it myself since we do not have the same code base, I can't find any clock handling in the mainline as per v4.12-rc6.
Is the ftpci100.c clock handling being queued for this merge window ?
This patch:
https://patchwork.ozlabs.org/patch/778716/
fixes a commit that is not in v4.12-rc6, I need some input to understand how to proceed.
Thanks,
Lorenzo
Quoted 52 lines
drivers/pci/host/pci-ftpci100.c +8
-6int ret;u32 val;LIST_HEAD (res);@@ -553,27 +555,27 @@ static int faraday_pci_probe(struct platform_device *pdev)unsigned long rate;u32 val; -faraday_pci_read_config (p->bus,0 , -FARADAY_PCI_STATUS_CMD ,4 , &val); +faraday_raw_pci_read_config (p,0 ,0 , +FARADAY_PCI_STATUS_CMD ,4 , &val); rate =clk_get_rate (p->bus_clk);if ((rate ==33000000 ) && (val &PCI_STATUS_66MHZ_CAPABLE )) {dev_info (dev,"33MHz bus is 66MHz capable\n" ); - p->bus->max_bus_speed = PCI_SPEED_66MHz; + max_bus_speed = PCI_SPEED_66MHz; ret =clk_set_rate (p->bus_clk,66000000 );if (ret)dev_err (dev,"failed to set bus clock\n" ); }else {dev_info (dev,"33MHz only bus\n" ); - p->bus->max_bus_speed = PCI_SPEED_33MHz; + max_bus_speed = PCI_SPEED_33MHz; }/* Bumping the clock may fail so read back the rate */ rate =clk_get_rate (p->bus_clk);if (rate ==33000000 ) - p->bus->cur_bus_speed = PCI_SPEED_33MHz; + cur_bus_speed = PCI_SPEED_33MHz;if (rate ==66000000 ) - p->bus->cur_bus_speed = PCI_SPEED_66MHz; + cur_bus_speed = PCI_SPEED_66MHz; } ret =faraday_pci_parse_map_dma_ranges (p, dev->of_node);@@ -587,6 +589,8 @@ static int faraday_pci_probe(struct platform_device *pdev)return ret; } p->bus = host->bus; + p->bus->max_bus_speed = max_bus_speed; + p->bus->cur_bus_speed = cur_bus_speed;pci_bus_assign_resources (p->bus);pci_bus_add_devices (p->bus);I'll send a modified and tested version of your patch.
Yours,
Linus Walleij
v2 cover PCI: ARM/ARM64: remove pci_fixup_irqs() usage
Quoted 1 line · Lorenzo Pieralisi
Is the
ftpci100.cclock handling being queued for this merge window ?
Yups, it's in Bjorn's tree and visible in linux-next.
Quoted 6 lines
This patch:
https://patchwork.ozlabs.org/patch/778716/
fixes a commit that is not in v4.12-rc6, I need some input to understand how to proceed.
Yeah that is just a fix I had to do when fixing this other issue.
It's cool, I just sent a patch. If Bjorn applied your series he can just apply this on top and all will be fine (for me).
Yours,
Linus Walleij