[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1369762514-27352-1-git-send-email-linux@roeck-us.net>
Date: Tue, 28 May 2013 10:35:14 -0700
From: Guenter Roeck <linux@...ck-us.net>
To: Benjamin Herrenschmidt <benh@...nel.crashing.org>
Cc: Paul Mackerras <paulus@...ba.org>, linuxppc-dev@...ts.ozlabs.org,
linux-kernel@...r.kernel.org, Guenter Roeck <linux@...ck-us.net>,
Yuanquan Chen <Yuanquan.Chen@...escale.com>,
Hiroo Matsumoto <matsumoto.hiroo@...fujitsu.com>
Subject: [PATCH] powerpc/pci: Improve device hotplug initialization
Commit 37f02195b (powerpc/pci: fix PCI-e devices rescan issue on powerpc
platform) fixes a problem with interrupt and DMA initialization on hot
plugged devices. With this commit, interrupt and DMA initialization for
hot plugged devices is handled in the pci device enable function.
This approach has a couple of drawbacks. First, it creates two code paths
for device initialization, one for hot plugged devices and another for devices
known during the initial PCI scan. Second, the initialization code for hot
plugged devices is only called when the device is enabled, ie typically
in the probe function. Also, the platform specific setup code is called each
time pci_enable_device() is called, not only once during device discovery,
meaning it is actually called multiple times, once for devices discovered
during the initial scan and again each time a driver is re-loaded.
The visible result is that interrupt pins are only assigned to hot plugged
devices when the device driver is loaded. Effectively this changes the PCI
probe API, since pci_dev->irq and the device's dma configuration will now
only be valid after pci_enable() was called at least once. A more subtle
change is that platform specific PCI device setup is moved from device
discovery into the driver's probe function, more specifically into the
pci_enable_device() call.
To fix the inconsistencies, replace pcibios_setup_device() with
pcibios_add_device(). Drop explicit calls to pcibios_setup_device();
this makes pcibios_setup_bus_devices() a noop function which could
eventually be dropped. With this change, device initialization is called
exactly once and consistently for both static and hot plugged devices.
Since pcibios_add_device() is called from pci_device_add(), which initializes
the numa node, drop the now redundant additional numa node initialization.
Cc: Yuanquan Chen <Yuanquan.Chen@...escale.com>
Cc: Benjamin Herrenschmidt <benh@...nel.crashing.org>
Cc: Hiroo Matsumoto <matsumoto.hiroo@...fujitsu.com>
Signed-off-by: Guenter Roeck <linux@...ck-us.net>
---
arch/powerpc/kernel/pci-common.c | 25 ++++---------------------
1 file changed, 4 insertions(+), 21 deletions(-)
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 6053f03..41dd980 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1004,13 +1004,8 @@ void pcibios_setup_bus_self(struct pci_bus *bus)
ppc_md.pci_dma_bus_setup(bus);
}
-void pcibios_setup_device(struct pci_dev *dev)
+int pcibios_add_device(struct pci_dev *dev)
{
- /* Fixup NUMA node as it may not be setup yet by the generic
- * code and is needed by the DMA init
- */
- set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
-
/* Hook up default DMA ops */
set_dma_ops(&dev->dev, pci_dma_ops);
set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
@@ -1023,24 +1018,16 @@ void pcibios_setup_device(struct pci_dev *dev)
pci_read_irq_line(dev);
if (ppc_md.pci_irq_fixup)
ppc_md.pci_irq_fixup(dev);
+
+ return 0;
}
void pcibios_setup_bus_devices(struct pci_bus *bus)
{
- struct pci_dev *dev;
-
pr_debug("PCI: Fixup bus devices %d (%s)\n",
bus->number, bus->self ? pci_name(bus->self) : "PHB");
- list_for_each_entry(dev, &bus->devices, bus_list) {
- /* Cardbus can call us to add new devices to a bus, so ignore
- * those who are already fully discovered
- */
- if (dev->is_added)
- continue;
-
- pcibios_setup_device(dev);
- }
+ /* nothing to do */
}
void pcibios_set_master(struct pci_dev *dev)
@@ -1479,10 +1466,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
if (ppc_md.pcibios_enable_device_hook(dev))
return -EINVAL;
- /* avoid pcie irq fix up impact on cardbus */
- if (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
- pcibios_setup_device(dev);
-
return pci_enable_resources(dev, mask);
}
--
1.7.9.7
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists