Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index 988a62f..7ba2baa 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -1,4 +1,5 @@
 Accessing PCI device resources through sysfs
+--------------------------------------------
 
 sysfs, usually mounted at /sys, provides access to PCI resources on platforms
 that support it.  For example, a given bus might look like this:
@@ -47,14 +48,21 @@
   binary - file contains binary data
   cpumask - file contains a cpumask type
 
-The read only files are informational, writes to them will be ignored.
-Writable files can be used to perform actions on the device (e.g. changing
-config space, detaching a device).  mmapable files are available via an
-mmap of the file at offset 0 and can be used to do actual device programming
-from userspace.  Note that some platforms don't support mmapping of certain
-resources, so be sure to check the return value from any attempted mmap.
+The read only files are informational, writes to them will be ignored, with
+the exception of the 'rom' file.  Writable files can be used to perform
+actions on the device (e.g. changing config space, detaching a device).
+mmapable files are available via an mmap of the file at offset 0 and can be
+used to do actual device programming from userspace.  Note that some platforms
+don't support mmapping of certain resources, so be sure to check the return
+value from any attempted mmap.
+
+The 'rom' file is special in that it provides read-only access to the device's
+ROM file, if available.  It's disabled by default, however, so applications
+should write the string "1" to the file to enable it before attempting a read
+call, and disable it following the access by writing "0" to the file.
 
 Accessing legacy resources through sysfs
+----------------------------------------
 
 Legacy I/O port and ISA memory resources are also provided in sysfs if the
 underlying platform supports them.  They're located in the PCI class heirarchy,
@@ -75,6 +83,7 @@
 to access legacy memory space.
 
 Supporting PCI access on new platforms
+--------------------------------------
 
 In order to support PCI resource mapping as described above, Linux platform
 code must define HAVE_PCI_MMAP and provide a pci_mmap_page_range function.
diff --git a/Documentation/pci-error-recovery.txt b/Documentation/pci-error-recovery.txt
new file mode 100644
index 0000000..d089967
--- /dev/null
+++ b/Documentation/pci-error-recovery.txt
@@ -0,0 +1,246 @@
+
+                       PCI Error Recovery
+                       ------------------
+                         May 31, 2005
+
+               Current document maintainer:
+           Linas Vepstas <linas@austin.ibm.com>
+
+
+Some PCI bus controllers are able to detect certain "hard" PCI errors
+on the bus, such as parity errors on the data and address busses, as
+well as SERR and PERR errors.  These chipsets are then able to disable
+I/O to/from the affected device, so that, for example, a bad DMA
+address doesn't end up corrupting system memory.  These same chipsets
+are also able to reset the affected PCI device, and return it to
+working condition.  This document describes a generic API form
+performing error recovery.
+
+The core idea is that after a PCI error has been detected, there must
+be a way for the kernel to coordinate with all affected device drivers
+so that the pci card can be made operational again, possibly after
+performing a full electrical #RST of the PCI card.  The API below
+provides a generic API for device drivers to be notified of PCI
+errors, and to be notified of, and respond to, a reset sequence.
+
+Preliminary sketch of API, cut-n-pasted-n-modified email from
+Ben Herrenschmidt, circa 5 april 2005
+
+The error recovery API support is exposed to the driver in the form of
+a structure of function pointers pointed to by a new field in struct
+pci_driver. The absence of this pointer in pci_driver denotes an
+"non-aware" driver, behaviour on these is platform dependant.
+Platforms like ppc64 can try to simulate pci hotplug remove/add.
+
+The definition of "pci_error_token" is not covered here. It is based on
+Seto's work on the synchronous error detection. We still need to define
+functions for extracting infos out of an opaque error token. This is
+separate from this API.
+
+This structure has the form:
+
+struct pci_error_handlers
+{
+	int (*error_detected)(struct pci_dev *dev, pci_error_token error);
+	int (*mmio_enabled)(struct pci_dev *dev);
+	int (*resume)(struct pci_dev *dev);
+	int (*link_reset)(struct pci_dev *dev);
+	int (*slot_reset)(struct pci_dev *dev);
+};
+
+A driver doesn't have to implement all of these callbacks. The
+only mandatory one is error_detected(). If a callback is not
+implemented, the corresponding feature is considered unsupported.
+For example, if mmio_enabled() and resume() aren't there, then the
+driver is assumed as not doing any direct recovery and requires
+a reset. If link_reset() is not implemented, the card is assumed as
+not caring about link resets, in which case, if recover is supported,
+the core can try recover (but not slot_reset() unless it really did
+reset the slot). If slot_reset() is not supported, link_reset() can
+be called instead on a slot reset.
+
+At first, the call will always be :
+
+	1) error_detected()
+
+	Error detected. This is sent once after an error has been detected. At
+this point, the device might not be accessible anymore depending on the
+platform (the slot will be isolated on ppc64). The driver may already
+have "noticed" the error because of a failing IO, but this is the proper
+"synchronisation point", that is, it gives a chance to the driver to
+cleanup, waiting for pending stuff (timers, whatever, etc...) to
+complete; it can take semaphores, schedule, etc... everything but touch
+the device. Within this function and after it returns, the driver
+shouldn't do any new IOs. Called in task context. This is sort of a
+"quiesce" point. See note about interrupts at the end of this doc.
+
+	Result codes:
+		- PCIERR_RESULT_CAN_RECOVER:
+		  Driever returns this if it thinks it might be able to recover
+		  the HW by just banging IOs or if it wants to be given
+		  a chance to extract some diagnostic informations (see
+		  below).
+		- PCIERR_RESULT_NEED_RESET:
+		  Driver returns this if it thinks it can't recover unless the
+		  slot is reset.
+		- PCIERR_RESULT_DISCONNECT:
+		  Return this if driver thinks it won't recover at all,
+		  (this will detach the driver ? or just leave it
+		  dangling ? to be decided)
+
+So at this point, we have called error_detected() for all drivers
+on the segment that had the error. On ppc64, the slot is isolated. What
+happens now typically depends on the result from the drivers. If all
+drivers on the segment/slot return PCIERR_RESULT_CAN_RECOVER, we would
+re-enable IOs on the slot (or do nothing special if the platform doesn't
+isolate slots) and call 2). If not and we can reset slots, we go to 4),
+if neither, we have a dead slot. If it's an hotplug slot, we might
+"simulate" reset by triggering HW unplug/replug though.
+
+>>> Current ppc64 implementation assumes that a device driver will
+>>> *not* schedule or semaphore in this routine; the current ppc64
+>>> implementation uses one kernel thread to notify all devices;
+>>> thus, of one device sleeps/schedules, all devices are affected.
+>>> Doing better requires complex multi-threaded logic in the error
+>>> recovery implementation (e.g. waiting for all notification threads
+>>> to "join" before proceeding with recovery.)  This seems excessively
+>>> complex and not worth implementing.
+
+>>> The current ppc64 implementation doesn't much care if the device
+>>> attempts i/o at this point, or not.  I/O's will fail, returning
+>>> a value of 0xff on read, and writes will be dropped. If the device
+>>> driver attempts more than 10K I/O's to a frozen adapter, it will
+>>> assume that the device driver has gone into an infinite loop, and
+>>> it will panic the the kernel.
+
+	2) mmio_enabled()
+
+	This is the "early recovery" call. IOs are allowed again, but DMA is
+not (hrm... to be discussed, I prefer not), with some restrictions. This
+is NOT a callback for the driver to start operations again, only to
+peek/poke at the device, extract diagnostic information, if any, and
+eventually do things like trigger a device local reset or some such,
+but not restart operations. This is sent if all drivers on a segment
+agree that they can try to recover and no automatic link reset was
+performed by the HW. If the platform can't just re-enable IOs without
+a slot reset or a link reset, it doesn't call this callback and goes
+directly to 3) or 4). All IOs should be done _synchronously_ from
+within this callback, errors triggered by them will be returned via
+the normal pci_check_whatever() api, no new error_detected() callback
+will be issued due to an error happening here. However, such an error
+might cause IOs to be re-blocked for the whole segment, and thus
+invalidate the recovery that other devices on the same segment might
+have done, forcing the whole segment into one of the next states,
+that is link reset or slot reset.
+
+	Result codes:
+		- PCIERR_RESULT_RECOVERED
+		  Driver returns this if it thinks the device is fully
+		  functionnal and thinks it is ready to start
+		  normal driver operations again. There is no
+		  guarantee that the driver will actually be
+		  allowed to proceed, as another driver on the
+		  same segment might have failed and thus triggered a
+		  slot reset on platforms that support it.
+
+		- PCIERR_RESULT_NEED_RESET
+		  Driver returns this if it thinks the device is not
+		  recoverable in it's current state and it needs a slot
+		  reset to proceed.
+
+		- PCIERR_RESULT_DISCONNECT
+		  Same as above. Total failure, no recovery even after
+		  reset driver dead. (To be defined more precisely)
+
+>>> The current ppc64 implementation does not implement this callback.
+
+	3) link_reset()
+
+	This is called after the link has been reset. This is typically
+a PCI Express specific state at this point and is done whenever a
+non-fatal error has been detected that can be "solved" by resetting
+the link. This call informs the driver of the reset and the driver
+should check if the device appears to be in working condition.
+This function acts a bit like 2) mmio_enabled(), in that the driver
+is not supposed to restart normal driver I/O operations right away.
+Instead, it should just "probe" the device to check it's recoverability
+status. If all is right, then the core will call resume() once all
+drivers have ack'd link_reset().
+
+	Result codes:
+		(identical to mmio_enabled)
+
+>>> The current ppc64 implementation does not implement this callback.
+
+	4) slot_reset()
+
+	This is called after the slot has been soft or hard reset by the
+platform.  A soft reset consists of asserting the adapter #RST line
+and then restoring the PCI BARs and PCI configuration header. If the
+platform supports PCI hotplug, then it might instead perform a hard
+reset by toggling power on the slot off/on. This call gives drivers
+the chance to re-initialize the hardware (re-download firmware, etc.),
+but drivers shouldn't restart normal I/O processing operations at
+this point.  (See note about interrupts; interrupts aren't guaranteed
+to be delivered until the resume() callback has been called). If all
+device drivers report success on this callback, the patform will call
+resume() to complete the error handling and let the driver restart
+normal I/O processing.
+
+A driver can still return a critical failure for this function if
+it can't get the device operational after reset.  If the platform
+previously tried a soft reset, it migh now try a hard reset (power
+cycle) and then call slot_reset() again.  It the device still can't
+be recovered, there is nothing more that can be done;  the platform
+will typically report a "permanent failure" in such a case.  The
+device will be considered "dead" in this case.
+
+	Result codes:
+		- PCIERR_RESULT_DISCONNECT
+		Same as above.
+
+>>> The current ppc64 implementation does not try a power-cycle reset
+>>> if the driver returned PCIERR_RESULT_DISCONNECT. However, it should.
+
+	5) resume()
+
+	This is called if all drivers on the segment have returned
+PCIERR_RESULT_RECOVERED from one of the 3 prevous callbacks.
+That basically tells the driver to restart activity, tht everything
+is back and running. No result code is taken into account here. If
+a new error happens, it will restart a new error handling process.
+
+That's it. I think this covers all the possibilities. The way those
+callbacks are called is platform policy. A platform with no slot reset
+capability for example may want to just "ignore" drivers that can't
+recover (disconnect them) and try to let other cards on the same segment
+recover. Keep in mind that in most real life cases, though, there will
+be only one driver per segment.
+
+Now, there is a note about interrupts. If you get an interrupt and your
+device is dead or has been isolated, there is a problem :)
+
+After much thinking, I decided to leave that to the platform. That is,
+the recovery API only precies that:
+
+ - There is no guarantee that interrupt delivery can proceed from any
+device on the segment starting from the error detection and until the
+restart callback is sent, at which point interrupts are expected to be
+fully operational.
+
+ - There is no guarantee that interrupt delivery is stopped, that is, ad
+river that gets an interrupts after detecting an error, or that detects
+and error within the interrupt handler such that it prevents proper
+ack'ing of the interrupt (and thus removal of the source) should just
+return IRQ_NOTHANDLED. It's up to the platform to deal with taht
+condition, typically by masking the irq source during the duration of
+the error handling. It is expected that the platform "knows" which
+interrupts are routed to error-management capable slots and can deal
+with temporarily disabling that irq number during error processing (this
+isn't terribly complex). That means some IRQ latency for other devices
+sharing the interrupt, but there is simply no other way. High end
+platforms aren't supposed to share interrupts between many devices
+anyway :)
+
+
+Revised: 31 May 2005 Linas Vepstas <linas@austin.ibm.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index 9b788d7..0742016 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1987,6 +1987,13 @@
 L:	linux-abi-devel@lists.sourceforge.net
 S:	Maintained
 
+PCI ERROR RECOVERY
+P:	Linas Vepstas
+M:	linas@austin.ibm.com
+L:	linux-kernel@vger.kernel.org
+L:	linux-pci@atrey.karlin.mff.cuni.cz
+S:	Supported
+
 PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
 P:	Thomas Sailer
 M:	sailer@ife.ee.ethz.ch
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 145dcde..d7f0e97 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -254,7 +254,7 @@
 	 * motherboard, by looking for a 21040 TULIP in slot 6, which is
 	 * built into XLT and BRET/MAVERICK, but not available on ALCOR.
 	 */
-	dev = pci_find_device(PCI_VENDOR_ID_DEC,
+	dev = pci_get_device(PCI_VENDOR_ID_DEC,
 			      PCI_DEVICE_ID_DEC_TULIP,
 			      NULL);
 	if (dev && dev->devfn == PCI_DEVFN(6,0)) {
@@ -262,6 +262,7 @@
 		printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",
 		       __FUNCTION__);
 	}
+	pci_dev_put(dev);
 }
 
 
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index 47df48a..131a2d9 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -105,7 +105,7 @@
 	struct pci_dev *dev = NULL;
 
 	/* Iterate through the devices, collecting IRQ levels.  */
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	for_each_pci_dev(dev) {
 		if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
 		    (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
 			continue;
@@ -229,8 +229,8 @@
 	 */
 
 	dev = NULL;
-	while ((dev = pci_find_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
-                if (dev->device == PCI_DEVICE_ID_NCR_53C810
+	while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
+		if (dev->device == PCI_DEVICE_ID_NCR_53C810
 		    || dev->device == PCI_DEVICE_ID_NCR_53C815
 		    || dev->device == PCI_DEVICE_ID_NCR_53C820
 		    || dev->device == PCI_DEVICE_ID_NCR_53C825) {
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 83e5489..0a26bf6 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -142,9 +142,7 @@
 	u16 command;
 	struct resource *r, *pr;
 
-	while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),
-	       dev != NULL
-	       ) {
+	for_each_pci_dev(dev) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for(idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -188,9 +186,7 @@
 	int idx;
 	struct resource *r;
 
-	while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),
-	       dev != NULL
-	       ) {
+	for_each_pci_dev(dev) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index 24622d8..c4a1144 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -48,9 +48,7 @@
 	struct pci_dev *dev = NULL;
 	uint8_t line, pin;
 
-	while (dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev),
-	       dev != NULL
-	       ) {
+	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];
diff --git a/arch/i386/kernel/scx200.c b/arch/i386/kernel/scx200.c
index 9c968ae..321f5fd 100644
--- a/arch/i386/kernel/scx200.c
+++ b/arch/i386/kernel/scx200.c
@@ -143,7 +143,7 @@
 {
 	printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n");
 
-	return pci_module_init(&scx200_pci_driver);
+	return pci_register_driver(&scx200_pci_driver);
 }
 
 static void __exit scx200_cleanup(void)
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
index 4c4522b..b33aea8 100644
--- a/arch/i386/pci/acpi.c
+++ b/arch/i386/pci/acpi.c
@@ -53,7 +53,7 @@
 		 * don't use pci_enable_device().
 		 */
 		printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
-		while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+		for_each_pci_dev(dev)
 			acpi_pci_irq_enable(dev);
 	} else
 		printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\".  If it helps, post a report\n");
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index eeb1b1f..65f6707 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -413,6 +413,13 @@
 			DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"),
 		},
 	},
+	{
+		.ident = "Toshiba A40 based laptop",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
+		},
+	},
 	{ }
 };
 
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index ee8e016..e715aa9 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -78,7 +78,7 @@
 	for (i=0; i < rt->size; i++)
 		sum += addr[i];
 	if (!sum) {
-		DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+		DBG(KERN_DEBUG "PCI: Interrupt Routing Table found at 0x%p\n", rt);
 		return rt;
 	}
 	return NULL;
@@ -128,7 +128,7 @@
 #ifdef DEBUG
 		{
 			int j;
-			DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
+			DBG(KERN_DEBUG "%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
 			for(j=0; j<4; j++)
 				DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
 			DBG("\n");
@@ -160,10 +160,10 @@
 		return;
 
 	eisa_irq_mask |= (1 << irq);
-	printk("PCI: setting IRQ %u as level-triggered\n", irq);
+	printk(KERN_DEBUG "PCI: setting IRQ %u as level-triggered\n", irq);
 	val = inb(port);
 	if (!(val & mask)) {
-		DBG(" -> edge");
+		DBG(KERN_DEBUG " -> edge");
 		outb(val | mask, port);
 	}
 }
@@ -677,11 +677,11 @@
 	{
 	case PCI_DEVICE_ID_AL_M1533:
 	case PCI_DEVICE_ID_AL_M1563:
-		printk("PCI: Using ALI IRQ Router\n");
-			r->name = "ALI";
-			r->get = pirq_ali_get;
-			r->set = pirq_ali_set;
-			return 1;
+		printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n");
+		r->name = "ALI";
+		r->get = pirq_ali_get;
+		r->set = pirq_ali_set;
+		return 1;
 	}
 	return 0;
 }
@@ -749,12 +749,13 @@
 	r->get = NULL;
 	r->set = NULL;
 	
-	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
+	DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n",
 	    rt->rtr_vendor, rt->rtr_device);
 
 	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
 	if (!pirq_router_dev) {
-		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
+		DBG(KERN_DEBUG "PCI: Interrupt router not found at "
+			"%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
 		return;
 	}
 
@@ -799,7 +800,7 @@
 	/* Find IRQ pin */
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 	if (!pin) {
-		DBG(" -> no interrupt pin\n");
+		DBG(KERN_DEBUG " -> no interrupt pin\n");
 		return 0;
 	}
 	pin = pin - 1;
@@ -809,16 +810,16 @@
 	if (!pirq_table)
 		return 0;
 	
-	DBG("IRQ for %s[%c]", pci_name(dev), 'A' + pin);
+	DBG(KERN_DEBUG "IRQ for %s[%c]", pci_name(dev), 'A' + pin);
 	info = pirq_get_info(dev);
 	if (!info) {
-		DBG(" -> not found in routing table\n");
+		DBG(" -> not found in routing table\n" KERN_DEBUG);
 		return 0;
 	}
 	pirq = info->irq[pin].link;
 	mask = info->irq[pin].bitmap;
 	if (!pirq) {
-		DBG(" -> not routed\n");
+		DBG(" -> not routed\n" KERN_DEBUG);
 		return 0;
 	}
 	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
@@ -848,7 +849,10 @@
 	newirq = dev->irq;
 	if (newirq && !((1 << newirq) & mask)) {
 		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
-		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev));
+		else printk("\n" KERN_WARNING
+			"PCI: IRQ %i for device %s doesn't match PIRQ mask "
+			"- try pci=usepirqmask\n" KERN_DEBUG, newirq,
+			pci_name(dev));
 	}
 	if (!newirq && assign) {
 		for (i = 0; i < 16; i++) {
@@ -923,14 +927,14 @@
 	struct pci_dev *dev = NULL;
 	u8 pin;
 
-	DBG("PCI: IRQ fixup\n");
+	DBG(KERN_DEBUG "PCI: IRQ fixup\n");
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		/*
 		 * 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) {
-			DBG("%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq);
+			DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n", pci_name(dev), dev->irq);
 			dev->irq = 0;
 		}
 		/* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
@@ -1039,7 +1043,7 @@
 
 static int __init pcibios_irq_init(void)
 {
-	DBG("PCI: IRQ init\n");
+	DBG(KERN_DEBUG "PCI: IRQ init\n");
 
 	if (pcibios_enable_irq || raw_pci_ops == NULL)
 		return 0;
diff --git a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c
index 462a9af..cc52e75 100644
--- a/arch/mips/vr41xx/common/vrc4173.c
+++ b/arch/mips/vr41xx/common/vrc4173.c
@@ -561,7 +561,7 @@
 {
 	int err;
 
-	err = pci_module_init(&vrc4173_driver);
+	err = pci_register_driver(&vrc4173_driver);
 	if (err < 0)
 		return err;
 
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 50c75ee..704c846 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -503,7 +503,7 @@
 	u16 command;
 	struct resource *r;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	for_each_pci_dev(dev) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for (idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -540,7 +540,7 @@
 	int idx;
 	struct resource *r;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	for_each_pci_dev(dev) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
@@ -867,14 +867,15 @@
 	 */
 	if (!pci_to_OF_bus_map)
 		return 0;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (pci_to_OF_bus_map[dev->bus->number] != *bus)
-			continue;
-		if (dev->devfn != *devfn)
-			continue;
-		*bus = dev->bus->number;
-		return 0;
-	}
+
+	for_each_pci_dev(dev)
+		if (pci_to_OF_bus_map[dev->bus->number] == *bus &&
+				dev->devfn == *devfn) {
+			*bus = dev->bus->number;
+			pci_dev_put(dev);
+			return 0;
+		}
+
 	return -ENODEV;
 }
 EXPORT_SYMBOL(pci_device_from_OF_node);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 5e8cc5e..2959e3c 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -351,10 +351,10 @@
 void __init
 mpc85xx_cds_pcibios_fixup(void)
 {
-        struct pci_dev *dev = NULL;
+        struct pci_dev *dev;
 	u_char		c;
 
-        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+	if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
                                         PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
                 /*
                  * U-Boot does not set the enable bits
@@ -371,21 +371,24 @@
 		 */
                 dev->irq = 14;
                 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+		pci_dev_put(dev);
         }
 
 	/*
 	 * Force legacy USB interrupt routing
 	 */
-        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+	if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
                                         PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
                 dev->irq = 10;
                 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
+		pci_dev_put(dev);
         }
 
-        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+	if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
                                         PCI_DEVICE_ID_VIA_82C586_2, dev))) {
                 dev->irq = 11;
                 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+		pci_dev_put(dev);
         }
 }
 #endif /* CONFIG_PCI */
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 6ffbeb7..7991e91 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -527,18 +527,12 @@
 {
 	struct pci_dev *pdev = start;
 
-	do {
-		pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev);
-		if (pdev &&
-		    (pdev->device == PCI_DEVICE_ID_SUN_EBUS ||
-		     pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS))
+	while ((pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev)))
+		if (pdev->device == PCI_DEVICE_ID_SUN_EBUS ||
+			pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)
 			break;
-	} while (pdev != NULL);
 
-	if (pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS))
-		*is_rio_p = 1;
-	else
-		*is_rio_p = 0;
+	*is_rio_p = !!(pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS));
 
 	return pdev;
 }
@@ -637,6 +631,7 @@
 		ebus->is_rio = is_rio;
 		++num_ebus;
 	}
+	pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */
 
 #ifdef CONFIG_SUN_AUXIO
 	auxio_probe();
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 09567c2..e567c03 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -361,8 +361,7 @@
 
 		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
 			/* PC card has the same IRQ as its cardbridge */
-			pci_read_config_byte(bridge, PCI_INTERRUPT_PIN,
-					     &bridge_pin);
+			bridge_pin = bridge->pin;
 			if (!bridge_pin) {
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 						  "No interrupt pin configured for device %s\n",
@@ -412,7 +411,7 @@
 	if (!dev)
 		return_VALUE(-EINVAL);
 
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	pin = dev->pin;
 	if (!pin) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "No interrupt pin configured for device %s\n",
@@ -503,7 +502,7 @@
 	if (!dev || !dev->bus)
 		return_VOID;
 
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	pin = dev->pin;
 	if (!pin)
 		return_VOID;
 	pin--;
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 4a7bb7d..6ede1f3 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -7179,7 +7179,7 @@
 {
 	int ret;
 
-	ret =  pci_module_init(&DAC960_pci_driver);
+	ret =  pci_register_driver(&DAC960_pci_driver);
 #ifdef DAC960_GAM_MINOR
 	if (!ret)
 		DAC960_gam_init();
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index e4e9f25..12d7b9b 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3360,7 +3360,7 @@
 	printk(KERN_INFO DRIVER_NAME "\n");
 
 	/* Register for our PCI devices */
-	return pci_module_init(&cciss_pci_driver);
+	return pci_register_driver(&cciss_pci_driver);
 }
 
 static void __exit cciss_cleanup(void)
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 4bdf957..2ae08b3 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1755,7 +1755,7 @@
 
 static int __init carm_init(void)
 {
-	return pci_module_init(&carm_driver);
+	return pci_register_driver(&carm_driver);
 }
 
 static void __exit carm_exit(void)
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 15299e7..a3614e6 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -1174,7 +1174,7 @@
 
 	printk(KERN_INFO DRIVER_VERSION " : " DRIVER_DESC "\n");
 
-	retval = pci_module_init(&mm_pci_driver);
+	retval = pci_register_driver(&mm_pci_driver);
 	if (retval)
 		return -ENOMEM;
 
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index d00a726..3eb08f0 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -841,7 +841,7 @@
 
 static int __init sm_vt8231_init(void)
 {
-	return pci_module_init(&vt8231_pci_driver);
+	return pci_register_driver(&vt8231_pci_driver);
 }
 
 static void __exit sm_vt8231_exit(void)
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 42c8fce..69ac8aa 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -395,7 +395,7 @@
 
 static int __init gemtek_pci_init_module( void )
 {
-	return pci_module_init( &gemtek_pci_driver );
+	return pci_register_driver( &gemtek_pci_driver );
 }
 
 static void __exit gemtek_pci_cleanup_module( void )
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 3086930..c975ddd 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -338,7 +338,7 @@
 
 static int __init maxiradio_radio_init(void)
 {
-	return pci_module_init(&maxiradio_driver);
+	return pci_register_driver(&maxiradio_driver);
 }
 
 static void __exit maxiradio_radio_exit(void)
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index d3dad0a..76dd077 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -464,7 +464,7 @@
 
 static int __init parport_serial_init (void)
 {
-	return pci_module_init (&parport_serial_pci_driver);
+	return pci_register_driver (&parport_serial_pci_driver);
 }
 
 static void __exit parport_serial_exit (void)
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 8e21f6a..509a5b3 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -794,12 +794,14 @@
 			if (PCI_SLOT(dev->devfn) != slot->device)
 				continue;
 			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
 				max = pci_scan_bridge(bus, dev, max, pass);
+				if (pass && dev->subordinate)
+					pci_bus_size_bridges(dev->subordinate);
+			}
 		}
 	}
 
-	pci_bus_size_bridges(bus);
 	pci_bus_assign_resources(bus);
 	acpiphp_sanitize_bus(bus);
 	pci_enable_bridges(bus);
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index 092491e..cb88404 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -317,6 +317,7 @@
 	u16 vendor_id;
 	struct work_struct int_task_event;
 	wait_queue_head_t queue;	/* sleep & wake process */
+	struct dentry *dentry;		/* debugfs dentry */
 };
 
 struct irq_mapping {
@@ -399,8 +400,11 @@
 #define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
 
 
-/* sysfs functions for the hotplug controller info */
-extern void cpqhp_create_ctrl_files		(struct controller *ctrl);
+/* debugfs functions for the hotplug controller info */
+extern void cpqhp_initialize_debugfs		(void);
+extern void cpqhp_shutdown_debugfs		(void);
+extern void cpqhp_create_debugfs_files		(struct controller *ctrl);
+extern void cpqhp_remove_debugfs_files		(struct controller *ctrl);
 
 /* controller functions */
 extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 9aed8ef..b3659ff 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -327,7 +327,9 @@
 			void __iomem *smbios_start,
 			void __iomem *smbios_table)
 {
-	struct slot *new_slot;
+	struct slot *slot;
+	struct hotplug_slot *hotplug_slot;
+	struct hotplug_slot_info *hotplug_slot_info;
 	u8 number_of_slots;
 	u8 slot_device;
 	u8 slot_number;
@@ -345,93 +347,105 @@
 	slot_number = ctrl->first_slot;
 
 	while (number_of_slots) {
-		new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
-		if (!new_slot)
+		slot = kmalloc(sizeof(*slot), GFP_KERNEL);
+		if (!slot)
 			goto error;
 
-		memset(new_slot, 0, sizeof(struct slot));
-		new_slot->hotplug_slot = kmalloc(sizeof(*(new_slot->hotplug_slot)),
+		memset(slot, 0, sizeof(struct slot));
+		slot->hotplug_slot = kmalloc(sizeof(*(slot->hotplug_slot)),
 						GFP_KERNEL);
-		if (!new_slot->hotplug_slot)
+		if (!slot->hotplug_slot)
 			goto error_slot;
-		memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
+		hotplug_slot = slot->hotplug_slot;
+		memset(hotplug_slot, 0, sizeof(struct hotplug_slot));
 
-		new_slot->hotplug_slot->info =
-				kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
+		hotplug_slot->info =
+				kmalloc(sizeof(*(hotplug_slot->info)),
 							GFP_KERNEL);
-		if (!new_slot->hotplug_slot->info)
+		if (!hotplug_slot->info)
 			goto error_hpslot;
-		memset(new_slot->hotplug_slot->info, 0,
+		hotplug_slot_info = hotplug_slot->info;
+		memset(hotplug_slot_info, 0,
 				sizeof(struct hotplug_slot_info));
-		new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-		if (!new_slot->hotplug_slot->name)
+		hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+
+		if (!hotplug_slot->name)
 			goto error_info;
 
-		new_slot->ctrl = ctrl;
-		new_slot->bus = ctrl->bus;
-		new_slot->device = slot_device;
-		new_slot->number = slot_number;
-		dbg("slot->number = %d\n",new_slot->number);
+		slot->ctrl = ctrl;
+		slot->bus = ctrl->bus;
+		slot->device = slot_device;
+		slot->number = slot_number;
+		dbg("slot->number = %d\n", slot->number);
 
 		slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9,
 					slot_entry);
 
-		while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != new_slot->number)) {
+		while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) !=
+				slot->number)) {
 			slot_entry = get_SMBIOS_entry(smbios_start,
 						smbios_table, 9, slot_entry);
 		}
 
-		new_slot->p_sm_slot = slot_entry;
+		slot->p_sm_slot = slot_entry;
 
-		init_timer(&new_slot->task_event);
-		new_slot->task_event.expires = jiffies + 5 * HZ;
-		new_slot->task_event.function = cpqhp_pushbutton_thread;
+		init_timer(&slot->task_event);
+		slot->task_event.expires = jiffies + 5 * HZ;
+		slot->task_event.function = cpqhp_pushbutton_thread;
 
 		//FIXME: these capabilities aren't used but if they are
 		//       they need to be correctly implemented
-		new_slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
-		new_slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
+		slot->capabilities |= PCISLOT_REPLACE_SUPPORTED;
+		slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED;
 
-		if (is_slot64bit(new_slot))
-			new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
-		if (is_slot66mhz(new_slot))
-			new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
+		if (is_slot64bit(slot))
+			slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
+		if (is_slot66mhz(slot))
+			slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
 		if (ctrl->speed == PCI_SPEED_66MHz)
-			new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
+			slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
 
-		ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
+		ctrl_slot =
+			slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
 
 		// Check presence
-		new_slot->capabilities |= ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
+		slot->capabilities |=
+			((((~tempdword) >> 23) |
+			 ((~tempdword) >> 15)) >> ctrl_slot) & 0x02;
 		// Check the switch state
-		new_slot->capabilities |= ((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
+		slot->capabilities |=
+			((~tempdword & 0xFF) >> ctrl_slot) & 0x01;
 		// Check the slot enable
-		new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
+		slot->capabilities |=
+			((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04;
 
 		/* register this slot with the hotplug pci core */
-		new_slot->hotplug_slot->release = &release_slot;
-		new_slot->hotplug_slot->private = new_slot;
-		make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
-		new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
+		hotplug_slot->release = &release_slot;
+		hotplug_slot->private = slot;
+		make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot);
+		hotplug_slot->ops = &cpqphp_hotplug_slot_ops;
 		
-		new_slot->hotplug_slot->info->power_status = get_slot_enabled(ctrl, new_slot);
-		new_slot->hotplug_slot->info->attention_status = cpq_get_attention_status(ctrl, new_slot);
-		new_slot->hotplug_slot->info->latch_status = cpq_get_latch_status(ctrl, new_slot);
-		new_slot->hotplug_slot->info->adapter_status = get_presence_status(ctrl, new_slot);
+		hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot);
+		hotplug_slot_info->attention_status =
+			cpq_get_attention_status(ctrl, slot);
+		hotplug_slot_info->latch_status =
+			cpq_get_latch_status(ctrl, slot);
+		hotplug_slot_info->adapter_status =
+			get_presence_status(ctrl, slot);
 		
-		dbg ("registering bus %d, dev %d, number %d, "
+		dbg("registering bus %d, dev %d, number %d, "
 				"ctrl->slot_device_offset %d, slot %d\n",
-				new_slot->bus, new_slot->device,
-				new_slot->number, ctrl->slot_device_offset,
+				slot->bus, slot->device,
+				slot->number, ctrl->slot_device_offset,
 				slot_number);
-		result = pci_hp_register (new_slot->hotplug_slot);
+		result = pci_hp_register(hotplug_slot);
 		if (result) {
-			err ("pci_hp_register failed with error %d\n", result);
+			err("pci_hp_register failed with error %d\n", result);
 			goto error_name;
 		}
 		
-		new_slot->next = ctrl->slot;
-		ctrl->slot = new_slot;
+		slot->next = ctrl->slot;
+		ctrl->slot = slot;
 
 		number_of_slots--;
 		slot_device++;
@@ -439,15 +453,14 @@
 	}
 
 	return 0;
-
 error_name:
-	kfree(new_slot->hotplug_slot->name);
+	kfree(hotplug_slot->name);
 error_info:
-	kfree(new_slot->hotplug_slot->info);
+	kfree(hotplug_slot_info);
 error_hpslot:
-	kfree(new_slot->hotplug_slot);
+	kfree(hotplug_slot);
 error_slot:
-	kfree(new_slot);
+	kfree(slot);
 error:
 	return result;
 }
@@ -466,6 +479,8 @@
 		old_slot = next_slot;
 	}
 
