All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging
@ 2015-10-23  5:03 Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 01/29] PCI: Build setup-irq.o on all arches Matthew Minter
                   ` (29 more replies)
  0 siblings, 30 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi

Hi again everyone, this is the extremely long awaited version 4 of this patchset.

It has been rebased to the head of the lastest mainline kernel as of a few days
ago as well as a huge number of small restructures have been included.

I have tried to include every suggested change from last round's reviewing
but appologise in advance if I missed one, there were dozens of comments which
I have tried to implement or fix. If I have indeed missed anything please let
me know, it was likely not my rejecting the feedback but just missing it while
reading through all the feedback I got.

The most notable change is this version should be bisectable as I have kept
all the old mechanisms working untill all arches have been converted to the
new code paths though I have not tested actually booting all the intermediate
versions.

I have only been able to test this on an ACPI enabled amd64 computer (my own
desktop) as I am now working on it only in free time without any resources
from a lab so testing on other arches is very much appreciated.

I shall also note that my time to work on this in the future is very limited
so any help anyone can provide in making any further changes which may be
needed if another version is required would be appreciated as to avoid more
potentially very long delays due to my limited availability.

Unlike the previous version, it should in theory be safe to apply patches
1 to 6 separately to the rest of the set, then the architecture specific
patch sets could be applied in any order over time and the last patch to tidy
up the old code can be applied last of all.

I am sorry for all the silly whitespace fixes, found in the last version
their inclusion was due to my misconfigured editor applying them automatically
then me failing to see them while reading over the diffs.

As always, comments and testers are appreciated but I am not sure I will be
able to produce another version in the near future so any help with changes
is also very much appreciated if there are issues.

This time I have also uploaded the patch set to github to aid any testers who
do not wish to attempt to merge the patches from this email chain:

https://github.com/Vality/linux/tree/pci-fixes

Note that the changes are all in my pci-fixes branch so make sure to check
out that before building.

Many thanks,
Matthew

Patch description (same as v3) follows:

pci_fixup_irqs is the current method used in most arches to assign IRQs to
PCI devices. This has a number of flaws including it requiring an extra walk
of the PCI bus and most importantly not running for devices which are added
after boot time, this includes hot-added devices on boards that support this.

This patch set modifies the IRQ mapping and swizzling infrastructure
such that functions are registered by the boot code (instead of being
run directly by the boot code) and then run later in the enable_device
path such that it will apply to all devices and not only those inserted
at boot time.

This is cleaner as it unifies how each architecture allocates PCI IRQs as much
as possible (some arches were particularly resistant to these changes so some
work-arounds have been used or the change disabled completely).

The caveat here is that I have been forced to modify some architecture specific
code for various architectures which I cannot test due to not having such boards
available. The code seems correct and the changes in most cases are small and
trivial however I have not tested all the patches for rare arches.

arch/alpha/kernel/pci.c                 |  7 ++++++-
arch/alpha/kernel/sys_nautilus.c        |  1 -
arch/arm/kernel/bios32.c                |  9 +++++++--
arch/cris/arch-v32/drivers/pci/bios.c   | 12 ++++++++----
arch/frv/mb93090-mb00/pci-frv.h         |  1 -
arch/frv/mb93090-mb00/pci-irq.c         | 24 ++++++++++++------------
arch/frv/mb93090-mb00/pci-vdk.c         |  1 -
arch/m68k/coldfire/pci.c                |  8 +++++++-
arch/microblaze/pci/pci-common.c        |  9 ++++++---
arch/mips/pci/pci.c                     |  9 +++++++--
arch/mn10300/unit-asb2305/pci-asb2305.h |  5 +----
arch/mn10300/unit-asb2305/pci-irq.c     | 24 ++++--------------------
arch/mn10300/unit-asb2305/pci.c         | 19 ++++++-------------
arch/powerpc/kernel/pci-common.c        | 25 ++++++++++++-------------
arch/sh/drivers/pci/fixups-cayman.c     |  2 +-
arch/sh/drivers/pci/fixups-dreamcast.c  |  2 +-
arch/sh/drivers/pci/fixups-r7780rp.c    |  2 +-
arch/sh/drivers/pci/fixups-rts7751r2d.c |  6 +++---
arch/sh/drivers/pci/fixups-sdk7780.c    |  4 ++--
arch/sh/drivers/pci/fixups-se7751.c     |  2 +-
arch/sh/drivers/pci/fixups-sh03.c       |  2 +-
arch/sh/drivers/pci/fixups-snapgear.c   |  2 +-
arch/sh/drivers/pci/fixups-titan.c      |  4 ++--
arch/sh/drivers/pci/pci.c               | 10 +++++++---
arch/sh/drivers/pci/pcie-sh7786.c       |  2 +-
arch/sparc/kernel/leon_pci.c            | 12 ++++++++++--
arch/sparc/kernel/pci.c                 | 23 +++++++++++++++++++----
arch/tile/kernel/pci.c                  | 10 +++++++---
arch/tile/kernel/pci_gx.c               | 10 +++++++---
arch/unicore32/kernel/pci.c             | 11 ++++++++---
arch/x86/include/asm/pci_x86.h          |  7 ++++---
arch/x86/kernel/x86_init.c              |  1 -
arch/x86/pci/acpi.c                     | 15 ---------------
arch/x86/pci/irq.c                      | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------
drivers/of/of_pci_irq.c                 |  2 +-
drivers/pci/Makefile                    | 16 ++--------------
drivers/pci/host/pci-host-generic.c     |  5 ++++-
drivers/pci/host/pci-versatile.c        |  7 +++++--
drivers/pci/host/pcie-iproc.c           | 12 ++++++++----
drivers/pci/pci.c                       |  2 ++
drivers/pci/pci.h                       |  1 +
drivers/pci/setup-irq.c                 | 34 ++++++++++++++++------------------
include/linux/pci.h                     |  5 +++--
43 files changed, 246 insertions(+), 210 deletions(-)

^ permalink raw reply	[flat|nested] 41+ messages in thread

* [PATCH V4 01/29] PCI: Build setup-irq.o on all arches
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 02/29] PCI: Add a prototype for pci_find_host_bridge to pci.h Matthew Minter
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

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.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/Makefile | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index be3f631..8417f55 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -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
+			irq.o vpd.o setup-bus.o vc.o setup-irq.o
+
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSFS) += slot.o
 
@@ -29,19 +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_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
 #
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 02/29] PCI: Add a prototype for pci_find_host_bridge to pci.h
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 01/29] PCI: Build setup-irq.o on all arches Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 03/29] PCI: Add IRQ mapping function pointers to pci_host_bridge struct Matthew Minter
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The function pci_find_host_bridge is currently only used within
drivers/pci/host-bridge.c however the deferred IRQ assignment
requires its use in multiple files, therefore add a prototype
use within the pci drivers.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/pci.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 24ba9dc..dfdf606 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -80,6 +80,7 @@ void pci_config_pm_runtime_put(struct pci_dev *dev);
 void pci_pm_init(struct pci_dev *dev);
 void pci_allocate_cap_save_buffers(struct pci_dev *dev);
 void pci_free_cap_save_buffers(struct pci_dev *dev);
+struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
 
 static inline void pci_wakeup_event(struct pci_dev *dev)
 {
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 03/29] PCI: Add IRQ mapping function pointers to pci_host_bridge struct
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 01/29] PCI: Build setup-irq.o on all arches Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 02/29] PCI: Add a prototype for pci_find_host_bridge to pci.h Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 04/29] PCI: Remove const from the pci_dev struct passed to pci_fixup_irqs Matthew Minter
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

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.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 include/linux/pci.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index e90eb22..f1bae1d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -409,6 +409,8 @@ struct pci_host_bridge {
 	struct device dev;
 	struct pci_bus *bus;		/* root bus */
 	struct list_head windows;	/* resource_entry */
+	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* platform irq swizzler */
+	int (*map_irq)(struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
 	void *release_data;
 	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 04/29] PCI: Remove const from the pci_dev struct passed to pci_fixup_irqs
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (2 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 03/29] PCI: Add IRQ mapping function pointers to pci_host_bridge struct Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 05/29] PCI: Add pci_assign_irq function and have pci_fixup_irqs use it Matthew Minter
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The pci_fixup_irqs function currently gets passed a const struct pci_dev *.
This is fine for the current implementation which never modifies the pci_dev
however the deferred IRQ assignment version may have to modify this pci_dev
on some architectures so the const is no longer correct.

Therefore we remove it, fortunately no users currently seem to rely on it
being a const so no changes to callers are needed.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/setup-irq.c | 2 +-
 include/linux/pci.h     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index 95c225b..c7d9f26 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -58,7 +58,7 @@ 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))
+		    int (*map_irq)(struct pci_dev *, u8, u8))
 {
 	struct pci_dev *dev = NULL;
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index f1bae1d..1073f27 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1121,7 +1121,7 @@ void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
 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));
+		    int (*)(struct pci_dev *, u8, u8));
 #define HAVE_PCI_REQ_REGIONS	2
 int __must_check pci_request_regions(struct pci_dev *, const char *);
 int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 05/29] PCI: Add pci_assign_irq function and have pci_fixup_irqs use it
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (3 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 04/29] PCI: Remove const from the pci_dev struct passed to pci_fixup_irqs Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 06/29] PCI: Add a call to pci_assign_irq in do_pci_enable_device Matthew Minter
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

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 deffered 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.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/setup-irq.c | 35 ++++++++++++++++++++++++++---------
 include/linux/pci.h     |  1 +
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index c7d9f26..a9b7a30 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -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,19 @@ 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 +68,18 @@ static void pdev_fixup_irq(struct pci_dev *dev,
 void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
 		    int (*map_irq)(struct pci_dev *, u8, u8))
 {
+	/* This code should be removed shortly, but in the mean time
+	   it can wrap the new codepath in order to allow arches
+	   still using it to continue working */
 	struct pci_dev *dev = NULL;
+	struct pci_host_bridge *hbrg = NULL;
 
 	for_each_pci_dev(dev)
-		pdev_fixup_irq(dev, swizzle, map_irq);
+		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);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1073f27..e88ad4f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1122,6 +1122,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 (*)(struct pci_dev *, u8, u8));
+void pci_assign_irq(struct pci_dev *dev);
 #define HAVE_PCI_REQ_REGIONS	2
 int __must_check pci_request_regions(struct pci_dev *, const char *);
 int __must_check pci_request_regions_exclusive(struct pci_dev *, const char *);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 06/29] PCI: Add a call to pci_assign_irq in do_pci_enable_device
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (4 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 05/29] PCI: Add pci_assign_irq function and have pci_fixup_irqs use it Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 07/29] x86/pci: Move pcibios_root_bridge_prepare from acpi.c to irq.c Matthew Minter
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

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 do_pci_enable_device 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 noop, however as support
for these function pointers is added to arch specific code this will
cause irq asignment to migrate to device enable time allowing the new
codepaths to be used.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6a9a111..6907312 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1226,6 +1226,8 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
 	if (err < 0 && err != -EIO)
 		return err;
 
+	pci_assign_irq(dev);
+
 	bridge = pci_upstream_bridge(dev);
 	if (bridge)
 		pcie_aspm_powersave_config_link(bridge);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 07/29] x86/pci: Move pcibios_root_bridge_prepare from acpi.c to irq.c
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (5 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 06/29] PCI: Add a call to pci_assign_irq in do_pci_enable_device Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time Matthew Minter
                   ` (22 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

It is always safe to run ACPI_COMPANION_SET even if we are using
a non acpi system. Therefore we move pcibios_root_bridge_prepare
into irq.c.

This should make no difference to behaviour at this time but
prepares for additional changes to pcibios_root_bridge_prepare
which must apply both to acpi and non acpi systems.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/x86/pci/acpi.c | 15 ---------------
 arch/x86/pci/irq.c  | 15 +++++++++++++++
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index ff99117..9b2f170 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -493,21 +493,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
 	return bus;
 }
 
-int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
-{
-	/*
-	 * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
-	 * here, pci_create_root_bus() has been called by someone else and
-	 * sysdata is likely to be different from what we expect.  Let it go in
-	 * that case.
-	 */
-	if (!bridge->dev.parent) {
-		struct pci_sysdata *sd = bridge->bus->sysdata;
-		ACPI_COMPANION_SET(&bridge->dev, sd->companion);
-	}
-	return 0;
-}
-
 int __init pci_acpi_init(void)
 {
 	struct pci_dev *dev = NULL;
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 32e7034..350e785 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1162,6 +1162,21 @@ void __init pcibios_irq_init(void)
 	}
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	/*
+	 * We pass NULL as parent to pci_create_root_bus(), so if it is not NULL
+	 * here, pci_create_root_bus() has been called by someone else and
+	 * sysdata is likely to be different from what we expect.  Let it go in
+	 * that case.
+	 */
+	if (!bridge->dev.parent) {
+		struct pci_sysdata *sd = bridge->bus->sysdata;
+		ACPI_COMPANION_SET(&bridge->dev, sd->companion);
+	}
+	return 0;
+}
+
 static void pirq_penalize_isa_irq(int irq, int active)
 {
 	/*
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (6 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 07/29] x86/pci: Move pcibios_root_bridge_prepare from acpi.c to irq.c Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-12-23 23:04   ` Bjorn Helgaas
  2015-10-23  5:03 ` [PATCH V4 09/29] x86/pci: Pass pin into pcibios_lookup_irq rather than look it up Matthew Minter
                   ` (21 subsequent siblings)
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The x86 architecture boot code currently traverses the PCI buses with
an extra pass in order to initialise the PCI device IRQs at boot, this
patch avoids this pass and defers the IRQ assignment untill device
enable time which also has the benefit that hot-plugged devices are
assigned IRQs without additional code.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/x86/include/asm/pci_x86.h |  7 +++--
 arch/x86/kernel/x86_init.c     |  1 -
 arch/x86/pci/irq.c             | 70 +++++++++++++++++++++---------------------
 3 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index fa1195d..16fd8e9 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -90,6 +90,7 @@ extern unsigned int pcibios_irq_mask;
 
 extern raw_spinlock_t pci_config_lock;
 
+extern int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
 extern void (*pcibios_disable_irq)(struct pci_dev *dev);
 
@@ -119,7 +120,7 @@ extern int __init pci_acpi_init(void);
 extern void __init pcibios_irq_init(void);
 extern int __init pcibios_init(void);
 extern int pci_legacy_init(void);
-extern void pcibios_fixup_irqs(void);
+extern int pcibios_fixup_irq(struct pci_dev *dev, u8 pin);
 
 /* pci-mmconfig.c */
 
@@ -200,9 +201,9 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val)
 #  define x86_default_pci_init		pci_legacy_init
 # endif
 # define x86_default_pci_init_irq	pcibios_irq_init
-# define x86_default_pci_fixup_irqs	pcibios_fixup_irqs
+# define x86_default_pci_fixup_irq	pcibios_fixup_irq
 #else
 # define x86_default_pci_init		NULL
 # define x86_default_pci_init_irq	NULL
-# define x86_default_pci_fixup_irqs	NULL
+# define x86_default_pci_fixup_irq	NULL
 #endif
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 3839628..810f1dd 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -80,7 +80,6 @@ struct x86_init_ops x86_init __initdata = {
 	.pci = {
 		.init			= x86_default_pci_init,
 		.init_irq		= x86_default_pci_init_irq,
-		.fixup_irqs		= x86_default_pci_fixup_irqs,
 	},
 };
 
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 350e785..15c507b 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -1021,47 +1021,38 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
 	return 1;
 }
 
-void __init pcibios_fixup_irqs(void)
+int pcibios_fixup_irq(struct pci_dev *dev, u8 pin)
 {
-	struct pci_dev *dev = NULL;
-	u8 pin;
-
+	int irq = dev->irq;
 	DBG(KERN_DEBUG "PCI: IRQ fixup\n");
-	for_each_pci_dev(dev) {
-		/*
-		 * If the BIOS has set an out of range IRQ number, just
-		 * ignore it.  Also keep track of which IRQ's are
-		 * already in use.
-		 */
-		if (dev->irq >= 16) {
-			dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq);
-			dev->irq = 0;
-		}
-		/*
-		 * If the IRQ is already assigned to a PCI device,
-		 * ignore its ISA use penalty
-		 */
-		if (pirq_penalty[dev->irq] >= 100 &&
-				pirq_penalty[dev->irq] < 100000)
-			pirq_penalty[dev->irq] = 0;
-		pirq_penalty[dev->irq]++;
+	/*
+	 * If the BIOS has set an out of range IRQ number, just
+	 * ignore it.  Also keep track of which IRQ's are
+	 * already in use.
+	 */
+	if (irq >= 16) {
+		dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", irq);
+		irq = 0;
 	}
+	/*
+	 * If the IRQ is already assigned to a PCI device,
+	 * ignore its ISA use penalty
+	 */
+	if (pirq_penalty[irq] >= 100 &&
+			pirq_penalty[irq] < 100000)
+		pirq_penalty[irq] = 0;
+	pirq_penalty[irq]++;
 
-	if (io_apic_assign_pci_irqs)
-		return;
+	if (io_apic_assign_pci_irqs || !pin)
+		return irq;
 
-	dev = NULL;
-	for_each_pci_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-		if (!pin)
-			continue;
+	/*
+	 * Still no IRQ? Try to lookup one...
+	 */
+	if (!irq && pcibios_lookup_irq(dev, 0))
+		irq = dev->irq;
 
-		/*
-		 * Still no IRQ? Try to lookup one...
-		 */
-		if (!dev->irq)
-			pcibios_lookup_irq(dev, 0);
-	}
+	return irq;
 }
 
 /*
@@ -1174,6 +1165,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 		struct pci_sysdata *sd = bridge->bus->sysdata;
 		ACPI_COMPANION_SET(&bridge->dev, sd->companion);
 	}
+	bridge->map_irq = pci_map_irq;
 	return 0;
 }
 
@@ -1201,6 +1193,14 @@ void pcibios_penalize_isa_irq(int irq, int active)
 		pirq_penalize_isa_irq(irq, active);
 }
 
+int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	dev->irq = pcibios_fixup_irq(dev, pin);
+	if (pcibios_enable_irq(dev))
+		return -1;
+	return dev->irq;
+}
+
 static int pirq_enable_irq(struct pci_dev *dev)
 {
 	u8 pin = 0;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 09/29] x86/pci: Pass pin into pcibios_lookup_irq rather than look it up
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (7 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 10/29] ARM/PCI: Defer IRQ assignment to device enable time Matthew Minter
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The pcibios_lookup_irq currently looks up the pci interrupt pin manually.
However all callers now have that information stored already.
Therefore pass the pin in rather than look it up.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/x86/pci/irq.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 15c507b..7032798 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -876,9 +876,8 @@ static struct irq_info *pirq_get_info(struct pci_dev *dev)
 	return NULL;
 }
 
-static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
+static int pcibios_lookup_irq(struct pci_dev *dev, u8 pin, int assign)
 {
-	u8 pin;
 	struct irq_info *info;
 	int i, pirq, newirq;
 	int irq = 0;
@@ -888,7 +887,6 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
 	char *msg = NULL;
 
 	/* Find IRQ pin */
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 	if (!pin) {
 		dev_dbg(&dev->dev, "no interrupt pin\n");
 		return 0;
@@ -1049,7 +1047,7 @@ int pcibios_fixup_irq(struct pci_dev *dev, u8 pin)
 	/*
 	 * Still no IRQ? Try to lookup one...
 	 */
-	if (!irq && pcibios_lookup_irq(dev, 0))
+	if (!irq && pcibios_lookup_irq(dev, pin, 0))
 		irq = dev->irq;
 
 	return irq;
@@ -1206,7 +1204,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
 	u8 pin = 0;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	if (pin && !pcibios_lookup_irq(dev, 1)) {
+	if (pin && !pcibios_lookup_irq(dev, pin, 1)) {
 		char *msg = "";
 
 		if (!io_apic_assign_pci_irqs && dev->irq)
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 10/29] ARM/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (8 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 09/29] x86/pci: Pass pin into pcibios_lookup_irq rather than look it up Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 11/29] powerpc/pci: " Matthew Minter
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently PCI device IRQs under arm are initialised during the
pci_common_init_dev code path, this results in an extra sweep of the
PCI bus as well as causing PCI devices hot-plugged after boot to not
receive an IRQ.

This patch set defers this assignment untill the device enable phase
which prevents both these issues.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/arm/kernel/bios32.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 874e182..4137784 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -410,6 +410,13 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 	return irq;
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pcibios_swizzle;
+	bridge->map_irq = pcibios_map_irq;
+	return 0;
+}
+
 static int pcibios_init_resources(int busnr, struct pci_sys_data *sys)
 {
 	int ret;
@@ -506,8 +513,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;
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 11/29] powerpc/pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (9 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 10/29] ARM/PCI: Defer IRQ assignment to device enable time Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 12/29] sh/PCI: Remove __init optimisations from IRQ mapping functions/data Matthew Minter
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The powerpc PCI init code is currently initialising PCI device IRQ during
the boot time pcibios phase. This results in devices which are connected
after boot time not being asigned IRQs which can cause various problems.

This patch as part of its set fixes this be moving the IRQ initialisation
into the PCI device enable code path so that it is run for boot time and
hot-plugged devices alike.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/powerpc/kernel/pci-common.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 7587b2a..4189f50 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -231,7 +231,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
  * If the interrupt is used, then gets the interrupt line from the
  * openfirmware and sets it in the pci_dev and pci_config line.
  */
-static int pci_read_irq_line(struct pci_dev *pci_dev)
+static int pci_read_irq_line(struct pci_dev *pci_dev, u8 pin)
 {
 	struct of_phandle_args oirq;
 	unsigned int virq;
@@ -243,7 +243,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
 #endif
 	/* Try to get a mapping from the device-tree */
 	if (of_irq_parse_pci(pci_dev, &oirq)) {
-		u8 line, pin;
+		u8 line;
 
 		/* If that fails, lets fallback to what is in the config
 		 * space and map that through the default controller. We
@@ -252,10 +252,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
 		 * either provide a proper interrupt tree or don't use this
 		 * function.
 		 */
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
-			return -1;
-		if (pin == 0)
-			return -1;
 		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
 		    line == 0xff || line == 0) {
 			return -1;
@@ -280,9 +276,16 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
 
 	pr_debug(" Mapped to linux irq %d\n", virq);
 
-	pci_dev->irq = virq;
+	return virq;
+}
 
-	return 0;
+static int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* Read default IRQs and fixup if necessary */
+	dev->irq = pci_read_irq_line(dev, pin);
+	if (ppc_md.pci_irq_fixup)
+		ppc_md.pci_irq_fixup(dev);
+	return dev->irq;
 }
 
 /*
@@ -784,6 +787,7 @@ int pci_proc_domain(struct pci_bus *bus)
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
+	bridge->map_irq = pci_map_irq;
 	if (ppc_md.pcibios_root_bridge_prepare)
 		return ppc_md.pcibios_root_bridge_prepare(bridge);
 
@@ -983,11 +987,6 @@ static void pcibios_setup_device(struct pci_dev *dev)
 	phb = pci_bus_to_host(dev->bus);
 	if (phb->controller_ops.dma_dev_setup)
 		phb->controller_ops.dma_dev_setup(dev);
-
-	/* Read default IRQs and fixup if necessary */
-	pci_read_irq_line(dev);
-	if (ppc_md.pci_irq_fixup)
-		ppc_md.pci_irq_fixup(dev);
 }
 
 int pcibios_add_device(struct pci_dev *dev)
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 12/29] sh/PCI: Remove __init optimisations from IRQ mapping functions/data
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (10 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 11/29] powerpc/pci: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 13/29] sh/PCI: Defer IRQ assignment to device enable time Matthew Minter
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently the many IRQ mapping functions and data structures use
the __init and __initdata optimisations. These result in the
relevant functions being innacessable after boot time.

However for deferred IRQ assignment it is important to have
access to these functions at PCI device enable time.

Therefore the optimisation is removed from the relevant data
structures and functions to prepare for deferred IRQ assignment.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/sh/drivers/pci/fixups-cayman.c     | 2 +-
 arch/sh/drivers/pci/fixups-dreamcast.c  | 2 +-
 arch/sh/drivers/pci/fixups-r7780rp.c    | 2 +-
 arch/sh/drivers/pci/fixups-rts7751r2d.c | 6 +++---
 arch/sh/drivers/pci/fixups-sdk7780.c    | 4 ++--
 arch/sh/drivers/pci/fixups-se7751.c     | 2 +-
 arch/sh/drivers/pci/fixups-sh03.c       | 2 +-
 arch/sh/drivers/pci/fixups-snapgear.c   | 2 +-
 arch/sh/drivers/pci/fixups-titan.c      | 4 ++--
 arch/sh/drivers/pci/pcie-sh7786.c       | 2 +-
 10 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c
index edc2fb7..3246788 100644
--- a/arch/sh/drivers/pci/fixups-cayman.c
+++ b/arch/sh/drivers/pci/fixups-cayman.c
@@ -5,7 +5,7 @@
 #include <cpu/irq.h>
 #include "pci-sh5.h"
 
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	int result = -1;
 
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index 1d1c5a2..9d597f7 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -76,7 +76,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
 
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	/*
 	 * The interrupt routing semantics here are quite trivial.
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
index 57ed3f0..2c9b58f 100644
--- a/arch/sh/drivers/pci/fixups-r7780rp.c
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -15,7 +15,7 @@
 #include <linux/sh_intc.h>
 #include "pci-sh4.h"
 
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	return evt2irq(0xa20) + slot;
 }
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
index eaddb56..358ac10 100644
--- a/arch/sh/drivers/pci/fixups-rts7751r2d.c
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -20,18 +20,18 @@
 #define PCIMCR_MRSET_OFF	0xBFFFFFFF
 #define PCIMCR_RFSH_OFF		0xFFFFFFFB
 
-static u8 rts7751r2d_irq_tab[] __initdata = {
+static u8 rts7751r2d_irq_tab[] = {
 	IRQ_PCI_INTA,
 	IRQ_PCI_INTB,
 	IRQ_PCI_INTC,
 	IRQ_PCI_INTD,
 };
 
-static char lboxre2_irq_tab[] __initdata = {
+static char lboxre2_irq_tab[] = {
 	IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
 };
 
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	if (mach_is_lboxre2())
 		return lboxre2_irq_tab[slot];
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
index c0a015a..24e96df 100644
--- a/arch/sh/drivers/pci/fixups-sdk7780.c
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -22,7 +22,7 @@
 #define IRQ_INTD	evt2irq(0xa80)
 
 /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
-static char sdk7780_irq_tab[4][16] __initdata = {
+static char sdk7780_irq_tab[4][16] = {
 	/* INTA */
 	{ IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1,
 	  -1, -1, -1, -1, -1, -1 },
@@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = {
 	  -1, -1, -1 },
 };
 
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
        return sdk7780_irq_tab[pin-1][slot];
 }
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c
index 84a88ca..1cb8d0a 100644
--- a/arch/sh/drivers/pci/fixups-se7751.c
+++ b/arch/sh/drivers/pci/fixups-se7751.c
@@ -7,7 +7,7 @@
 #include <linux/sh_intc.h>
 #include "pci-sh4.h"
 
-int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
 {
         switch (slot) {
         case 0: return evt2irq(0x3a0);
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
index 16207be..55ac1ba 100644
--- a/arch/sh/drivers/pci/fixups-sh03.c
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -4,7 +4,7 @@
 #include <linux/pci.h>
 #include <linux/sh_intc.h>
 
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	int irq;
 
diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c
index 6e33ba4..a931e59 100644
--- a/arch/sh/drivers/pci/fixups-snapgear.c
+++ b/arch/sh/drivers/pci/fixups-snapgear.c
@@ -19,7 +19,7 @@
 #include <linux/sh_intc.h>
 #include "pci-sh4.h"
 
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	int irq = -1;
 
diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c
index bd1addb..a9d563e 100644
--- a/arch/sh/drivers/pci/fixups-titan.c
+++ b/arch/sh/drivers/pci/fixups-titan.c
@@ -19,7 +19,7 @@
 #include <mach/titan.h>
 #include "pci-sh4.h"
 
-static char titan_irq_tab[] __initdata = {
+static char titan_irq_tab[] = {
 	TITAN_IRQ_WAN,
 	TITAN_IRQ_LAN,
 	TITAN_IRQ_MPCIA,
@@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = {
 	TITAN_IRQ_USB,
 };
 
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	int irq = titan_irq_tab[slot];
 
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index a162a7f..0167a73 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
 	return 0;
 }
 
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
         return evt2irq(0xae0);
 }
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 13/29] sh/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (11 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 12/29] sh/PCI: Remove __init optimisations from IRQ mapping functions/data Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 14/29] alpha/PCI: " Matthew Minter
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently platform specific PCI device IRQ assignment is run during
the boot code, this results in a wide array of differing code paths
and causes hot-plugged PCI devices to not be assigned IRQs, this
patch removes the boot time initialisation of such IRQs and instead
registers assignment functions to be run during the PCI device enable
path.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/sh/drivers/pci/pci.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index d5462b7..28f8c90 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -144,16 +144,20 @@ static int __init pcibios_init(void)
 	for (hose = hose_head; hose; hose = hose->next)
 		pcibios_scanbus(hose);
 
-	pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
-
 	dma_debug_add_bus(&pci_bus_type);
-
 	pci_initialized = 1;
 
 	return 0;
 }
 subsys_initcall(pcibios_init);
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = pcibios_map_platform_irq;
+	return 0;
+}
+
 /*
  *  Called after each bus is probed, but before its children
  *  are examined.
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 14/29] alpha/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (12 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 13/29] sh/PCI: Defer IRQ assignment to device enable time Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 15/29] cris/PCI: " Matthew Minter
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

PCI IRQ initialisation is currently run during the boot code on alpha,
this has the issue that firstly an extra pass over the PCI bus is
required and second hot-plugged devices which are added after boot have
no way to be assigned an IRQ. This patch set fixes this by defering the
assignment of PCI IRQs untill device enable time which should solve
both of these issues.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/alpha/kernel/pci.c          | 7 ++++++-
 arch/alpha/kernel/sys_nautilus.c | 1 -
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 5f387ee..1c3c513 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -354,7 +354,6 @@ common_init_pci(void)
 	pcibios_claim_console_setup();
 
 	pci_assign_unassigned_resources();
-	pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
 	for (hose = hose_head; hose; hose = hose->next) {
 		bus = hose->bus;
 		if (bus)
@@ -362,6 +361,12 @@ common_init_pci(void)
 	}
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = alpha_mv.pci_swizzle;
+	bridge->map_irq = alpha_mv.pci_map_irq;
+	return 0;
+}
 
 struct pci_controller * __init
 alloc_pci_controller(void)
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
index 2cfaa0e..a3086dc 100644
--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -254,7 +254,6 @@ nautilus_init_pci(void)
 	/* pci_common_swizzle() relies on bus->self being NULL
 	   for the root bus, so just clear it. */
 	bus->self = NULL;
-	pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
 	pci_bus_add_devices(bus);
 }
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 15/29] cris/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (13 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 14/29] alpha/PCI: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 16/29] frv/PCI: " Matthew Minter
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

PCI IRQs are currently configured to be enabled once at boot in a
dedicated pass. This means that PCI devices which are hot-plugged after
boot time will not be given an IRQ, this patch-set fixes this by
registering the assignment function to be called later in the device
enable path.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/cris/arch-v32/drivers/pci/bios.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c
index 64a5fb9..2b7b79f 100644
--- a/arch/cris/arch-v32/drivers/pci/bios.c
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -80,9 +80,10 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-int pcibios_enable_irq(struct pci_dev *dev)
+int pcibios_enable_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	dev->irq = EXT_INTR_VECT;
+	if (!dev->msi_enabled)
+		dev->irq = EXT_INTR_VECT;
 	return 0;
 }
 
@@ -92,8 +93,11 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 
 	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
+	return 0;
+}
 
-	if (!dev->msi_enabled)
-		pcibios_enable_irq(dev);
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->map_irq = pcibios_enable_irq;
 	return 0;
 }
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 16/29] frv/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (14 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 15/29] cris/PCI: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 17/29] m68k/pci: " Matthew Minter
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

PCI IRQs are being assigned during the frv pcibios phase. This causes
devices which are not connected at boot but are later hot-plugged
to not receive an IRQ. This patch set causes the pcibios to instead
register an IRQ assignment function which is called during the enable
device path to apply to all devices.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/frv/mb93090-mb00/pci-frv.h |  1 -
 arch/frv/mb93090-mb00/pci-irq.c | 24 ++++++++++++------------
 arch/frv/mb93090-mb00/pci-vdk.c |  1 -
 3 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h
index d51992f..1537700 100644
--- a/arch/frv/mb93090-mb00/pci-frv.h
+++ b/arch/frv/mb93090-mb00/pci-frv.h
@@ -28,5 +28,4 @@ extern struct pci_ops *__nongpreldata pci_root_ops;
 extern unsigned int pcibios_irq_mask;
 
 void pcibios_irq_init(void);
-void pcibios_fixup_irqs(void);
 void pcibios_enable_irq(struct pci_dev *dev);
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index 1c35c93..2fde211 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -40,19 +40,19 @@ void __init pcibios_irq_init(void)
 {
 }
 
-void __init pcibios_fixup_irqs(void)
+int pcibios_map_irq(struct pci_dev *dev, uint8_t slot, uint8_t pin)
 {
-	struct pci_dev *dev = NULL;
-	uint8_t line, pin;
-
-	for_each_pci_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-		if (pin) {
-			dev->irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1];
-			pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-		}
-		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-	}
+	int irq;
+
+	irq = pci_bus0_irq_routing[PCI_SLOT(dev->devfn)][pin - 1];
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+	return irq;
+}
+
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->map_irq = pcibios_map_irq;
+	return 0;
 }
 
 void pcibios_enable_irq(struct pci_dev *dev)
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index f211839..22d59ed 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -387,7 +387,6 @@ int __init pcibios_init(void)
 	bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources);
 
 	pcibios_irq_init();
-	pcibios_fixup_irqs();
 	pcibios_resource_survey();
 	if (!bus)
 		return 0;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 17/29] m68k/pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (15 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 16/29] frv/PCI: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:44   ` kbuild test robot
  2015-10-23  5:03 ` [PATCH V4 18/29] microblaze/PCI: " Matthew Minter
                   ` (12 subsequent siblings)
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently PCI IRQs are assigned during mcf_pci_init which is only run
at boot time, this causes devices which are connected after boot time
to not receive an IRQ, this patch set fixes this by registering an IRQ
assignment function to be run later at device enable time.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/m68k/coldfire/pci.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c
index 821de92..86661cd 100644
--- a/arch/m68k/coldfire/pci.c
+++ b/arch/m68k/coldfire/pci.c
@@ -319,11 +319,17 @@ static int __init mcf_pci_init(void)
 	rootbus->resource[0] = &mcf_pci_io;
 	rootbus->resource[1] = &mcf_pci_mem;
 
-	pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq);
 	pci_bus_size_bridges(rootbus);
 	pci_bus_assign_resources(rootbus);
 	pci_bus_add_devices(rootbus);
 	return 0;
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = mcf_pci_map_irq;
+	return 0;
+}
+
 subsys_initcall(mcf_pci_init);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 18/29] microblaze/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (16 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 17/29] m68k/pci: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:40   ` kbuild test robot
  2015-10-23  5:03 ` [PATCH V4 19/29] MIPS/PCI: " Matthew Minter
                   ` (11 subsequent siblings)
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently microblaze assigns PCI IRQs during the pcibios phase, this means
that devices connected after boot will not be assigned an IRQ, instead the
boot code now registers IRQ assignment functions to be called later by the
device enable code paths.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/microblaze/pci/pci-common.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index ae838ed..99ea108 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -855,12 +855,15 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
 		 * code and is needed by the DMA init
 		 */
 		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
-
-		/* Read default IRQs and fixup if necessary */
-		dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
 	}
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->map_irq = of_irq_parse_and_map_pci;
+	return 0;
+}
+
 void pcibios_fixup_bus(struct pci_bus *bus)
 {
 	/* When called from the generic PCI probe, read PCI<->PCI bridge
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 19/29] MIPS/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (17 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 18/29] microblaze/PCI: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  6:02   ` kbuild test robot
  2015-10-23  5:03 ` [PATCH V4 20/29] mn10300: Defer PCI " Matthew Minter
                   ` (10 subsequent siblings)
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently mips PCI IRQs are assigned at boot, this creates an extra
pass over the PCI bus and causes hot-plugged devices which are not
present at boot to not be given IRQs, this patch set fixes this by
registering assignment functions which are then run later during the
device enable code path.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/mips/pci/pci.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index b8a0bf5..137d3fe 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -247,13 +247,18 @@ static int __init pcibios_init(void)
 	for (hose = hose_head; hose; hose = hose->next)
 		pcibios_scanbus(hose);
 
-	pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq);
-
 	pci_initialized = 1;
 
 	return 0;
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+       bridge->swizzle_irq = pci_common_swizzle;
+       bridge->map_irq = pcibios_map_irq;
+       return 0;
+}
+
 subsys_initcall(pcibios_init);
 
 static int pcibios_enable_resources(struct pci_dev *dev, int mask)
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 20/29] mn10300: Defer PCI IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (18 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 19/29] MIPS/PCI: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 21/29] mn10300: Remove pcibios_enable_device function Matthew Minter
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

PCI IRQs are being assigned during pcibios_irq_init currently, this causes
a problem by which hot-plug devices connected after boot will not recieve
an IRQ, this patch-set fixes this by registering the IRQ assignment
functions at boot, to then be called later by the device enable code.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/mn10300/unit-asb2305/pci-asb2305.h |  5 +----
 arch/mn10300/unit-asb2305/pci-irq.c     | 24 ++++--------------------
 arch/mn10300/unit-asb2305/pci.c         | 11 ++++++-----
 3 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.h b/arch/mn10300/unit-asb2305/pci-asb2305.h
index 96c484b..b7d5526 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.h
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.h
@@ -60,9 +60,6 @@ struct irq_routing_table {
 } __attribute__((packed));
 
 extern unsigned int pcibios_irq_mask;
-
-extern void pcibios_irq_init(void);
-extern void pcibios_fixup_irqs(void);
-extern void pcibios_enable_irq(struct pci_dev *dev);
+extern int pci_map_irq(struct pci_dev *, u8 slot, u8 pin);
 
 #endif /* PCI_ASB2305_H */
diff --git a/arch/mn10300/unit-asb2305/pci-irq.c b/arch/mn10300/unit-asb2305/pci-irq.c
index fcb28ce..d7d2ce9 100644
--- a/arch/mn10300/unit-asb2305/pci-irq.c
+++ b/arch/mn10300/unit-asb2305/pci-irq.c
@@ -20,27 +20,11 @@
 #include <asm/smp.h>
 #include "pci-asb2305.h"
 
-void __init pcibios_irq_init(void)
+int pci_map_irq(struct pci_dev *, u8 slot, u8 pin)
 {
-}
-
-void __init pcibios_fixup_irqs(void)
-{
-	struct pci_dev *dev = NULL;
-	u8 line, pin;
+	u8 line;
 
-	for_each_pci_dev(dev) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-		if (pin) {
-			dev->irq = XIRQ1;
-			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-					      dev->irq);
-		}
-		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-	}
-}
-
-void pcibios_enable_irq(struct pci_dev *dev)
-{
+	dev->irq = XIRQ1;
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
 }
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 3dfe2d3..37a22a5 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -375,14 +375,17 @@ static int __init pcibios_init(void)
 	bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources);
 	if (!bus)
 		return 0;
-
-	pcibios_irq_init();
-	pcibios_fixup_irqs();
 	pcibios_resource_survey();
 	pci_bus_add_devices(bus);
 	return 0;
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->map_irq = pci_map_irq;
+	return 0;
+}
+
 arch_initcall(pcibios_init);
 
 char *__init pcibios_setup(char *str)
@@ -400,8 +403,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	int err;
 
 	err = pci_enable_resources(dev, mask);
-	if (err == 0)
-		pcibios_enable_irq(dev);
 	return err;
 }
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 21/29] mn10300: Remove pcibios_enable_device function
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (19 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 20/29] mn10300: Defer PCI " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 22/29] sparc/PCI: Defer IRQ assignment to device enable time Matthew Minter
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The pcibios_enable_device is now identical to the generic version
in non arch specific code, so we can delete this one.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/mn10300/unit-asb2305/pci.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 37a22a5..c9fc19d 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -398,14 +398,6 @@ char *__init pcibios_setup(char *str)
 	return str;
 }
 
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-	int err;
-
-	err = pci_enable_resources(dev, mask);
-	return err;
-}
-
 /*
  * disable the ethernet chipset
  */
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 22/29] sparc/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (20 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 21/29] mn10300: Remove pcibios_enable_device function Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 23/29] tile: pci: " Matthew Minter
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently sparc allocates PCI IRQs through several different methods
based on device. This is done during the boot stage and faces a draw-back
by which hot-plugged devices will not be allocated an IRQ, this is fixed
by registering IRQ allocation functions for later use during the device
enable path.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/sparc/kernel/leon_pci.c | 12 ++++++++++--
 arch/sparc/kernel/pci.c      | 23 +++++++++++++++++++----
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index 4371f72..ca11fb8 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -13,6 +13,8 @@
 #include <asm/leon.h>
 #include <asm/leon_pci.h>
 
+int (*leon_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
+
 /* The LEON architecture does not rely on a BIOS or bootloader to setup
  * PCI for us. The Linux generic routines are used to setup resources,
  * reset values of configuration-space register settings are preserved.
@@ -39,14 +41,20 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 		return;
 	}
 
-	/* Setup IRQs of all devices using custom routines */
-	pci_fixup_irqs(pci_common_swizzle, info->map_irq);
+	leon_pci_map_irq = info->map_irq;
 
 	/* Assign devices with resources */
 	pci_assign_unassigned_resources();
 	pci_bus_add_devices(root_bus);
 }
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = leon_pci_map_irq;
+	return 0;
+}
+
 void pcibios_fixup_bus(struct pci_bus *pbus)
 {
 	struct pci_dev *dev;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b91d7f1..4841066 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -335,10 +335,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
 	} else {
 		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
 		dev->rom_base_reg = PCI_ROM_ADDRESS;
-
-		dev->irq = sd->op->archdata.irqs[0];
-		if (dev->irq == 0xffffffff)
-			dev->irq = PCI_IRQ_NONE;
 	}
 
 	pci_parse_of_addrs(sd->op, node, dev);
@@ -351,6 +347,25 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
 	return dev;
 }
 
+int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq;
+	struct platform_device *op = of_find_device_by_node(dev->sysdata);
+
+	irq = op->archdata.irqs[0];
+	if (irq == 0xffffffff)
+		irq = PCI_IRQ_NONE;
+	return irq;
+}
+
+#ifndef CONFIG_LEON_PCI
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->map_irq = pci_map_irq;
+	return 0;
+}
+#endif
+
 static void apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p)
 {
 	u32 idx, first, last;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 23/29] tile: pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (21 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 22/29] sparc/PCI: Defer IRQ assignment to device enable time Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:34   ` kbuild test robot
  2015-10-23  5:03 ` [PATCH V4 24/29] unicore32/PCI: " Matthew Minter
                   ` (6 subsequent siblings)
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Currently pcibios_init is running pci_fixup_irqs in order to assign
IRQs to PCI devices, this is only done once at boot-time and causes
devices hot-plugged after boot time to not be allocated an IRQ.
This is fixed in this patch-set by delaying the allocation untill
device enable time by registering the function to be called later.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/tile/kernel/pci.c    | 10 +++++++---
 arch/tile/kernel/pci_gx.c | 10 +++++++---
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index 9475a74..e151d80 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -313,9 +313,6 @@ int __init pcibios_init(void)
 		}
 	}
 
-	/* Do machine dependent PCI interrupt routing */
-	pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
-
 	/*
 	 * This comes from the generic Linux PCI driver.
 	 *
@@ -369,6 +366,13 @@ int __init pcibios_init(void)
 }
 subsys_initcall(pcibios_init);
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = tile_map_irq;
+	return 0;
+}
+
 /*
  * No bus fixups needed.
  */
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index 4c017d0..7eb3e2b 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -887,9 +887,6 @@ int __init pcibios_init(void)
 		next_busno = bus->busn_res.end + 1;
 	}
 
-	/* Do machine dependent PCI interrupt routing */
-	pci_fixup_irqs(pci_common_swizzle, tile_map_irq);
-
 	/*
 	 * This comes from the generic Linux PCI driver.
 	 *
@@ -1038,6 +1035,13 @@ alloc_mem_map_failed:
 }
 subsys_initcall(pcibios_init);
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = tile_map_irq;
+	return 0;
+}
+
 /* No bus fixups needed. */
 void pcibios_fixup_bus(struct pci_bus *bus)
 {
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 24/29] unicore32/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (22 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 23/29] tile: pci: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 25/29] PCI: Update pci-versatile to use IRQ deferred assignment Matthew Minter
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

PCI IRQs are currently assigned during pci_common_init, this is only run
at boot time so devices hot-plugged after boot will not be allocated an IRQ.
this is fixed here by defering the assignment untill the device enable code,
instead registering the function pointer at boot time.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 arch/unicore32/kernel/pci.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c
index d45fa5f..42295b2 100644
--- a/arch/unicore32/kernel/pci.c
+++ b/arch/unicore32/kernel/pci.c
@@ -101,7 +101,7 @@ void pci_puv3_preinit(void)
 	writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD);
 }
 
-static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	if (dev->bus->number == 0) {
 #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */
@@ -263,8 +263,6 @@ static int __init pci_common_init(void)
 	if (!puv3_bus)
 		panic("PCI: unable to scan bus!");
 
-	pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq);
-
 	if (!pci_has_flag(PCI_PROBE_ONLY)) {
 		pci_bus_size_bridges(puv3_bus);
 		pci_bus_assign_resources(puv3_bus);
@@ -274,6 +272,13 @@ static int __init pci_common_init(void)
 }
 subsys_initcall(pci_common_init);
 
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = pci_puv3_map_irq;
+	return 0;
+}
+
 char * __init pcibios_setup(char *str)
 {
 	if (!strcmp(str, "debug")) {
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 25/29] PCI: Update pci-versatile to use IRQ deferred assignment
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (23 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 24/29] unicore32/PCI: " Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:03 ` [PATCH V4 26/29] PCI: Update pcie-iproc to use IRQ deffered assignment Matthew Minter
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The pci-versatile platform device is using the fixup irqs code which
will be removed later in the code to migrate to deffered irq
assignment. This patch migrates it to use the new code path and
adds support for deffered irq assignment

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/host/pci-versatile.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
index 0863d9c..7f98f72 100644
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -135,6 +135,7 @@ static int versatile_pci_probe(struct platform_device *pdev)
 	u32 val;
 	void __iomem *local_pci_cfg_base;
 	struct pci_bus *bus;
+	struct pci_host_bridge *bridge;
 	LIST_HEAD(pci_res);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -211,8 +212,10 @@ static int versatile_pci_probe(struct platform_device *pdev)
 	bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, &sys, &pci_res);
 	if (!bus)
 		return -ENOMEM;
-
-	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	
+	bridge = pci_find_host_bridge(bus);
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = of_irq_parse_and_map_pci;
 	pci_assign_unassigned_bus_resources(bus);
 	pci_bus_add_devices(bus);
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 26/29] PCI: Update pcie-iproc to use IRQ deffered assignment
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (24 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 25/29] PCI: Update pci-versatile to use IRQ deferred assignment Matthew Minter
@ 2015-10-23  5:03 ` Matthew Minter
  2015-10-23  5:04 ` [PATCH V4 27/29] PCI: Update pci-host-generic " Matthew Minter
                   ` (3 subsequent siblings)
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:03 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The pcie-iproc device is using the fixup irqs code which
will be removed later in the code to migrate to deffered irq
assignment. This patch migrates it to use the new code path and
adds support for deffered irq assignment.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/host/pcie-iproc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index fe2efb1..b2e3305 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -195,6 +195,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 	int ret;
 	void *sysdata;
 	struct pci_bus *bus;
+#ifdef CONFIG_ARM
+	struct pci_host_bridge *bridge;
+#endif
 
 	if (!pcie || !pcie->dev || !pcie->base)
 		return -EINVAL;
@@ -235,12 +238,13 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 	}
 
 	iproc_pcie_enable(pcie);
-
-	pci_scan_child_bus(bus);
-	pci_assign_unassigned_bus_resources(bus);
 #ifdef CONFIG_ARM
-	pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
+	bridge = pci_find_host_bridge(bus);
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = pcie->map_irq;
 #endif
+	pci_scan_child_bus(bus);
+	pci_assign_unassigned_bus_resources(bus);
 	pci_bus_add_devices(bus);
 
 	return 0;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 27/29] PCI: Update pci-host-generic to use IRQ deffered assignment
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (25 preceding siblings ...)
  2015-10-23  5:03 ` [PATCH V4 26/29] PCI: Update pcie-iproc to use IRQ deffered assignment Matthew Minter
@ 2015-10-23  5:04 ` Matthew Minter
  2015-10-23  9:40   ` kbuild test robot
  2015-10-23  5:04 ` [PATCH V4 28/29] of/pci: Fix comment for pci_fixup_irqs changing to pci_assign_irq Matthew Minter
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:04 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

The pci-host-generic platform device is using the fixup irqs code which
will be removed later in the code to migrate to deffered irq
assignment. This patch migrates it to use the new code path and
adds support for deffered irq assignment

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/host/pci-host-generic.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 265dd25..0c12597 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -215,6 +215,7 @@ static int gen_pci_probe(struct platform_device *pdev)
 	struct device_node *np = dev->of_node;
 	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
 	struct pci_bus *bus, *child;
+	struct pci_host_bridge *bridge;
 
 	if (!pci)
 		return -ENOMEM;
@@ -262,7 +263,9 @@ static int gen_pci_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	bridge = pci_find_host_bridge(bus);
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = of_irq_parse_and_map_pci;
 
 	if (!pci_has_flag(PCI_PROBE_ONLY)) {
 		pci_bus_size_bridges(bus);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 28/29] of/pci: Fix comment for pci_fixup_irqs changing to pci_assign_irq
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (26 preceding siblings ...)
  2015-10-23  5:04 ` [PATCH V4 27/29] PCI: Update pci-host-generic " Matthew Minter
@ 2015-10-23  5:04 ` Matthew Minter
  2016-01-13 11:25   ` Lorenzo Pieralisi
  2015-10-23  5:04 ` [PATCH V4 29/29] PCI: Remove pci_fixup_irqs function Matthew Minter
  2015-12-07 17:32 ` [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Bjorn Helgaas
  29 siblings, 1 reply; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:04 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/of/of_pci_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
index 2306313..a742447 100644
--- a/drivers/of/of_pci_irq.c
+++ b/drivers/of/of_pci_irq.c
@@ -105,7 +105,7 @@ 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().
  */
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
 {
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* [PATCH V4 29/29] PCI: Remove pci_fixup_irqs function
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (27 preceding siblings ...)
  2015-10-23  5:04 ` [PATCH V4 28/29] of/pci: Fix comment for pci_fixup_irqs changing to pci_assign_irq Matthew Minter
@ 2015-10-23  5:04 ` Matthew Minter
  2015-12-07 17:32 ` [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Bjorn Helgaas
  29 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-10-23  5:04 UTC (permalink / raw)
  To: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi
  Cc: Matthew Minter

Now we have removed all callers of pci_fixup_irqs and
migrated everything to pci_assign_irq delete the
pci_fixup_irqs function completely.

Signed-off-by: Matthew Minter <matt@masarand.com>
---
 drivers/pci/setup-irq.c | 19 -------------------
 include/linux/pci.h     |  2 --
 2 files changed, 21 deletions(-)

diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index a9b7a30..0d4b83a 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -64,22 +64,3 @@ void pci_assign_irq(struct pci_dev *dev)
 	   the real IRQ to use; the device does not use it. */
 	pcibios_update_irq(dev, irq);
 }
-
-void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
-		    int (*map_irq)(struct pci_dev *, u8, u8))
-{
-	/* This code should be removed shortly, but in the mean time
-	   it can wrap the new codepath in order to allow arches
-	   still using it to continue working */
-	struct pci_dev *dev = NULL;
-	struct pci_host_bridge *hbrg = NULL;
-
-	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);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e88ad4f..6771d62 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1120,8 +1120,6 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
 void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
 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 (*)(struct pci_dev *, u8, u8));
 void pci_assign_irq(struct pci_dev *dev);
 #define HAVE_PCI_REQ_REGIONS	2
 int __must_check pci_request_regions(struct pci_dev *, const char *);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 23/29] tile: pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 ` [PATCH V4 23/29] tile: pci: " Matthew Minter
@ 2015-10-23  5:34   ` kbuild test robot
  0 siblings, 0 replies; 41+ messages in thread
From: kbuild test robot @ 2015-10-23  5:34 UTC (permalink / raw)
  To: Matthew Minter
  Cc: kbuild-all, linux-pci, bhelgaas, Liviu.Dudau, ddaney,
	lorenzo.pieralisi, Matthew Minter

[-- Attachment #1: Type: text/plain, Size: 1519 bytes --]

Hi Matthew,

[auto build test WARNING on v4.3-rc6 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/Matthew-Minter/PCI-Build-setup-irq-o-on-all-arches/20151023-131018
config: tile-allyesconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=tile 

All warnings (new ones prefixed by >>):

   arch/tile/kernel/pci_gx.c: In function 'pcibios_root_bridge_prepare':
>> arch/tile/kernel/pci_gx.c:1041:18: warning: assignment from incompatible pointer type [enabled by default]

vim +1041 arch/tile/kernel/pci_gx.c

  1025				continue;
  1026	
  1027	alloc_mem_map_failed:
  1028				break;
  1029			}
  1030	
  1031			pci_bus_add_devices(root_bus);
  1032		}
  1033	
  1034		return 0;
  1035	}
  1036	subsys_initcall(pcibios_init);
  1037	
  1038	int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
  1039	{
  1040		bridge->swizzle_irq = pci_common_swizzle;
> 1041		bridge->map_irq = tile_map_irq;
  1042		return 0;
  1043	}
  1044	
  1045	/* No bus fixups needed. */
  1046	void pcibios_fixup_bus(struct pci_bus *bus)
  1047	{
  1048	}
  1049	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 41622 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 18/29] microblaze/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 ` [PATCH V4 18/29] microblaze/PCI: " Matthew Minter
@ 2015-10-23  5:40   ` kbuild test robot
  0 siblings, 0 replies; 41+ messages in thread
From: kbuild test robot @ 2015-10-23  5:40 UTC (permalink / raw)
  To: Matthew Minter
  Cc: kbuild-all, linux-pci, bhelgaas, Liviu.Dudau, ddaney,
	lorenzo.pieralisi, Matthew Minter

[-- Attachment #1: Type: text/plain, Size: 1981 bytes --]

Hi Matthew,

[auto build test WARNING on v4.3-rc6 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/Matthew-Minter/PCI-Build-setup-irq-o-on-all-arches/20151023-131018
config: microblaze-mmu_defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=microblaze 

All warnings (new ones prefixed by >>):

   arch/microblaze/pci/pci-common.c: In function 'pcibios_root_bridge_prepare':
>> arch/microblaze/pci/pci-common.c:863:18: warning: assignment from incompatible pointer type
     bridge->map_irq = of_irq_parse_and_map_pci;
                     ^

vim +863 arch/microblaze/pci/pci-common.c

   847		pr_debug("PCI: Fixup bus devices %d (%s)\n",
   848			 bus->number, bus->self ? pci_name(bus->self) : "PHB");
   849	
   850		list_for_each_entry(dev, &bus->devices, bus_list) {
   851			/* Setup OF node pointer in archdata */
   852			dev->dev.of_node = pci_device_to_OF_node(dev);
   853	
   854			/* Fixup NUMA node as it may not be setup yet by the generic
   855			 * code and is needed by the DMA init
   856			 */
   857			set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
   858		}
   859	}
   860	
   861	int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
   862	{
 > 863		bridge->map_irq = of_irq_parse_and_map_pci;
   864		return 0;
   865	}
   866	
   867	void pcibios_fixup_bus(struct pci_bus *bus)
   868	{
   869		/* When called from the generic PCI probe, read PCI<->PCI bridge
   870		 * bases. This is -not- called when generating the PCI tree from
   871		 * the OF device-tree.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 11615 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 17/29] m68k/pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 ` [PATCH V4 17/29] m68k/pci: " Matthew Minter
@ 2015-10-23  5:44   ` kbuild test robot
  0 siblings, 0 replies; 41+ messages in thread
From: kbuild test robot @ 2015-10-23  5:44 UTC (permalink / raw)
  To: Matthew Minter
  Cc: kbuild-all, linux-pci, bhelgaas, Liviu.Dudau, ddaney,
	lorenzo.pieralisi, Matthew Minter

[-- Attachment #1: Type: text/plain, Size: 1629 bytes --]

Hi Matthew,

[auto build test WARNING on v4.3-rc6 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/Matthew-Minter/PCI-Build-setup-irq-o-on-all-arches/20151023-131018
config: m68k-m5475evb_defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=m68k 

All warnings (new ones prefixed by >>):

   arch/m68k/coldfire/pci.c: In function 'pcibios_root_bridge_prepare':
>> arch/m68k/coldfire/pci.c:331:18: warning: assignment from incompatible pointer type
     bridge->map_irq = mcf_pci_map_irq;
                     ^

vim +331 arch/m68k/coldfire/pci.c

   315		rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL);
   316		if (!rootbus)
   317			return -ENODEV;
   318	
   319		rootbus->resource[0] = &mcf_pci_io;
   320		rootbus->resource[1] = &mcf_pci_mem;
   321	
   322		pci_bus_size_bridges(rootbus);
   323		pci_bus_assign_resources(rootbus);
   324		pci_bus_add_devices(rootbus);
   325		return 0;
   326	}
   327	
   328	int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
   329	{
   330		bridge->swizzle_irq = pci_common_swizzle;
 > 331		bridge->map_irq = mcf_pci_map_irq;
   332		return 0;
   333	}
   334	
   335	subsys_initcall(mcf_pci_init);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 5891 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 19/29] MIPS/PCI: Defer IRQ assignment to device enable time
  2015-10-23  5:03 ` [PATCH V4 19/29] MIPS/PCI: " Matthew Minter
@ 2015-10-23  6:02   ` kbuild test robot
  0 siblings, 0 replies; 41+ messages in thread
From: kbuild test robot @ 2015-10-23  6:02 UTC (permalink / raw)
  To: Matthew Minter
  Cc: kbuild-all, linux-pci, bhelgaas, Liviu.Dudau, ddaney,
	lorenzo.pieralisi, Matthew Minter

[-- Attachment #1: Type: text/plain, Size: 1748 bytes --]

Hi Matthew,

[auto build test WARNING on v4.3-rc6 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/Matthew-Minter/PCI-Build-setup-irq-o-on-all-arches/20151023-131018
config: mips-fuloong2e_defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=mips 

All warnings (new ones prefixed by >>):

   arch/mips/pci/pci.c: In function 'pcibios_root_bridge_prepare':
>> arch/mips/pci/pci.c:258:24: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
           bridge->map_irq = pcibios_map_irq;
                           ^

vim +258 arch/mips/pci/pci.c

   242		struct pci_controller *hose;
   243	
   244		pcibios_set_cache_line_size();
   245	
   246		/* Scan all of the recorded PCI controllers.  */
   247		for (hose = hose_head; hose; hose = hose->next)
   248			pcibios_scanbus(hose);
   249	
   250		pci_initialized = 1;
   251	
   252		return 0;
   253	}
   254	
   255	int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
   256	{
   257	       bridge->swizzle_irq = pci_common_swizzle;
 > 258	       bridge->map_irq = pcibios_map_irq;
   259	       return 0;
   260	}
   261	
   262	subsys_initcall(pcibios_init);
   263	
   264	static int pcibios_enable_resources(struct pci_dev *dev, int mask)
   265	{
   266		u16 cmd, old_cmd;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 16396 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 27/29] PCI: Update pci-host-generic to use IRQ deffered assignment
  2015-10-23  5:04 ` [PATCH V4 27/29] PCI: Update pci-host-generic " Matthew Minter
@ 2015-10-23  9:40   ` kbuild test robot
  0 siblings, 0 replies; 41+ messages in thread
From: kbuild test robot @ 2015-10-23  9:40 UTC (permalink / raw)
  To: Matthew Minter
  Cc: kbuild-all, linux-pci, bhelgaas, Liviu.Dudau, ddaney,
	lorenzo.pieralisi, Matthew Minter

[-- Attachment #1: Type: text/plain, Size: 1912 bytes --]

Hi Matthew,

[auto build test ERROR on v4.3-rc6 -- if it's inappropriate base, please suggest rules for selecting the more suitable base]

url:    https://github.com/0day-ci/linux/commits/Matthew-Minter/PCI-Build-setup-irq-o-on-all-arches/20151023-131018
config: arm64-columbia_pt_defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All error/warnings (new ones prefixed by >>):

   drivers/pci/host/pci-host-generic.c: In function 'gen_pci_probe':
>> drivers/pci/host/pci-host-generic.c:266:2: error: implicit declaration of function 'pci_find_host_bridge' [-Werror=implicit-function-declaration]
     bridge = pci_find_host_bridge(bus);
     ^
>> drivers/pci/host/pci-host-generic.c:266:9: warning: assignment makes pointer from integer without a cast
     bridge = pci_find_host_bridge(bus);
            ^
>> drivers/pci/host/pci-host-generic.c:268:18: warning: assignment from incompatible pointer type
     bridge->map_irq = of_irq_parse_and_map_pci;
                     ^
   cc1: some warnings being treated as errors

vim +/pci_find_host_bridge +266 drivers/pci/host/pci-host-generic.c

   260		bus = pci_scan_root_bus(dev, 0, &gen_pci_ops, pci, &pci->resources);
   261		if (!bus) {
   262			dev_err(dev, "Scanning rootbus failed");
   263			return -ENODEV;
   264		}
   265	
 > 266		bridge = pci_find_host_bridge(bus);
   267		bridge->swizzle_irq = pci_common_swizzle;
 > 268		bridge->map_irq = of_irq_parse_and_map_pci;
   269	
   270		if (!pci_has_flag(PCI_PROBE_ONLY)) {
   271			pci_bus_size_bridges(bus);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 17911 bytes --]

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging
  2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
                   ` (28 preceding siblings ...)
  2015-10-23  5:04 ` [PATCH V4 29/29] PCI: Remove pci_fixup_irqs function Matthew Minter
@ 2015-12-07 17:32 ` Bjorn Helgaas
  2015-12-18 21:54   ` Christopher Covington
  29 siblings, 1 reply; 41+ messages in thread
From: Bjorn Helgaas @ 2015-12-07 17:32 UTC (permalink / raw)
  To: Matthew Minter
  Cc: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi

On Fri, Oct 23, 2015 at 06:03:33AM +0100, Matthew Minter wrote:
> Hi again everyone, this is the extremely long awaited version 4 of this patchset.
> 
> It has been rebased to the head of the lastest mainline kernel as of a few days
> ago as well as a huge number of small restructures have been included.

Hi Matthew,

Thanks a lot for updating this.  I noticed a few kbuild warnings; did you
get those, too?  I can forward them to you if you didn't.

Bjorn

> I have tried to include every suggested change from last round's reviewing
> but appologise in advance if I missed one, there were dozens of comments which
> I have tried to implement or fix. If I have indeed missed anything please let
> me know, it was likely not my rejecting the feedback but just missing it while
> reading through all the feedback I got.
> 
> The most notable change is this version should be bisectable as I have kept
> all the old mechanisms working untill all arches have been converted to the
> new code paths though I have not tested actually booting all the intermediate
> versions.
> 
> I have only been able to test this on an ACPI enabled amd64 computer (my own
> desktop) as I am now working on it only in free time without any resources
> from a lab so testing on other arches is very much appreciated.
> 
> I shall also note that my time to work on this in the future is very limited
> so any help anyone can provide in making any further changes which may be
> needed if another version is required would be appreciated as to avoid more
> potentially very long delays due to my limited availability.
> 
> Unlike the previous version, it should in theory be safe to apply patches
> 1 to 6 separately to the rest of the set, then the architecture specific
> patch sets could be applied in any order over time and the last patch to tidy
> up the old code can be applied last of all.
> 
> I am sorry for all the silly whitespace fixes, found in the last version
> their inclusion was due to my misconfigured editor applying them automatically
> then me failing to see them while reading over the diffs.
> 
> As always, comments and testers are appreciated but I am not sure I will be
> able to produce another version in the near future so any help with changes
> is also very much appreciated if there are issues.
> 
> This time I have also uploaded the patch set to github to aid any testers who
> do not wish to attempt to merge the patches from this email chain:
> 
> https://github.com/Vality/linux/tree/pci-fixes
> 
> Note that the changes are all in my pci-fixes branch so make sure to check
> out that before building.
> 
> Many thanks,
> Matthew
> 
> Patch description (same as v3) follows:
> 
> pci_fixup_irqs is the current method used in most arches to assign IRQs to
> PCI devices. This has a number of flaws including it requiring an extra walk
> of the PCI bus and most importantly not running for devices which are added
> after boot time, this includes hot-added devices on boards that support this.
> 
> This patch set modifies the IRQ mapping and swizzling infrastructure
> such that functions are registered by the boot code (instead of being
> run directly by the boot code) and then run later in the enable_device
> path such that it will apply to all devices and not only those inserted
> at boot time.
> 
> This is cleaner as it unifies how each architecture allocates PCI IRQs as much
> as possible (some arches were particularly resistant to these changes so some
> work-arounds have been used or the change disabled completely).
> 
> The caveat here is that I have been forced to modify some architecture specific
> code for various architectures which I cannot test due to not having such boards
> available. The code seems correct and the changes in most cases are small and
> trivial however I have not tested all the patches for rare arches.
> 
> arch/alpha/kernel/pci.c                 |  7 ++++++-
> arch/alpha/kernel/sys_nautilus.c        |  1 -
> arch/arm/kernel/bios32.c                |  9 +++++++--
> arch/cris/arch-v32/drivers/pci/bios.c   | 12 ++++++++----
> arch/frv/mb93090-mb00/pci-frv.h         |  1 -
> arch/frv/mb93090-mb00/pci-irq.c         | 24 ++++++++++++------------
> arch/frv/mb93090-mb00/pci-vdk.c         |  1 -
> arch/m68k/coldfire/pci.c                |  8 +++++++-
> arch/microblaze/pci/pci-common.c        |  9 ++++++---
> arch/mips/pci/pci.c                     |  9 +++++++--
> arch/mn10300/unit-asb2305/pci-asb2305.h |  5 +----
> arch/mn10300/unit-asb2305/pci-irq.c     | 24 ++++--------------------
> arch/mn10300/unit-asb2305/pci.c         | 19 ++++++-------------
> arch/powerpc/kernel/pci-common.c        | 25 ++++++++++++-------------
> arch/sh/drivers/pci/fixups-cayman.c     |  2 +-
> arch/sh/drivers/pci/fixups-dreamcast.c  |  2 +-
> arch/sh/drivers/pci/fixups-r7780rp.c    |  2 +-
> arch/sh/drivers/pci/fixups-rts7751r2d.c |  6 +++---
> arch/sh/drivers/pci/fixups-sdk7780.c    |  4 ++--
> arch/sh/drivers/pci/fixups-se7751.c     |  2 +-
> arch/sh/drivers/pci/fixups-sh03.c       |  2 +-
> arch/sh/drivers/pci/fixups-snapgear.c   |  2 +-
> arch/sh/drivers/pci/fixups-titan.c      |  4 ++--
> arch/sh/drivers/pci/pci.c               | 10 +++++++---
> arch/sh/drivers/pci/pcie-sh7786.c       |  2 +-
> arch/sparc/kernel/leon_pci.c            | 12 ++++++++++--
> arch/sparc/kernel/pci.c                 | 23 +++++++++++++++++++----
> arch/tile/kernel/pci.c                  | 10 +++++++---
> arch/tile/kernel/pci_gx.c               | 10 +++++++---
> arch/unicore32/kernel/pci.c             | 11 ++++++++---
> arch/x86/include/asm/pci_x86.h          |  7 ++++---
> arch/x86/kernel/x86_init.c              |  1 -
> arch/x86/pci/acpi.c                     | 15 ---------------
> arch/x86/pci/irq.c                      | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------------
> drivers/of/of_pci_irq.c                 |  2 +-
> drivers/pci/Makefile                    | 16 ++--------------
> drivers/pci/host/pci-host-generic.c     |  5 ++++-
> drivers/pci/host/pci-versatile.c        |  7 +++++--
> drivers/pci/host/pcie-iproc.c           | 12 ++++++++----
> drivers/pci/pci.c                       |  2 ++
> drivers/pci/pci.h                       |  1 +
> drivers/pci/setup-irq.c                 | 34 ++++++++++++++++------------------
> include/linux/pci.h                     |  5 +++--
> 43 files changed, 246 insertions(+), 210 deletions(-)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging
  2015-12-07 17:32 ` [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Bjorn Helgaas
@ 2015-12-18 21:54   ` Christopher Covington
  2015-12-19 11:50     ` Matthew Minter
  0 siblings, 1 reply; 41+ messages in thread
From: Christopher Covington @ 2015-12-18 21:54 UTC (permalink / raw)
  To: Bjorn Helgaas, Matthew Minter
  Cc: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi, tn

Hi Bjorn, Matthew,

On 12/07/2015 12:32 PM, Bjorn Helgaas wrote:
> On Fri, Oct 23, 2015 at 06:03:33AM +0100, Matthew Minter wrote:
>> Hi again everyone, this is the extremely long awaited version 4 of this patchset.
>>
>> It has been rebased to the head of the lastest mainline kernel as of a few days
>> ago as well as a huge number of small restructures have been included.
> 
> Hi Matthew,
> 
> Thanks a lot for updating this.  I noticed a few kbuild warnings; did you
> get those, too?  I can forward them to you if you didn't.

The compiler warnings are due to various map_irq functions still using
"const pci_dev *dev". I'm not familiar with this code, but based on a
brief build test of a change to tile, it seems like 04/29, PCI: Remove
const from the pci_dev struct passed to pci_fixup_irqs, needs to be
mirrored in some or all architecture directories. What I'm wondering is
whether just those warnings identified by the kbuild test robot should
be fixed, all of them (see bash snippet below), or something in between?

for f in $(git grep -l 'map_irq(const'); do
  sed -i 's/map_irq(const /map_irq(/' $f
done

Thanks,
Christopher Covington

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging
  2015-12-18 21:54   ` Christopher Covington
@ 2015-12-19 11:50     ` Matthew Minter
  0 siblings, 0 replies; 41+ messages in thread
From: Matthew Minter @ 2015-12-19 11:50 UTC (permalink / raw)
  To: Christopher Covington, Bjorn Helgaas
  Cc: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi, tn

Hi, Christopher, Bjorn,

Apologies for leaving these issues in. I don’t currently have resources to 
easily test compiling, yet alone running on most architectures.

I did not receive the buildbot warnings but have now had a look at them on the 
web archive since my attention was brought to them.

Attempting to remove constness from the pointer to map_irq functions was 
tricky as I was nervous to blindly change a bunch of functions for hardware I 
cannot easily compile for and cannot test on as it is hard for me to be 100% 
sure I have not broken behaviour without trying the code even if visually the 
changes look fine. I did not understand all the arch specific code well enough 
to verify for sure what behaviour was ok to change so ended up making the 
minimum changes to functionality of arch code possible.

I expect the ideal thing to do is to fix all of those pointers to be non const 
even where the buildbot did not give warnings as removing constness as far as 
I know should never break anything that isn't already broken but leaving it in 
incorrectly could cause hard to find issues. If it later becomes clear that it 
should be there it can always be re-added in another patch-set.

However a second opinion on this would be greatly appreciated as I dont know 
if some architecture code has non obvious restrictions here.

Also please note I will not have much time to spend developing and working on 
this over the next couple of weeks due to Christmas related events but will 
try and keep up to date on emails. But thanks everyone so far for the 
feedback.

Many thanks,
Matthew Minter

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time
  2015-10-23  5:03 ` [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time Matthew Minter
@ 2015-12-23 23:04   ` Bjorn Helgaas
  2016-01-12 11:25     ` Lorenzo Pieralisi
  0 siblings, 1 reply; 41+ messages in thread
From: Bjorn Helgaas @ 2015-12-23 23:04 UTC (permalink / raw)
  To: Matthew Minter
  Cc: linux-pci, bhelgaas, Liviu.Dudau, ddaney, lorenzo.pieralisi,
	Thomas Gleixner

[+cc Thomas]

Hi Matthew,

On Fri, Oct 23, 2015 at 06:03:41AM +0100, Matthew Minter wrote:
> The x86 architecture boot code currently traverses the PCI buses with
> an extra pass in order to initialise the PCI device IRQs at boot, this
> patch avoids this pass and defers the IRQ assignment untill device
> enable time which also has the benefit that hot-plugged devices are
> assigned IRQs without additional code.

I think the outline of this patch (doing the IRQ init at device
enable-time instead of at boot-time) is good, but I am concerned about
two things:

1) pcibios_lookup_irq() contains a for_each_pci_dev() loop that
updates dev->irq for all devices with the same pirq value.  Previously
we ran that loop at boot-time via this path:

  pci_subsys_init                   # subsys_initcall
    x86_init.pci.init_irq           # .init_irq = x86_default_pci_init_irq
    x86_default_pci_init_irq        # x86_default_pci_init_irq = pcibios_irq_init
    pcibios_irq_init
      x86_init.pci.fixup_irqs       # .fixup_irqs = x86_default_pci_fixup_irqs
      x86_default_pci_fixup_irqs    # x86_default_pci_fixup_irqs = pcibios_fixup_irqs
      pcibios_fixup_irqs
        for_each_pci_dev
          pcibios_lookup_irq

Now we'll run it later, in this path:

  pci_enable_device
    pci_enable_device_flags
      do_pci_enable_device
        pci_assign_irq
          pci_map_irq                   # bridge->map_irq
            pcibios_fixup_irq
              pcibios_lookup_irq
                for_each_pci_dev(dev2)
                  dev2->irq = irq       # <-- potential problem

The problem is that dev2 is an unrelated device and may already have a
driver bound to it, and we shouldn't change dev->irq after a driver
binds to a device.

I don't know enough about interrupts and PIRQ to know whether this is
really a problem in practice or not.  I added Thomas in case he knows.

2) I'm also worried about the fact that we don't do the IRQ init until
a driver calls pci_enable_device().  We've been doing some IRQ init in
pcibios_alloc_irq() in this path for a long time:

  pci_subsys_init
    ...
      pcibios_fixup_irqs                # <-- moved from here ...
        for_each_pci_dev
  ...
  pci_device_probe
    pcibios_alloc_irq
      pcibios_enable_irq                # pcibios_enable_irq = acpi_pci_irq_enable
                                        # (or pirq_enable_irq, x86_of_pci_irq_enable, lguest_enable_irq, etc)
      acpi_pci_irq_enable
    __pci_device_probe
      ...
	pci_drv->probe                  # driver .probe routine
	  ...
	    pci_enable_device
              ...
                pci_fixup_irq           # <-- ... to here

I think there are two problems here:

2.1) We changed the order of pcibios_enable_irq() and pci_fixup_irq().
Both update dev->irq, and I doubt it's safe to reverse the order.

2.2) It's conceivable that a driver may use interrupts without ever
calling pci_enable_device().  That driver would be broken by this
change.

I think we could probably fix both of these worries by calling
pci_assign_irq() from pci_device_probe() instead of from
do_pci_enable_device().

I'm not so sure about the pcibios_lookup_irq() problem.  That's a
little farther outside my area, so I'll have to look at that some
more.

I really want to merge this stuff because it's a major cleanup, so I'm
going to push on this more myself.  I'm just writing this as a
heads-up in case anybody else has ideas.

Bjorn

> Signed-off-by: Matthew Minter <matt@masarand.com>
> ---
>  arch/x86/include/asm/pci_x86.h |  7 +++--
>  arch/x86/kernel/x86_init.c     |  1 -
>  arch/x86/pci/irq.c             | 70 +++++++++++++++++++++---------------------
>  3 files changed, 39 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index fa1195d..16fd8e9 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -90,6 +90,7 @@ extern unsigned int pcibios_irq_mask;
>  
>  extern raw_spinlock_t pci_config_lock;
>  
> +extern int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
>  extern int (*pcibios_enable_irq)(struct pci_dev *dev);
>  extern void (*pcibios_disable_irq)(struct pci_dev *dev);
>  
> @@ -119,7 +120,7 @@ extern int __init pci_acpi_init(void);
>  extern void __init pcibios_irq_init(void);
>  extern int __init pcibios_init(void);
>  extern int pci_legacy_init(void);
> -extern void pcibios_fixup_irqs(void);
> +extern int pcibios_fixup_irq(struct pci_dev *dev, u8 pin);
>  
>  /* pci-mmconfig.c */
>  
> @@ -200,9 +201,9 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val)
>  #  define x86_default_pci_init		pci_legacy_init
>  # endif
>  # define x86_default_pci_init_irq	pcibios_irq_init
> -# define x86_default_pci_fixup_irqs	pcibios_fixup_irqs
> +# define x86_default_pci_fixup_irq	pcibios_fixup_irq
>  #else
>  # define x86_default_pci_init		NULL
>  # define x86_default_pci_init_irq	NULL
> -# define x86_default_pci_fixup_irqs	NULL
> +# define x86_default_pci_fixup_irq	NULL
>  #endif
> diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
> index 3839628..810f1dd 100644
> --- a/arch/x86/kernel/x86_init.c
> +++ b/arch/x86/kernel/x86_init.c
> @@ -80,7 +80,6 @@ struct x86_init_ops x86_init __initdata = {
>  	.pci = {
>  		.init			= x86_default_pci_init,
>  		.init_irq		= x86_default_pci_init_irq,
> -		.fixup_irqs		= x86_default_pci_fixup_irqs,
>  	},
>  };
>  
> diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
> index 350e785..15c507b 100644
> --- a/arch/x86/pci/irq.c
> +++ b/arch/x86/pci/irq.c
> @@ -1021,47 +1021,38 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
>  	return 1;
>  }
>  
> -void __init pcibios_fixup_irqs(void)
> +int pcibios_fixup_irq(struct pci_dev *dev, u8 pin)
>  {
> -	struct pci_dev *dev = NULL;
> -	u8 pin;
> -
> +	int irq = dev->irq;
>  	DBG(KERN_DEBUG "PCI: IRQ fixup\n");
> -	for_each_pci_dev(dev) {
> -		/*
> -		 * If the BIOS has set an out of range IRQ number, just
> -		 * ignore it.  Also keep track of which IRQ's are
> -		 * already in use.
> -		 */
> -		if (dev->irq >= 16) {
> -			dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq);
> -			dev->irq = 0;
> -		}
> -		/*
> -		 * If the IRQ is already assigned to a PCI device,
> -		 * ignore its ISA use penalty
> -		 */
> -		if (pirq_penalty[dev->irq] >= 100 &&
> -				pirq_penalty[dev->irq] < 100000)
> -			pirq_penalty[dev->irq] = 0;
> -		pirq_penalty[dev->irq]++;
> +	/*
> +	 * If the BIOS has set an out of range IRQ number, just
> +	 * ignore it.  Also keep track of which IRQ's are
> +	 * already in use.
> +	 */
> +	if (irq >= 16) {
> +		dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", irq);
> +		irq = 0;
>  	}
> +	/*
> +	 * If the IRQ is already assigned to a PCI device,
> +	 * ignore its ISA use penalty
> +	 */
> +	if (pirq_penalty[irq] >= 100 &&
> +			pirq_penalty[irq] < 100000)
> +		pirq_penalty[irq] = 0;
> +	pirq_penalty[irq]++;
>  
> -	if (io_apic_assign_pci_irqs)
> -		return;
> +	if (io_apic_assign_pci_irqs || !pin)
> +		return irq;
>  
> -	dev = NULL;
> -	for_each_pci_dev(dev) {
> -		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
> -		if (!pin)
> -			continue;
> +	/*
> +	 * Still no IRQ? Try to lookup one...
> +	 */
> +	if (!irq && pcibios_lookup_irq(dev, 0))
> +		irq = dev->irq;
>  
> -		/*
> -		 * Still no IRQ? Try to lookup one...
> -		 */
> -		if (!dev->irq)
> -			pcibios_lookup_irq(dev, 0);
> -	}
> +	return irq;
>  }
>  
>  /*
> @@ -1174,6 +1165,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
>  		struct pci_sysdata *sd = bridge->bus->sysdata;
>  		ACPI_COMPANION_SET(&bridge->dev, sd->companion);
>  	}
> +	bridge->map_irq = pci_map_irq;
>  	return 0;
>  }
>  
> @@ -1201,6 +1193,14 @@ void pcibios_penalize_isa_irq(int irq, int active)
>  		pirq_penalize_isa_irq(irq, active);
>  }
>  
> +int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
> +{
> +	dev->irq = pcibios_fixup_irq(dev, pin);
> +	if (pcibios_enable_irq(dev))
> +		return -1;
> +	return dev->irq;
> +}
> +
>  static int pirq_enable_irq(struct pci_dev *dev)
>  {
>  	u8 pin = 0;
> -- 
> 2.6.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time
  2015-12-23 23:04   ` Bjorn Helgaas
@ 2016-01-12 11:25     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 41+ messages in thread
From: Lorenzo Pieralisi @ 2016-01-12 11:25 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Matthew Minter, linux-pci, bhelgaas, Liviu.Dudau, ddaney,
	Thomas Gleixner

Hi Bjorn,

On Wed, Dec 23, 2015 at 05:04:33PM -0600, Bjorn Helgaas wrote:
> [+cc Thomas]
> 
> Hi Matthew,
> 
> On Fri, Oct 23, 2015 at 06:03:41AM +0100, Matthew Minter wrote:
> > The x86 architecture boot code currently traverses the PCI buses with
> > an extra pass in order to initialise the PCI device IRQs at boot, this
> > patch avoids this pass and defers the IRQ assignment untill device
> > enable time which also has the benefit that hot-plugged devices are
> > assigned IRQs without additional code.
> 
> I think the outline of this patch (doing the IRQ init at device
> enable-time instead of at boot-time) is good, but I am concerned about
> two things:
> 
> 1) pcibios_lookup_irq() contains a for_each_pci_dev() loop that
> updates dev->irq for all devices with the same pirq value.  Previously
> we ran that loop at boot-time via this path:
> 
>   pci_subsys_init                   # subsys_initcall
>     x86_init.pci.init_irq           # .init_irq = x86_default_pci_init_irq
>     x86_default_pci_init_irq        # x86_default_pci_init_irq = pcibios_irq_init
>     pcibios_irq_init
>       x86_init.pci.fixup_irqs       # .fixup_irqs = x86_default_pci_fixup_irqs
>       x86_default_pci_fixup_irqs    # x86_default_pci_fixup_irqs = pcibios_fixup_irqs
>       pcibios_fixup_irqs
>         for_each_pci_dev
>           pcibios_lookup_irq
> 
> Now we'll run it later, in this path:
> 
>   pci_enable_device
>     pci_enable_device_flags
>       do_pci_enable_device
>         pci_assign_irq
>           pci_map_irq                   # bridge->map_irq
>             pcibios_fixup_irq
>               pcibios_lookup_irq
>                 for_each_pci_dev(dev2)
>                   dev2->irq = irq       # <-- potential problem
> 
> The problem is that dev2 is an unrelated device and may already have a
> driver bound to it, and we shouldn't change dev->irq after a driver
> binds to a device.

Yes, this looks wrong. On the other hand, removing pci_fixup_irqs from
generic PCI code does not mean that we cannot implement it in x86 using
pci_assign_irq() (in arch code) and leave the current behaviour unchanged.

True, do_pci_enable_device() (or better pci_device_probe() as you say
below) would carry out the fixup unconditionally, but if arch code
carries out the fixup before do_pci_enable_device() I *guess* that the
one carried out in do_pci_enable_device() would become a nop (the fixup
already assigned an IRQ so basically doing it again in do_pci_enable_device()
should not change anything. Still, I am not a fan of this solution either).

I would avoid holding this patch series back, it is a nice clean-up.

> I don't know enough about interrupts and PIRQ to know whether this is
> really a problem in practice or not.  I added Thomas in case he knows.
> 
> 2) I'm also worried about the fact that we don't do the IRQ init until
> a driver calls pci_enable_device().  We've been doing some IRQ init in
> pcibios_alloc_irq() in this path for a long time:
> 
>   pci_subsys_init
>     ...
>       pcibios_fixup_irqs                # <-- moved from here ...
>         for_each_pci_dev
>   ...
>   pci_device_probe
>     pcibios_alloc_irq
>       pcibios_enable_irq                # pcibios_enable_irq = acpi_pci_irq_enable
>                                         # (or pirq_enable_irq, x86_of_pci_irq_enable, lguest_enable_irq, etc)
>       acpi_pci_irq_enable
>     __pci_device_probe
>       ...
> 	pci_drv->probe                  # driver .probe routine
> 	  ...
> 	    pci_enable_device
>               ...
>                 pci_fixup_irq           # <-- ... to here
> 
> I think there are two problems here:
> 
> 2.1) We changed the order of pcibios_enable_irq() and pci_fixup_irq().
> Both update dev->irq, and I doubt it's safe to reverse the order.
> 
> 2.2) It's conceivable that a driver may use interrupts without ever
> calling pci_enable_device().  That driver would be broken by this
> change.
> 
> I think we could probably fix both of these worries by calling
> pci_assign_irq() from pci_device_probe() instead of from
> do_pci_enable_device().

Yes, I think your proposal makes sense (we can even add it to
pci_device_add() (?), the pointers in the bridge used to carry out the
mapping, set-up in pci_create_root_bus()->pcibios_root_bridge_prepare()
are already set-up by the time that function is called).

Actually, executing pci_assign_irq() in pci_device_add(), would not
it solve the issue above too ? Certainly we would still have an issue
with hot-added devices (I have no idea how this works at present
on x86).

We have to decide if the assignment can be done in generic code or
in pcibios_* arches callbacks (to do it on a per-arch basis).

> I'm not so sure about the pcibios_lookup_irq() problem.  That's a
> little farther outside my area, so I'll have to look at that some
> more.
> 
> I really want to merge this stuff because it's a major cleanup, so I'm
> going to push on this more myself.  I'm just writing this as a
> heads-up in case anybody else has ideas.

+1, I am reviewing the ARM/ARM64 code to check for correctness.

Thanks,
Lorenzo

> 
> Bjorn
> 
> > Signed-off-by: Matthew Minter <matt@masarand.com>
> > ---
> >  arch/x86/include/asm/pci_x86.h |  7 +++--
> >  arch/x86/kernel/x86_init.c     |  1 -
> >  arch/x86/pci/irq.c             | 70 +++++++++++++++++++++---------------------
> >  3 files changed, 39 insertions(+), 39 deletions(-)
> > 
> > diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> > index fa1195d..16fd8e9 100644
> > --- a/arch/x86/include/asm/pci_x86.h
> > +++ b/arch/x86/include/asm/pci_x86.h
> > @@ -90,6 +90,7 @@ extern unsigned int pcibios_irq_mask;
> >  
> >  extern raw_spinlock_t pci_config_lock;
> >  
> > +extern int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
> >  extern int (*pcibios_enable_irq)(struct pci_dev *dev);
> >  extern void (*pcibios_disable_irq)(struct pci_dev *dev);
> >  
> > @@ -119,7 +120,7 @@ extern int __init pci_acpi_init(void);
> >  extern void __init pcibios_irq_init(void);
> >  extern int __init pcibios_init(void);
> >  extern int pci_legacy_init(void);
> > -extern void pcibios_fixup_irqs(void);
> > +extern int pcibios_fixup_irq(struct pci_dev *dev, u8 pin);
> >  
> >  /* pci-mmconfig.c */
> >  
> > @@ -200,9 +201,9 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val)
> >  #  define x86_default_pci_init		pci_legacy_init
> >  # endif
> >  # define x86_default_pci_init_irq	pcibios_irq_init
> > -# define x86_default_pci_fixup_irqs	pcibios_fixup_irqs
> > +# define x86_default_pci_fixup_irq	pcibios_fixup_irq
> >  #else
> >  # define x86_default_pci_init		NULL
> >  # define x86_default_pci_init_irq	NULL
> > -# define x86_default_pci_fixup_irqs	NULL
> > +# define x86_default_pci_fixup_irq	NULL
> >  #endif
> > diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
> > index 3839628..810f1dd 100644
> > --- a/arch/x86/kernel/x86_init.c
> > +++ b/arch/x86/kernel/x86_init.c
> > @@ -80,7 +80,6 @@ struct x86_init_ops x86_init __initdata = {
> >  	.pci = {
> >  		.init			= x86_default_pci_init,
> >  		.init_irq		= x86_default_pci_init_irq,
> > -		.fixup_irqs		= x86_default_pci_fixup_irqs,
> >  	},
> >  };
> >  
> > diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
> > index 350e785..15c507b 100644
> > --- a/arch/x86/pci/irq.c
> > +++ b/arch/x86/pci/irq.c
> > @@ -1021,47 +1021,38 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
> >  	return 1;
> >  }
> >  
> > -void __init pcibios_fixup_irqs(void)
> > +int pcibios_fixup_irq(struct pci_dev *dev, u8 pin)
> >  {
> > -	struct pci_dev *dev = NULL;
> > -	u8 pin;
> > -
> > +	int irq = dev->irq;
> >  	DBG(KERN_DEBUG "PCI: IRQ fixup\n");
> > -	for_each_pci_dev(dev) {
> > -		/*
> > -		 * If the BIOS has set an out of range IRQ number, just
> > -		 * ignore it.  Also keep track of which IRQ's are
> > -		 * already in use.
> > -		 */
> > -		if (dev->irq >= 16) {
> > -			dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq);
> > -			dev->irq = 0;
> > -		}
> > -		/*
> > -		 * If the IRQ is already assigned to a PCI device,
> > -		 * ignore its ISA use penalty
> > -		 */
> > -		if (pirq_penalty[dev->irq] >= 100 &&
> > -				pirq_penalty[dev->irq] < 100000)
> > -			pirq_penalty[dev->irq] = 0;
> > -		pirq_penalty[dev->irq]++;
> > +	/*
> > +	 * If the BIOS has set an out of range IRQ number, just
> > +	 * ignore it.  Also keep track of which IRQ's are
> > +	 * already in use.
> > +	 */
> > +	if (irq >= 16) {
> > +		dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", irq);
> > +		irq = 0;
> >  	}
> > +	/*
> > +	 * If the IRQ is already assigned to a PCI device,
> > +	 * ignore its ISA use penalty
> > +	 */
> > +	if (pirq_penalty[irq] >= 100 &&
> > +			pirq_penalty[irq] < 100000)
> > +		pirq_penalty[irq] = 0;
> > +	pirq_penalty[irq]++;
> >  
> > -	if (io_apic_assign_pci_irqs)
> > -		return;
> > +	if (io_apic_assign_pci_irqs || !pin)
> > +		return irq;
> >  
> > -	dev = NULL;
> > -	for_each_pci_dev(dev) {
> > -		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
> > -		if (!pin)
> > -			continue;
> > +	/*
> > +	 * Still no IRQ? Try to lookup one...
> > +	 */
> > +	if (!irq && pcibios_lookup_irq(dev, 0))
> > +		irq = dev->irq;
> >  
> > -		/*
> > -		 * Still no IRQ? Try to lookup one...
> > -		 */
> > -		if (!dev->irq)
> > -			pcibios_lookup_irq(dev, 0);
> > -	}
> > +	return irq;
> >  }
> >  
> >  /*
> > @@ -1174,6 +1165,7 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
> >  		struct pci_sysdata *sd = bridge->bus->sysdata;
> >  		ACPI_COMPANION_SET(&bridge->dev, sd->companion);
> >  	}
> > +	bridge->map_irq = pci_map_irq;
> >  	return 0;
> >  }
> >  
> > @@ -1201,6 +1193,14 @@ void pcibios_penalize_isa_irq(int irq, int active)
> >  		pirq_penalize_isa_irq(irq, active);
> >  }
> >  
> > +int pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
> > +{
> > +	dev->irq = pcibios_fixup_irq(dev, pin);
> > +	if (pcibios_enable_irq(dev))
> > +		return -1;
> > +	return dev->irq;
> > +}
> > +
> >  static int pirq_enable_irq(struct pci_dev *dev)
> >  {
> >  	u8 pin = 0;
> > -- 
> > 2.6.2
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: [PATCH V4 28/29] of/pci: Fix comment for pci_fixup_irqs changing to pci_assign_irq
  2015-10-23  5:04 ` [PATCH V4 28/29] of/pci: Fix comment for pci_fixup_irqs changing to pci_assign_irq Matthew Minter
@ 2016-01-13 11:25   ` Lorenzo Pieralisi
  0 siblings, 0 replies; 41+ messages in thread
From: Lorenzo Pieralisi @ 2016-01-13 11:25 UTC (permalink / raw)
  To: Matthew Minter; +Cc: linux-pci, bhelgaas, Liviu.Dudau, ddaney

On Fri, Oct 23, 2015 at 06:04:01AM +0100, Matthew Minter wrote:
> Signed-off-by: Matthew Minter <matt@masarand.com>
> ---
>  drivers/of/of_pci_irq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
> index 2306313..a742447 100644
> --- a/drivers/of/of_pci_irq.c
> +++ b/drivers/of/of_pci_irq.c
> @@ -105,7 +105,7 @@ 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().

No,

>   */
>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
				^^^^^