+	cpqhp_remove_debugfs_files(ctrl);
+
 	//Free IRQ associated with hot plug device
 	free_irq(ctrl->interrupt, ctrl);
 	//Unmap the memory
@@ -1262,7 +1277,7 @@
 	// Done with exclusive hardware access
 	up(&ctrl->crit_sect);
 
-	cpqhp_create_ctrl_files(ctrl);
+	cpqhp_create_debugfs_files(ctrl);
 
 	return 0;
 
@@ -1502,6 +1517,7 @@
 	cpqhp_debug = debug;
 
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	cpqhp_initialize_debugfs();
 	result = pci_register_driver(&cpqhpc_driver);
 	dbg("pci_register_driver = %d\n", result);
 	return result;
@@ -1515,6 +1531,7 @@
 
 	dbg("pci_unregister_driver\n");
 	pci_unregister_driver(&cpqhpc_driver);
+	cpqhp_shutdown_debugfs();
 }
 
 
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index 10a5a76..771ed34 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -2630,29 +2630,15 @@
 			hold_mem_node = NULL;
 		}
 
-		/* If we have prefetchable memory resources copy them and 
-		 * fill in the bridge's memory range registers.  Otherwise,
-		 * fill in the range registers with values that disable them. */
-		if (p_mem_node) {
-			memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
-			p_mem_node->next = NULL;
+		memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource));
+		p_mem_node->next = NULL;
 
-			/* set Pre Mem base and Limit registers */
-			temp_word = p_mem_node->base >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+		/* set Pre Mem base and Limit registers */
+		temp_word = p_mem_node->base >> 16;
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
 
-			temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-		} else {
-			temp_word = 0xFFFF;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
-
-			temp_word = 0x0000;
-			rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
-
-			kfree(hold_p_mem_node);
-			hold_p_mem_node = NULL;
-		}
+		temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
+		rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
 
 		/* Adjust this to compensate for extra adjustment in first loop */
 		irqs.barber_pole--;
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 4c11048..bbfeed7 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -33,22 +33,15 @@
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
 #include <linux/pci.h>
+#include <linux/debugfs.h>
 #include "cpqphp.h"
 
-
-/* A few routines that create sysfs entries for the hot plug controller */
-
-static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
+static int show_ctrl (struct controller *ctrl, char *buf)
 {
-	struct pci_dev *pci_dev;
-	struct controller *ctrl;
-	char * out = buf;
+	char *out = buf;
 	int index;
 	struct pci_resource *res;
 
-	pci_dev = container_of (dev, struct pci_dev, dev);
-	ctrl = pci_get_drvdata(pci_dev);
-
 	out += sprintf(buf, "Free resources: memory\n");
 	index = 11;
 	res = ctrl->mem_head;
@@ -80,22 +73,16 @@
 
 	return out - buf;
 }
-static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
 
-static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
+static int show_dev (struct controller *ctrl, char *buf)
 {
-	struct pci_dev *pci_dev;
-	struct controller *ctrl;
 	char * out = buf;
 	int index;
 	struct pci_resource *res;
 	struct pci_func *new_slot;
 	struct slot *slot;
 
-	pci_dev = container_of (dev, struct pci_dev, dev);
-	ctrl = pci_get_drvdata(pci_dev);
-
-	slot=ctrl->slot;
+	slot = ctrl->slot;
 
 	while (slot) {
 		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
@@ -134,10 +121,117 @@
 
 	return out - buf;
 }
-static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
 
-void cpqhp_create_ctrl_files (struct controller *ctrl)
+static int spew_debug_info(struct controller *ctrl, char *data, int size)
 {
-	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
-	device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
+	int used;
+
+	used = size - show_ctrl(ctrl, data);
+	used = (size - used) - show_dev(ctrl, &data[used]);
+	return used;
 }
+
+struct ctrl_dbg {
+	int size;
+	char *data;
+	struct controller *ctrl;
+};
+
+#define MAX_OUTPUT	(4*PAGE_SIZE)
+
+static int open(struct inode *inode, struct file *file)
+{
+	struct controller *ctrl = inode->u.generic_ip;
+	struct ctrl_dbg *dbg;
+	int retval = -ENOMEM;
+
+	lock_kernel();
+	dbg = kmalloc(sizeof(*dbg), GFP_KERNEL);
+	if (!dbg)
+		goto exit;
+	dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL);
+	if (!dbg->data) {
+		kfree(dbg);
+		goto exit;
+	}
+	dbg->size = spew_debug_info(ctrl, dbg->data, MAX_OUTPUT);
+	file->private_data = dbg;
+	retval = 0;
+exit:
+	unlock_kernel();
+	return retval;
+}
+
+static loff_t lseek(struct file *file, loff_t off, int whence)
+{
+	struct ctrl_dbg *dbg;
+	loff_t new = -1;
+
+	lock_kernel();
+	dbg = file->private_data;
+
+	switch (whence) {
+	case 0:
+		new = off;
+		break;
+	case 1:
+		new = file->f_pos + off;
+		break;
+	}
+	if (new < 0 || new > dbg->size) {
+		unlock_kernel();
+		return -EINVAL;
+	}
+	unlock_kernel();
+	return (file->f_pos = new);
+}
+
+static ssize_t read(struct file *file, char __user *buf,
+		    size_t nbytes, loff_t *ppos)
+{
+	struct ctrl_dbg *dbg = file->private_data;
+	return simple_read_from_buffer(buf, nbytes, ppos, dbg->data, dbg->size);
+}
+
+static int release(struct inode *inode, struct file *file)
+{
+	struct ctrl_dbg *dbg = file->private_data;
+
+	kfree(dbg->data);
+	kfree(dbg);
+	return 0;
+}
+
+static struct file_operations debug_ops = {
+	.owner = THIS_MODULE,
+	.open = open,
+	.llseek = lseek,
+	.read = read,
+	.release = release,
+};
+
+static struct dentry *root;
+
+void cpqhp_initialize_debugfs(void)
+{
+	if (!root)
+		root = debugfs_create_dir("cpqhp", NULL);
+}
+
+void cpqhp_shutdown_debugfs(void)
+{
+	debugfs_remove(root);
+}
+
+void cpqhp_create_debugfs_files(struct controller *ctrl)
+{
+	ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);
+}
+
+void cpqhp_remove_debugfs_files(struct controller *ctrl)
+{
+	if (ctrl->dentry)
+		debugfs_remove(ctrl->dentry);
+	ctrl->dentry = NULL;
+}
+
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index b1ba429..155133f 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -969,7 +969,7 @@
 			debug ("io 32\n");
 			need_io_upper = TRUE;
 		}
-		if ((io_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
+		if ((pfmem_base & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
 			debug ("pfmem 64\n");
 			need_pfmem_upper = TRUE;
 		}
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 8df7048..4fb5690 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -103,7 +103,10 @@
 
 static int init_slots(struct controller *ctrl)
 {
-	struct slot *new_slot;
+	struct slot *slot;
+	struct hpc_ops *hpc_ops;
+	struct hotplug_slot *hotplug_slot;
+	struct hotplug_slot_info *hotplug_slot_info;
 	u8 number_of_slots;
 	u8 slot_device;
 	u32 slot_number;
@@ -114,59 +117,66 @@
 	slot_number = ctrl->first_slot;
 
 	while (number_of_slots) {
-		new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
-		if (!new_slot)
+		slot = kmalloc(sizeof(*slot), GFP_KERNEL);
+		if (!slot)
 			goto error;
 
-		memset(new_slot, 0, sizeof(struct slot));
-		new_slot->hotplug_slot =
-				kmalloc(sizeof(*(new_slot->hotplug_slot)),
+		memset(slot, 0, sizeof(struct slot));
+		slot->hotplug_slot =
+				kmalloc(sizeof(*(slot->hotplug_slot)),
 						GFP_KERNEL);
-		if (!new_slot->hotplug_slot)
+		if (!slot->hotplug_slot)
 			goto error_slot;
-		memset(new_slot->hotplug_slot, 0, sizeof(struct hotplug_slot));
+		hotplug_slot = slot->hotplug_slot;
+		memset(hotplug_slot, 0, sizeof(struct hotplug_slot));
 
-		new_slot->hotplug_slot->info =
-			kmalloc(sizeof(*(new_slot->hotplug_slot->info)),
+		hotplug_slot->info =
+			kmalloc(sizeof(*(hotplug_slot->info)),
 						GFP_KERNEL);
-		if (!new_slot->hotplug_slot->info)
+		if (!hotplug_slot->info)
 			goto error_hpslot;
-		memset(new_slot->hotplug_slot->info, 0,
+		hotplug_slot_info = hotplug_slot->info;
+		memset(hotplug_slot_info, 0,
 					sizeof(struct hotplug_slot_info));
-		new_slot->hotplug_slot->name = kmalloc(SLOT_NAME_SIZE,
-						GFP_KERNEL);
-		if (!new_slot->hotplug_slot->name)
+		hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
+		if (!hotplug_slot->name)
 			goto error_info;
 
-		new_slot->ctrl = ctrl;
-		new_slot->bus = ctrl->slot_bus;
-		new_slot->device = slot_device;
-		new_slot->hpc_ops = ctrl->hpc_ops;
+		slot->ctrl = ctrl;
+		slot->bus = ctrl->slot_bus;
+		slot->device = slot_device;
+		slot->hpc_ops = hpc_ops = ctrl->hpc_ops;
 
-		new_slot->number = ctrl->first_slot;
-		new_slot->hp_slot = slot_device - ctrl->slot_device_offset;
+		slot->number = ctrl->first_slot;
+		slot->hp_slot = slot_device - ctrl->slot_device_offset;
 
 		/* register this slot with the hotplug pci core */
-		new_slot->hotplug_slot->private = new_slot;
-		new_slot->hotplug_slot->release = &release_slot;
-		make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot);
-		new_slot->hotplug_slot->ops = &pciehp_hotplug_slot_ops;
+		hotplug_slot->private = slot;
+		hotplug_slot->release = &release_slot;
+		make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot);
+		hotplug_slot->ops = &pciehp_hotplug_slot_ops;
 
-		new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status));
-		new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status));
-		new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status));
-		new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status));
+		hpc_ops->get_power_status(slot,
+			&(hotplug_slot_info->power_status));
+		hpc_ops->get_attention_status(slot,
+			&(hotplug_slot_info->attention_status));
+		hpc_ops->get_latch_status(slot,
+			&(hotplug_slot_info->latch_status));
+		hpc_ops->get_adapter_status(slot,
+			&(hotplug_slot_info->adapter_status));
 
-		dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", 
-			new_slot->bus, new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset);
-		result = pci_hp_register (new_slot->hotplug_slot);
+		dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
+			"slot_device_offset=%x\n",
+			slot->bus, slot->device, slot->hp_slot, slot->number,
+			ctrl->slot_device_offset);
+		result = pci_hp_register(hotplug_slot);
 		if (result) {
 			err ("pci_hp_register failed with error %d\n", result);
 			goto error_name;
 		}
 
-		new_slot->next = ctrl->slot;
-		ctrl->slot = new_slot;
+		slot->next = ctrl->slot;
+		ctrl->slot = slot;
 
 		number_of_slots--;
 		slot_device++;
@@ -176,13 +186,13 @@
 	return 0;
 
 error_name:
-	kfree(new_slot->hotplug_slot->name);
+	kfree(hotplug_slot->name);
 error_info:
-	kfree(new_slot->hotplug_slot->info);
+	kfree(hotplug_slot_info);
 error_hpslot:
-	kfree(new_slot->hotplug_slot);
+	kfree(hotplug_slot);
 error_slot:
-	kfree(new_slot);
+	kfree(slot);
 error:
 	return result;
 }
@@ -502,7 +512,7 @@
 
 }
 
-int hpdriver_context = 0;
+static int hpdriver_context = 0;
 
 static void pciehp_remove (struct pcie_device *device)
 {
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index ac1e495..77e5303 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -787,8 +787,13 @@
 
 	slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
 
+	/* Enable detection that we turned off at slot power-off time */
 	if (!pciehp_poll_mode)
-		slot_cmd = slot_cmd | HP_INTR_ENABLE; 
+		slot_cmd = slot_cmd |
+		           PWR_FAULT_DETECT_ENABLE |
+		           MRL_DETECT_ENABLE |
+		           PRSN_DETECT_ENABLE |
+		           HP_INTR_ENABLE;
 
 	retval = pcie_write_cmd(slot, slot_cmd);
 
@@ -833,8 +838,18 @@
 
 	slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
 
+	/*
+	 * If we get MRL or presence detect interrupts now, the isr
+	 * will notice the sticky power-fault bit too and issue power
+	 * indicator change commands. This will lead to an endless loop
+	 * of command completions, since the power-fault bit remains on
+	 * till the slot is powered on again.
+	 */
 	if (!pciehp_poll_mode)
-		slot_cmd = slot_cmd | HP_INTR_ENABLE; 
+		slot_cmd = (slot_cmd &
+		            ~PWR_FAULT_DETECT_ENABLE &
+		            ~MRL_DETECT_ENABLE &
+		            ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE;
 
 	retval = pcie_write_cmd(slot, slot_cmd);
 
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 647673a..4017fb0 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -34,6 +34,31 @@
 #include "../pci.h"
 #include "pciehp.h"
 
+static int pciehp_add_bridge(struct pci_dev *dev)
+{
+	struct pci_bus *parent = dev->bus;
+	int pass, busnr, start = parent->secondary;
+	int end = parent->subordinate;
+
+	for (busnr = start; busnr <= end; busnr++) {
+		if (!pci_find_bus(pci_domain_nr(parent), busnr))
+			break;
+	}
+	if (busnr-- > end) {
+		err("No bus number available for hot-added bridge %s\n",
+				pci_name(dev));
+		return -1;
+	}
+	for (pass = 0; pass < 2; pass++)
+		busnr = pci_scan_bridge(parent, dev, busnr, pass);
+	if (!dev->subordinate)
+		return -1;
+	pci_bus_size_bridges(dev->subordinate);
+	pci_bus_assign_resources(parent);
+	pci_enable_bridges(parent);
+	pci_bus_add_devices(parent);
+	return 0;
+}
 
 int pciehp_configure_device(struct slot *p_slot)
 {
@@ -55,8 +80,8 @@
 	}
 
 	for (fn = 0; fn < 8; fn++) {
-		if (!(dev = pci_find_slot(p_slot->bus,
-					PCI_DEVFN(p_slot->device, fn))))
+		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
+		if (!dev)
 			continue;
 		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
 			err("Cannot hot-add display device %s\n",
@@ -65,27 +90,7 @@
 		}
 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
 				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
-			/* Find an unused bus number for the new bridge */
-			struct pci_bus *child;
-			unsigned char busnr, start = parent->secondary;
-			unsigned char end = parent->subordinate;
-			for (busnr = start; busnr <= end; busnr++) {
-				if (!pci_find_bus(pci_domain_nr(parent),
-							busnr))
-					break;
-			}
-			if (busnr >= end) {
-				err("No free bus for hot-added bridge\n");
-				continue;
-			}
-			child = pci_add_new_bus(parent, dev, busnr);
-			if (!child) {
-				err("Cannot add new bus for %s\n",
-						pci_name(dev));
-				continue;
-			}
-			child->subordinate = pci_do_scan_bus(child);
-			pci_bus_size_bridges(child);
+			pciehp_add_bridge(dev);
 		}
 		/* TBD: program firmware provided _HPP values */
 		/* program_fw_provided_values(dev); */
@@ -93,7 +98,6 @@
 
 	pci_bus_assign_resources(parent);
 	pci_bus_add_devices(parent);
-	pci_enable_bridges(parent);
 	return 0;
 }
 
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index ae244e2..2bdb30f 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -174,7 +174,9 @@
 	acpi_status status;
 	acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
 	struct pci_dev *pdev = dev;
+	struct pci_bus *parent;
 	u8 *path_name;
+
 	/*
 	 * Per PCI firmware specification, we should run the ACPI _OSC
 	 * method to get control of hotplug hardware before using it.
@@ -190,17 +192,18 @@
 		 */
 		if (!pdev || !pdev->bus->parent)
 			break;
+		parent = pdev->bus->parent;
 		dbg("Could not find %s in acpi namespace, trying parent\n",
 				pci_name(pdev));
-		if (!pdev->bus->parent->self)
+		if (!parent->self)
 			/* Parent must be a host bridge */
 			handle = acpi_get_pci_rootbridge_handle(
-					pci_domain_nr(pdev->bus->parent),
-					pdev->bus->parent->number);
+					pci_domain_nr(parent),
+					parent->number);
 		else
 			handle = DEVICE_ACPI_HANDLE(
-					&(pdev->bus->parent->self->dev));
-		pdev = pdev->bus->parent->self;
+					&(parent->self->dev));
+		pdev = parent->self;
 	}
 
 	while (handle) {
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index cc03609..7d93dba 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -112,28 +112,6 @@
         return NULL;
 }
 
-static void rpadlpar_claim_one_bus(struct pci_bus *b)
-{
-	struct list_head *ld;
-	struct pci_bus *child_bus;
-
-	for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
-		struct pci_dev *dev = pci_dev_b(ld);
-		int i;
-
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource *r = &dev->resource[i];
-
-			if (r->parent || !r->start || !r->flags)
-				continue;
-			rpaphp_claim_resource(dev, i);
-		}
-	}
-
-	list_for_each_entry(child_bus, &b->children, node)
-		rpadlpar_claim_one_bus(child_bus);
-}
-
 static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
 					struct device_node *dev_dn)
 {
@@ -154,7 +132,8 @@
 	struct pci_controller *phb = pdn->phb;
 	struct pci_dev *dev = NULL;
 
-	rpaphp_eeh_init_nodes(dn);
+	eeh_add_device_tree_early(dn);
+
 	/* Add EADS device to PHB bus, adding new entry to bus->devices */
 	dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);
 	if (!dev) {
@@ -170,7 +149,7 @@
 	rpaphp_init_new_devs(dev->subordinate);
 
 	/* Claim new bus resources */
-	rpadlpar_claim_one_bus(dev->bus);
+	pcibios_claim_one_bus(dev->bus);
 
 	/* ioremap() for child bus, which may or may not succeed */
 	(void) remap_bus_range(dev->bus);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 4b35097..396b54b 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -62,28 +62,6 @@
 }
 EXPORT_SYMBOL_GPL(rpaphp_find_pci_bus);
 
-int rpaphp_claim_resource(struct pci_dev *dev, int resource)
-{
-	struct resource *res = &dev->resource[resource];
-	struct resource *root = pci_find_parent_resource(dev, res);
-	char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge";
-	int err = -EINVAL;
-
-	if (root != NULL) {
-		err = request_resource(root, res);
-	}
-
-	if (err) {
-		err("PCI: %s region %d of %s %s [%lx:%lx]\n",
-		    root ? "Address space collision on" :
-		    "No parent found for",
-		    resource, dtype, pci_name(dev), res->start, res->end);
-	}
-	return err;
-}
-
-EXPORT_SYMBOL_GPL(rpaphp_claim_resource);
-
 static int rpaphp_get_sensor_state(struct slot *slot, int *state)
 {
 	int rc;
@@ -177,7 +155,7 @@
 
 				if (r->parent || !r->start || !r->flags)
 					continue;
-				rpaphp_claim_resource(dev, i);
+				pci_claim_resource(dev, i);
 			}
 		}
 	}
@@ -287,18 +265,6 @@
 	return dev;
 }
 
-void rpaphp_eeh_init_nodes(struct device_node *dn)
-{
-	struct device_node *sib;
-
-	for (sib = dn->child; sib; sib = sib->sibling) 
-		rpaphp_eeh_init_nodes(sib);
-	eeh_add_device_early(dn);
-	return;
-	
-}
-EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
-
 static void print_slot_pci_funcs(struct pci_bus *bus)
 {
 	struct device_node *dn;
@@ -324,7 +290,7 @@
 	if (!dn)
 		goto exit;
 
-	rpaphp_eeh_init_nodes(dn);
+	eeh_add_device_tree_early(dn);
 	dev = rpaphp_pci_config_slot(bus);
 	if (!dev) {
 		err("%s: can't find any devices.\n", __FUNCTION__);
@@ -370,13 +336,14 @@
 
 static int setup_pci_hotplug_slot_info(struct slot *slot)
 {
+	struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info;
+
 	dbg("%s Initilize the PCI slot's hotplug->info structure ...\n",
 	    __FUNCTION__);
-	rpaphp_get_power_status(slot, &slot->hotplug_slot->info->power_status);
+	rpaphp_get_power_status(slot, &hotplug_slot_info->power_status);
 	rpaphp_get_pci_adapter_status(slot, 1,
-				      &slot->hotplug_slot->info->
-				      adapter_status);
-	if (slot->hotplug_slot->info->adapter_status == NOT_VALID) {
+				      &hotplug_slot_info->adapter_status);
+	if (hotplug_slot_info->adapter_status == NOT_VALID) {
 		err("%s: NOT_VALID: skip dn->full_name=%s\n",
 		    __FUNCTION__, slot->dn->full_name);
 		return -EINVAL;
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 08ad26a..ce0e9b6 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -98,6 +98,10 @@
 	enum pci_bus_speed speed;
 	u32 first_slot;		/* First physical slot number */
 	u8 slot_bus;		/* Bus where the slots handled by this controller sit */
+	u32 cap_offset;
+	unsigned long mmio_base;
+	unsigned long mmio_size;
+	volatile int cmd_busy;
 };
 
 struct hotplug_params {
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 63628e0..a2b3f00 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -65,6 +65,7 @@
 static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
 static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
+static int get_address		(struct hotplug_slot *slot, u32 *value);
 static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
@@ -77,6 +78,7 @@
 	.get_attention_status =	get_attention_status,
 	.get_latch_status =	get_latch_status,
 	.get_adapter_status =	get_adapter_status,
+	.get_address =		get_address,
 	.get_max_bus_speed =	get_max_bus_speed,
 	.get_cur_bus_speed =	get_cur_bus_speed,
 };
@@ -314,6 +316,18 @@
 	return 0;
 }
 
+static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	*value = (pci_domain_nr(bus) << 16) | (slot->bus << 8) | slot->device;
+
+	return 0;
+}
+
 static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
@@ -377,8 +391,6 @@
 		goto err_out_free_ctrl;
 	}
 