it can't without getting compile warnings:

drivers/pci/host/pci-host-generic.c: In function 'gen_pci_probe':
drivers/pci/host/pci-host-generic.c:265:18: warning: assignment from
incompatible pointer type [-Wincompatible-pointer-types]
  bridge->map_irq = of_irq_parse_and_map_pci;

You did not add the const qualifier in the bridge *map_irq prototype
because the x86 implementation has to modify the dev passed to it,
question is if the x86 implementation may be made to return the irq
instead of modifying the dev directly, which is IMHO the expected
behaviour (I know there is x86 legacy code to deal with, I will have a
look to see if we can refactor that code).

of_irq_parse_and_map_pci() is not supposed to change the dev passed to
it so I think we should keep it as is.

Lorenzo

^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2016-01-13 11:24 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-23  5:03 [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Matthew Minter
2015-10-23  5:03 ` [PATCH V4 01/29] PCI: Build setup-irq.o on all arches Matthew Minter
2015-10-23  5:03 ` [PATCH V4 02/29] PCI: Add a prototype for pci_find_host_bridge to pci.h Matthew Minter
2015-10-23  5:03 ` [PATCH V4 03/29] PCI: Add IRQ mapping function pointers to pci_host_bridge struct Matthew Minter
2015-10-23  5:03 ` [PATCH V4 04/29] PCI: Remove const from the pci_dev struct passed to pci_fixup_irqs Matthew Minter
2015-10-23  5:03 ` [PATCH V4 05/29] PCI: Add pci_assign_irq function and have pci_fixup_irqs use it Matthew Minter
2015-10-23  5:03 ` [PATCH V4 06/29] PCI: Add a call to pci_assign_irq in do_pci_enable_device Matthew Minter
2015-10-23  5:03 ` [PATCH V4 07/29] x86/pci: Move pcibios_root_bridge_prepare from acpi.c to irq.c Matthew Minter
2015-10-23  5:03 ` [PATCH V4 08/29] x86/pci: Defer IRQ assignment to device enable time Matthew Minter
2015-12-23 23:04   ` Bjorn Helgaas
2016-01-12 11:25     ` Lorenzo Pieralisi
2015-10-23  5:03 ` [PATCH V4 09/29] x86/pci: Pass pin into pcibios_lookup_irq rather than look it up Matthew Minter
2015-10-23  5:03 ` [PATCH V4 10/29] ARM/PCI: Defer IRQ assignment to device enable time Matthew Minter
2015-10-23  5:03 ` [PATCH V4 11/29] powerpc/pci: " Matthew Minter
2015-10-23  5:03 ` [PATCH V4 12/29] sh/PCI: Remove __init optimisations from IRQ mapping functions/data Matthew Minter
2015-10-23  5:03 ` [PATCH V4 13/29] sh/PCI: Defer IRQ assignment to device enable time Matthew Minter
2015-10-23  5:03 ` [PATCH V4 14/29] alpha/PCI: " Matthew Minter
2015-10-23  5:03 ` [PATCH V4 15/29] cris/PCI: " Matthew Minter
2015-10-23  5:03 ` [PATCH V4 16/29] frv/PCI: " Matthew Minter
2015-10-23  5:03 ` [PATCH V4 17/29] m68k/pci: " Matthew Minter
2015-10-23  5:44   ` kbuild test robot
2015-10-23  5:03 ` [PATCH V4 18/29] microblaze/PCI: " Matthew Minter
2015-10-23  5:40   ` kbuild test robot
2015-10-23  5:03 ` [PATCH V4 19/29] MIPS/PCI: " Matthew Minter
2015-10-23  6:02   ` kbuild test robot
2015-10-23  5:03 ` [PATCH V4 20/29] mn10300: Defer PCI " Matthew Minter
2015-10-23  5:03 ` [PATCH V4 21/29] mn10300: Remove pcibios_enable_device function Matthew Minter
2015-10-23  5:03 ` [PATCH V4 22/29] sparc/PCI: Defer IRQ assignment to device enable time Matthew Minter
2015-10-23  5:03 ` [PATCH V4 23/29] tile: pci: " Matthew Minter
2015-10-23  5:34   ` kbuild test robot
2015-10-23  5:03 ` [PATCH V4 24/29] unicore32/PCI: " Matthew Minter
2015-10-23  5:03 ` [PATCH V4 25/29] PCI: Update pci-versatile to use IRQ deferred assignment Matthew Minter
2015-10-23  5:03 ` [PATCH V4 26/29] PCI: Update pcie-iproc to use IRQ deffered assignment Matthew Minter
2015-10-23  5:04 ` [PATCH V4 27/29] PCI: Update pci-host-generic " Matthew Minter
2015-10-23  9:40   ` kbuild test robot
2015-10-23  5:04 ` [PATCH V4 28/29] of/pci: Fix comment for pci_fixup_irqs changing to pci_assign_irq Matthew Minter
2016-01-13 11:25   ` Lorenzo Pieralisi
2015-10-23  5:04 ` [PATCH V4 29/29] PCI: Remove pci_fixup_irqs function Matthew Minter
2015-12-07 17:32 ` [PATCH V4] Delay allocation of PCI device IRQs from boot time until bus scan time to fix PCI hotplugging Bjorn Helgaas
2015-12-18 21:54   ` Christopher Covington
2015-12-19 11:50     ` Matthew Minter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.