-	ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
-
 	pci_set_drvdata(pdev, ctrl);
 
 	ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 5861935..25ccb0e 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -248,7 +248,6 @@
 		up(&ctrl->crit_sect);
 		return WRONG_BUS_FREQUENCY;
 	}
-	wait_for_ctrl_irq (ctrl);
 		
 	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
 		err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
@@ -330,9 +329,6 @@
 		up(&ctrl->crit_sect);
 		return -1;
 	}
-			
-	/* Wait for the command to complete */
-	wait_for_ctrl_irq (ctrl);
 	
 	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
 	if (rc) {
@@ -352,7 +348,6 @@
 			up(&ctrl->crit_sect);
 			return WRONG_BUS_FREQUENCY;
 		}
-		wait_for_ctrl_irq (ctrl);
 		
 		if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
 			err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
@@ -367,7 +362,6 @@
 			up(&ctrl->crit_sect);
 			return rc;
 		}
-		wait_for_ctrl_irq (ctrl);
 
 		if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
 			err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
@@ -494,7 +488,6 @@
 		up(&ctrl->crit_sect);
 		return rc;
 	}
-	wait_for_ctrl_irq (ctrl);
 
 	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
 		err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
@@ -532,9 +525,6 @@
 
 	p_slot->hpc_ops->green_led_on(p_slot);
 
-	/* Wait for the command to complete */
-	wait_for_ctrl_irq (ctrl);
-
 	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
 
@@ -552,8 +542,6 @@
 		up(&ctrl->crit_sect);
 		return rc;
 	}
-	/* Wait for the command to complete */
-	wait_for_ctrl_irq (ctrl);
 
 	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
 	if (rc) {
@@ -603,8 +591,6 @@
 		up(&ctrl->crit_sect);
 		return rc;
 	}
-	/* Wait for the command to complete */
-	wait_for_ctrl_irq (ctrl);
 
 	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
 	if (rc) {
@@ -621,8 +607,6 @@
 		up(&ctrl->crit_sect);
 		return rc;
 	}
-	/* Wait for the command to complete */
-	wait_for_ctrl_irq (ctrl);
 
 	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
@@ -676,9 +660,6 @@
 
 			p_slot->hpc_ops->green_led_off(p_slot);
 
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (p_slot->ctrl);
-
 			/* Done with exclusive hardware access */
 			up(&p_slot->ctrl->crit_sect);
 		}
@@ -790,14 +771,9 @@
 						down(&ctrl->crit_sect);
 
 						p_slot->hpc_ops->green_led_on(p_slot);
-						/* Wait for the command to complete */
-						wait_for_ctrl_irq (ctrl);
 
 						p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-						/* Wait for the command to complete */
-						wait_for_ctrl_irq (ctrl);
-
 						/* Done with exclusive hardware access */
 						up(&ctrl->crit_sect);
 						break;
@@ -806,12 +782,8 @@
 						down(&ctrl->crit_sect);
 
 						p_slot->hpc_ops->green_led_off(p_slot);
-						/* Wait for the command to complete */
-						wait_for_ctrl_irq (ctrl);
 
 						p_slot->hpc_ops->set_attention_status(p_slot, 0);
-						/* Wait for the command to complete */
-						wait_for_ctrl_irq (ctrl);
 
 						/* Done with exclusive hardware access */
 						up(&ctrl->crit_sect);
@@ -845,14 +817,9 @@
 
 					/* blink green LED and turn off amber */
 					p_slot->hpc_ops->green_led_blink(p_slot);
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
 					
 					p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-
 					/* Done with exclusive hardware access */
 					up(&ctrl->crit_sect);
 
@@ -870,12 +837,8 @@
 					down(&ctrl->crit_sect);
 
 					p_slot->hpc_ops->set_attention_status(p_slot, 1);
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
 					
 					p_slot->hpc_ops->green_led_off(p_slot);
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
 
 					/* Done with exclusive hardware access */
 					up(&ctrl->crit_sect);
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 9987a6f..b4226ff 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -275,6 +275,25 @@
 	return;
 }
 
+static inline int shpc_wait_cmd(struct controller *ctrl)
+{
+	int retval = 0;
+	unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;
+	unsigned long timeout = msecs_to_jiffies(timeout_msec);
+	int rc = wait_event_interruptible_timeout(ctrl->queue,
+						  !ctrl->cmd_busy, timeout);
+	if (!rc) {
+		retval = -EIO;
+		err("Command not completed in %d msec\n", timeout_msec);
+	} else if (rc < 0) {
+		retval = -EINTR;
+		info("Command was interrupted by a signal\n");
+	}
+	ctrl->cmd_busy = 0;
+
+	return retval;
+}
+
 static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
 {
 	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
@@ -314,8 +333,14 @@
 	/* To make sure the Controller Busy bit is 0 before we send out the
 	 * command. 
 	 */
+	slot->ctrl->cmd_busy = 1;
 	writew(temp_word, php_ctlr->creg + CMD);
 
+	/*
+	 * Wait for command completion.
+	 */
+	retval = shpc_wait_cmd(slot->ctrl);
+
 	DBG_LEAVE_ROUTINE 
 	return retval;
 }
@@ -604,7 +629,7 @@
 	sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
 
 	if (pi == 2) {
-		*mode = (sec_bus_status & 0x0100) >> 7;
+		*mode = (sec_bus_status & 0x0100) >> 8;
 	} else {
 		retval = -1;
 	}
@@ -791,7 +816,7 @@
 	}
 	if (php_ctlr->pci_dev) {
 		iounmap(php_ctlr->creg);
-		release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
+		release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
 		php_ctlr->pci_dev = NULL;
 	}
 
@@ -1058,12 +1083,13 @@
 	if (intr_loc & 0x0001) {
 		/* 
 		 * Command Complete Interrupt Pending 
-		 * RO only - clear by writing 0 to the Command Completion
+		 * RO only - clear by writing 1 to the Command Completion
 		 * Detect bit in Controller SERR-INT register
 		 */
 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
-		temp_dword &= 0xfffeffff;
+		temp_dword &= 0xfffdffff;
 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+		ctrl->cmd_busy = 0;
 		wake_up_interruptible(&ctrl->queue);
 	}
 
@@ -1121,7 +1147,6 @@
 	int retval = 0;
 	u8 pi;
 	u32 slot_avail1, slot_avail2;
-	int slot_num;
 
 	DBG_ENTER_ROUTINE 
 
@@ -1140,39 +1165,39 @@
 	slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
 
 	if (pi == 2) {
-		if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27)  ) != 0 )
+		if (slot_avail2 & SLOT_133MHZ_PCIX_533)
 			bus_speed = PCIX_133MHZ_533;
-		else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23)  ) != 0 )
+		else if (slot_avail2 & SLOT_100MHZ_PCIX_533)
 			bus_speed = PCIX_100MHZ_533;
-		else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19)  ) != 0 )
+		else if (slot_avail2 & SLOT_66MHZ_PCIX_533)
 			bus_speed = PCIX_66MHZ_533;
-		else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15)  ) != 0 )
+		else if (slot_avail2 & SLOT_133MHZ_PCIX_266)
 			bus_speed = PCIX_133MHZ_266;
-		else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11)  ) != 0 )
+		else if (slot_avail2 & SLOT_100MHZ_PCIX_266)
 			bus_speed = PCIX_100MHZ_266;
-		else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7)  ) != 0 )
+		else if (slot_avail2 & SLOT_66MHZ_PCIX_266)
 			bus_speed = PCIX_66MHZ_266;
-		else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23)  ) != 0 )
+		else if (slot_avail1 & SLOT_133MHZ_PCIX)
 			bus_speed = PCIX_133MHZ;
-		else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15)  ) != 0 )
+		else if (slot_avail1 & SLOT_100MHZ_PCIX)
 			bus_speed = PCIX_100MHZ;
-		else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7)  ) != 0 )
+		else if (slot_avail1 & SLOT_66MHZ_PCIX)
 			bus_speed = PCIX_66MHZ;
-		else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
+		else if (slot_avail2 & SLOT_66MHZ)
 			bus_speed = PCI_66MHZ;
-		else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
+		else if (slot_avail1 & SLOT_33MHZ)
 			bus_speed = PCI_33MHZ;
 		else bus_speed = PCI_SPEED_UNKNOWN;
 	} else {
-		if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23)  ) != 0 )
+		if (slot_avail1 & SLOT_133MHZ_PCIX)
 			bus_speed = PCIX_133MHZ;
-		else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15)  ) != 0 )
+		else if (slot_avail1 & SLOT_100MHZ_PCIX)
 			bus_speed = PCIX_100MHZ;
-		else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7)  ) != 0 )
+		else if (slot_avail1 & SLOT_66MHZ_PCIX)
 			bus_speed = PCIX_66MHZ;
-		else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
+		else if (slot_avail2 & SLOT_66MHZ)
 			bus_speed = PCI_66MHZ;
-		else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
+		else if (slot_avail1 & SLOT_33MHZ)
 			bus_speed = PCI_33MHZ;
 		else bus_speed = PCI_SPEED_UNKNOWN;
 	}
@@ -1321,19 +1346,34 @@
 	.check_cmd_status		= hpc_check_cmd_status,
 };
 
+inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
+					  u32 *value)
+{
+	int rc;
+	u32 cap_offset = ctrl->cap_offset;
+	struct pci_dev *pdev = ctrl->pci_dev;
+
+	rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index);
+	if (rc)
+		return rc;
+	return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value);
+}
+
 int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
 {
 	struct php_ctlr_state_s *php_ctlr, *p;
 	void *instance_id = ctrl;
-	int rc;
+	int rc, num_slots = 0;
 	u8 hp_slot;
 	static int first = 1;
-	u32 shpc_cap_offset, shpc_base_offset;
+	u32 shpc_base_offset;
 	u32 tempdword, slot_reg;
 	u8 i;
 
 	DBG_ENTER_ROUTINE
 
+	ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
+
 	spin_lock_init(&list_lock);
 	php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
 
@@ -1348,41 +1388,45 @@
 
 	if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
 				PCI_DEVICE_ID_AMD_GOLAM_7450)) {
-		shpc_base_offset = 0;  /* amd shpc driver doesn't use this; assume 0 */
+		/* amd shpc driver doesn't use Base Offset; assume 0 */
+		ctrl->mmio_base = pci_resource_start(pdev, 0);
+		ctrl->mmio_size = pci_resource_len(pdev, 0);
 	} else {
-		if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
-			err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
+		ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);
+		if (!ctrl->cap_offset) {
+			err("%s : cap_offset == 0\n", __FUNCTION__);
 			goto abort_free_ctlr;
 		}
-		dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);	
-	
-		rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
+		dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
+
+		rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset);
 		if (rc) {
-			err("%s : pci_word_config_byte failed\n", __FUNCTION__);
-			goto abort_free_ctlr;
-		}
-	
-		rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset);
-		if (rc) {
-			err("%s : pci_read_config_dword failed\n", __FUNCTION__);
+			err("%s: cannot read base_offset\n", __FUNCTION__);
 			goto abort_free_ctlr;
 		}
 
-		for (i = 0; i <= 14; i++) {
-			rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset +  DWORD_SELECT , i);
+		rc = shpc_indirect_creg_read(ctrl, 3, &tempdword);
+		if (rc) {
+			err("%s: cannot read slot config\n", __FUNCTION__);
+			goto abort_free_ctlr;
+		}
+		num_slots = tempdword & SLOT_NUM;
+		dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
+
+		for (i = 0; i < 9 + num_slots; i++) {
+			rc = shpc_indirect_creg_read(ctrl, i, &tempdword);
 			if (rc) {
-				err("%s : pci_word_config_byte failed\n", __FUNCTION__);
-				goto abort_free_ctlr;
-			}
-	
-			rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword);
-			if (rc) {
-				err("%s : pci_read_config_dword failed\n", __FUNCTION__);
+				err("%s: cannot read creg (index = %d)\n",
+				    __FUNCTION__, i);
 				goto abort_free_ctlr;
 			}
 			dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
 					tempdword);
 		}
+
+		ctrl->mmio_base =
+			pci_resource_start(pdev, 0) + shpc_base_offset;
+		ctrl->mmio_size = 0x24 + 0x4 * num_slots;
 	}
 
 	if (first) {
@@ -1396,16 +1440,16 @@
 	if (pci_enable_device(pdev))
 		goto abort_free_ctlr;
 
-	if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) {
+	if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
 		err("%s: cannot reserve MMIO region\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
 
-	php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
+	php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
 	if (!php_ctlr->creg) {
-		err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0), 
-			pci_resource_start(pdev, 0) + shpc_base_offset);
-		release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
+		err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
+		    ctrl->mmio_size, ctrl->mmio_base);
+		release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
 		goto abort_free_ctlr;
 	}
 	dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 38009bc..19e1a5e 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -89,10 +89,11 @@
 	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
 	int num, fn;
 
-	dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
+	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
 	if (dev) {
 		err("Device %s already exists at %x:%x, cannot hot-add\n",
 				pci_name(dev), p_slot->bus, p_slot->device);
+		pci_dev_put(dev);
 		return -EINVAL;
 	}
 
@@ -103,12 +104,13 @@
 	}
 
 	for (fn = 0; fn < 8; fn++) {
-		if (!(dev = pci_find_slot(p_slot->bus,
-					PCI_DEVFN(p_slot->device, fn))))
+		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
+		if (!dev)
 			continue;
 		if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
 			err("Cannot hot-add display device %s\n",
 					pci_name(dev));
+			pci_dev_put(dev);
 			continue;
 		}
 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
@@ -124,18 +126,21 @@
 			}
 			if (busnr >= end) {
 				err("No free bus for hot-added bridge\n");
+				pci_dev_put(dev);
 				continue;
 			}
 			child = pci_add_new_bus(parent, dev, busnr);
 			if (!child) {
 				err("Cannot add new bus for %s\n",
 						pci_name(dev));
+				pci_dev_put(dev);
 				continue;
 			}
 			child->subordinate = pci_do_scan_bus(child);
 			pci_bus_size_bridges(child);
 		}
 		program_fw_provided_values(dev);
+		pci_dev_put(dev);
 	}
 
 	pci_bus_assign_resources(parent);
@@ -149,17 +154,19 @@
 	int rc = 0;
 	int j;
 	u8 bctl = 0;
-	
+	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
+
 	dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);
 
 	for (j=0; j<8 ; j++) {
-		struct pci_dev* temp = pci_find_slot(p_slot->bus,
+		struct pci_dev* temp = pci_get_slot(parent,
 				(p_slot->device << 3) | j);
 		if (!temp)
 			continue;
 		if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
 			err("Cannot remove display device %s\n",
 					pci_name(temp));
+			pci_dev_put(temp);
 			continue;
 		}
 		if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
@@ -167,10 +174,12 @@
 			if (bctl & PCI_BRIDGE_CTL_VGA) {
 				err("Cannot remove display device %s\n",
 						pci_name(temp));
+				pci_dev_put(temp);
 				continue;
 			}
 		}
 		pci_remove_bus_device(temp);
+		pci_dev_put(temp);
 	}
 	return rc;
 }
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8e287a8..d2a633e 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -19,6 +19,7 @@
 #include <asm/dma.h>	/* isa_dma_bridge_buggy */
 #include "pci.h"
 
+#if 0
 
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
@@ -63,6 +64,8 @@
 	return max;
 }
 
+#endif  /*  0  */
+
 static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
 {
 	u8 id;
@@ -587,7 +590,7 @@
 {
 	u8 pin;
 
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+	pin = dev->pin;
 	if (!pin)
 		return -1;
 	pin--;
@@ -917,8 +920,6 @@
 EXPORT_SYMBOL(pci_enable_device_bars);
 EXPORT_SYMBOL(pci_enable_device);
 EXPORT_SYMBOL(pci_disable_device);
-EXPORT_SYMBOL(pci_max_busnr);
-EXPORT_SYMBOL(pci_bus_max_busnr);
 EXPORT_SYMBOL(pci_find_capability);
 EXPORT_SYMBOL(pci_bus_find_capability);
 EXPORT_SYMBOL(pci_release_regions);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 294849d..a6dfee2 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -26,20 +26,15 @@
 #ifdef CONFIG_PROC_FS
 extern int pci_proc_attach_device(struct pci_dev *dev);
 extern int pci_proc_detach_device(struct pci_dev *dev);
-extern int pci_proc_attach_bus(struct pci_bus *bus);
 extern int pci_proc_detach_bus(struct pci_bus *bus);
 #else
 static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; }
 static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; }
-static inline int pci_proc_attach_bus(struct pci_bus *bus) { return 0; }
 static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
 #endif
 
 /* Functions for PCI Hotplug drivers to use */
 extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
-extern int pci_remove_device_safe(struct pci_dev *dev);
-extern unsigned char pci_max_busnr(void);
-extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
 
 extern void pci_remove_legacy_files(struct pci_bus *bus);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 467a4ce..e4e5f1e 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -238,8 +238,8 @@
 	device->driver = NULL;
 	device->driver_data = NULL;
 	device->release = release_pcie_device;	/* callback to free pcie dev */
-	sprintf(&device->bus_id[0], "pcie%02x",
-		get_descriptor_id(port_type, service_type));
+	snprintf(device->bus_id, sizeof(device->bus_id), "%s:pcie%02x",
+		 pci_name(parent), get_descriptor_id(port_type, service_type));
 	device->parent = &parent->dev;
 }
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index fce2cb2..adfad4f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -264,8 +264,10 @@
 
 	if (base <= limit) {
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
-		res->start = base;
-		res->end = limit + 0xfff;
+		if (!res->start)
+			res->start = base;
+		if (!res->end)
+			res->end = limit + 0xfff;
 	}
 
 	res = child->resource[1];
@@ -431,7 +433,7 @@
 {
 	struct pci_bus *child;
 	int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
-	u32 buses, i;
+	u32 buses, i, j = 0;
 	u16 bctl;
 
 	pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -541,10 +543,29 @@
 			 * as cards with a PCI-to-PCI bridge can be
 			 * inserted later.
 			 */
-			for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
+			for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) {
+				struct pci_bus *parent = bus;
 				if (pci_find_bus(pci_domain_nr(bus),
 							max+i+1))
 					break;
+				while (parent->parent) {
+					if ((!pcibios_assign_all_busses()) &&
+					    (parent->subordinate > max) &&
+					    (parent->subordinate <= max+i)) {
+						j = 1;
+					}
+					parent = parent->parent;
+				}
+				if (j) {
+					/*
+					 * Often, there are two cardbus bridges
+					 * -- try to leave one valid bus number
+					 * for each one.
+					 */
+					i /= 2;
+					break;
+				}
+			}
 			max += i;
 			pci_fixup_parent_subordinate_busnr(child, max);
 		}
@@ -559,6 +580,22 @@
 
 	sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
 
+	while (bus->parent) {
+		if ((child->subordinate > bus->subordinate) ||
+		    (child->number > bus->subordinate) ||
+		    (child->number < bus->number) ||
+		    (child->subordinate < bus->number)) {
+			printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be "
+			       "hidden behind%s bridge #%02x (-#%02x)%s\n",
+			       child->number, child->subordinate,
+			       bus->self->transparent ? " transparent" : " ",
+			       bus->number, bus->subordinate,
+			       pcibios_assign_all_busses() ? " " :
+			       " (try 'pci=assign-busses')");
+		}
+		bus = bus->parent;
+	}
+
 	return max;
 }
 
@@ -571,6 +608,7 @@
 	unsigned char irq;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq);
+	dev->pin = irq;
 	if (irq)
 		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 	dev->irq = irq;
@@ -624,6 +662,7 @@
 		/* The PCI-to-PCI bridge spec requires that subtractive
 		   decoding (i.e. transparent) bridge must have programming
 		   interface code of 0x01. */ 
+		pci_read_irq(dev);
 		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
 		break;
@@ -678,7 +717,7 @@
  * reading the dword at 0x100 which must either be 0 or a valid extended
  * capability header.
  */
-static int pci_cfg_space_size(struct pci_dev *dev)
+int pci_cfg_space_size(struct pci_dev *dev)
 {
 	int pos;
 	u32 status;
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 9cb6dd0..92a8857 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -431,6 +431,7 @@
 	return 0;
 }
 
+#if 0
 int pci_proc_attach_bus(struct pci_bus* bus)
 {
 	struct proc_dir_entry *de = bus->procdir;
@@ -447,6 +448,7 @@
 	}
 	return 0;
 }
+#endif  /*  0  */
 
 int pci_proc_detach_bus(struct pci_bus* bus)
 {
@@ -612,7 +614,6 @@
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_proc_attach_device);
-EXPORT_SYMBOL(pci_proc_attach_bus);
 EXPORT_SYMBOL(pci_proc_detach_bus);
 #endif
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index f28ebdd..605f0df 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1342,6 +1342,32 @@
 	pci_do_fixups(dev, start, end);
 }
 
+/* Enable 1k I/O space granularity on the Intel P64H2 */
+static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
+{
+	u16 en1k;
+	u8 io_base_lo, io_limit_lo;
+	unsigned long base, limit;
+	struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+
+	pci_read_config_word(dev, 0x40, &en1k);
+
+	if (en1k & 0x200) {
+		printk(KERN_INFO "PCI: Enable I/O Space to 1 KB Granularity\n");
+
+		pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
+		pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
+		base = (io_base_lo & (PCI_IO_RANGE_MASK | 0x0c)) << 8;
+		limit = (io_limit_lo & (PCI_IO_RANGE_MASK | 0x0c)) << 8;
+
+		if (base <= limit) {
+			res->start = base;
+			res->end = limit + 0x3ff;
+		}
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	0x1460,		quirk_p64h2_1k_io);
+
 EXPORT_SYMBOL(pcie_mch_quirk);
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_fixup_device);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 27a294b..1a6bf9d 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -48,6 +48,7 @@
  * in question is not being used by a driver.
  * Returns 0 on success.
  */
+#if 0
 int pci_remove_device_safe(struct pci_dev *dev)
 {
 	if (pci_dev_driver(dev))
@@ -55,7 +56,7 @@
 	pci_destroy_dev(dev);
 	return 0;
 }
-EXPORT_SYMBOL(pci_remove_device_safe);
+#endif  /*  0  */
 
 void pci_remove_bus(struct pci_bus *pci_bus)
 {
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index 1b277d2..b502db2 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -561,7 +561,7 @@
 {
 	vrc4173_cardu_slots = 0;
 
-	return pci_module_init(&vrc4173_cardu_driver);
+	return pci_register_driver(&vrc4173_cardu_driver);
 }
 
 static void __devexit vrc4173_cardu_exit(void)
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index f10c86d..995d9dd 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -1195,7 +1195,7 @@
 		serial_txx9_register_ports(&serial_txx9_reg);
 
 #ifdef ENABLE_SERIAL_TXX9_PCI
-		ret = pci_module_init(&serial_txx9_pci_driver);
+		ret = pci_register_driver(&serial_txx9_pci_driver);
 #endif
 	}
 	return ret;
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index e9f5dee..2b97246 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -1666,6 +1666,7 @@
 #endif
 	output("CyblaFB version %s initializing\n", VERSION);
 	return pci_module_init(&cyblafb_pci_driver);
+	return pci_register_driver(&cyblafb_pci_driver);
 }
 
 static void __exit cyblafb_exit(void)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index de690ca..0a44072 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -78,6 +78,23 @@
 #define PCI_UNKNOWN	((pci_power_t __force) 5)
 #define PCI_POWER_ERROR	((pci_power_t __force) -1)
 
+/** The pci_channel state describes connectivity between the CPU and
+ *  the pci device.  If some PCI bus between here and the pci device
+ *  has crashed or locked up, this info is reflected here.
+ */
+typedef unsigned int __bitwise pci_channel_state_t;
+
+enum pci_channel_state {
+	/* I/O channel is in normal state */
+	pci_channel_io_normal = (__force pci_channel_state_t) 1,
+
+	/* I/O to channel is blocked */
+	pci_channel_io_frozen = (__force pci_channel_state_t) 2,
+
+	/* PCI card is dead */
+	pci_channel_io_perm_failure = (__force pci_channel_state_t) 3,
+};
+
 /*
  * The pci_dev structure is used to describe PCI devices.
  */
@@ -98,6 +115,7 @@
 	unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */
 	u8		hdr_type;	/* PCI header type (`multi' flag masked out) */
 	u8		rom_base_reg;	/* which config register controls the ROM */
+	u8		pin;  		/* which interrupt pin this device uses */
 
 	struct pci_driver *driver;	/* which driver has allocated this device */
 	u64		dma_mask;	/* Mask of the bits of bus address this
@@ -110,6 +128,7 @@
 					   this is D0-D3, D0 being fully functional,
 					   and D3 being off. */
 
+	pci_channel_state_t error_state;	/* current connectivity state */
 	struct	device	dev;		/* Generic device interface */
 
 	/* device is compatible with these IDs */
@@ -232,6 +251,54 @@
 	unsigned int use_driver_data:1; /* pci_driver->driver_data is used */
 };
 
+/* ---------------------------------------------------------------- */
+/** PCI Error Recovery System (PCI-ERS).  If a PCI device driver provides
+ *  a set fof callbacks in struct pci_error_handlers, then that device driver
+ *  will be notified of PCI bus errors, and will be driven to recovery
+ *  when an error occurs.
+ */
+
+typedef unsigned int __bitwise pci_ers_result_t;
+
+enum pci_ers_result {
+	/* no result/none/not supported in device driver */
+	PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1,
+
+	/* Device driver can recover without slot reset */
+	PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2,
+
+	/* Device driver wants slot to be reset. */
+	PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3,
+
+	/* Device has completely failed, is unrecoverable */
+	PCI_ERS_RESULT_DISCONNECT = (__force pci_ers_result_t) 4,
+
+	/* Device driver is fully recovered and operational */
+	PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5,
+};
+
+/* PCI bus error event callbacks */
+struct pci_error_handlers
+{
+	/* PCI bus error detected on this device */
+	pci_ers_result_t (*error_detected)(struct pci_dev *dev,
+	                      enum pci_channel_state error);
+
+	/* MMIO has been re-enabled, but not DMA */
+	pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev);
+
+	/* PCI Express link has been reset */
+	pci_ers_result_t (*link_reset)(struct pci_dev *dev);
+
+	/* PCI slot has been reset */
+	pci_ers_result_t (*slot_reset)(struct pci_dev *dev);
+
+	/* Device driver may resume normal operations */
+	void (*resume)(struct pci_dev *dev);
+};
+
+/* ---------------------------------------------------------------- */
+
 struct module;
 struct pci_driver {
 	struct list_head node;
@@ -244,6 +311,7 @@
 	int  (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable);   /* Enable wake event */
 	void (*shutdown) (struct pci_dev *dev);
 
+	struct pci_error_handlers *err_handler;
 	struct device_driver	driver;
 	struct pci_dynids dynids;
 };
@@ -448,6 +516,7 @@
 
 void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
 		  void *userdata);
+int pci_cfg_space_size(struct pci_dev *dev);
 
 /* kmem_cache style wrapper around pci_alloc_consistent() */
 
diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c
index 2cfd214..a0d73f3 100644
--- a/sound/oss/ad1889.c
+++ b/sound/oss/ad1889.c
@@ -1089,7 +1089,7 @@
 
 static int __init ad1889_init_module(void)
 {
-	return pci_module_init(&ad1889_driver);
+	return pci_register_driver(&ad1889_driver);
 }
 
 static void ad1889_exit_module(void)
diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c
index a85093f..4007a56 100644
--- a/sound/oss/btaudio.c
+++ b/sound/oss/btaudio.c
@@ -1101,7 +1101,7 @@
 	       digital ? "digital" : "",
 	       analog && digital ? "+" : "",
 	       analog ? "analog" : "");
-	return pci_module_init(&btaudio_pci_driver);
+	return pci_register_driver(&btaudio_pci_driver);
 }
 
 static void btaudio_cleanup_module(void)
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
index 74dcca7..7cfbb08 100644
--- a/sound/oss/cmpci.c
+++ b/sound/oss/cmpci.c
@@ -3366,7 +3366,7 @@
 static int __init init_cmpci(void)
 {
 	printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n");
-	return pci_module_init(&cm_driver);
+	return pci_register_driver(&cm_driver);
 }
 
 static void __exit cleanup_cmpci(void)
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
index 46dd41d..0720365 100644
--- a/sound/oss/cs4281/cs4281m.c
+++ b/sound/oss/cs4281/cs4281m.c
@@ -4461,7 +4461,7 @@
 	printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
 	       __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
 	       CS4281_ARCH);
-	rtn = pci_module_init(&cs4281_pci_driver);
+	rtn = pci_register_driver(&cs4281_pci_driver);
 
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
 		  printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn));
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index 0da4d93..58e25c8 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -5690,7 +5690,7 @@
 	int rtn = 0;
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
 		"cs46xx: cs46xx_init_module()+ \n"));
-	rtn = pci_module_init(&cs46xx_pci_driver);
+	rtn = pci_register_driver(&cs46xx_pci_driver);
 
 	if(rtn == -ENODEV)
 	{
diff --git a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c
index 9b905ba..23241cb 100644
--- a/sound/oss/emu10k1/main.c
+++ b/sound/oss/emu10k1/main.c
@@ -1428,7 +1428,7 @@
 {
 	printk(KERN_INFO "Creative EMU10K1 PCI Audio Driver, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
-	return pci_module_init(&emu10k1_pci_driver);
+	return pci_register_driver(&emu10k1_pci_driver);
 }
 
 static void __exit emu10k1_cleanup_module(void)
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c
index 8538085..ae55c53 100644
--- a/sound/oss/es1370.c
+++ b/sound/oss/es1370.c
@@ -2779,7 +2779,7 @@
 static int __init init_es1370(void)
 {
 	printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n");
-	return pci_module_init(&es1370_driver);
+	return pci_register_driver(&es1370_driver);
 }
 
 static void __exit cleanup_es1370(void)
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
index 12a56d5..5c697f16 100644
--- a/sound/oss/es1371.c
+++ b/sound/oss/es1371.c
@@ -3090,7 +3090,7 @@
 static int __init init_es1371(void)
 {
 	printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n");
-	return pci_module_init(&es1371_driver);
+	return pci_register_driver(&es1371_driver);
 }
 
 static void __exit cleanup_es1371(void)
diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c
index 26e5944..8fd2f9a 100644
--- a/sound/oss/ite8172.c
+++ b/sound/oss/ite8172.c
@@ -2206,7 +2206,7 @@
 static int __init init_it8172(void)
 {
 	info("version v0.5 time " __TIME__ " " __DATE__);
-	return pci_module_init(&it8172_driver);
+	return pci_register_driver(&it8172_driver);
 }
 
 static void __exit cleanup_it8172(void)
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 808c5ef..2835a7c 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -218,7 +218,7 @@
 static int __init kahlua_init_module(void)
 {
 	printk(KERN_INFO "Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc\n");
-	return pci_module_init(&kahlua_driver);
+	return pci_register_driver(&kahlua_driver);
 }
 
 static void __devexit kahlua_cleanup_module(void)
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
index f9ac5b1..d4b569a 100644
--- a/sound/oss/maestro.c
+++ b/sound/oss/maestro.c
@@ -3624,7 +3624,7 @@
 {
 	int rc;
 
-	rc = pci_module_init(&maestro_pci_driver);
+	rc = pci_register_driver(&maestro_pci_driver);
 	if (rc < 0)
 		return rc;
 
diff --git a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c
index 9ac4bf7..fbb9170 100644
--- a/sound/oss/nec_vrc5477.c
+++ b/sound/oss/nec_vrc5477.c
@@ -2045,7 +2045,7 @@
 static int __init init_vrc5477_ac97(void)
 {
 	printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");
-	return pci_module_init(&vrc5477_ac97_driver);
+	return pci_register_driver(&vrc5477_ac97_driver);
 }
 
 static void __exit cleanup_vrc5477_ac97(void)
diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c
index 42d8f05..7de079b 100644
--- a/sound/oss/nm256_audio.c
+++ b/sound/oss/nm256_audio.c
@@ -1644,7 +1644,7 @@
 static int __init do_init_nm256(void)
 {
     printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n");
-    return pci_module_init(&nm256_pci_driver);
+    return pci_register_driver(&nm256_pci_driver);
 }
 
 static void __exit cleanup_nm256 (void)
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
index 318dc51..faa0b79 100644
--- a/sound/oss/rme96xx.c
+++ b/sound/oss/rme96xx.c
@@ -1095,7 +1095,7 @@
 	devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
 	printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
         numcards = 0;
-	return pci_module_init(&rme96xx_driver);
+	return pci_register_driver(&rme96xx_driver);
 }
 
 static void __exit cleanup_rme96xx(void)
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
index 17d0e46..71b05e2 100644
--- a/sound/oss/sonicvibes.c
+++ b/sound/oss/sonicvibes.c
@@ -2765,7 +2765,7 @@
 	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
 		printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
 #endif
-	return pci_module_init(&sv_driver);
+	return pci_register_driver(&sv_driver);
 }
 
 static void __exit cleanup_sonicvibes(void)
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
index 8dae59b..f8bd72e 100644
--- a/sound/oss/ymfpci.c
+++ b/sound/oss/ymfpci.c
@@ -2680,7 +2680,7 @@
 
 static int __init ymf_init_module(void)
 {
-	return pci_module_init(&ymfpci_driver);
+	return pci_register_driver(&ymfpci_driver);
 }
 
 static void __exit ymf_cleanup_module (void)