Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/Documentation/pci.txt                         |   13 
 25-akpm/Documentation/power/pci.txt                   |   51 +-
 25-akpm/arch/alpha/kernel/console.c                   |    2 
 25-akpm/arch/alpha/kernel/pci.c                       |   20 
 25-akpm/arch/alpha/kernel/pci_impl.h                  |    1 
 25-akpm/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c     |    3 
 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c  |   15 
 25-akpm/arch/i386/kernel/cpu/cyrix.c                  |   11 
 25-akpm/arch/i386/kernel/cpu/mtrr/main.c              |    8 
 25-akpm/arch/i386/kernel/scx200.c                     |   67 +-
 25-akpm/arch/i386/pci/i386.c                          |   18 
 25-akpm/arch/i386/pci/irq.c                           |   20 
 25-akpm/arch/ia64/pci/pci.c                           |    6 
 25-akpm/arch/ia64/sn/io/machvec/pci_bus_cvlink.c      |    4 
 25-akpm/arch/ppc/kernel/pci.c                         |   28 -
 25-akpm/arch/ppc64/kernel/pSeries_pci.c               |  213 +++++++-
 25-akpm/arch/ppc64/kernel/pci.c                       |  167 ++++--
 25-akpm/arch/ppc64/kernel/pci.h                       |    6 
 25-akpm/arch/ppc64/kernel/pci_dn.c                    |   12 
 25-akpm/arch/sparc/kernel/pcic.c                      |    6 
 25-akpm/drivers/acpi/motherboard.c                    |    6 
 25-akpm/drivers/acpi/processor.c                      |   15 
 25-akpm/drivers/atm/eni.c                             |    4 
 25-akpm/drivers/atm/firestream.c                      |   12 
 25-akpm/drivers/atm/idt77252.c                        |   19 
 25-akpm/drivers/block/cpqarray.c                      |    4 
 25-akpm/drivers/char/agp/intel-agp.c                  |    2 
 25-akpm/drivers/char/agp/intel-mch-agp.c              |    2 
 25-akpm/drivers/char/applicom.c                       |    2 
 25-akpm/drivers/char/drm/drm_fops.h                   |    7 
 25-akpm/drivers/char/epca.c                           |   13 
 25-akpm/drivers/char/ipmi/ipmi_si_intf.c              |   14 
 25-akpm/drivers/isdn/hisax/hisax_fcpcipnp.c           |   12 
 25-akpm/drivers/media/video/bttv-cards.c              |    6 
 25-akpm/drivers/media/video/bttv-driver.c             |    4 
 25-akpm/drivers/media/video/bttvp.h                   |    1 
 25-akpm/drivers/media/video/cx88/cx88-video.c         |    4 
 25-akpm/drivers/media/video/cx88/cx88.h               |    1 
 25-akpm/drivers/media/video/meye.c                    |    4 
 25-akpm/drivers/media/video/meye.h                    |    1 
 25-akpm/drivers/message/fusion/mptbase.c              |    4 
 25-akpm/drivers/message/fusion/mptbase.h              |    3 
 25-akpm/drivers/misc/ibmasm/ibmasm.h                  |    2 
 25-akpm/drivers/misc/ibmasm/ibmasmfs.c                |    4 
 25-akpm/drivers/misc/ibmasm/lowlevel.c                |    2 
 25-akpm/drivers/misc/ibmasm/lowlevel.h                |   30 -
 25-akpm/drivers/misc/ibmasm/module.c                  |    6 
 25-akpm/drivers/misc/ibmasm/uart.c                    |    2 
 25-akpm/drivers/net/3c59x.c                           |   11 
 25-akpm/drivers/net/8139cp.c                          |    5 
 25-akpm/drivers/net/8139too.c                         |    6 
 25-akpm/drivers/net/amd8111e.c                        |    4 
 25-akpm/drivers/net/amd8111e.h                        |    1 
 25-akpm/drivers/net/b44.c                             |    4 
 25-akpm/drivers/net/b44.h                             |    1 
 25-akpm/drivers/net/dgrs.c                            |    4 
 25-akpm/drivers/net/e100.c                            |    5 
 25-akpm/drivers/net/e1000/e1000.h                     |    1 
 25-akpm/drivers/net/e1000/e1000_main.c                |    4 
 25-akpm/drivers/net/eepro100.c                        |    7 
 25-akpm/drivers/net/hamachi.c                         |    5 
 25-akpm/drivers/net/irda/via-ircc.c                   |   10 
 25-akpm/drivers/net/irda/vlsi_ir.c                    |    4 
 25-akpm/drivers/net/irda/vlsi_ir.h                    |    1 
 25-akpm/drivers/net/ixgb/ixgb.h                       |    1 
 25-akpm/drivers/net/ixgb/ixgb_main.c                  |    2 
 25-akpm/drivers/net/pci-skeleton.c                    |    5 
 25-akpm/drivers/net/s2io.c                            |    4 
 25-akpm/drivers/net/s2io.h                            |    1 
 25-akpm/drivers/net/sis900.c                          |    6 
 25-akpm/drivers/net/tg3.c                             |    8 
 25-akpm/drivers/net/tg3.h                             |    1 
 25-akpm/drivers/net/tokenring/abyss.c                 |    9 
 25-akpm/drivers/net/tokenring/tmspci.c                |    9 
 25-akpm/drivers/net/tulip/xircom_tulip_cb.c           |    7 
 25-akpm/drivers/net/typhoon.c                         |    7 
 25-akpm/drivers/net/via-rhine.c                       |    4 
 25-akpm/drivers/net/via-velocity.c                    |    4 
 25-akpm/drivers/net/via-velocity.h                    |    4 
 25-akpm/drivers/net/wan/sbni.c                        |    6 
 25-akpm/drivers/net/wireless/airo.c                   |    5 
 25-akpm/drivers/net/wireless/prism54/islpci_dev.h     |    1 
 25-akpm/drivers/net/wireless/prism54/islpci_hotplug.c |    4 
 25-akpm/drivers/net/wireless/prism54/islpci_mgt.c     |    4 
 25-akpm/drivers/parport/parport_pc.c                  |    8 
 25-akpm/drivers/pci/hotplug/acpiphp_ibm.c             |  101 ++--
 25-akpm/drivers/pci/hotplug/cpcihp_zt5550.c           |   15 
 25-akpm/drivers/pci/hotplug/cpqphp.h                  |    9 
 25-akpm/drivers/pci/hotplug/cpqphp_core.c             |   38 -
 25-akpm/drivers/pci/hotplug/cpqphp_ctrl.c             |    4 
 25-akpm/drivers/pci/hotplug/cpqphp_nvram.h            |   12 
 25-akpm/drivers/pci/hotplug/cpqphp_pci.c              |   12 
 25-akpm/drivers/pci/hotplug/ibmphp_core.c             |    2 
 25-akpm/drivers/pci/hotplug/ibmphp_ebda.c             |    4 
 25-akpm/drivers/pci/hotplug/ibmphp_hpc.c              |   28 -
 25-akpm/drivers/pci/hotplug/pciehp.h                  |   11 
 25-akpm/drivers/pci/hotplug/pciehp_core.c             |    4 
 25-akpm/drivers/pci/hotplug/rpadlpar_core.c           |  170 +++++-
 25-akpm/drivers/pci/hotplug/rpaphp.h                  |    4 
 25-akpm/drivers/pci/hotplug/rpaphp_core.c             |  147 +++--
 25-akpm/drivers/pci/hotplug/rpaphp_pci.c              |   80 ++-
 25-akpm/drivers/pci/hotplug/rpaphp_slot.c             |   11 
 25-akpm/drivers/pci/hotplug/rpaphp_vio.c              |    4 
 25-akpm/drivers/pci/hotplug/shpchp.h                  |    9 
 25-akpm/drivers/pci/hotplug/shpchp_core.c             |    4 
 25-akpm/drivers/pci/hotplug/shpchp_ctrl.c             |  447 ++++--------------
 25-akpm/drivers/pci/hotplug/shpchp_hpc.c              |    9 
 25-akpm/drivers/pci/hotplug/shpchprm_acpi.c           |    6 
 25-akpm/drivers/pci/msi.c                             |   20 
 25-akpm/drivers/pci/msi.h                             |    2 
 25-akpm/drivers/pci/pci-driver.c                      |   68 +-
 25-akpm/drivers/pci/pci.c                             |   40 -
 25-akpm/drivers/pci/pci.h                             |   21 
 25-akpm/drivers/pci/pci.ids                           |    8 
 25-akpm/drivers/pci/probe.c                           |   36 +
 25-akpm/drivers/pci/proc.c                            |    5 
 25-akpm/drivers/pci/quirks.c                          |   33 -
 25-akpm/drivers/pci/search.c                          |   77 ++-
 25-akpm/drivers/pci/setup-bus.c                       |   12 
 25-akpm/drivers/pci/setup-irq.c                       |    2 
 25-akpm/drivers/pcmcia/yenta_socket.c                 |   12 
 25-akpm/drivers/pcmcia/yenta_socket.h                 |    2 
 25-akpm/drivers/pnp/system.c                          |    6 
 25-akpm/drivers/scsi/eata.c                           |   12 
 25-akpm/drivers/scsi/ipr.c                            |    4 
 25-akpm/drivers/scsi/ipr.h                            |    1 
 25-akpm/drivers/scsi/megaraid/megaraid_mbox.c         |    8 
 25-akpm/drivers/scsi/nsp32.c                          |    5 
 25-akpm/drivers/scsi/nsp32.h                          |    3 
 25-akpm/drivers/usb/core/hcd-pci.c                    |    4 
 25-akpm/drivers/usb/core/hcd.h                        |    1 
 25-akpm/drivers/usb/gadget/goku_udc.c                 |    2 
 25-akpm/drivers/usb/gadget/net2280.c                  |    2 
 25-akpm/drivers/usb/host/ehci-hcd.c                   |    2 
 25-akpm/drivers/usb/host/ohci-pci.c                   |    2 
 25-akpm/drivers/usb/host/uhci-hcd.c                   |    2 
 25-akpm/drivers/video/i810/i810.h                     |    1 
 25-akpm/drivers/video/i810/i810_main.c                |   14 
 25-akpm/drivers/video/riva/fbdev.c                    |    5 
 25-akpm/include/asm-generic/vmlinux.lds.h             |    3 
 25-akpm/include/asm-ppc64/pci-bridge.h                |    6 
 25-akpm/include/asm-ppc64/pci.h                       |    2 
 25-akpm/include/linux/pci.h                           |   60 +-
 25-akpm/sound/core/init.c                             |    2 
 25-akpm/sound/oss/ali5455.c                           |   11 
 25-akpm/sound/oss/esssolo1.c                          |    6 
 25-akpm/sound/oss/forte.c                             |    7 
 25-akpm/sound/oss/i810_audio.c                        |   15 
 25-akpm/sound/oss/maestro3.c                          |    3 
 25-akpm/sound/oss/trident.c                           |    6 
 25-akpm/sound/oss/via82cxxx_audio.c                   |    8 
 151 files changed, 1447 insertions(+), 1255 deletions(-)

diff -puN arch/alpha/kernel/console.c~bk-pci arch/alpha/kernel/console.c
--- 25/arch/alpha/kernel/console.c~bk-pci	2004-10-06 20:35:45.257944128 -0700
+++ 25-akpm/arch/alpha/kernel/console.c	2004-10-06 20:35:45.824857944 -0700
@@ -47,7 +47,7 @@ locate_and_init_vga(void *(*sel_func)(vo
 
 	if (!sel_func) sel_func = (void *)default_vga_hose_select;
 
-	for(dev=NULL; (dev=pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
+	for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) {
 		if (!hose) hose = dev->sysdata;
 		else hose = sel_func(hose, dev->sysdata);
 	}
diff -puN arch/alpha/kernel/pci.c~bk-pci arch/alpha/kernel/pci.c
--- 25/arch/alpha/kernel/pci.c~bk-pci	2004-10-06 20:35:45.259943824 -0700
+++ 25-akpm/arch/alpha/kernel/pci.c	2004-10-06 20:35:45.825857792 -0700
@@ -227,7 +227,7 @@ pdev_save_srm_config(struct pci_dev *dev
 	tmp->next = srm_saved_configs;
 	tmp->dev = dev;
 
-	pci_save_state(dev, tmp->regs);
+	pci_save_state(dev);
 
 	srm_saved_configs = tmp;
 }
@@ -243,7 +243,7 @@ pci_restore_srm_config(void)
 
 	/* Restore SRM config. */
 	for (tmp = srm_saved_configs; tmp; tmp = tmp->next) {
-		pci_restore_state(tmp->dev, tmp->regs);
+		pci_restore_state(tmp->dev);
 	}
 }
 #endif
@@ -280,7 +280,6 @@ pcibios_fixup_bus(struct pci_bus *bus)
 	/* Propagate hose info into the subordinate devices.  */
 
 	struct pci_controller *hose = bus->sysdata;
-	struct list_head *ln;
 	struct pci_dev *dev = bus->self;
 
 	if (!dev) {
@@ -304,9 +303,7 @@ pcibios_fixup_bus(struct pci_bus *bus)
  		pcibios_fixup_device_resources(dev, bus);
 	} 
 
-	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-		struct pci_dev *dev = pci_dev_b(ln);
-
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 		pdev_save_srm_config(dev);
 		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 			pcibios_fixup_device_resources(dev, bus);
@@ -403,11 +400,10 @@ pcibios_set_master(struct pci_dev *dev)
 static void __init
 pcibios_claim_one_bus(struct pci_bus *b)
 {
-	struct list_head *ld;
+	struct pci_dev *dev;
 	struct pci_bus *child_bus;
 
-	for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
-		struct pci_dev *dev = pci_dev_b(ld);
+	list_for_each_entry(dev, &b->devices, bus_list) {
 		int i;
 
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -426,12 +422,10 @@ pcibios_claim_one_bus(struct pci_bus *b)
 static void __init
 pcibios_claim_console_setup(void)
 {
-	struct list_head *lb;
+	struct pci_bus *b;
 
-	for(lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) {
-		struct pci_bus *b = pci_bus_b(lb);
+	list_for_each_entry(b, &pci_root_buses, node)
 		pcibios_claim_one_bus(b);
-	}
 }
 
 void __init
diff -puN arch/alpha/kernel/pci_impl.h~bk-pci arch/alpha/kernel/pci_impl.h
--- 25/arch/alpha/kernel/pci_impl.h~bk-pci	2004-10-06 20:35:45.260943672 -0700
+++ 25-akpm/arch/alpha/kernel/pci_impl.h	2004-10-06 20:35:45.825857792 -0700
@@ -166,7 +166,6 @@ struct pdev_srm_saved_conf
 {
 	struct pdev_srm_saved_conf *next;
 	struct pci_dev *dev;
-	u32 regs[16];
 };
 
 extern void pci_restore_srm_config(void);
diff -puN arch/i386/kernel/cpu/cpufreq/gx-suspmod.c~bk-pci arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- 25/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c~bk-pci	2004-10-06 20:35:45.262943368 -0700
+++ 25-akpm/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2004-10-06 20:35:45.826857640 -0700
@@ -199,7 +199,7 @@ static __init struct pci_dev *gx_detect_
 	}
 
 	/* detect which companion chip is used */
-	while ((gx_pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
+	while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
 		if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
 			return gx_pci;
 		}
@@ -499,6 +499,7 @@ static int __init cpufreq_gx_init(void)
 static void __exit cpufreq_gx_exit(void)
 {
 	cpufreq_unregister_driver(&gx_suspmod_driver);
+	pci_dev_put(gx_params->cs55x0);
 	kfree(gx_params);
 }
 
diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~bk-pci arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
--- 25/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~bk-pci	2004-10-06 20:35:45.263943216 -0700
+++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2004-10-06 20:35:45.827857488 -0700
@@ -171,7 +171,7 @@ static int speedstep_activate (void)
  */
 static unsigned int speedstep_detect_chipset (void)
 {
-	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801DB_12,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -179,7 +179,7 @@ static unsigned int speedstep_detect_chi
 	if (speedstep_chipset_dev)
 		return 4; /* 4-M */
 
-	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801CA_12,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -188,7 +188,7 @@ static unsigned int speedstep_detect_chi
 		return 3; /* 3-M */
 
 
-	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82801BA_10,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -201,7 +201,7 @@ static unsigned int speedstep_detect_chi
 		static struct pci_dev *hostbridge;
 		u8 rev = 0;
 
-		hostbridge  = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+		hostbridge  = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82815_MC,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
@@ -214,9 +214,11 @@ static unsigned int speedstep_detect_chi
 		if (rev < 5) {
 			dprintk(KERN_INFO "cpufreq: hostbridge does not support speedstep\n");
 			speedstep_chipset_dev = NULL;
+			pci_dev_put(hostbridge);
 			return 0;
 		}
 
+		pci_dev_put(hostbridge);
 		return 2; /* 2-M */
 	}
 
@@ -397,8 +399,10 @@ static int __init speedstep_init(void)
 	}
 
 	/* activate speedstep support */
-	if (speedstep_activate())
+	if (speedstep_activate()) {
+		pci_dev_put(speedstep_chipset_dev);
 		return -EINVAL;
+	}
 
 	return cpufreq_register_driver(&speedstep_driver);
 }
@@ -411,6 +415,7 @@ static int __init speedstep_init(void)
  */
 static void __exit speedstep_exit(void)
 {
+	pci_dev_put(speedstep_chipset_dev);
 	cpufreq_unregister_driver(&speedstep_driver);
 }
 
diff -puN arch/i386/kernel/cpu/cyrix.c~bk-pci arch/i386/kernel/cpu/cyrix.c
--- 25/arch/i386/kernel/cpu/cyrix.c~bk-pci	2004-10-06 20:35:45.264943064 -0700
+++ 25-akpm/arch/i386/kernel/cpu/cyrix.c	2004-10-06 20:35:45.827857488 -0700
@@ -187,6 +187,14 @@ static void __init geode_configure(void)
 }
 
 
+#ifdef CONFIG_PCI
+static struct pci_device_id cyrix_55x0[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) },
+	{ },
+};
+#endif
+
 static void __init init_cyrix(struct cpuinfo_x86 *c)
 {
 	unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
@@ -274,8 +282,7 @@ static void __init init_cyrix(struct cpu
 		/*
 		 *  The 5510/5520 companion chips have a funky PIT.
 		 */  
-		if (pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||
-		    pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))
+		if (pci_dev_present(cyrix_55x0))
 			pit_latch_buggy = 1;
 
 		/* GXm supports extended cpuid levels 'ala' AMD */
diff -puN arch/i386/kernel/cpu/mtrr/main.c~bk-pci arch/i386/kernel/cpu/mtrr/main.c
--- 25/arch/i386/kernel/cpu/mtrr/main.c~bk-pci	2004-10-06 20:35:45.266942760 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mtrr/main.c	2004-10-06 20:35:45.828857336 -0700
@@ -77,22 +77,24 @@ static int have_wrcomb(void)
 {
 	struct pci_dev *dev;
 	
-	if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
+	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
 		/* ServerWorks LE chipsets have problems with write-combining 
 		   Don't allow it and leave room for other chipsets to be tagged */
 		if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
 		    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
 			printk(KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n");
+			pci_dev_put(dev);
 			return 0;
 		}
 		/* Intel 450NX errata # 23. Non ascending cachline evictions to
 		   write combining memory may resulting in data corruption */
 		if (dev->vendor == PCI_VENDOR_ID_INTEL &&
-		    dev->device == PCI_DEVICE_ID_INTEL_82451NX)
-		{
+		    dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
 			printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
+			pci_dev_put(dev);
 			return 0;
 		}
+		pci_dev_put(dev);
 	}		
 	return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0);
 }
diff -puN arch/i386/kernel/scx200.c~bk-pci arch/i386/kernel/scx200.c
--- 25/arch/i386/kernel/scx200.c~bk-pci	2004-10-06 20:35:45.267942608 -0700
+++ 25-akpm/arch/i386/kernel/scx200.c	2004-10-06 20:35:45.829857184 -0700
@@ -22,9 +22,47 @@ MODULE_LICENSE("GPL");
 unsigned scx200_gpio_base = 0;
 long scx200_gpio_shadow[2];
 
+static struct pci_device_id scx200_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+	{ },
+};
+MODULE_DEVICE_TABLE(pci,scx200_tbl);
+
+static int __devinit scx200_probe(struct pci_dev *, const struct pci_device_id *);
+
+static struct pci_driver scx200_pci_driver = {
+	.name = "scx200",
+	.id_table = scx200_tbl,
+	.probe = scx200_probe,
+};
+
 spinlock_t scx200_gpio_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t scx200_gpio_config_lock = SPIN_LOCK_UNLOCKED;
 
+static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int bank;
+	unsigned base;
+
+	base = pci_resource_start(pdev, 0);
+	printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
+
+	if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0) {
+		printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n");
+		return -EBUSY;
+	}
+
+	scx200_gpio_base = base;
+
+	/* read the current values driven on the GPIO signals */
+	for (bank = 0; bank < 2; ++bank)
+		scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank);
+
+	return 0;
+
+}
+
 u32 scx200_gpio_configure(int index, u32 mask, u32 bits)
 {
 	u32 config, new_config;
@@ -77,39 +115,14 @@ void scx200_gpio_dump(unsigned index)
 
 int __init scx200_init(void)
 {
-	struct pci_dev *bridge;
-	int bank;
-	unsigned base;
-
 	printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n");
 
-	if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, 
-				      PCI_DEVICE_ID_NS_SCx200_BRIDGE,
-				      NULL)) == NULL
-	    && (bridge = pci_find_device(PCI_VENDOR_ID_NS,
-					 PCI_DEVICE_ID_NS_SC1100_BRIDGE,
-					 NULL)) == NULL)
-		return -ENODEV;
-
-	base = pci_resource_start(bridge, 0);
-	printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
-
-	if (request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO") == 0) {
-		printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n");
-		return -EBUSY;
-	}
-
-	scx200_gpio_base = base;
-
-	/* read the current values driven on the GPIO signals */
-	for (bank = 0; bank < 2; ++bank)
-		scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank);
-
-	return 0;
+	return pci_module_init(&scx200_pci_driver);
 }
 
 void __exit scx200_cleanup(void)
 {
+	pci_unregister_driver(&scx200_pci_driver);
 	release_region(scx200_gpio_base, SCx200_GPIO_SIZE);
 }
 
diff -puN arch/i386/pci/i386.c~bk-pci arch/i386/pci/i386.c
--- 25/arch/i386/pci/i386.c~bk-pci	2004-10-06 20:35:45.268942456 -0700
+++ 25-akpm/arch/i386/pci/i386.c	2004-10-06 20:35:45.829857184 -0700
@@ -96,15 +96,13 @@ pcibios_align_resource(void *data, struc
 
 static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
 {
-	struct list_head *ln;
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 	int idx;
 	struct resource *r, *pr;
 
 	/* Depth-First Search on bus tree */
-	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, bus_list, node) {
 		if ((dev = bus->self)) {
 			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
 				r = &dev->resource[idx];
@@ -126,7 +124,7 @@ static void __init pcibios_allocate_reso
 	u16 command;
 	struct resource *r, *pr;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
 		for(idx = 0; idx < 6; idx++) {
 			r = &dev->resource[idx];
@@ -164,13 +162,13 @@ static void __init pcibios_allocate_reso
 	}
 }
 
-static void __init pcibios_assign_resources(void)
+static int __init pcibios_assign_resources(void)
 {
 	struct pci_dev *dev = NULL;
 	int idx;
 	struct resource *r;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		int class = dev->class >> 8;
 
 		/* Don't touch classless devices and host bridges */
@@ -204,6 +202,7 @@ static void __init pcibios_assign_resour
 				pci_assign_resource(dev, PCI_ROM_RESOURCE);
 		}
 	}
+	return 0;
 }
 
 void __init pcibios_resource_survey(void)
@@ -212,9 +211,14 @@ void __init pcibios_resource_survey(void
 	pcibios_allocate_bus_resources(&pci_root_buses);
 	pcibios_allocate_resources(0);
 	pcibios_allocate_resources(1);
-	pcibios_assign_resources();
 }
 
+/**
+ * called in fs_initcall (one below subsys_initcall),
+ * give a chance for motherboard reserve resources
+ */
+fs_initcall(pcibios_assign_resources);
+
 int pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
diff -puN arch/i386/pci/irq.c~bk-pci arch/i386/pci/irq.c
--- 25/arch/i386/pci/irq.c~bk-pci	2004-10-06 20:35:45.270942152 -0700
+++ 25-akpm/arch/i386/pci/irq.c	2004-10-06 20:35:45.830857032 -0700
@@ -455,12 +455,18 @@ static int pirq_bios_set(struct pci_dev 
 
 static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
 {
+	struct pci_dev *dev1, *dev2;
+
 	/* 440GX has a proprietary PIRQ router -- don't use it */
-	if (	pci_find_device(PCI_VENDOR_ID_INTEL,
-				PCI_DEVICE_ID_INTEL_82443GX_0, NULL) ||
-		pci_find_device(PCI_VENDOR_ID_INTEL,
-				PCI_DEVICE_ID_INTEL_82443GX_2, NULL))
+	dev1 = pci_get_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82443GX_0, NULL);
+	dev2 = pci_get_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82443GX_2, NULL);
+	if ((dev1 != NULL) || (dev2 != NULL)) {
+		pci_dev_put(dev1);
+		pci_dev_put(dev2);
 		return 0;
+	}
 
 	switch(device)
 	{
@@ -804,7 +810,7 @@ static int pcibios_lookup_irq(struct pci
 	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, pci_name(dev));
 
 	/* Update IRQ for all devices with the same pirq value */
-	while ((dev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
+	while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
 		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
 		if (!pin)
 			continue;
@@ -838,7 +844,7 @@ static void __init pcibios_fixup_irqs(vo
 	u8 pin;
 
 	DBG("PCI: IRQ fixup\n");
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	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.
@@ -854,7 +860,7 @@ static void __init pcibios_fixup_irqs(vo
 	}
 
 	dev = NULL;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 #ifdef CONFIG_X86_IO_APIC
 		/*
diff -puN arch/ia64/pci/pci.c~bk-pci arch/ia64/pci/pci.c
--- 25/arch/ia64/pci/pci.c~bk-pci	2004-10-06 20:35:45.271942000 -0700
+++ 25-akpm/arch/ia64/pci/pci.c	2004-10-06 20:35:45.831856880 -0700
@@ -365,10 +365,10 @@ pcibios_fixup_device_resources (struct p
 void __devinit
 pcibios_fixup_bus (struct pci_bus *b)
 {
-	struct list_head *ln;
+	struct pci_dev *dev;
 
-	for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
-		pcibios_fixup_device_resources(pci_dev_b(ln), b);
+	list_for_each_entry(dev, &b->devices, bus_list)
+		pcibios_fixup_device_resources(dev, b);
 
 	return;
 }
diff -puN arch/ia64/sn/io/machvec/pci_bus_cvlink.c~bk-pci arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- 25/arch/ia64/sn/io/machvec/pci_bus_cvlink.c~bk-pci	2004-10-06 20:35:45.273941696 -0700
+++ 25-akpm/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2004-10-06 20:35:45.832856728 -0700
@@ -832,7 +832,6 @@ sn_pci_init (void)
 {
 	int i = 0;
 	struct pci_controller *controller;
-	struct list_head *ln;
 	struct pci_bus *pci_bus = NULL;
 	struct pci_dev *pci_dev = NULL;
 	int ret;
@@ -879,8 +878,7 @@ sn_pci_init (void)
 	/*
 	 * Initialize the pci bus vertex in the pci_bus struct.
 	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
+	list_for_each_entry(pci_bus, &pci_root_buses, node) {
 		ret = sn_pci_fixup_bus(pci_bus);
 		if ( ret ) {
 			printk(KERN_WARNING
diff -puN arch/ppc64/kernel/pci.c~bk-pci arch/ppc64/kernel/pci.c
--- 25/arch/ppc64/kernel/pci.c~bk-pci	2004-10-06 20:35:45.274941544 -0700
+++ 25-akpm/arch/ppc64/kernel/pci.c	2004-10-06 20:35:45.837855968 -0700
@@ -179,26 +179,11 @@ void pcibios_align_resource(void *data, 
 	res->start = start;
 }
 
-/* 
- * Allocate pci_controller(phb) initialized common variables. 
- */
-struct pci_controller * __init
-pci_alloc_pci_controller(enum phb_types controller_type)
+static void phb_set_model(struct pci_controller *hose, 
+			  enum phb_types controller_type)
 {
-        struct pci_controller *hose;
 	char *model;
 
-#ifdef CONFIG_PPC_ISERIES
-        hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
-#else
-        hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
-#endif
-        if(hose == NULL) {
-                printk(KERN_ERR "PCI: Allocate pci_controller failed.\n");
-                return NULL;
-        }
-        memset(hose, 0, sizeof(struct pci_controller));
-
 	switch(controller_type) {
 #ifdef CONFIG_PPC_ISERIES
 	case phb_type_hypervisor:
@@ -226,21 +211,71 @@ pci_alloc_pci_controller(enum phb_types 
 		strcpy(hose->what,model);
         else
 		memcpy(hose->what,model,7);
-        hose->type = controller_type;
-        hose->global_number = global_phb_number++;
+}
+/*
+ * Allocate pci_controller(phb) initialized common variables.
+ */
+struct pci_controller * __init
+pci_alloc_pci_controller(enum phb_types controller_type)
+{
+	struct pci_controller *hose;
+
+#ifdef CONFIG_PPC_ISERIES
+	hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
+						GFP_KERNEL);
+#else
+	hose = (struct pci_controller *)alloc_bootmem(sizeof(struct pci_controller));
+#endif
+	if (hose == NULL) {
+		printk(KERN_ERR "PCI: Allocate pci_controller failed.\n");
+		return NULL;
+	}
+	memset(hose, 0, sizeof(struct pci_controller));
+
+	phb_set_model(hose, controller_type);
+
+	hose->is_dynamic = 0;
+	hose->type = controller_type;
+	hose->global_number = global_phb_number++;
+
+	list_add_tail(&hose->list_node, &hose_list);
+
+	return hose;
+}
+
+/*
+ * Dymnamically allocate pci_controller(phb), initialize common variables.
+ */
+struct pci_controller *
+pci_alloc_phb_dynamic(enum phb_types controller_type)
+{
+	struct pci_controller *hose;
+
+	hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
+						GFP_KERNEL);
+	if(hose == NULL) {
+		printk(KERN_ERR "PCI: Allocate pci_controller failed.\n");
+		return NULL;
+	}
+	memset(hose, 0, sizeof(struct pci_controller));
+
+	phb_set_model(hose, controller_type);
+
+	hose->is_dynamic = 1;
+	hose->type = controller_type;
+	hose->global_number = global_phb_number++;
 
 	list_add_tail(&hose->list_node, &hose_list);
 
-        return hose;
+	return hose;
 }
 
 static void __init pcibios_claim_one_bus(struct pci_bus *b)
 {
-	struct list_head *ld;
+	struct pci_dev *dev;
 	struct pci_bus *child_bus;
 
-	for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
-		struct pci_dev *dev = pci_dev_b(ld);
+	list_for_each_entry(dev, &b->devices, bus_list) {
 		int i;
 
 		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -259,12 +294,10 @@ static void __init pcibios_claim_one_bus
 #ifndef CONFIG_PPC_ISERIES
 static void __init pcibios_claim_of_setup(void)
 {
-	struct list_head *lb;
+	struct pci_bus *b;
 
-	for (lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) {
-		struct pci_bus *b = pci_bus_b(lb);
+	list_for_each_entry(b, &pci_root_buses, node)
 		pcibios_claim_one_bus(b);
-	}
 }
 #endif
 
@@ -303,7 +336,7 @@ static int __init pcibios_init(void)
 		ppc_md.pcibios_fixup();
 
 	/* Cache the location of the ISA bridge (if we have one) */
-	ppc64_isabridge_dev = pci_find_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+	ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
 	if (ppc64_isabridge_dev != NULL)
 		printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
@@ -534,7 +567,7 @@ void pcibios_add_platform_entries(struct
 #define ISA_SPACE_MASK 0x1
 #define ISA_SPACE_IO 0x1
 
-static void pci_process_ISA_OF_ranges(struct device_node *isa_node,
+static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
 				      unsigned long phb_io_base_phys,
 				      void * phb_io_base_virt)
 {
@@ -579,8 +612,8 @@ static void pci_process_ISA_OF_ranges(st
 	}
 }
 
-void __init pci_process_bridge_OF_ranges(struct pci_controller *hose,
-					 struct device_node *dev, int primary)
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+					struct device_node *dev)
 {
 	unsigned int *ranges;
 	unsigned long size;
@@ -589,7 +622,6 @@ void __init pci_process_bridge_OF_ranges
 	struct resource *res;
 	int np, na = prom_n_addr_cells(dev);
 	unsigned long pci_addr, cpu_phys_addr;
-	struct device_node *isa_dn;
 
 	np = na + 5;
 
@@ -617,31 +649,11 @@ void __init pci_process_bridge_OF_ranges
 		switch (ranges[0] >> 24) {
 		case 1:		/* I/O space */
 			hose->io_base_phys = cpu_phys_addr;
-			hose->io_base_virt = reserve_phb_iospace(size);
-			PPCDBG(PPCDBG_PHBINIT, 
-			       "phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", 
-			       hose->global_number, hose->io_base_phys, 
-			       (unsigned long) hose->io_base_virt);
-
-			if (primary) {
-				pci_io_base = (unsigned long)hose->io_base_virt;
-				isa_dn = of_find_node_by_type(NULL, "isa");
-				if (isa_dn) {
-					isa_io_base = pci_io_base;
-					pci_process_ISA_OF_ranges(isa_dn,
-						hose->io_base_phys,
-						hose->io_base_virt);
-					of_node_put(isa_dn);
-                                        /* Allow all IO */
-                                        io_page_mask = -1;
-				}
-			}
+			hose->pci_io_size = size;
 
 			res = &hose->io_resource;
 			res->flags = IORESOURCE_IO;
 			res->start = pci_addr;
-			res->start += (unsigned long)hose->io_base_virt -
-				pci_io_base;
 			break;
 		case 2:		/* memory space */
 			memno = 0;
@@ -668,6 +680,55 @@ void __init pci_process_bridge_OF_ranges
 	}
 }
 
+void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
+{
+	unsigned long size = hose->pci_io_size;
+	unsigned long io_virt_offset;
+	struct resource *res;
+	struct device_node *isa_dn;
+
+	hose->io_base_virt = reserve_phb_iospace(size);
+	PPCDBG(PPCDBG_PHBINIT, "phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
+		hose->global_number, hose->io_base_phys,
+		(unsigned long) hose->io_base_virt);
+
+	if (primary) {
+		pci_io_base = (unsigned long)hose->io_base_virt;
+		isa_dn = of_find_node_by_type(NULL, "isa");
+		if (isa_dn) {
+			isa_io_base = pci_io_base;
+			pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
+						hose->io_base_virt);
+			of_node_put(isa_dn);
+			/* Allow all IO */
+			io_page_mask = -1;
+		}
+	}
+
+	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+	res = &hose->io_resource;
+	res->start += io_virt_offset;
+	res->end += io_virt_offset;
+}
+
+void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose)
+{
+	unsigned long size = hose->pci_io_size;
+	unsigned long io_virt_offset;
+	struct resource *res;
+
+	hose->io_base_virt = __ioremap(hose->io_base_phys, size,
+					_PAGE_NO_CACHE);
+	PPCDBG(PPCDBG_PHBINIT, "phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
+		hose->global_number, hose->io_base_phys,
+		(unsigned long) hose->io_base_virt);
+
+	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+	res = &hose->io_resource;
+	res->start += io_virt_offset;
+	res->end += io_virt_offset;
+}
+
 /*********************************************************************** 
  * pci_find_hose_for_OF_device
  *
diff -puN arch/ppc64/kernel/pci_dn.c~bk-pci arch/ppc64/kernel/pci_dn.c
--- 25/arch/ppc64/kernel/pci_dn.c~bk-pci	2004-10-06 20:35:45.275941392 -0700
+++ 25-akpm/arch/ppc64/kernel/pci_dn.c	2004-10-06 20:35:45.838855816 -0700
@@ -42,7 +42,7 @@
  * Traverse_func that inits the PCI fields of the device node.
  * NOTE: this *must* be done before read/write config to the device.
  */
-static void * __init update_dn_pci_info(struct device_node *dn, void *data)
+static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 {
 	struct pci_controller *phb = data;
 	u32 *regs;
@@ -139,6 +139,12 @@ static void *traverse_all_pci_devices(tr
 	return NULL;
 }
 
+void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
+{
+	/* Update dn->phb ptrs for new phb and children devices */
+	traverse_pci_devices((struct device_node *)phb->arch_data,
+			update_dn_pci_info, phb);
+}
 
 /*
  * Traversal func that looks for a <busno,devfcn> value.
@@ -196,11 +202,9 @@ void __init pci_devs_phb_init(void)
 
 static void __init pci_fixup_bus_sysdata_list(struct list_head *bus_list)
 {
-	struct list_head *ln;
 	struct pci_bus *bus;
 
-	for (ln = bus_list->next; ln != bus_list; ln = ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, bus_list, node) {
 		if (bus->self)
 			bus->sysdata = bus->self->sysdata;
 		pci_fixup_bus_sysdata_list(&bus->children);
diff -puN arch/ppc64/kernel/pci.h~bk-pci arch/ppc64/kernel/pci.h
--- 25/arch/ppc64/kernel/pci.h~bk-pci	2004-10-06 20:35:45.277941088 -0700
+++ 25-akpm/arch/ppc64/kernel/pci.h	2004-10-06 20:35:45.838855816 -0700
@@ -15,7 +15,12 @@
 extern unsigned long isa_io_base;
 
 extern struct pci_controller* pci_alloc_pci_controller(enum phb_types controller_type);
+extern struct pci_controller* pci_alloc_phb_dynamic(enum phb_types controller_type);
+extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
+
 extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
+extern void pci_setup_phb_io_dynamic(struct pci_controller *hose);
+
 
 extern struct list_head hose_list;
 extern int global_phb_number;
@@ -36,6 +41,7 @@ void *traverse_pci_devices(struct device
 		void *data);
 
 void pci_devs_phb_init(void);
+void pci_devs_phb_init_dynamic(struct pci_controller *phb);
 void pci_fix_bus_sysdata(void);
 struct device_node *fetch_dev_dn(struct pci_dev *dev);
 
diff -puN arch/ppc64/kernel/pSeries_pci.c~bk-pci arch/ppc64/kernel/pSeries_pci.c
--- 25/arch/ppc64/kernel/pSeries_pci.c~bk-pci	2004-10-06 20:35:45.278940936 -0700
+++ 25-akpm/arch/ppc64/kernel/pSeries_pci.c	2004-10-06 20:35:45.835856272 -0700
@@ -190,7 +190,7 @@ void __init init_pci_config_tokens (void
 	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
 }
 
-unsigned long __init get_phb_buid (struct device_node *phb)
+unsigned long __devinit get_phb_buid (struct device_node *phb)
 {
 	int addr_cells;
 	unsigned int *buid_vals;
@@ -220,48 +220,85 @@ unsigned long __init get_phb_buid (struc
 	return buid;
 }
 
-static struct pci_controller * __init alloc_phb(struct device_node *dev,
-				 unsigned int addr_size_words)
+static enum phb_types get_phb_type(struct device_node *dev)
 {
-	struct pci_controller *phb;
-	unsigned int *ui_ptr = NULL, len;
-	struct reg_property64 reg_struct;
-	int *bus_range;
+	enum phb_types type;
 	char *model;
-	enum phb_types phb_type;
- 	struct property *of_prop;
 
 	model = (char *)get_property(dev, "model", NULL);
 
 	if (!model) {
-		printk(KERN_ERR "alloc_phb: phb has no model property\n");
+		printk(KERN_ERR "%s: phb has no model property\n",
+				__FUNCTION__);
 		model = "<empty>";
 	}
 
+	if (strstr(model, "Python")) {
+		type = phb_type_python;
+	} else if (strstr(model, "Speedwagon")) {
+		type = phb_type_speedwagon;
+	} else if (strstr(model, "Winnipeg")) {
+		type = phb_type_winnipeg;
+	} else {
+		printk(KERN_ERR "%s: unknown PHB %s\n", __FUNCTION__, model);
+		type = phb_type_unknown;
+	}
+
+	return type;
+}
+
+int get_phb_reg_prop(struct device_node *dev, unsigned int addr_size_words,
+		struct reg_property64 *reg)
+{
+	unsigned int *ui_ptr = NULL, len;
+
 	/* Found a PHB, now figure out where his registers are mapped. */
 	ui_ptr = (unsigned int *) get_property(dev, "reg", &len);
 	if (ui_ptr == NULL) {
 		PPCDBG(PPCDBG_PHBINIT, "\tget reg failed.\n"); 
-		return NULL;
+		return 1;
 	}
 
 	if (addr_size_words == 1) {
-		reg_struct.address = ((struct reg_property32 *)ui_ptr)->address;
-		reg_struct.size    = ((struct reg_property32 *)ui_ptr)->size;
+		reg->address = ((struct reg_property32 *)ui_ptr)->address;
+		reg->size    = ((struct reg_property32 *)ui_ptr)->size;
 	} else {
-		reg_struct = *((struct reg_property64 *)ui_ptr);
+		*reg = *((struct reg_property64 *)ui_ptr);
 	}
 
-	if (strstr(model, "Python")) {
-		phb_type = phb_type_python;
-	} else if (strstr(model, "Speedwagon")) {
-		phb_type = phb_type_speedwagon;
-	} else if (strstr(model, "Winnipeg")) {
-		phb_type = phb_type_winnipeg;
-	} else {
-		printk(KERN_ERR "alloc_phb: unknown PHB %s\n", model);
-		phb_type = phb_type_unknown;
-	}
+	return 0;
+}
+
+int phb_set_bus_ranges(struct device_node *dev, struct pci_controller *phb)
+{
+	int *bus_range;
+	unsigned int len;
+
+	bus_range = (int *) get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		return 1;
+ 	}
+ 
+	phb->first_busno =  bus_range[0];
+	phb->last_busno  =  bus_range[1];
+
+	return 0;
+}
+
+static struct pci_controller *alloc_phb(struct device_node *dev,
+				 unsigned int addr_size_words)
+{
+	struct pci_controller *phb;
+	struct reg_property64 reg_struct;
+	enum phb_types phb_type;
+	struct property *of_prop;
+	int rc;
+
+	phb_type = get_phb_type(dev);
+
+	rc = get_phb_reg_prop(dev, addr_size_words, &reg_struct);
+	if (rc)
+		return NULL;
 
 	phb = pci_alloc_pci_controller(phb_type);
 	if (phb == NULL)
@@ -270,11 +307,9 @@ static struct pci_controller * __init al
 	if (phb_type == phb_type_python)
 		python_countermeasures(reg_struct.address);
 
-	bus_range = (int *) get_property(dev, "bus-range", &len);
-	if (bus_range == NULL || len < 2 * sizeof(int)) {
-		kfree(phb);
+	rc = phb_set_bus_ranges(dev, phb);
+	if (rc)
 		return NULL;
-	}
 
 	of_prop = (struct property *)alloc_bootmem(sizeof(struct property) +
 			sizeof(phb->global_number));        
@@ -291,9 +326,6 @@ static struct pci_controller * __init al
 	memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
 	prom_add_property(dev, of_prop);
 
-	phb->first_busno =  bus_range[0];
-	phb->last_busno  =  bus_range[1];
-
 	phb->arch_data   = dev;
 	phb->ops = &rtas_pci_ops;
 
@@ -302,6 +334,40 @@ static struct pci_controller * __init al
 	return phb;
 }
 
+static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
+{
+	struct pci_controller *phb;
+	struct reg_property64 reg_struct;
+	enum phb_types phb_type;
+	int rc;
+
+	phb_type = get_phb_type(dev);
+
+	rc = get_phb_reg_prop(dev, addr_size_words, &reg_struct);
+	if (rc)
+		return NULL;
+
+	phb = pci_alloc_phb_dynamic(phb_type);
+	if (phb == NULL)
+		return NULL;
+
+	if (phb_type == phb_type_python)
+		python_countermeasures(reg_struct.address);
+
+	rc = phb_set_bus_ranges(dev, phb);
+	if (rc)
+		return NULL;
+
+	/* TODO: linux,pci-domain? */
+
+	phb->arch_data   = dev;
+	phb->ops = &rtas_pci_ops;
+
+	phb->buid = get_phb_buid(dev);
+
+ 	return phb;
+}
+
 unsigned long __init find_and_init_phbs(void)
 {
 	struct device_node *node;
@@ -330,7 +396,8 @@ unsigned long __init find_and_init_phbs(
 		if (!phb)
 			continue;
 
-		pci_process_bridge_OF_ranges(phb, node, index == 0);
+		pci_process_bridge_OF_ranges(phb, node);
+		pci_setup_phb_io(phb, index == 0);
 
 		if (naca->interrupt_controller == IC_OPEN_PIC) {
 			int addr = root_size_cells * (index + 2) - 1;
@@ -346,6 +413,34 @@ unsigned long __init find_and_init_phbs(
 	return 0;
 }
 
+struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
+{
+	struct device_node *root = of_find_node_by_path("/");
+	unsigned int root_size_cells = 0;
+	struct pci_controller *phb;
+	struct pci_bus *bus;
+
+	root_size_cells = prom_n_size_cells(root);
+
+	phb = alloc_phb_dynamic(dn, root_size_cells);
+	if (!phb)
+		return NULL;
+
+	pci_process_bridge_OF_ranges(phb, dn);
+
+	pci_setup_phb_io_dynamic(phb);
+	of_node_put(root);
+
+	pci_devs_phb_init_dynamic(phb);
+	phb->last_busno = 0xff;
+	bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
+	phb->bus = bus;
+	phb->last_busno = bus->subordinate;
+
+	return phb;
+}
+EXPORT_SYMBOL(init_phb_dynamic);
+
 #if 0
 void pcibios_name_device(struct pci_dev *dev)
 {
@@ -464,7 +559,7 @@ int remap_bus_range(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(remap_bus_range);
 
-static void phbs_fixup_io(void)
+static void phbs_remap_io(void)
 {
 	struct pci_controller *hose, *tmp;
 
@@ -472,6 +567,56 @@ static void phbs_fixup_io(void)
 		remap_bus_range(hose->bus);
 }
 
+/* RPA-specific bits for removing PHBs */
+int pcibios_remove_root_bus(struct pci_controller *phb)
+{
+	struct pci_bus *b = phb->bus;
+	struct resource *res;
+	int rc, i;
+
+	res = b->resource[0];
+	if (!res->flags) {
+		printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
+				b->name);
+		return 1;
+	}
+
+	rc = unmap_bus_range(b);
+	if (rc) {
+		printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
+			__FUNCTION__, b->name);
+		return 1;
+	}
+
+	if (release_resource(res)) {
+		printk(KERN_ERR "%s: failed to release IO on bus %s\n",
+				__FUNCTION__, b->name);
+		return 1;
+	}
+
+	for (i = 1; i < 3; ++i) {
+		res = b->resource[i];
+		if (!res->flags && i == 0) {
+			printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
+				__FUNCTION__, b->name);
+			return 1;
+		}
+		if (res->flags && release_resource(res)) {
+			printk(KERN_ERR
+			       "%s: failed to release IO %d on bus %s\n",
+				__FUNCTION__, i, b->name);
+			return 1;
+		}
+	}
+
+	list_del(&phb->list_node);
+	if (phb->is_dynamic)
+		kfree(phb);
+
+	return 0;
+}
+EXPORT_SYMBOL(pcibios_remove_root_bus);
+
 static void __init pSeries_request_regions(void)
 {
 	struct device_node *i8042;
@@ -511,7 +656,7 @@ void __init pSeries_final_fixup(void)
 		}
 	}
 
-	phbs_fixup_io();
+	phbs_remap_io();
 	pSeries_request_regions();
 	pci_fix_bus_sysdata();
 
diff -puN arch/ppc/kernel/pci.c~bk-pci arch/ppc/kernel/pci.c
--- 25/arch/ppc/kernel/pci.c~bk-pci	2004-10-06 20:35:45.280940632 -0700
+++ 25-akpm/arch/ppc/kernel/pci.c	2004-10-06 20:35:45.834856424 -0700
@@ -231,14 +231,12 @@ EXPORT_SYMBOL(pcibios_align_resource);
 static void __init
 pcibios_allocate_bus_resources(struct list_head *bus_list)
 {
-	struct list_head *ln;
 	struct pci_bus *bus;
 	int i;
 	struct resource *res, *pr;
 
 	/* Depth-First Search on bus tree */
-	for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, bus_list, node) {
 		for (i = 0; i < 4; ++i) {
 			if ((res = bus->resource[i]) == NULL || !res->flags
 			    || res->start > res->end)
@@ -381,7 +379,6 @@ probe_resource(struct pci_bus *parent, s
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 	struct resource *r;
-	struct list_head *ln;
 	int i;
 
 	for (r = pr->child; r != NULL; r = r->sibling) {
@@ -390,9 +387,7 @@ probe_resource(struct pci_bus *parent, s
 			return 1;
 		}
 	}
-	for (ln = parent->children.next; ln != &parent->children;
-	     ln = ln->next) {
-		bus = pci_bus_b(ln);
+	list_for_each_entry(bus, &parent->children, node) {
 		for (i = 0; i < 4; ++i) {
 			if ((r = bus->resource[i]) == NULL)
 				continue;
@@ -406,8 +401,7 @@ probe_resource(struct pci_bus *parent, s
 			}
 		}
 	}
-	for (ln = parent->devices.next; ln != &parent->devices; ln=ln->next) {
-		dev = pci_dev_b(ln);
+	list_for_each_entry(dev, &parent->devices, bus_list) {
 		for (i = 0; i < 6; ++i) {
 			r = &dev->resource[i];
 			if (!r->flags || (r->flags & IORESOURCE_UNSET))
@@ -1102,7 +1096,7 @@ do_update_p2p_io_resource(struct pci_bus
 static int __init
 check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
 {
-	struct list_head *ln;
+	struct pci_dev *dev;
 	int	i;
 	int	rc = 0;
 
@@ -1110,8 +1104,7 @@ check_for_io_childs(struct pci_bus *bus,
 	res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
     } while (0)
 
-	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-		struct pci_dev *dev = pci_dev_b(ln);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u16 class = dev->class >> 8;
 
 		if (class == PCI_CLASS_DISPLAY_VGA ||
@@ -1152,7 +1145,7 @@ check_for_io_childs(struct pci_bus *bus,
 static void __init
 do_fixup_p2p_level(struct pci_bus *bus)
 {
-	struct list_head *ln;
+	struct pci_bus *b;
 	int i, parent_io;
 	int has_vga = 0;
 
@@ -1163,8 +1156,7 @@ do_fixup_p2p_level(struct pci_bus *bus)
 	if (parent_io >= 4)
 		return;
 
-	for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
-		struct pci_bus *b = pci_bus_b(ln);
+	list_for_each_entry(b, &bus->children, node) {
 		struct pci_dev *d = b->self;
 		struct pci_controller* hose = (struct pci_controller *)d->sysdata;
 		struct resource *res = b->resource[0];
@@ -1237,12 +1229,10 @@ do_fixup_p2p_level(struct pci_bus *bus)
 static void
 pcibios_fixup_p2p_bridges(void)
 {
-	struct list_head *ln;
+	struct pci_bus *b;
 
-	for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
-		struct pci_bus *b = pci_bus_b(ln);
+	list_for_each_entry(b, &pci_root_buses, node)
 		do_fixup_p2p_level(b);
-	}
 }
 
 #endif /* CONFIG_PPC_PMAC */
diff -puN arch/sparc/kernel/pcic.c~bk-pci arch/sparc/kernel/pcic.c
--- 25/arch/sparc/kernel/pcic.c~bk-pci	2004-10-06 20:35:45.281940480 -0700
+++ 25-akpm/arch/sparc/kernel/pcic.c	2004-10-06 20:35:45.839855664 -0700
@@ -603,7 +603,7 @@ pcic_fill_irq(struct linux_pcic *pcic, s
  */
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct list_head *walk;
+	struct pci_dev *dev;
 	int i, has_io, has_mem;
 	unsigned int cmd;
 	struct linux_pcic *pcic;
@@ -625,9 +625,7 @@ void __init pcibios_fixup_bus(struct pci
 		return;
 	}
 
-	walk = &bus->devices;
-	for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
-		struct pci_dev *dev = pci_dev_b(walk);
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 
 		/*
 		 * Comment from i386 branch:
diff -puN Documentation/pci.txt~bk-pci Documentation/pci.txt
--- 25/Documentation/pci.txt~bk-pci	2004-10-06 20:35:45.282940328 -0700
+++ 25-akpm/Documentation/pci.txt	2004-10-06 20:35:45.822858248 -0700
@@ -141,16 +141,16 @@ for PCI devices manually using the follo
 Searching by vendor and device ID:
 
 	struct pci_dev *dev = NULL;
-	while (dev = pci_find_device(VENDOR_ID, DEVICE_ID, dev))
+	while (dev = pci_get_device(VENDOR_ID, DEVICE_ID, dev))
 		configure_device(dev);
 
 Searching by class ID (iterate in a similar way):
 
-	pci_find_class(CLASS_ID, dev)
+	pci_get_class(CLASS_ID, dev)
 
 Searching by both vendor/device and subsystem vendor/device ID:
 
-	pci_find_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).
+	pci_get_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).
 
    You can use the constant PCI_ANY_ID as a wildcard replacement for
 VENDOR_ID or DEVICE_ID.  This allows searching for any device from a
@@ -275,11 +275,12 @@ pci_present()			of PCI subsystem when tr
 				devices just return NULL.
 pcibios_(read|write)_*		Superseded by their pci_(read|write)_*
 				counterparts.
-pcibios_find_*			Superseded by their pci_find_* counterparts.
-pci_for_each_dev()		Superseded by pci_find_device()
+pcibios_find_*			Superseded by their pci_get_* counterparts.
+pci_for_each_dev()		Superseded by pci_get_device()
 pci_for_each_dev_reverse()	Superseded by pci_find_device_reverse()
 pci_for_each_bus()		Superseded by pci_find_next_bus()
 pci_find_device()		Superseded by pci_get_device()
 pci_find_subsys()		Superseded by pci_get_subsys()
-pcibios_find_class()		Superseded by pci_find_class()
+pcibios_find_class()		Superseded by pci_get_class()
+pci_find_class()		Superseded by pci_get_class()
 pci_(read|write)_*_nodev()	Superseded by pci_bus_(read|write)_*()
diff -puN Documentation/power/pci.txt~bk-pci Documentation/power/pci.txt
--- 25/Documentation/power/pci.txt~bk-pci	2004-10-06 20:35:45.284940024 -0700
+++ 25-akpm/Documentation/power/pci.txt	2004-10-06 20:35:45.824857944 -0700
@@ -5,6 +5,7 @@ PCI Power Management
 An overview of the concepts and the related functions in the Linux kernel
 
 Patrick Mochel <mochel@transmeta.com>
+(and others)
 
 ---------------------------------------------------------------------------
 
@@ -31,10 +32,15 @@ The PCI PM spec defines 4 operating stat
 the higher the number, the longer the latency is for the device to return to 
 an operational state (D0).
 
+There are actually two D3 states.  When someone talks about D3, they usually
+mean D3hot, which corresponds to an ACPI D2 state (power is reduced, the
+device may lose some context).  But they may also mean D3cold, which is an
+ACPI D3 state (power is fully off, all state was discarded); or both.
+
 Bus power management is not covered in this version of this document.
 
-Note that all PCI devices support D0 and D3 by default, regardless of whether or
-not they implement any of the PCI PM spec.
+Note that all PCI devices support D0 and D3cold by default, regardless of
+whether or not they implement any of the PCI PM spec.
 
 The possible state transitions that a device can undergo are:
 
@@ -204,15 +210,16 @@ if (dev->driver && dev->driver->suspend)
 	dev->driver->suspend(dev,state);
 
 A driver uses this function to actually transition the device into a low power
-state. This may include disabling I/O, memory and bus-mastering, as well as
-physically transitioning the device to a lower power state.
+state. This should include disabling I/O, IRQs, and bus-mastering, as well as
+physically transitioning the device to a lower power state; it may also include
+calls to pci_enable_wake().
 
 Bus mastering may be disabled by doing:
 
 pci_disable_device(dev);
 
 For devices that support the PCI PM Spec, this may be used to set the device's
-power state:
+power state to match the suspend() parameter:
 
 pci_set_power_state(dev,state);
 
@@ -223,7 +230,7 @@ The driver should be sure to track the c
 obviate the need for some operations.
 
 The driver should update the current_state field in its pci_dev structure in
-this function.
+this function, except for PM-capable devices when pci_set_power_state is used.
 
 resume
 ------
@@ -237,16 +244,28 @@ The resume callback may be called from a
 transition the device to the D0 state. 
 
 The driver is responsible for reenabling any features of the device that had
-been disabled during previous suspend calls and restoring all state that was
-saved in previous save_state calls.
+been disabled during previous suspend calls, such as IRQs and bus mastering,
+as well as calling pci_restore_state().
+
+If the device is currently in D3, it may need to be reinitialized in resume().
 
-If the device is currently in D3, it must be completely reinitialized, as it
-must be assumed that the device has lost all of its context (even that of its
-PCI config space). For almost all current drivers, this means that the
-initialization code that the driver does at boot must be separated out and
-called again from the resume callback. Note that some values for the device may
-not have to be probed for this time around if they are saved before entering the
-low power state.
+  * Some types of devices, like bus controllers, will preserve context in D3hot
+    (using Vcc power).  Their drivers will often want to avoid re-initializing
+    them after re-entering D0 (perhaps to avoid resetting downstream devices).
+
+  * Other kinds of devices in D3hot will discard device context as part of a
+    soft reset when re-entering the D0 state.
+    
+  * Devices resuming from D3cold always go through a power-on reset.  Some
+    device context can also be preserved using Vaux power.
+
+  * Some systems hide D3cold resume paths from drivers.  For example, on PCs
+    the resume path for suspend-to-disk often runs BIOS powerup code, which
+    will sometimes re-initialize the device.
+
+To handle resets during D3 to D0 transitions, it may be convenient to share
+device initialization code between probe() and resume().  Device parameters
+can also be saved before the driver suspends into D3, avoiding re-probe.
 
 If the device supports the PCI PM Spec, it can use this to physically transition
 the device to D0:
@@ -263,7 +282,7 @@ The driver should take note of the state
 ensure correct (and speedy) operation.
 
 The driver should update the current_state field in its pci_dev structure in
-this function.
+this function, except for PM-capable devices when pci_set_power_state is used.
 
 
 enable_wake
diff -puN drivers/acpi/motherboard.c~bk-pci drivers/acpi/motherboard.c
--- 25/drivers/acpi/motherboard.c~bk-pci	2004-10-06 20:35:45.285939872 -0700
+++ 25-akpm/drivers/acpi/motherboard.c	2004-10-06 20:35:45.839855664 -0700
@@ -170,4 +170,8 @@ static int __init acpi_motherboard_init(
 	return 0;
 }
 
-subsys_initcall(acpi_motherboard_init);
+/**
+ * Reserve motherboard resources after PCI claim BARs,
+ * but before PCI assign resources for uninitialized PCI devices
+ */
+fs_initcall(acpi_motherboard_init);
diff -puN drivers/acpi/processor.c~bk-pci drivers/acpi/processor.c
--- 25/drivers/acpi/processor.c~bk-pci	2004-10-06 20:35:45.287939568 -0700
+++ 25-akpm/drivers/acpi/processor.c	2004-10-06 20:35:45.841855360 -0700
@@ -213,11 +213,13 @@ acpi_processor_errata_piix4 (
 		 * each IDE controller's DMA status to make sure we catch all
 		 * DMA activity.
 		 */
-		dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
 		           PCI_DEVICE_ID_INTEL_82371AB, 
                            PCI_ANY_ID, PCI_ANY_ID, NULL);
-		if (dev)
+		if (dev) {
 			errata.piix4.bmisx = pci_resource_start(dev, 4);
+			pci_dev_put(dev);
+		}
 
 		/* 
 		 * Type-F DMA
@@ -228,7 +230,7 @@ acpi_processor_errata_piix4 (
 		 * disable C3 support if this is enabled, as some legacy 
 		 * devices won't operate well if fast DMA is disabled.
 		 */
-		dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, 
+		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 
 			PCI_DEVICE_ID_INTEL_82371AB_0, 
 			PCI_ANY_ID, PCI_ANY_ID, NULL);
 		if (dev) {
@@ -236,6 +238,7 @@ acpi_processor_errata_piix4 (
 			pci_read_config_byte(dev, 0x77, &value2);
 			if ((value1 & 0x80) || (value2 & 0x80))
 				errata.piix4.fdma = 1;
+			pci_dev_put(dev);
 		}
 
 		break;
@@ -267,10 +270,12 @@ acpi_processor_errata (
 	/*
 	 * PIIX4
 	 */
-	dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, 
+	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL, 
 		PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID, PCI_ANY_ID, NULL);
-	if (dev)
+	if (dev) {
 		result = acpi_processor_errata_piix4(dev);
+		pci_dev_put(dev);
+	}
 
 	return_VALUE(result);
 }
diff -puN drivers/atm/eni.c~bk-pci drivers/atm/eni.c
--- 25/drivers/atm/eni.c~bk-pci	2004-10-06 20:35:45.300937592 -0700
+++ 25-akpm/drivers/atm/eni.c	2004-10-06 20:35:45.843855056 -0700
@@ -2290,9 +2290,7 @@ static int __init eni_init(void)
 		    sizeof(skb->cb),sizeof(struct eni_skb_prv));
 		return -EIO;
 	}
-	if (pci_register_driver(&eni_driver) > 0) return 0;
-	pci_unregister_driver (&eni_driver);
-	return -ENODEV;
+	return pci_register_driver(&eni_driver);
 }
 
 
diff -puN drivers/atm/firestream.c~bk-pci drivers/atm/firestream.c
--- 25/drivers/atm/firestream.c~bk-pci	2004-10-06 20:35:45.302937288 -0700
+++ 25-akpm/drivers/atm/firestream.c	2004-10-06 20:35:45.845854752 -0700
@@ -2045,7 +2045,6 @@ int __init fs_detect(void)
 int __init init_PCI (void)
 { /* Begin init_PCI */
 	
-	int pci_count;
 	printk ("init_PCI\n");
 	/*
 	  memset (&firestream_driver, 0, sizeof (firestream_driver));
@@ -2053,15 +2052,7 @@ int __init init_PCI (void)
 	  firestream_driver.id_table = firestream_pci_tbl;
 	  firestream_driver.probe = fs_register_and_init;
 	*/
-	pci_count = pci_register_driver (&firestream_driver);
-	
-	if (pci_count <= 0) {
-		pci_unregister_driver (&firestream_driver);
-		pci_count = 0;
-	}
-
-	return(pci_count);
-
+	return pci_register_driver(&firestream_driver);
 } /* End init_PCI */
 #endif
 #endif
@@ -2110,3 +2101,4 @@ module_exit(firestream_cleanup_module);
 MODULE_LICENSE("GPL");
 
 
+
diff -puN drivers/atm/idt77252.c~bk-pci drivers/atm/idt77252.c
--- 25/drivers/atm/idt77252.c~bk-pci	2004-10-06 20:35:45.314935464 -0700
+++ 25-akpm/drivers/atm/idt77252.c	2004-10-06 20:35:45.848854296 -0700
@@ -1266,8 +1266,9 @@ idt77252_rx_raw(struct idt77252_dev *car
 	head = IDT77252_PRV_PADDR(queue) + (queue->data - queue->head - 16);
 	tail = readl(SAR_REG_RAWCT);
 
-	pci_dma_sync_single(card->pcidev, IDT77252_PRV_PADDR(queue),
-			    queue->end - queue->head - 16, PCI_DMA_FROMDEVICE);
+	pci_dma_sync_single_for_cpu(card->pcidev, IDT77252_PRV_PADDR(queue),
+				    queue->end - queue->head - 16,
+				    PCI_DMA_FROMDEVICE);
 
 	while (head != tail) {
 		unsigned int vpi, vci, pti;
@@ -1360,10 +1361,10 @@ drop:
 			if (next) {
 				card->raw_cell_head = next;
 				queue = card->raw_cell_head;
-				pci_dma_sync_single(card->pcidev,
-						    IDT77252_PRV_PADDR(queue),
-						    queue->end - queue->data,
-						    PCI_DMA_FROMDEVICE);
+				pci_dma_sync_single_for_cpu(card->pcidev,
+							    IDT77252_PRV_PADDR(queue),
+							    queue->end - queue->data,
+							    PCI_DMA_FROMDEVICE);
 			} else {
 				card->raw_cell_head = NULL;
 				printk("%s: raw cell queue overrun\n",
@@ -3840,11 +3841,7 @@ static int __init idt77252_init(void)
 		return -EIO;
 	}
 
-	if (pci_register_driver(&idt77252_driver) > 0)
-		return 0;
-
-	pci_unregister_driver(&idt77252_driver);
-	return -ENODEV;
+	return pci_register_driver(&idt77252_driver);
 }
 
 static void __exit idt77252_exit(void)
diff -puN drivers/block/cpqarray.c~bk-pci drivers/block/cpqarray.c
--- 25/drivers/block/cpqarray.c~bk-pci	2004-10-06 20:35:45.316935160 -0700
+++ 25-akpm/drivers/block/cpqarray.c	2004-10-06 20:35:45.849854144 -0700
@@ -569,9 +569,9 @@ int __init cpqarray_init_step2(void)
 
 	/* detect controllers */
 	printk(DRIVER_NAME "\n");
-/* TODO: If it's an eisa only system, will rc return negative? */
+
 	rc = pci_register_driver(&cpqarray_pci_driver);
-	if (rc < 0)
+	if (rc)
 		return rc;
 	cpqarray_eisa_detect();
 	
diff -puN drivers/char/agp/intel-agp.c~bk-pci drivers/char/agp/intel-agp.c
--- 25/drivers/char/agp/intel-agp.c~bk-pci	2004-10-06 20:35:45.317935008 -0700
+++ 25-akpm/drivers/char/agp/intel-agp.c	2004-10-06 20:35:45.851853840 -0700
@@ -1723,7 +1723,7 @@ static int agp_intel_resume(struct pci_d
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
-	pci_restore_state(pdev, pdev->saved_config_space);
+	pci_restore_state(pdev);
 
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
diff -puN drivers/char/agp/intel-mch-agp.c~bk-pci drivers/char/agp/intel-mch-agp.c
--- 25/drivers/char/agp/intel-mch-agp.c~bk-pci	2004-10-06 20:35:45.319934704 -0700
+++ 25-akpm/drivers/char/agp/intel-mch-agp.c	2004-10-06 20:35:45.852853688 -0700
@@ -573,7 +573,7 @@ static int agp_intelmch_resume(struct pc
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 	
-	pci_restore_state(pdev, pdev->saved_config_space);
+	pci_restore_state(pdev);
 
 	if (bridge->driver == &intel_845_driver)
 		intel_845_configure();
diff -puN drivers/char/applicom.c~bk-pci drivers/char/applicom.c
--- 25/drivers/char/applicom.c~bk-pci	2004-10-06 20:35:45.320934552 -0700
+++ 25-akpm/drivers/char/applicom.c	2004-10-06 20:35:45.852853688 -0700
@@ -200,7 +200,7 @@ int __init applicom_init(void)
 
 	/* No mem and irq given - check for a PCI card */
 
-	while ( (dev = pci_find_class(PCI_CLASS_OTHERS << 16, dev))) {
+	while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) {
 
 		if (dev->vendor != PCI_VENDOR_ID_APPLICOM)
 			continue;
diff -puN drivers/char/drm/drm_fops.h~bk-pci drivers/char/drm/drm_fops.h
--- 25/drivers/char/drm/drm_fops.h~bk-pci	2004-10-06 20:35:45.321934400 -0700
+++ 25-akpm/drivers/char/drm/drm_fops.h	2004-10-06 20:35:45.853853536 -0700
@@ -99,8 +99,11 @@ int DRM(open_helper)(struct inode *inode
 	 */
 	if (!dev->hose) {
 		struct pci_dev *pci_dev;
-		pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
-		if (pci_dev) dev->hose = pci_dev->sysdata;
+		pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+		if (pci_dev) {
+			dev->hose = pci_dev->sysdata;
+			pci_dev_put(pci_dev);
+		}
 		if (!dev->hose) {
 			struct pci_bus *b = pci_bus_b(pci_root_buses.next);
 			if (b) dev->hose = b->sysdata;
diff -puN drivers/char/epca.c~bk-pci drivers/char/epca.c
--- 25/drivers/char/epca.c~bk-pci	2004-10-06 20:35:45.323934096 -0700
+++ 25-akpm/drivers/char/epca.c	2004-10-06 20:35:45.856853080 -0700
@@ -3933,23 +3933,12 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
 
 int __init init_PCI (void)
 { /* Begin init_PCI */
-	
-	int pci_count;
-	
 	memset (&epca_driver, 0, sizeof (epca_driver));
 	epca_driver.name = "epca";
 	epca_driver.id_table = epca_pci_tbl;
 	epca_driver.probe = epca_init_one;
 
-	pci_count = pci_register_driver (&epca_driver);
-	
-	if (pci_count <= 0) {
-		pci_unregister_driver (&epca_driver);
-		pci_count = 0;
-	}
-
-	return(pci_count);
-
+	return pci_register_driver(&epca_driver);
 } /* End init_PCI */
 
 #endif /* ENABLE_PCI */
diff -puN drivers/char/ipmi/ipmi_si_intf.c~bk-pci drivers/char/ipmi/ipmi_si_intf.c
--- 25/drivers/char/ipmi/ipmi_si_intf.c~bk-pci	2004-10-06 20:35:45.325933792 -0700
+++ 25-akpm/drivers/char/ipmi/ipmi_si_intf.c	2004-10-06 20:35:45.866851560 -0700
@@ -1775,10 +1775,10 @@ static int find_pci_smic(int intf_num, s
 
 	pci_smic_checked = 1;
 
-	if ((pci_dev = pci_find_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
+	if ((pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
 				       NULL)))
 		;
-	else if ((pci_dev = pci_find_class(PCI_ERMC_CLASSCODE, NULL)) &&
+	else if ((pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL)) &&
 		 pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)
 		fe_rmc = 1;
 	else
@@ -1787,6 +1787,7 @@ static int find_pci_smic(int intf_num, s
 	error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr);
 	if (error)
 	{
+		pci_dev_put(pci_dev);
 		printk(KERN_ERR
 		       "ipmi_si: pci_read_config_word() failed (%d).\n",
 		       error);
@@ -1796,6 +1797,7 @@ static int find_pci_smic(int intf_num, s
 	/* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */
 	if (!(base_addr & 0x0001))
 	{
+		pci_dev_put(pci_dev);
 		printk(KERN_ERR
 		       "ipmi_si: memory mapped I/O not supported for PCI"
 		       " smic.\n");
@@ -1807,11 +1809,14 @@ static int find_pci_smic(int intf_num, s
 		/* Data register starts at base address + 1 in eRMC */
 		++base_addr;
 
-	if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr))
-	    return -ENODEV;
+	if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) {
+		pci_dev_put(pci_dev);
+		return -ENODEV;
+	}
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info) {
+		pci_dev_put(pci_dev);
 		printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n");
 		return -ENOMEM;
 	}
@@ -1834,6 +1839,7 @@ static int find_pci_smic(int intf_num, s
 	printk("ipmi_si: Found PCI SMIC at I/O address 0x%lx\n",
 		(long unsigned int) base_addr);
 
+	pci_dev_put(pci_dev);
 	return 0;
 }
 #endif /* CONFIG_PCI */
diff -puN drivers/isdn/hisax/hisax_fcpcipnp.c~bk-pci drivers/isdn/hisax/hisax_fcpcipnp.c
--- 25/drivers/isdn/hisax/hisax_fcpcipnp.c~bk-pci	2004-10-06 20:35:45.331932880 -0700
+++ 25-akpm/drivers/isdn/hisax/hisax_fcpcipnp.c	2004-10-06 20:35:45.867851408 -0700
@@ -1001,23 +1001,13 @@ static int __init hisax_fcpcipnp_init(vo
 	printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");
 
 	retval = pci_register_driver(&fcpci_driver);
-	if (retval < 0)
+	if (retval)
 		goto out;
-	pci_nr_found = retval;
-	retval = 0;
-
 #ifdef __ISAPNP__
 	retval = pnp_register_driver(&fcpnp_driver);
 	if (retval < 0)
 		goto out_unregister_pci;
 #endif
-
-#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
-	if (pci_nr_found + retval == 0) {
-		retval = -ENODEV;
-		goto out_unregister_isapnp;
-	}
-#endif
 	return 0;
 
 #if !defined(CONFIG_HOTPLUG) || defined(MODULE)
diff -puN drivers/media/video/bttv-cards.c~bk-pci drivers/media/video/bttv-cards.c
--- 25/drivers/media/video/bttv-cards.c~bk-pci	2004-10-06 20:35:45.333932576 -0700
+++ 25-akpm/drivers/media/video/bttv-cards.c	2004-10-06 20:35:45.870850952 -0700
@@ -4045,7 +4045,7 @@ void __devinit bttv_check_chipset(void)
 
 #if 0
 	/* print which chipset we have */
-	while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
+	while ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
 		printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
 #endif
 
@@ -4064,8 +4064,8 @@ void __devinit bttv_check_chipset(void)
 	if (UNSET != latency)
 		printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
 
-	while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-				      PCI_DEVICE_ID_INTEL_82441, dev))) {
+	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82441, dev))) {
                 unsigned char b;
 		pci_read_config_byte(dev, 0x53, &b);
 		if (bttv_debug)
diff -puN drivers/media/video/bttv-driver.c~bk-pci drivers/media/video/bttv-driver.c
--- 25/drivers/media/video/bttv-driver.c~bk-pci	2004-10-06 20:35:45.335932272 -0700
+++ 25-akpm/drivers/media/video/bttv-driver.c	2004-10-06 20:35:45.873850496 -0700
@@ -3944,7 +3944,7 @@ static int bttv_suspend(struct pci_dev *
 	btv->state.gpio_data   = gpio_read();
 
 	/* save pci state */
-	pci_save_state(pci_dev, btv->state.pci_cfg);
+	pci_save_state(pci_dev);
 	if (0 != pci_set_power_state(pci_dev, state)) {
 		pci_disable_device(pci_dev);
 		btv->state.disabled = 1;
@@ -3965,7 +3965,7 @@ static int bttv_resume(struct pci_dev *p
 		btv->state.disabled = 0;
 	}
 	pci_set_power_state(pci_dev, 0);
-	pci_restore_state(pci_dev, btv->state.pci_cfg);
+	pci_restore_state(pci_dev);
 
 	/* restore bt878 state */
 	bttv_reinit_bt848(btv);
diff -puN drivers/media/video/bttvp.h~bk-pci drivers/media/video/bttvp.h
--- 25/drivers/media/video/bttvp.h~bk-pci	2004-10-06 20:35:45.336932120 -0700
+++ 25-akpm/drivers/media/video/bttvp.h	2004-10-06 20:35:45.874850344 -0700
@@ -277,7 +277,6 @@ struct bttv_input {
 };
 
 struct bttv_suspend_state {
-	u32  pci_cfg[64 / sizeof(u32)];
 	u32  gpio_enable;
 	u32  gpio_data;
 	int  disabled;
diff -puN drivers/media/video/cx88/cx88.h~bk-pci drivers/media/video/cx88/cx88.h
--- 25/drivers/media/video/cx88/cx88.h~bk-pci	2004-10-06 20:35:45.337931968 -0700
+++ 25-akpm/drivers/media/video/cx88/cx88.h	2004-10-06 20:35:45.876850040 -0700
@@ -216,7 +216,6 @@ struct cx8800_fh {
 };
 
 struct cx8800_suspend_state {
-	u32                        pci_cfg[64 / sizeof(u32)];
 	int                        disabled;
 };
 
diff -puN drivers/media/video/cx88/cx88-video.c~bk-pci drivers/media/video/cx88/cx88-video.c
--- 25/drivers/media/video/cx88/cx88-video.c~bk-pci	2004-10-06 20:35:45.339931664 -0700
+++ 25-akpm/drivers/media/video/cx88/cx88-video.c	2004-10-06 20:35:45.876850040 -0700
@@ -2545,7 +2545,7 @@ static int cx8800_suspend(struct pci_dev
 	cx8800_shutdown(dev);
 	del_timer(&dev->vidq.timeout);
 	
-	pci_save_state(pci_dev, dev->state.pci_cfg);
+	pci_save_state(pci_dev);
 	if (0 != pci_set_power_state(pci_dev, state)) {
 		pci_disable_device(pci_dev);
 		dev->state.disabled = 1;
@@ -2564,7 +2564,7 @@ static int cx8800_resume(struct pci_dev 
 		dev->state.disabled = 0;
 	}
 	pci_set_power_state(pci_dev, 0);
-	pci_restore_state(pci_dev, dev->state.pci_cfg);
+	pci_restore_state(pci_dev);
 
 	/* re-initialize hardware */
 	cx8800_reset(dev);
diff -puN drivers/media/video/meye.c~bk-pci drivers/media/video/meye.c
--- 25/drivers/media/video/meye.c~bk-pci	2004-10-06 20:35:45.340931512 -0700
+++ 25-akpm/drivers/media/video/meye.c	2004-10-06 20:35:45.878849736 -0700
@@ -1236,7 +1236,7 @@ static struct video_device meye_template
 #ifdef CONFIG_PM
 static int meye_suspend(struct pci_dev *pdev, u32 state)
 {
-	pci_save_state(pdev, meye.pm_state);
+	pci_save_state(pdev);
 	meye.pm_mchip_mode = meye.mchip_mode;
 	mchip_hic_stop();
 	mchip_set(MCHIP_MM_INTA, 0x0);
@@ -1245,7 +1245,7 @@ static int meye_suspend(struct pci_dev *
 
 static int meye_resume(struct pci_dev *pdev)
 {
-	pci_restore_state(pdev, meye.pm_state);
+	pci_restore_state(pdev);
 	pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
 
 	mchip_delay(MCHIP_HIC_CMD, 0);
diff -puN drivers/media/video/meye.h~bk-pci drivers/media/video/meye.h
--- 25/drivers/media/video/meye.h~bk-pci	2004-10-06 20:35:45.342931208 -0700
+++ 25-akpm/drivers/media/video/meye.h	2004-10-06 20:35:45.878849736 -0700
@@ -315,7 +315,6 @@ struct meye {
 	struct video_picture picture;	/* video picture parameters */
 	struct meye_params params;	/* additional parameters */
 #ifdef CONFIG_PM
-	u32 pm_state[16];		/* PCI configuration space */
 	u8 pm_mchip_mode;		/* old mchip mode */
 #endif
 };
diff -puN drivers/message/fusion/mptbase.c~bk-pci drivers/message/fusion/mptbase.c
--- 25/drivers/message/fusion/mptbase.c~bk-pci	2004-10-06 20:35:45.344930904 -0700
+++ 25-akpm/drivers/message/fusion/mptbase.c	2004-10-06 20:35:45.882849128 -0700
@@ -1517,7 +1517,7 @@ mptbase_suspend(struct pci_dev *pdev, u3
 		}
 	}
 
-	pci_save_state(pdev, ioc->PciState);
+	pci_save_state(pdev);
 
 	/* put ioc into READY_STATE */
 	if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
@@ -1557,7 +1557,7 @@ mptbase_resume(struct pci_dev *pdev)
 		ioc->name, pdev, pci_name(pdev), device_state);
 
 	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev, ioc->PciState);
+	pci_restore_state(pdev);
 	pci_enable_device(pdev);
 
 	/* enable interrupts */
diff -puN drivers/message/fusion/mptbase.h~bk-pci drivers/message/fusion/mptbase.h
--- 25/drivers/message/fusion/mptbase.h~bk-pci	2004-10-06 20:35:45.345930752 -0700
+++ 25-akpm/drivers/message/fusion/mptbase.h	2004-10-06 20:35:45.884848824 -0700
@@ -663,9 +663,6 @@ typedef struct _MPT_ADAPTER
 	FCPortPage0_t		 fc_port_page0[2];
 	LANPage0_t		 lan_cnfg_page0;
 	LANPage1_t		 lan_cnfg_page1;
-#ifdef CONFIG_PM
-	u32           		 PciState[64];     /* save PCI state to this area */
-#endif
 	u8			 FirstWhoInit;
 	u8			 upload_fw;	/* If set, do a fw upload */
 	u8			 reload_fw;	/* Force a FW Reload on next reset */
diff -puN drivers/misc/ibmasm/ibmasmfs.c~bk-pci drivers/misc/ibmasm/ibmasmfs.c
--- 25/drivers/misc/ibmasm/ibmasmfs.c~bk-pci	2004-10-06 20:35:45.347930448 -0700
+++ 25-akpm/drivers/misc/ibmasm/ibmasmfs.c	2004-10-06 20:35:45.885848672 -0700
@@ -520,7 +520,7 @@ static int remote_settings_file_close(st
 
 static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
-	unsigned long address = (unsigned long)file->private_data;
+	void __iomem *address = (void __iomem *)file->private_data;
 	unsigned char *page;
 	int retval;
 	int len = 0;
@@ -554,7 +554,7 @@ exit:
 
 static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
 {
-	unsigned long address = (unsigned long)file->private_data;
+	void __iomem *address = (void __iomem *)file->private_data;
 	char *buff;
 	unsigned int value;
 
diff -puN drivers/misc/ibmasm/ibmasm.h~bk-pci drivers/misc/ibmasm/ibmasm.h
--- 25/drivers/misc/ibmasm/ibmasm.h~bk-pci	2004-10-06 20:35:45.348930296 -0700
+++ 25-akpm/drivers/misc/ibmasm/ibmasm.h	2004-10-06 20:35:45.884848824 -0700
@@ -158,7 +158,7 @@ struct remote_queue {
 struct service_processor {
 	struct list_head	node;
 	spinlock_t		lock;
-	void 			*base_address;
+	void __iomem		*base_address;
 	unsigned int		irq;
 	struct command		*current_command;
 	struct command		*heartbeat;
diff -puN drivers/misc/ibmasm/lowlevel.c~bk-pci drivers/misc/ibmasm/lowlevel.c
--- 25/drivers/misc/ibmasm/lowlevel.c~bk-pci	2004-10-06 20:35:45.349930144 -0700
+++ 25-akpm/drivers/misc/ibmasm/lowlevel.c	2004-10-06 20:35:45.885848672 -0700
@@ -58,7 +58,7 @@ irqreturn_t ibmasm_interrupt_handler(int
 {
 	u32	mfa;
 	struct service_processor *sp = (struct service_processor *)dev_id;
-	void *base_address = sp->base_address;
+	void __iomem *base_address = sp->base_address;
 
 	if (!sp_interrupt_pending(base_address))
 		return IRQ_NONE;
diff -puN drivers/misc/ibmasm/lowlevel.h~bk-pci drivers/misc/ibmasm/lowlevel.h
--- 25/drivers/misc/ibmasm/lowlevel.h~bk-pci	2004-10-06 20:35:45.350929992 -0700
+++ 25-akpm/drivers/misc/ibmasm/lowlevel.h	2004-10-06 20:35:45.886848520 -0700
@@ -52,51 +52,51 @@
 #define SCOUT_COM_C_BASE         0x0200   
 #define SCOUT_COM_D_BASE         0x0300   
 
-static inline int sp_interrupt_pending(void *base_address)
+static inline int sp_interrupt_pending(void __iomem *base_address)
 {
 	return SP_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
 }
 
-static inline int uart_interrupt_pending(void *base_address)
+static inline int uart_interrupt_pending(void __iomem *base_address)
 {
 	return UART_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
 }
 
-static inline void ibmasm_enable_interrupts(void *base_address, int mask)
+static inline void ibmasm_enable_interrupts(void __iomem *base_address, int mask)
 {
-	void *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
+	void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
 	writel( readl(ctrl_reg) & ~mask, ctrl_reg);
 }
 
-static inline void ibmasm_disable_interrupts(void *base_address, int mask)
+static inline void ibmasm_disable_interrupts(void __iomem *base_address, int mask)
 {
-	void *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
+	void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
 	writel( readl(ctrl_reg) | mask, ctrl_reg);
 }
 
-static inline void enable_sp_interrupts(void *base_address)
+static inline void enable_sp_interrupts(void __iomem *base_address)
 {
 	ibmasm_enable_interrupts(base_address, SP_INTR_MASK);
 }
 
-static inline void disable_sp_interrupts(void *base_address)
+static inline void disable_sp_interrupts(void __iomem *base_address)
 {
 	ibmasm_disable_interrupts(base_address, SP_INTR_MASK);
 }
 
-static inline void enable_uart_interrupts(void *base_address)
+static inline void enable_uart_interrupts(void __iomem *base_address)
 {
 	ibmasm_enable_interrupts(base_address, UART_INTR_MASK); 
 }
 
-static inline void disable_uart_interrupts(void *base_address)
+static inline void disable_uart_interrupts(void __iomem *base_address)
 {
 	ibmasm_disable_interrupts(base_address, UART_INTR_MASK); 
 }
 
 #define valid_mfa(mfa)	( (mfa) != NO_MFAS_AVAILABLE )
 
-static inline u32 get_mfa_outbound(void *base_address)
+static inline u32 get_mfa_outbound(void __iomem *base_address)
 {
 	int retry;
 	u32 mfa;
@@ -109,12 +109,12 @@ static inline u32 get_mfa_outbound(void 
 	return mfa;
 }
 
-static inline void set_mfa_outbound(void *base_address, u32 mfa)
+static inline void set_mfa_outbound(void __iomem *base_address, u32 mfa)
 {
    	writel(mfa, base_address + OUTBOUND_QUEUE_PORT);
 }
 
-static inline u32 get_mfa_inbound(void *base_address)
+static inline u32 get_mfa_inbound(void __iomem *base_address)
 {
 	u32 mfa = readl(base_address + INBOUND_QUEUE_PORT);
 
@@ -124,12 +124,12 @@ static inline u32 get_mfa_inbound(void *
 	return mfa;
 }
 
-static inline void set_mfa_inbound(void *base_address, u32 mfa)
+static inline void set_mfa_inbound(void __iomem *base_address, u32 mfa)
 {
    	writel(mfa, base_address + INBOUND_QUEUE_PORT);
 }
 
-static inline struct i2o_message *get_i2o_message(void *base_address, u32 mfa)
+static inline struct i2o_message *get_i2o_message(void __iomem *base_address, u32 mfa)
 {
 	return (struct i2o_message *)(GET_MFA_ADDR(mfa) + base_address);
 }
diff -puN drivers/misc/ibmasm/module.c~bk-pci drivers/misc/ibmasm/module.c
--- 25/drivers/misc/ibmasm/module.c~bk-pci	2004-10-06 20:35:45.352929688 -0700
+++ 25-akpm/drivers/misc/ibmasm/module.c	2004-10-06 20:35:45.887848368 -0700
@@ -209,10 +209,9 @@ static int __init ibmasm_init(void)
 		return result;
 	}
 	result = pci_register_driver(&ibmasm_driver);
-	if (result <= 0) {
-		pci_unregister_driver(&ibmasm_driver);
+	if (result) {
 		ibmasmfs_unregister();
-		return -ENODEV;
+		return result;
 	}
 	ibmasm_register_panic_notifier();
 	info(DRIVER_DESC " version " DRIVER_VERSION " loaded");
@@ -225,3 +224,4 @@ module_exit(ibmasm_exit);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
+
diff -puN drivers/misc/ibmasm/uart.c~bk-pci drivers/misc/ibmasm/uart.c
--- 25/drivers/misc/ibmasm/uart.c~bk-pci	2004-10-06 20:35:45.353929536 -0700
+++ 25-akpm/drivers/misc/ibmasm/uart.c	2004-10-06 20:35:45.887848368 -0700
@@ -34,7 +34,7 @@
 void ibmasm_register_uart(struct service_processor *sp)
 {
 	struct serial_struct serial;
-	unsigned char *iomem_base;
+	void __iomem *iomem_base;
 
 	iomem_base = sp->base_address + SCOUT_COM_B_BASE;
 
diff -puN drivers/net/3c59x.c~bk-pci drivers/net/3c59x.c
--- 25/drivers/net/3c59x.c~bk-pci	2004-10-06 20:35:45.355929232 -0700
+++ 25-akpm/drivers/net/3c59x.c	2004-10-06 20:35:45.890847912 -0700
@@ -817,7 +817,7 @@ struct vortex_private {
 		partner_flow_ctrl:1,			/* Partner supports flow control */
 		has_nway:1,
 		enable_wol:1,					/* Wake-on-LAN is enabled */
-		pm_state_valid:1,				/* power_state[] has sane contents */
+		pm_state_valid:1,				/* pci_dev->saved_config_space has sane contents */
 		open:1,
 		medialock:1,
 		must_free_region:1,				/* Flag: if zero, Cardbus owns the I/O region */
@@ -834,7 +834,6 @@ struct vortex_private {
 	u16 io_size;						/* Size of PCI region (for release_region) */
 	spinlock_t lock;					/* Serialise access to device & its vortex_private */
 	spinlock_t mdio_lock;				/* Serialise access to mdio hardware */
-	u32 power_state[16];
 };
 
 #ifdef CONFIG_PCI
@@ -1494,7 +1493,7 @@ static int __devinit vortex_probe1(struc
 #endif
 	if (pdev && vp->enable_wol) {
 		vp->pm_state_valid = 1;
- 		pci_save_state(VORTEX_PCI(vp), vp->power_state);
+ 		pci_save_state(VORTEX_PCI(vp));
  		acpi_set_WOL(dev);
 	}
 	retval = register_netdev(dev);
@@ -1551,7 +1550,7 @@ vortex_up(struct net_device *dev)
 
 	if (VORTEX_PCI(vp) && vp->enable_wol) {
 		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
-		pci_restore_state(VORTEX_PCI(vp), vp->power_state);
+		pci_restore_state(VORTEX_PCI(vp));
 	}
 
 	/* Before initializing select the active media port. */
@@ -2708,7 +2707,7 @@ vortex_down(struct net_device *dev, int 
 		outl(0, ioaddr + DownListPtr);
 
 	if (final_down && VORTEX_PCI(vp) && vp->enable_wol) {
-		pci_save_state(VORTEX_PCI(vp), vp->power_state);
+		pci_save_state(VORTEX_PCI(vp));
 		acpi_set_WOL(dev);
 	}
 }
@@ -3166,7 +3165,7 @@ static void __devexit vortex_remove_one 
 	if (VORTEX_PCI(vp) && vp->enable_wol) {
 		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
 		if (vp->pm_state_valid)
-			pci_restore_state(VORTEX_PCI(vp), vp->power_state);
+			pci_restore_state(VORTEX_PCI(vp));
 	}
 	/* Should really use issue_and_wait() here */
 	outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
diff -puN drivers/net/8139cp.c~bk-pci drivers/net/8139cp.c
--- 25/drivers/net/8139cp.c~bk-pci	2004-10-06 20:35:45.356929080 -0700
+++ 25-akpm/drivers/net/8139cp.c	2004-10-06 20:35:45.899846544 -0700
@@ -371,7 +371,6 @@ struct cp_private {
 #endif
 
 	unsigned int		wol_enabled : 1; /* Is Wake-on-LAN enabled? */
-	u32			power_state[16];
 
 	struct mii_if_info	mii_if;
 };
@@ -1883,7 +1882,7 @@ static int cp_suspend (struct pci_dev *p
 	spin_unlock_irqrestore (&cp->lock, flags);
 
 	if (cp->pdev && cp->wol_enabled) {
-		pci_save_state (cp->pdev, cp->power_state);
+		pci_save_state (cp->pdev);
 		cp_set_d3_state (cp);
 	}
 
@@ -1902,7 +1901,7 @@ static int cp_resume (struct pci_dev *pd
 	
 	if (cp->pdev && cp->wol_enabled) {
 		pci_set_power_state (cp->pdev, 0);
-		pci_restore_state (cp->pdev, cp->power_state);
+		pci_restore_state (cp->pdev);
 	}
 	
 	cp_init_hw (cp);
diff -puN drivers/net/8139too.c~bk-pci drivers/net/8139too.c
--- 25/drivers/net/8139too.c~bk-pci	2004-10-06 20:35:45.373926496 -0700
+++ 25-akpm/drivers/net/8139too.c	2004-10-06 20:35:45.904845784 -0700
@@ -573,7 +573,6 @@ struct rtl8139_private {
 	void *mmio_addr;
 	int drv_flags;
 	struct pci_dev *pci_dev;
-	u32 pci_state[16];
 	u32 msg_enable;
 	struct net_device_stats stats;
 	unsigned char *rx_ring;
@@ -2593,7 +2592,7 @@ static int rtl8139_suspend (struct pci_d
 	void *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
-	pci_save_state (pdev, tp->pci_state);
+	pci_save_state (pdev);
 
 	if (!netif_running (dev))
 		return 0;
@@ -2621,9 +2620,8 @@ static int rtl8139_suspend (struct pci_d
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
-	struct rtl8139_private *tp = dev->priv;
 
-	pci_restore_state (pdev, tp->pci_state);
+	pci_restore_state (pdev);
 	if (!netif_running (dev))
 		return 0;
 	pci_set_power_state (pdev, 0);
diff -puN drivers/net/amd8111e.c~bk-pci drivers/net/amd8111e.c
--- 25/drivers/net/amd8111e.c~bk-pci	2004-10-06 20:35:45.374926344 -0700
+++ 25-akpm/drivers/net/amd8111e.c	2004-10-06 20:35:45.911844720 -0700
@@ -1835,7 +1835,7 @@ static int amd8111e_suspend(struct pci_d
 		pci_enable_wake(pci_dev, 4, 0); /* 4 == D3 cold */
 	}
 	
-	pci_save_state(pci_dev, lp->pm_state);
+	pci_save_state(pci_dev);
 	pci_set_power_state(pci_dev, 3);
 
 	return 0;
@@ -1849,7 +1849,7 @@ static int amd8111e_resume(struct pci_de
 		return 0;
 
 	pci_set_power_state(pci_dev, 0);
-	pci_restore_state(pci_dev, lp->pm_state);
+	pci_restore_state(pci_dev);
 
 	pci_enable_wake(pci_dev, 3, 0);
 	pci_enable_wake(pci_dev, 4, 0); /* D3 cold */
diff -puN drivers/net/amd8111e.h~bk-pci drivers/net/amd8111e.h
--- 25/drivers/net/amd8111e.h~bk-pci	2004-10-06 20:35:45.376926040 -0700
+++ 25-akpm/drivers/net/amd8111e.h	2004-10-06 20:35:45.912844568 -0700
@@ -780,7 +780,6 @@ struct amd8111e_priv{
 	
 	struct amd8111e_link_config link_config;
 	int pm_cap;
-	u32 pm_state[12];
 
 	struct net_device *next;
 	int mii;
diff -puN drivers/net/b44.c~bk-pci drivers/net/b44.c
--- 25/drivers/net/b44.c~bk-pci	2004-10-06 20:35:45.377925888 -0700
+++ 25-akpm/drivers/net/b44.c	2004-10-06 20:35:45.913844416 -0700
@@ -1841,7 +1841,7 @@ static int __devinit b44_init_one(struct
 
 	pci_set_drvdata(pdev, dev);
 
-	pci_save_state(bp->pdev, bp->pci_cfg_state);
+	pci_save_state(bp->pdev);
 
 	printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
 	for (i = 0; i < 6; i++)
@@ -1907,7 +1907,7 @@ static int b44_resume(struct pci_dev *pd
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct b44 *bp = dev->priv;
 
-	pci_restore_state(pdev, bp->pci_cfg_state);
+	pci_restore_state(pdev);
 
 	if (!netif_running(dev))
 		return 0;
diff -puN drivers/net/b44.h~bk-pci drivers/net/b44.h
--- 25/drivers/net/b44.h~bk-pci	2004-10-06 20:35:45.379925584 -0700
+++ 25-akpm/drivers/net/b44.h	2004-10-06 20:35:45.915844112 -0700
@@ -433,7 +433,6 @@ struct b44 {
 
 	u32			rx_pending;
 	u32			tx_pending;
-	u32			pci_cfg_state[64 / sizeof(u32)];
 	u8			phy_addr;
 	u8			core_unit;
 
diff -puN drivers/net/dgrs.c~bk-pci drivers/net/dgrs.c
--- 25/drivers/net/dgrs.c~bk-pci	2004-10-06 20:35:45.380925432 -0700
+++ 25-akpm/drivers/net/dgrs.c	2004-10-06 20:35:45.916843960 -0700
@@ -1597,10 +1597,10 @@ static int __init dgrs_init_module (void
 #endif
 #ifdef CONFIG_PCI
 	pcicount = pci_register_driver(&dgrs_pci_driver);
-	if (pcicount < 0)
+	if (pcicount)
 		return pcicount;
 #endif
-	return (eisacount + pcicount) == 0 ? -ENODEV : 0;
+	return 0;
 }
 
 static void __exit dgrs_cleanup_module (void)
diff -puN drivers/net/e1000/e1000.h~bk-pci drivers/net/e1000/e1000.h
--- 25/drivers/net/e1000/e1000.h~bk-pci	2004-10-06 20:35:45.398922696 -0700
+++ 25-akpm/drivers/net/e1000/e1000.h	2004-10-06 20:35:45.921843200 -0700
@@ -252,7 +252,6 @@ struct e1000_adapter {
 	struct e1000_desc_ring test_rx_ring;
 
 
-	uint32_t pci_state[16];
 	int msg_enable;
 };
 #endif /* _E1000_H_ */
diff -puN drivers/net/e1000/e1000_main.c~bk-pci drivers/net/e1000/e1000_main.c
--- 25/drivers/net/e1000/e1000_main.c~bk-pci	2004-10-06 20:35:45.400922392 -0700
+++ 25-akpm/drivers/net/e1000/e1000_main.c	2004-10-06 20:35:45.926842440 -0700
@@ -2856,7 +2856,7 @@ e1000_suspend(struct pci_dev *pdev, uint
 		pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
 	}
 
-	pci_save_state(pdev, adapter->pci_state);
+	pci_save_state(pdev);
 
 	if(adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
@@ -2887,7 +2887,7 @@ e1000_resume(struct pci_dev *pdev)
 
 	ret = pci_enable_device(pdev);
 	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev, adapter->pci_state);
+	pci_restore_state(pdev);
 
 	pci_enable_wake(pdev, 3, 0);
 	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
diff -puN drivers/net/e100.c~bk-pci drivers/net/e100.c
--- 25/drivers/net/e100.c~bk-pci	2004-10-06 20:35:45.402922088 -0700
+++ 25-akpm/drivers/net/e100.c	2004-10-06 20:35:45.920843352 -0700
@@ -563,7 +563,6 @@ struct nic {
 	u16 leds;
 	u16 eeprom_wc;
 	u16 eeprom[256];
-	u32 pm_state[16];
 };
 
 static inline void e100_write_flush(struct nic *nic)
@@ -2326,7 +2325,7 @@ static int e100_suspend(struct pci_dev *
 	e100_hw_reset(nic);
 	netif_device_detach(netdev);
 
-	pci_save_state(pdev, nic->pm_state);
+	pci_save_state(pdev);
 	pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic)));
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, state);
@@ -2340,7 +2339,7 @@ static int e100_resume(struct pci_dev *p
 	struct nic *nic = netdev_priv(netdev);
 
 	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev, nic->pm_state);
+	pci_restore_state(pdev);
 	e100_hw_init(nic);
 
 	netif_device_attach(netdev);
diff -puN drivers/net/eepro100.c~bk-pci drivers/net/eepro100.c
--- 25/drivers/net/eepro100.c~bk-pci	2004-10-06 20:35:45.403921936 -0700
+++ 25-akpm/drivers/net/eepro100.c	2004-10-06 20:35:45.933841376 -0700
@@ -462,9 +462,6 @@ struct speedo_private {
 	unsigned short partner;			/* Link partner caps. */
 	struct mii_if_info mii_if;		/* MII API hooks, info */
 	u32 msg_enable;				/* debug message level */
-#ifdef CONFIG_PM
-	u32 pm_state[16];
-#endif
 };
 
 /* The parameters for a CmdConfigure operation.
@@ -2290,7 +2287,7 @@ static int eepro100_suspend(struct pci_d
 	struct speedo_private *sp = netdev_priv(dev);
 	void __iomem *ioaddr = sp->regs;
 
-	pci_save_state(pdev, sp->pm_state);
+	pci_save_state(pdev);
 
 	if (!netif_running(dev))
 		return 0;
@@ -2310,7 +2307,7 @@ static int eepro100_resume(struct pci_de
 	struct speedo_private *sp = netdev_priv(dev);
 	void __iomem *ioaddr = sp->regs;
 
-	pci_restore_state(pdev, sp->pm_state);
+	pci_restore_state(pdev);
 
 	if (!netif_running(dev))
 		return 0;
diff -puN drivers/net/hamachi.c~bk-pci drivers/net/hamachi.c
--- 25/drivers/net/hamachi.c~bk-pci	2004-10-06 20:35:45.405921632 -0700
+++ 25-akpm/drivers/net/hamachi.c	2004-10-06 20:35:45.937840768 -0700
@@ -2006,10 +2006,7 @@ static int __init hamachi_init (void)
 #ifdef MODULE
 	printk(version);
 #endif
-	if (pci_register_driver(&hamachi_driver) > 0)
-		return 0;
-	pci_unregister_driver(&hamachi_driver);
-	return -ENODEV;
+	return pci_register_driver(&hamachi_driver);
 }
 
 static void __exit hamachi_exit (void)
diff -puN drivers/net/irda/via-ircc.c~bk-pci drivers/net/irda/via-ircc.c
--- 25/drivers/net/irda/via-ircc.c~bk-pci	2004-10-06 20:35:45.416919960 -0700
+++ 25-akpm/drivers/net/irda/via-ircc.c	2004-10-06 20:35:45.939840464 -0700
@@ -157,15 +157,7 @@ static int __init via_ircc_init(void)
 #ifdef	HEADMSG
         DBG(printk(KERN_INFO "via_ircc_init :rc = %d......\n",rc));
 #endif
-	if (rc < 1) {
-#ifdef	HEADMSG
-        DBG(printk(KERN_INFO "via_ircc_init return -ENODEV......\n"));
-#endif
-		if (rc == 0)	pci_unregister_driver (&via_driver);
-		return -ENODEV;
-	}
-	return 0;
-
+	return rc;
 }
 
 static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id)
diff -puN drivers/net/irda/vlsi_ir.c~bk-pci drivers/net/irda/vlsi_ir.c
--- 25/drivers/net/irda/vlsi_ir.c~bk-pci	2004-10-06 20:35:45.419919504 -0700
+++ 25-akpm/drivers/net/irda/vlsi_ir.c	2004-10-06 20:35:45.940840312 -0700
@@ -1768,7 +1768,7 @@ static int vlsi_irda_suspend(struct pci_
 	if (netif_running(ndev)) {
 		netif_device_detach(ndev);
 		vlsi_stop_hw(idev);
-		pci_save_state(pdev, idev->cfg_space);
+		pci_save_state(pdev);
 		if (!idev->new_baud)
 			/* remember speed settings to restore on resume */
 			idev->new_baud = idev->baud;
@@ -1819,7 +1819,7 @@ static int vlsi_irda_resume(struct pci_d
 	}
 
 	if (netif_running(ndev)) {
-		pci_restore_state(pdev, idev->cfg_space);
+		pci_restore_state(pdev);
 		vlsi_start_hw(idev);
 		netif_device_attach(ndev);
 	}
diff -puN drivers/net/irda/vlsi_ir.h~bk-pci drivers/net/irda/vlsi_ir.h
--- 25/drivers/net/irda/vlsi_ir.h~bk-pci	2004-10-06 20:35:45.420919352 -0700
+++ 25-akpm/drivers/net/irda/vlsi_ir.h	2004-10-06 20:35:45.941840160 -0700
@@ -769,7 +769,6 @@ typedef struct vlsi_irda_dev {
 	spinlock_t		lock;
 	struct semaphore	sem;
 
-	u32			cfg_space[64/sizeof(u32)];
 	u8			resume_ok;	
 	struct proc_dir_entry	*proc_entry;
 
diff -puN drivers/net/ixgb/ixgb.h~bk-pci drivers/net/ixgb/ixgb.h
--- 25/drivers/net/ixgb/ixgb.h~bk-pci	2004-10-06 20:35:45.433917376 -0700
+++ 25-akpm/drivers/net/ixgb/ixgb.h	2004-10-06 20:35:45.942840008 -0700
@@ -178,6 +178,5 @@ struct ixgb_adapter {
 	/* structs defined in ixgb_hw.h */
 	struct ixgb_hw hw;
 	struct ixgb_hw_stats stats;
-	uint32_t pci_state[16];
 };
 #endif				/* _IXGB_H_ */
diff -puN drivers/net/ixgb/ixgb_main.c~bk-pci drivers/net/ixgb/ixgb_main.c
--- 25/drivers/net/ixgb/ixgb_main.c~bk-pci	2004-10-06 20:35:45.434917224 -0700
+++ 25-akpm/drivers/net/ixgb/ixgb_main.c	2004-10-06 20:35:45.947839248 -0700
@@ -2101,7 +2101,7 @@ static int ixgb_suspend(struct pci_dev *
 	if (netif_running(netdev))
 		ixgb_down(adapter, TRUE);
 
-	pci_save_state(pdev, adapter->pci_state);
+	pci_save_state(pdev);
 
 	state = (state > 0) ? 3 : 0;
 	pci_set_power_state(pdev, state);
diff -puN drivers/net/pci-skeleton.c~bk-pci drivers/net/pci-skeleton.c
--- 25/drivers/net/pci-skeleton.c~bk-pci	2004-10-06 20:35:45.436916920 -0700
+++ 25-akpm/drivers/net/pci-skeleton.c	2004-10-06 20:35:45.949838944 -0700
@@ -481,7 +481,6 @@ struct netdrv_private {
 	unsigned int mediasense:1;	/* Media sensing in progress. */
 	spinlock_t lock;
 	chip_t chipset;
-	u32 pci_state[16];	/* Data saved during suspend */
 };
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
@@ -1921,7 +1920,7 @@ static int netdrv_suspend (struct pci_de
 
 	spin_unlock_irqrestore (&tp->lock, flags);
 
-	pci_save_state (pdev, tp->pci_state);
+	pci_save_state (pdev);
 	pci_set_power_state (pdev, 3);
 
 	return 0;
@@ -1936,7 +1935,7 @@ static int netdrv_resume (struct pci_dev
 	if (!netif_running(dev))
 		return 0;
 	pci_set_power_state (pdev, 0);
-	pci_restore_state (pdev, tp->pci_state);
+	pci_restore_state (pdev);
 	netif_device_attach (dev);
 	netdrv_hw_start (dev);
 
diff -puN drivers/net/s2io.c~bk-pci drivers/net/s2io.c
--- 25/drivers/net/s2io.c~bk-pci	2004-10-06 20:35:45.438916616 -0700
+++ 25-akpm/drivers/net/s2io.c	2004-10-06 20:35:45.952838488 -0700
@@ -1935,7 +1935,7 @@ void s2io_reset(nic_t * sp)
 	schedule_timeout(HZ / 4);
 
 	/* Restore the PCI state saved during initializarion. */
-	pci_restore_state(sp->pdev, sp->config_space);
+	pci_restore_state(sp->pdev);
 	s2io_init_pci(sp);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
@@ -4238,7 +4238,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		goto register_failed;
 	}
 
-	pci_save_state(sp->pdev, sp->config_space);
+	pci_save_state(sp->pdev);
 
 	/* Setting swapper control on the NIC, for proper reset operation */
 	if (s2io_set_swapper(sp)) {
diff -puN drivers/net/s2io.h~bk-pci drivers/net/s2io.h
--- 25/drivers/net/s2io.h~bk-pci	2004-10-06 20:35:45.439916464 -0700
+++ 25-akpm/drivers/net/s2io.h	2004-10-06 20:35:45.953838336 -0700
@@ -667,7 +667,6 @@ typedef struct s2io_nic {
 	u8 cache_line;
 	u32 rom_expansion;
 	u16 pcix_cmd;
-	u32 config_space[256 / sizeof(u32)];
 	u32 irq;
 	atomic_t rx_bufs_left[MAX_RX_RINGS];
 
diff -puN drivers/net/sis900.c~bk-pci drivers/net/sis900.c
--- 25/drivers/net/sis900.c~bk-pci	2004-10-06 20:35:45.441916160 -0700
+++ 25-akpm/drivers/net/sis900.c	2004-10-06 20:35:45.960837272 -0700
@@ -172,7 +172,6 @@ struct sis900_private {
 
 	unsigned int tx_full; /* The Tx queue is full. */
 	u8 host_bridge_rev;
-	u32 pci_state[16];
 };
 
 MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
@@ -2228,7 +2227,6 @@ static void __devexit sis900_remove(stru
 static int sis900_suspend(struct pci_dev *pci_dev, u32 state)
 {
 	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	struct sis900_private *sis_priv = net_dev->priv;
 	long ioaddr = net_dev->base_addr;
 
 	if(!netif_running(net_dev))
@@ -2241,7 +2239,7 @@ static int sis900_suspend(struct pci_dev
 	outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
 
 	pci_set_power_state(pci_dev, 3);
-	pci_save_state(pci_dev, sis_priv->pci_state);
+	pci_save_state(pci_dev);
 
 	return 0;
 }
@@ -2254,7 +2252,7 @@ static int sis900_resume(struct pci_dev 
 
 	if(!netif_running(net_dev))
 		return 0;
-	pci_restore_state(pci_dev, sis_priv->pci_state);
+	pci_restore_state(pci_dev);
 	pci_set_power_state(pci_dev, 0);
 
 	sis900_init_rxfilter(net_dev);
diff -puN drivers/net/tg3.c~bk-pci drivers/net/tg3.c
--- 25/drivers/net/tg3.c~bk-pci	2004-10-06 20:35:45.443915856 -0700
+++ 25-akpm/drivers/net/tg3.c	2004-10-06 20:35:45.966836360 -0700
@@ -3788,7 +3788,7 @@ static int tg3_chip_reset(struct tg3 *tp
 		val |= PCISTATE_RETRY_SAME_DMA;
 	pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
 
-	pci_restore_state(tp->pdev, tp->pci_cfg_state);
+	pci_restore_state(tp->pdev);
 
 	/* Make sure PCI-X relaxed ordering bit is clear. */
 	pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
@@ -8316,7 +8316,7 @@ static int __devinit tg3_init_one(struct
 	 */
 	if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
 	    (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
-		pci_save_state(tp->pdev, tp->pci_cfg_state);
+		pci_save_state(tp->pdev);
 		tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
 		tg3_halt(tp);
 	}
@@ -8355,7 +8355,7 @@ static int __devinit tg3_init_one(struct
 	 * of the PCI config space.  We need to restore this after
 	 * GRC_MISC_CFG core clock resets and some resume events.
 	 */
-	pci_save_state(tp->pdev, tp->pci_cfg_state);
+	pci_save_state(tp->pdev);
 
 	printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ",
 	       dev->name,
@@ -8474,7 +8474,7 @@ static int tg3_resume(struct pci_dev *pd
 	if (!netif_running(dev))
 		return 0;
 
-	pci_restore_state(tp->pdev, tp->pci_cfg_state);
+	pci_restore_state(tp->pdev);
 
 	err = tg3_set_power_state(tp, 0);
 	if (err)
diff -puN drivers/net/tg3.h~bk-pci drivers/net/tg3.h
--- 25/drivers/net/tg3.h~bk-pci	2004-10-06 20:35:45.445915552 -0700
+++ 25-akpm/drivers/net/tg3.h	2004-10-06 20:35:45.968836056 -0700
@@ -2120,7 +2120,6 @@ struct tg3 {
 	u8				pci_lat_timer;
 	u8				pci_hdr_type;
 	u8				pci_bist;
-	u32				pci_cfg_state[64 / sizeof(u32)];
 
 	int				pm_cap;
 
diff -puN drivers/net/tokenring/abyss.c~bk-pci drivers/net/tokenring/abyss.c
--- 25/drivers/net/tokenring/abyss.c~bk-pci	2004-10-06 20:35:45.461913120 -0700
+++ 25-akpm/drivers/net/tokenring/abyss.c	2004-10-06 20:35:45.969835904 -0700
@@ -457,14 +457,7 @@ static struct pci_driver abyss_driver = 
 
 static int __init abyss_init (void)
 {
-	int rc = pci_register_driver (&abyss_driver);
-	if (rc < 0)
-		return rc;
-	if (rc == 0) {
-		pci_unregister_driver (&abyss_driver);
-		return -ENODEV;
-	}
-	return 0;
+	return pci_register_driver(&abyss_driver);
 }
 
 static void __exit abyss_rmmod (void)
diff -puN drivers/net/tokenring/tmspci.c~bk-pci drivers/net/tokenring/tmspci.c
--- 25/drivers/net/tokenring/tmspci.c~bk-pci	2004-10-06 20:35:45.462912968 -0700
+++ 25-akpm/drivers/net/tokenring/tmspci.c	2004-10-06 20:35:45.970835752 -0700
@@ -243,14 +243,7 @@ static struct pci_driver tms_pci_driver 
 
 static int __init tms_pci_init (void)
 {
-	int rc = pci_register_driver (&tms_pci_driver);
-	if (rc < 0)
-		return rc;
-	if (rc == 0) {
-		pci_unregister_driver (&tms_pci_driver);
-		return -ENODEV;
-	}
-	return 0;
+	return pci_register_driver(&tms_pci_driver);
 }
 
 static void __exit tms_pci_rmmod (void)
diff -puN drivers/net/tulip/xircom_tulip_cb.c~bk-pci drivers/net/tulip/xircom_tulip_cb.c
--- 25/drivers/net/tulip/xircom_tulip_cb.c~bk-pci	2004-10-06 20:35:45.473911296 -0700
+++ 25-akpm/drivers/net/tulip/xircom_tulip_cb.c	2004-10-06 20:35:45.975834992 -0700
@@ -329,9 +329,6 @@ struct xircom_private {
 	int saved_if_port;
 	struct pci_dev *pdev;
 	spinlock_t lock;
-#ifdef CONFIG_PM
-	u32 pci_state[16];
-#endif
 };
 
 static int mdio_read(struct net_device *dev, int phy_id, int location);
@@ -1663,7 +1660,7 @@ static int xircom_suspend(struct pci_dev
 	if (tp->open)
 		xircom_down(dev);
 
-	pci_save_state(pdev, tp->pci_state);
+	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, 3);
 
@@ -1679,7 +1676,7 @@ static int xircom_resume(struct pci_dev 
 
 	pci_set_power_state(pdev,0);
 	pci_enable_device(pdev);
-	pci_restore_state(pdev, tp->pci_state);
+	pci_restore_state(pdev);
 
 	/* Bring the chip out of sleep mode.
 	   Caution: Snooze mode does not work with some boards! */
diff -puN drivers/net/typhoon.c~bk-pci drivers/net/typhoon.c
--- 25/drivers/net/typhoon.c~bk-pci	2004-10-06 20:35:45.475910992 -0700
+++ 25-akpm/drivers/net/typhoon.c	2004-10-06 20:35:45.980834232 -0700
@@ -287,7 +287,6 @@ struct typhoon {
 	u16			xcvr_select;
 	u16			wol_events;
 	u32			offload;
-	u32			pci_state[16];
 
 	/* unused stuff (future use) */
 	int			capabilities;
@@ -1859,7 +1858,7 @@ typhoon_wakeup(struct typhoon *tp, int w
 	void __iomem *ioaddr = tp->ioaddr;
 
 	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev, tp->pci_state);
+	pci_restore_state(pdev);
 
 	/* Post 2.x.x versions of the Sleep Image require a reset before
 	 * we can download the Runtime Image. But let's not make users of
@@ -2339,7 +2338,7 @@ typhoon_init_one(struct pci_dev *pdev, c
 	tp->dev = dev;
 
 	/* need to be able to restore PCI state after a suspend */
-	pci_save_state(pdev, tp->pci_state);
+	pci_save_state(pdev);
 
 	/* Init sequence:
 	 * 1) Reset the adapter to clear any bad juju
@@ -2513,7 +2512,7 @@ typhoon_remove_one(struct pci_dev *pdev)
 
 	unregister_netdev(dev);
 	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev, tp->pci_state);
+	pci_restore_state(pdev);
 	typhoon_reset(tp->ioaddr, NoWait);
 	iounmap(tp->ioaddr);
 	pci_free_consistent(pdev, sizeof(struct typhoon_shared),
diff -puN drivers/net/via-rhine.c~bk-pci drivers/net/via-rhine.c
--- 25/drivers/net/via-rhine.c~bk-pci	2004-10-06 20:35:45.476910840 -0700
+++ 25-akpm/drivers/net/via-rhine.c	2004-10-06 20:35:45.982833928 -0700
@@ -1951,7 +1951,7 @@ static int rhine_suspend(struct pci_dev 
 		return 0;
 
 	netif_device_detach(dev);
-	pci_save_state(pdev, pdev->saved_config_space);
+	pci_save_state(pdev);
 
 	spin_lock_irqsave(&rp->lock, flags);
 	rhine_shutdown(&pdev->dev);
@@ -1975,7 +1975,7 @@ static int rhine_resume(struct pci_dev *
 		printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n",
 			dev->name, ret ? "failed" : "succeeded", ret);
 
-	pci_restore_state(pdev, pdev->saved_config_space);
+	pci_restore_state(pdev);
 
 	spin_lock_irqsave(&rp->lock, flags);
 #ifdef USE_MMIO
diff -puN drivers/net/via-velocity.c~bk-pci drivers/net/via-velocity.c
--- 25/drivers/net/via-velocity.c~bk-pci	2004-10-06 20:35:45.478910536 -0700
+++ 25-akpm/drivers/net/via-velocity.c	2004-10-06 20:35:45.984833624 -0700
@@ -3221,7 +3221,7 @@ static int velocity_suspend(struct pci_d
 	netif_device_detach(vptr->dev);
 
 	spin_lock_irqsave(&vptr->lock, flags);
-	pci_save_state(pdev, vptr->pci_state);
+	pci_save_state(pdev);
 #ifdef ETHTOOL_GWOL
 	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
 		velocity_get_ip(vptr);
@@ -3254,7 +3254,7 @@ static int velocity_resume(struct pci_de
 
 	pci_set_power_state(pdev, 0);
 	pci_enable_wake(pdev, 0, 0);
-	pci_restore_state(pdev, vptr->pci_state);
+	pci_restore_state(pdev);
 
 	mac_wol_reset(vptr->mac_regs);
 
diff -puN drivers/net/via-velocity.h~bk-pci drivers/net/via-velocity.h
--- 25/drivers/net/via-velocity.h~bk-pci	2004-10-06 20:35:45.480910232 -0700
+++ 25-akpm/drivers/net/via-velocity.h	2004-10-06 20:35:45.986833320 -0700
@@ -1739,10 +1739,6 @@ struct velocity_info {
 	struct net_device *dev;
 	struct net_device_stats stats;
 
-#ifdef CONFIG_PM
-	u32 pci_state[16];
-#endif
-
 	dma_addr_t rd_pool_dma;
 	dma_addr_t td_pool_dma[TX_QUEUE_NO];
 
diff -puN drivers/net/wan/sbni.c~bk-pci drivers/net/wan/sbni.c
--- 25/drivers/net/wan/sbni.c~bk-pci	2004-10-06 20:35:45.490908712 -0700
+++ 25-akpm/drivers/net/wan/sbni.c	2004-10-06 20:35:45.987833168 -0700
@@ -294,7 +294,7 @@ sbni_pci_probe( struct net_device  *dev 
 {
 	struct pci_dev  *pdev = NULL;
 
-	while( (pdev = pci_find_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
+	while( (pdev = pci_get_class( PCI_CLASS_NETWORK_OTHER << 8, pdev ))
 	       != NULL ) {
 		int  pci_irq_line;
 		unsigned long  pci_ioaddr;
@@ -331,10 +331,14 @@ sbni_pci_probe( struct net_device  *dev 
 		/* avoiding re-enable dual adapters */
 		if( (pci_ioaddr & 7) == 0  &&  pci_enable_device( pdev ) ) {
 			release_region( pci_ioaddr, SBNI_IO_EXTENT );
+			pci_dev_put( pdev );
 			return  -EIO;
 		}
 		if( sbni_probe1( dev, pci_ioaddr, pci_irq_line ) ) {
 			SET_NETDEV_DEV(dev, &pdev->dev);
+			/* not the best thing to do, but this is all messed up 
+			   for hotplug systems anyway... */
+			pci_dev_put( pdev );
 			return  0;
 		}
 	}
diff -puN drivers/net/wireless/airo.c~bk-pci drivers/net/wireless/airo.c
--- 25/drivers/net/wireless/airo.c~bk-pci	2004-10-06 20:35:45.511905520 -0700
+++ 25-akpm/drivers/net/wireless/airo.c	2004-10-06 20:35:46.000831192 -0700
@@ -1211,7 +1211,6 @@ struct airo_info {
 	SsidRid			*SSID;
 	APListRid		*APList;
 #define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
-	u32			pci_state[16];
 	char			proc_name[IFNAMSIZ];
 };
 
@@ -5496,7 +5495,7 @@ static int airo_pci_suspend(struct pci_d
 	issuecommand(ai, &cmd, &rsp);
 
 	pci_enable_wake(pdev, state, 1);
-	pci_save_state(pdev, ai->pci_state);
+	pci_save_state(pdev);
 	return pci_set_power_state(pdev, state);
 }
 
@@ -5507,7 +5506,7 @@ static int airo_pci_resume(struct pci_de
 	Resp rsp;
 
 	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev, ai->pci_state);
+	pci_restore_state(pdev);
 	pci_enable_wake(pdev, ai->power, 0);
 
 	if (ai->power > 1) {
diff -puN drivers/net/wireless/prism54/islpci_dev.h~bk-pci drivers/net/wireless/prism54/islpci_dev.h
--- 25/drivers/net/wireless/prism54/islpci_dev.h~bk-pci	2004-10-06 20:35:45.513905216 -0700
+++ 25-akpm/drivers/net/wireless/prism54/islpci_dev.h	2004-10-06 20:35:46.001831040 -0700
@@ -110,7 +110,6 @@ typedef struct {
 
 	/* PCI bus allocation & configuration members */
 	struct pci_dev *pdev;	/* PCI structure information */
-	u32 pci_state[16];	/* used for suspend/resume */
 	char firmware[33];
 
 	void __iomem *device_base;	/* ioremapped device base address */
diff -puN drivers/net/wireless/prism54/islpci_hotplug.c~bk-pci drivers/net/wireless/prism54/islpci_hotplug.c
--- 25/drivers/net/wireless/prism54/islpci_hotplug.c~bk-pci	2004-10-06 20:35:45.514905064 -0700
+++ 25-akpm/drivers/net/wireless/prism54/islpci_hotplug.c	2004-10-06 20:35:46.002830888 -0700
@@ -270,7 +270,7 @@ prism54_suspend(struct pci_dev *pdev, u3
 	printk(KERN_NOTICE "%s: got suspend request (state %d)\n",
 	       ndev->name, state);
 
-	pci_save_state(pdev, priv->pci_state);
+	pci_save_state(pdev);
 
 	/* tell the device not to trigger interrupts for now... */
 	isl38xx_disable_interrupts(priv->device_base);
@@ -294,7 +294,7 @@ prism54_resume(struct pci_dev *pdev)
 
 	printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
 
-	pci_restore_state(pdev, priv->pci_state);
+	pci_restore_state(pdev);
 
 	/* alright let's go into the PREBOOT state */
 	islpci_reset(priv, 1);
diff -puN drivers/net/wireless/prism54/islpci_mgt.c~bk-pci drivers/net/wireless/prism54/islpci_mgt.c
--- 25/drivers/net/wireless/prism54/islpci_mgt.c~bk-pci	2004-10-06 20:35:45.515904912 -0700
+++ 25-akpm/drivers/net/wireless/prism54/islpci_mgt.c	2004-10-06 20:35:46.002830888 -0700
@@ -319,8 +319,8 @@ islpci_mgt_receive(struct net_device *nd
 		}
 
 		/* Ensure the results of device DMA are visible to the CPU. */
-		pci_dma_sync_single(priv->pdev, buf->pci_addr,
-				    buf->size, PCI_DMA_FROMDEVICE);
+		pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr,
+					    buf->size, PCI_DMA_FROMDEVICE);
 
 		/* Perform endianess conversion for PIMFOR header in-place. */
 		header = pimfor_decode_header(buf->mem, frag_len);
diff -puN drivers/parport/parport_pc.c~bk-pci drivers/parport/parport_pc.c
--- 25/drivers/parport/parport_pc.c~bk-pci	2004-10-06 20:35:45.527903088 -0700
+++ 25-akpm/drivers/parport/parport_pc.c	2004-10-06 20:35:46.011829520 -0700
@@ -3016,10 +3016,10 @@ static int __init parport_pc_find_ports 
 	count += parport_pc_find_nonpci_ports (autoirq, autodma);
 
 	r = pci_register_driver (&parport_pc_pci_driver);
-	if (r >= 0) {
-		pci_registered_parport = 1;
-		count += r;
-	}
+	if (r)
+		return r;
+	pci_registered_parport = 1;
+	count += 1;
 
 	return count;
 }
diff -puN drivers/pci/hotplug/acpiphp_ibm.c~bk-pci drivers/pci/hotplug/acpiphp_ibm.c
--- 25/drivers/pci/hotplug/acpiphp_ibm.c~bk-pci	2004-10-06 20:35:45.546900200 -0700
+++ 25-akpm/drivers/pci/hotplug/acpiphp_ibm.c	2004-10-06 20:35:46.012829368 -0700
@@ -64,6 +64,8 @@ do {							\
 #define IBM_HARDWARE_ID1 "IBM37D0"
 #define IBM_HARDWARE_ID2 "IBM37D4"
 
+#define hpslot_to_sun(A) (((struct slot *)((A)->private))->acpi_slot->sun)
+
 /* union apci_descriptor - allows access to the
  * various device descriptors that are embedded in the
  * aPCI table
@@ -84,6 +86,7 @@ union apci_descriptor {
 		u8  attn;
 		u8  status[2];
 		u8  sun;
+		u8  res[3];
 	} slot;
 	struct {
 		u8 type;
@@ -128,6 +131,43 @@ static struct acpiphp_attention_info ibm
 	.owner = THIS_MODULE,
 };
 
+/**
+ * ibm_slot_from_id - workaround for bad ibm hardware
+ * @id: the slot number that linux refers to the slot by
+ *
+ * Description: this method returns the aCPI slot descriptor
+ * corresponding to the Linux slot number.  This descriptor
+ * has info about the aPCI slot id and attention status.
+ * This descriptor must be freed using kfree when done.
+ **/
+static union apci_descriptor *ibm_slot_from_id(int id)
+{
+	int ind = 0, size;
+	union apci_descriptor *ret = NULL, *des;
+	char *table;
+
+	size = ibm_get_table_from_acpi(&table);
+	des = (union apci_descriptor *)table;
+	if (memcmp(des->header.sig, "aPCI", 4) != 0)
+		goto ibm_slot_done;
+
+	des = (union apci_descriptor *)&table[ind += des->header.len];
+	while (ind < size && (des->generic.type != 0x82 ||
+			des->slot.slot_num != id)) {
+		des = (union apci_descriptor *)&table[ind += des->generic.len];
+	}
+
+	if (ind < size && des->slot.slot_num == id)
+		ret = des;
+
+ibm_slot_done:
+	if (ret) {
+		ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL);
+		memcpy(ret, des, sizeof(union apci_descriptor));
+	}
+	kfree(table);
+	return ret;
+}
 
 /**
  * ibm_set_attention_status - callback method to set the attention LED
@@ -139,32 +179,34 @@ static struct acpiphp_attention_info ibm
  **/
 static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)
 {
-	int retval = 0;
 	union acpi_object args[2]; 
 	struct acpi_object_list params = { .pointer = args, .count = 2 };
 	acpi_status stat; 
-	unsigned long rc = 0;
-	struct acpiphp_slot *acpi_slot;
+	unsigned long rc;
+	union apci_descriptor *ibm_slot;
 
-	acpi_slot = ((struct slot *)(slot->private))->acpi_slot;
+	ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
 
-	dbg("%s: set slot %d attention status to %d\n", __FUNCTION__,
-			acpi_slot->sun, (status ? 1 : 0));
+	dbg("%s: set slot %d (%d) attention status to %d\n", __FUNCTION__,
+			ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
+			(status ? 1 : 0));
 
 	args[0].type = ACPI_TYPE_INTEGER;
-	args[0].integer.value = acpi_slot->sun;
+	args[0].integer.value = ibm_slot->slot.slot_id;
 	args[1].type = ACPI_TYPE_INTEGER;
 	args[1].integer.value = (status) ? 1 : 0;
 
+	kfree(ibm_slot);
+
 	stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", &params, &rc);
 	if (ACPI_FAILURE(stat)) {
-		retval = -ENODEV;
 		err("APLS evaluation failed:  0x%08x\n", stat);
+		return -ENODEV;
 	} else if (!rc) {
-		retval = -ERANGE;
 		err("APLS method failed:  0x%08lx\n", rc);
+		return -ERANGE;
 	}
-	return retval;
+	return 0;
 }
 
 /**
@@ -181,38 +223,21 @@ static int ibm_set_attention_status(stru
  **/
 static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status)
 {
-	int retval = -EINVAL, ind = 0, size;
-	char *table = NULL;
-	struct acpiphp_slot *acpi_slot;
-	union apci_descriptor *des;
+	union apci_descriptor *ibm_slot;
 
-	acpi_slot = ((struct slot *)(slot->private))->acpi_slot;
+	ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot));
 
-	size = ibm_get_table_from_acpi(&table);
-	if (size <= 0 || !table)
-		goto get_attn_done;
-	// read the header
-	des = (union apci_descriptor *)&table[ind];
-	if (memcmp(des->header.sig, "aPCI", 4) != 0)
-		goto get_attn_done;
-	des = (union apci_descriptor *)&table[ind += des->header.len];
-	while (ind < size && (des->generic.type != 0x82 ||
-			des->slot.slot_id != acpi_slot->sun))
-		des = (union apci_descriptor *)&table[ind += des->generic.len];
-	if (ind < size && des->slot.slot_id == acpi_slot->sun) {
-		retval = 0;
-		if (des->slot.attn & 0xa0 || des->slot.status[1] & 0x08)
-			*status = 1;
-		else
-			*status = 0;
-	}
+	if (ibm_slot->slot.attn & 0xa0 || ibm_slot->slot.status[1] & 0x08)
+		*status = 1;
+	else
+		*status = 0;
 
-	dbg("%s: get slot %d attention status is %d retval=%x\n",
-			__FUNCTION__, acpi_slot->sun, *status, retval);
+	dbg("%s: get slot %d (%d) attention status is %d\n", __FUNCTION__,
+			ibm_slot->slot.slot_num, ibm_slot->slot.slot_id,
+			*status);
 
-get_attn_done:
-	kfree(table);
-	return retval;
+	kfree(ibm_slot);
+	return 0;
 }
 
 /**
diff -puN drivers/pci/hotplug/cpcihp_zt5550.c~bk-pci drivers/pci/hotplug/cpcihp_zt5550.c
--- 25/drivers/pci/hotplug/cpcihp_zt5550.c~bk-pci	2004-10-06 20:35:45.548899896 -0700
+++ 25-akpm/drivers/pci/hotplug/cpcihp_zt5550.c	2004-10-06 20:35:46.013829216 -0700
@@ -69,11 +69,11 @@ static struct pci_bus *bus0;
 static struct pci_dev *hc_dev;
 
 /* Host controller register addresses */
-static void *hc_registers;
-static void *csr_hc_index;
-static void *csr_hc_data;
-static void *csr_int_status;
-static void *csr_int_mask;
+static void __iomem *hc_registers;
+static void __iomem *csr_hc_index;
+static void __iomem *csr_hc_data;
+static void __iomem *csr_int_status;
+static void __iomem *csr_int_mask;
 
 
 static int zt5550_hc_config(struct pci_dev *pdev)
@@ -219,12 +219,13 @@ static int zt5550_hc_init_one (struct pc
 	dbg("registered controller");
 
 	/* Look for first device matching cPCI bus's bridge vendor and device IDs */
-	if(!(bus0_dev = pci_find_device(PCI_VENDOR_ID_DEC,
+	if(!(bus0_dev = pci_get_device(PCI_VENDOR_ID_DEC,
 					 PCI_DEVICE_ID_DEC_21154, NULL))) {
 		status = -ENODEV;
 		goto init_register_error;
 	}
 	bus0 = bus0_dev->subordinate;
+	pci_dev_put(bus0_dev);
 
 	status = cpci_hp_register_bus(bus0, 0x0a, 0x0f);
 	if(status != 0) {
@@ -282,7 +283,7 @@ static int __init zt5550_init(void)
 	if(!r)
 		return -EBUSY;
 
-	return pci_module_init(&zt5550_hc_driver);
+	return pci_register_driver(&zt5550_hc_driver);
 }
 
 static void __exit
diff -puN drivers/pci/hotplug/cpqphp_core.c~bk-pci drivers/pci/hotplug/cpqphp_core.c
--- 25/drivers/pci/hotplug/cpqphp_core.c~bk-pci	2004-10-06 20:35:45.553899136 -0700
+++ 25-akpm/drivers/pci/hotplug/cpqphp_core.c	2004-10-06 20:35:46.016828760 -0700
@@ -55,9 +55,9 @@ struct controller *cpqhp_ctrl_list;	/* =
 struct pci_func *cpqhp_slot_list[256];
 
 /* local variables */
-static void *smbios_table;
-static void *smbios_start;
-static void *cpqhp_rom_start;
+static void __iomem *smbios_table;
+static void __iomem *smbios_start;
+static void __iomem *cpqhp_rom_start;
 static int power_mode;
 static int debug;
 
@@ -123,10 +123,10 @@ static inline int is_slot66mhz(struct sl
  * Returns pointer to the head of the SMBIOS tables (or NULL)
  *
  */
-static void * detect_SMBIOS_pointer(void *begin, void *end)
+static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *end)
 {
-	void *fp;
-	void *endp;
+	void __iomem *fp;
+	void __iomem *endp;
 	u8 temp1, temp2, temp3, temp4;
 	int status = 0;
 
@@ -232,13 +232,14 @@ static int pci_print_IRQ_route (void)
  *
  * returns a pointer to an SMBIOS structure or NULL if none found
  */
-static void *get_subsequent_smbios_entry(void *smbios_start,
-			void *smbios_table, void *curr)
+static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start,
+						void __iomem *smbios_table,
+						void __iomem *curr)
 {
 	u8 bail = 0;
 	u8 previous_byte = 1;
-	void *p_temp;
-	void *p_max;
+	void __iomem *p_temp;
+	void __iomem *p_max;
 
 	if (!smbios_table || !curr)
 		return(NULL);
@@ -282,8 +283,10 @@ static void *get_subsequent_smbios_entry
  *
  * returns a pointer to an SMBIOS structure or %NULL if none found
  */
-static void *get_SMBIOS_entry(void *smbios_start, void *smbios_table, u8 type,
-			void * previous)
+static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start,
+					void __iomem *smbios_table,
+					u8 type,
+					void __iomem *previous)
 {
 	if (!smbios_table)
 		return NULL;
@@ -319,8 +322,9 @@ static void release_slot(struct hotplug_
 	kfree(slot);
 }
 
-static int ctrl_slot_setup(struct controller * ctrl, void *smbios_start,
-			void *smbios_table)
+static int ctrl_slot_setup(struct controller *ctrl,
+			void __iomem *smbios_start,
+			void __iomem *smbios_table)
 {
 	struct slot *new_slot;
 	u8 number_of_slots;
@@ -328,7 +332,7 @@ static int ctrl_slot_setup(struct contro
 	u8 slot_number;
 	u8 ctrl_slot;
 	u32 tempdword;
-	void *slot_entry= NULL;
+	void __iomem *slot_entry= NULL;
 	int result = -ENOMEM;
 
 	dbg("%s\n", __FUNCTION__);
@@ -1483,8 +1487,8 @@ static int __init cpqhpc_init(void)
 	cpqhp_debug = debug;
 
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
-	result = pci_module_init(&cpqhpc_driver);
-	dbg("pci_module_init = %d\n", result);
+	result = pci_register_driver(&cpqhpc_driver);
+	dbg("pci_register_driver = %d\n", result);
 	return result;
 }
 
diff -puN drivers/pci/hotplug/cpqphp_ctrl.c~bk-pci drivers/pci/hotplug/cpqphp_ctrl.c
--- 25/drivers/pci/hotplug/cpqphp_ctrl.c~bk-pci	2004-10-06 20:35:45.555898832 -0700
+++ 25-akpm/drivers/pci/hotplug/cpqphp_ctrl.c	2004-10-06 20:35:46.018828456 -0700
@@ -69,10 +69,8 @@ static void long_delay(int delay)
 	init_waitqueue_head(&delay_wait);
 
 	add_wait_queue(&delay_wait, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(delay);
+	msleep_interruptible(jiffies_to_msecs(delay));
 	remove_wait_queue(&delay_wait, &wait);
-	set_current_state(TASK_RUNNING);
 	
 	up(&delay_sem);
 }
diff -puN drivers/pci/hotplug/cpqphp.h~bk-pci drivers/pci/hotplug/cpqphp.h
--- 25/drivers/pci/hotplug/cpqphp.h~bk-pci	2004-10-06 20:35:45.556898680 -0700
+++ 25-akpm/drivers/pci/hotplug/cpqphp.h	2004-10-06 20:35:46.014829064 -0700
@@ -268,7 +268,7 @@ struct slot {
 	struct timer_list task_event;
 	u8 hp_slot;
 	struct controller *ctrl;
-	void *p_sm_slot;
+	void __iomem *p_sm_slot;
 	struct hotplug_slot *hotplug_slot;
 };
 
@@ -287,7 +287,7 @@ struct controller {
 	struct controller *next;
 	u32 ctrl_int_comp;
 	struct semaphore crit_sect;	/* critical section semaphore */
-	void *hpc_reg;			/* cookie for our pci controller location */
+	void __iomem *hpc_reg;		/* cookie for our pci controller location */
 	struct pci_resource *mem_head;
 	struct pci_resource *p_mem_head;
 	struct pci_resource *io_head;
@@ -405,7 +405,7 @@ extern void cpqhp_create_ctrl_files		(st
 /* controller functions */
 extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
 extern irqreturn_t cpqhp_ctrl_intr		(int IRQ, void *data, struct pt_regs *regs);
-extern int	cpqhp_find_available_resources	(struct controller *ctrl, void *rom_start);
+extern int	cpqhp_find_available_resources	(struct controller *ctrl, void __iomem *rom_start);
 extern int	cpqhp_event_start_thread	(void);
 extern void	cpqhp_event_stop_thread		(void);
 extern struct pci_func *cpqhp_slot_create	(unsigned char busnumber);
@@ -707,9 +707,8 @@ static inline int wait_for_ctrl_irq(stru
 
 	dbg("%s - start\n", __FUNCTION__);
 	add_wait_queue(&ctrl->queue, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
 	/* Sleep for up to 1 second to wait for the LED to change. */
-	schedule_timeout(1*HZ);
+	msleep_interruptible(1000);
 	remove_wait_queue(&ctrl->queue, &wait);
 	if (signal_pending(current))
 		retval =  -EINTR;
diff -puN drivers/pci/hotplug/cpqphp_nvram.h~bk-pci drivers/pci/hotplug/cpqphp_nvram.h
--- 25/drivers/pci/hotplug/cpqphp_nvram.h~bk-pci	2004-10-06 20:35:45.558898376 -0700
+++ 25-akpm/drivers/pci/hotplug/cpqphp_nvram.h	2004-10-06 20:35:46.018828456 -0700
@@ -30,26 +30,26 @@
 
 #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM
 
-static inline void compaq_nvram_init (void *rom_start)
+static inline void compaq_nvram_init (void __iomem *rom_start)
 {
 	return;
 }
 
-static inline int compaq_nvram_load (void *rom_start, struct controller *ctrl)
+static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
 {
 	return 0;
 }
 
-static inline int compaq_nvram_store (void *rom_start)
+static inline int compaq_nvram_store (void __iomem *rom_start)
 {
 	return 0;
 }
 
 #else
 
-extern void compaq_nvram_init	(void *rom_start);
-extern int compaq_nvram_load	(void *rom_start, struct controller *ctrl);
-extern int compaq_nvram_store	(void *rom_start);
+extern void compaq_nvram_init	(void __iomem *rom_start);
+extern int compaq_nvram_load	(void __iomem *rom_start, struct controller *ctrl);
+extern int compaq_nvram_store	(void __iomem *rom_start);
 
 #endif
 
diff -puN drivers/pci/hotplug/cpqphp_pci.c~bk-pci drivers/pci/hotplug/cpqphp_pci.c
--- 25/drivers/pci/hotplug/cpqphp_pci.c~bk-pci	2004-10-06 20:35:45.559898224 -0700
+++ 25-akpm/drivers/pci/hotplug/cpqphp_pci.c	2004-10-06 20:35:46.020828152 -0700
@@ -51,10 +51,10 @@ static u16 unused_IRQ;
  * find the Hot Plug Resource Table in the specified region of memory.
  *
  */
-static void *detect_HRT_floating_pointer(void *begin, void *end)
+static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iomem *end)
 {
-	void *fp;
-	void *endp;
+	void __iomem *fp;
+	void __iomem *endp;
 	u8 temp1, temp2, temp3, temp4;
 	int status = 0;
 
@@ -1162,12 +1162,13 @@ int cpqhp_valid_replace(struct controlle
  *
  * returns 0 if success
  */  
-int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
+int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start)
 {
 	u8 temp;
 	u8 populated_slot;
 	u8 bridged_slot;
-	void *one_slot;
+	void __iomem *one_slot;
+	void __iomem *rom_resource_table;
 	struct pci_func *func = NULL;
 	int i = 10, index;
 	u32 temp_dword, rc;
@@ -1175,7 +1176,6 @@ int cpqhp_find_available_resources (stru
 	struct pci_resource *p_mem_node;
 	struct pci_resource *io_node;
 	struct pci_resource *bus_node;
-	void *rom_resource_table;
 
 	rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff);
 	dbg("rom_resource_table = %p\n", rom_resource_table);
diff -puN drivers/pci/hotplug/ibmphp_core.c~bk-pci drivers/pci/hotplug/ibmphp_core.c
--- 25/drivers/pci/hotplug/ibmphp_core.c~bk-pci	2004-10-06 20:35:45.561897920 -0700
+++ 25-akpm/drivers/pci/hotplug/ibmphp_core.c	2004-10-06 20:35:46.021828000 -0700
@@ -886,7 +886,7 @@ static int set_bus (struct slot * slot_c
 				break;
 			case BUS_SPEED_133:
 				/* This is to take care of the bug in CIOBX chip */
-				while ((dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS,
+				while ((dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
 							      0x0101, dev)) != NULL)
 					ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
 				cmd = HPC_BUS_133PCIXMODE;
diff -puN drivers/pci/hotplug/ibmphp_ebda.c~bk-pci drivers/pci/hotplug/ibmphp_ebda.c
--- 25/drivers/pci/hotplug/ibmphp_ebda.c~bk-pci	2004-10-06 20:35:45.562897768 -0700
+++ 25-akpm/drivers/pci/hotplug/ibmphp_ebda.c	2004-10-06 20:35:46.022827848 -0700
@@ -63,7 +63,7 @@ static LIST_HEAD (rio_vg_head);
 static LIST_HEAD (rio_lo_head);
 static LIST_HEAD (opt_vg_head);
 static LIST_HEAD (opt_lo_head);
-static void *io_mem;
+static void __iomem *io_mem;
 
 /* Local functions */
 static int ebda_rsrc_controller (void);
@@ -1246,7 +1246,7 @@ int ibmphp_register_pci (void)
 	list_for_each (tmp, &ebda_hpc_head) {
 		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
 		if (ctrl->ctlr_type == 1) {
-			rc = pci_module_init (&ibmphp_driver);
+			rc = pci_register_driver(&ibmphp_driver);
 			break;
 		}
 	}
diff -puN drivers/pci/hotplug/ibmphp_hpc.c~bk-pci drivers/pci/hotplug/ibmphp_hpc.c
--- 25/drivers/pci/hotplug/ibmphp_hpc.c~bk-pci	2004-10-06 20:35:45.564897464 -0700
+++ 25-akpm/drivers/pci/hotplug/ibmphp_hpc.c	2004-10-06 20:35:46.024827544 -0700
@@ -108,8 +108,8 @@ static struct semaphore sem_exit;	// mak
 //----------------------------------------------------------------------------
 // local function prototypes
 //----------------------------------------------------------------------------
-static u8 i2c_ctrl_read (struct controller *, void *, u8);
-static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
+static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8);
+static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8);
 static u8 hpc_writecmdtoindex (u8, u8);
 static u8 hpc_readcmdtoindex (u8, u8);
 static void get_hpc_access (void);
@@ -118,7 +118,7 @@ static void poll_hpc (void);
 static int process_changeinstatus (struct slot *, struct slot *);
 static int process_changeinlatch (u8, u8, struct controller *);
 static int hpc_poll_thread (void *);
-static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *);
+static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *);
 //----------------------------------------------------------------------------
 
 
@@ -147,11 +147,11 @@ void __init ibmphp_hpc_initvars (void)
 * Action:  read from HPC over I2C
 *
 *---------------------------------------------------------------------*/
-static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
+static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
 {
 	u8 status;
 	int i;
-	void *wpg_addr;		// base addr + offset
+	void __iomem *wpg_addr;	// base addr + offset
 	unsigned long wpg_data;	// data to/from WPG LOHI format
 	unsigned long ultemp;
 	unsigned long data;	// actual data HILO format
@@ -255,10 +255,10 @@ static u8 i2c_ctrl_read (struct controll
 *
 * Return   0 or error codes
 *---------------------------------------------------------------------*/
-static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
+static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
 {
 	u8 rc;
-	void *wpg_addr;		// base addr + offset
+	void __iomem *wpg_addr;	// base addr + offset
 	unsigned long wpg_data;	// data to/from WPG LOHI format 
 	unsigned long ultemp;
 	unsigned long data;	// actual data HILO format
@@ -399,7 +399,7 @@ static u8 pci_ctrl_write (struct control
 	return rc;
 }
 
-static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
+static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
 {
 	u8 rc;
 	switch (ctlr->ctlr_type) {
@@ -419,7 +419,7 @@ static u8 ctrl_read (struct controller *
 	return rc;
 }
 
-static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
+static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
 {
 	u8 rc = 0;
 	switch (ctlr->ctlr_type) {
@@ -536,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8
 *---------------------------------------------------------------------*/
 int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
 {
-	void *wpg_bbar = NULL;
+	void __iomem *wpg_bbar = NULL;
 	struct controller *ctlr_ptr;
 	struct list_head *pslotlist;
 	u8 index, status;
@@ -660,7 +660,7 @@ int ibmphp_hpc_readslot (struct slot * p
 	
 	// remove physical to logical address mapping
 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		iounmap (wpg_bbar);	
+		iounmap (wpg_bbar);
 	
 	free_hpc_access ();
 
@@ -675,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * p
 *---------------------------------------------------------------------*/
 int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
 {
-	void *wpg_bbar = NULL;
+	void __iomem *wpg_bbar = NULL;
 	struct controller *ctlr_ptr;
 	u8 index, status;
 	int busindex;
@@ -764,7 +764,7 @@ int ibmphp_hpc_writeslot (struct slot * 
 
 	// remove physical to logical address mapping
 	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
-		iounmap (wpg_bbar);	
+		iounmap (wpg_bbar);
 	free_hpc_access ();
 
 	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
@@ -1130,7 +1130,7 @@ void __exit ibmphp_hpc_stop_poll_thread 
 * Return   0, HPC_ERROR
 * Value:
 *---------------------------------------------------------------------*/
-static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar,
+static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
 				    u8 * pstatus)
 {
 	int rc = 0;
diff -puN drivers/pci/hotplug/pciehp_core.c~bk-pci drivers/pci/hotplug/pciehp_core.c
--- 25/drivers/pci/hotplug/pciehp_core.c~bk-pci	2004-10-06 20:35:45.565897312 -0700
+++ 25-akpm/drivers/pci/hotplug/pciehp_core.c	2004-10-06 20:35:46.025827392 -0700
@@ -602,8 +602,8 @@ static int __init pcied_init(void)
 
 	retval = pciehprm_init(PCI);
 	if (!retval) {
-		retval = pci_module_init(&pcie_driver);
-		dbg("pci_module_init = %d\n", retval);
+		retval = pci_register_driver(&pcie_driver);
+		dbg("pci_register_driver = %d\n", retval);
 		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
 	}
 
diff -puN drivers/pci/hotplug/pciehp.h~bk-pci drivers/pci/hotplug/pciehp.h
--- 25/drivers/pci/hotplug/pciehp.h~bk-pci	2004-10-06 20:35:45.567897008 -0700
+++ 25-akpm/drivers/pci/hotplug/pciehp.h	2004-10-06 20:35:46.025827392 -0700
@@ -31,6 +31,7 @@
 
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 #include <asm/semaphore.h>
 #include <asm/io.h>		
 #include "pci_hotplug.h"
@@ -261,14 +262,12 @@ static inline int wait_for_ctrl_irq(stru
 
 	dbg("%s : start\n", __FUNCTION__);
 	add_wait_queue(&ctrl->queue, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	if (!pciehp_poll_mode) {
+	if (!pciehp_poll_mode)
 		/* Sleep for up to 1 second */
-		schedule_timeout(1*HZ);
-	} else
-		schedule_timeout(2.5*HZ);
+		msleep_interruptible(1000);
+	else
+		msleep_interruptible(2500);
 	
-	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ctrl->queue, &wait);
 	if (signal_pending(current))
 		retval =  -EINTR;
diff -puN drivers/pci/hotplug/rpadlpar_core.c~bk-pci drivers/pci/hotplug/rpadlpar_core.c
--- 25/drivers/pci/hotplug/rpadlpar_core.c~bk-pci	2004-10-06 20:35:45.568896856 -0700
+++ 25-akpm/drivers/pci/hotplug/rpadlpar_core.c	2004-10-06 20:35:46.027827088 -0700
@@ -25,6 +25,10 @@
 
 static DECLARE_MUTEX(rpadlpar_sem);
 
+#define NODE_TYPE_VIO  1
+#define NODE_TYPE_SLOT 2
+#define NODE_TYPE_PHB  3
+
 static struct device_node *find_php_slot_vio_node(char *drc_name)
 {
 	struct device_node *child;
@@ -44,21 +48,50 @@ static struct device_node *find_php_slot
 	return NULL;
 }
 
-static struct device_node *find_php_slot_pci_node(char *drc_name)
+/* Find dlpar-capable pci node that contains the specified name and type */
+static struct device_node *find_php_slot_pci_node(char *drc_name,
+						  char *drc_type)
 {
 	struct device_node *np = NULL;
 	char *name;
+	char *type;
+	int rc;
 
-	while ((np = of_find_node_by_type(np, "pci")))
-		if (is_hotplug_capable(np)) {
-			name = rpaphp_get_drc_name(np);
-			if (name && (!strcmp(drc_name, name)))
+	while ((np = of_find_node_by_type(np, "pci"))) {
+		rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL);
+		if (rc == 0)
+			if (!strcmp(drc_name, name) && !strcmp(drc_type, type))
 				break;
-		}
+	}
 
 	return np;
 }
 
+static struct device_node *find_newly_added_node(char *drc_name, int *node_type)
+{
+	struct device_node *dn;
+
+	dn = find_php_slot_pci_node(drc_name, "SLOT");
+	if (dn) {
+		*node_type = NODE_TYPE_SLOT;
+		return dn;
+	}
+
+	dn = find_php_slot_pci_node(drc_name, "PHB");
+	if (dn) {
+		*node_type = NODE_TYPE_PHB;
+		return dn;
+	}
+
+	dn = find_php_slot_vio_node(drc_name);
+	if (dn) {
+		*node_type = NODE_TYPE_VIO;
+		return dn;
+	}
+
+	return NULL;
+}
+
 static struct slot *find_slot(char *drc_name)
 {
 	struct list_head *tmp, *n;
@@ -125,12 +158,8 @@ static int pci_add_secondary_bus(struct 
 
 	dn->bussubno = child->number;
 
-	/* ioremap() for child bus */
-	if (remap_bus_range(child)) {
-		printk(KERN_ERR "%s: could not ioremap() child bus\n",
-			__FUNCTION__);
-		return 1;
-	}
+	/* ioremap() for child bus, which may or may not succeed */
+	remap_bus_range(child);
 
 	return 0;
 }
@@ -205,6 +234,71 @@ static inline int dlpar_add_pci_slot(cha
 	return 0;
 }
 
+static int dlpar_remove_root_bus(struct pci_controller *phb)
+{
+	struct pci_bus *phb_bus;
+	int rc;
+
+	phb_bus = phb->bus;
+	if (!(list_empty(&phb_bus->children) &&
+	      list_empty(&phb_bus->devices))) {
+		return -EBUSY;
+	}
+
+	rc = pcibios_remove_root_bus(phb);
+	if (rc)
+		return -EIO;
+
+	device_unregister(phb_bus->bridge);
+	pci_remove_bus(phb_bus);
+
+	return 0;
+}
+
+static int dlpar_remove_phb(struct slot *slot)
+{
+	struct pci_controller *phb;
+	struct device_node *dn;
+	int rc = 0;
+
+	dn = slot->dn;
+	if (!dn) {
+		printk(KERN_ERR "%s: unexpected NULL slot device node\n",
+				__FUNCTION__);
+		return -EIO;
+	}
+
+	phb = dn->phb;
+	if (!phb) {
+		printk(KERN_ERR "%s: unexpected NULL phb pointer\n",
+				__FUNCTION__);
+		return -EIO;
+	}
+
+	if (rpaphp_remove_slot(slot)) {
+		printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
+			__FUNCTION__, slot->location);
+		return -EIO;
+	}
+
+	rc = dlpar_remove_root_bus(phb);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+static int dlpar_add_phb(struct device_node *dn)
+{
+	struct pci_controller *phb;
+
+	phb = init_phb_dynamic(dn);
+	if (!phb)
+		return 1;
+
+	return 0;
+}
+
 /**
  * dlpar_add_slot - DLPAR add an I/O Slot
  * @drc_name: drc-name of newly added slot
@@ -220,7 +314,8 @@ static inline int dlpar_add_pci_slot(cha
  */
 int dlpar_add_slot(char *drc_name)
 {
-	struct device_node *dn;
+	struct device_node *dn = NULL;
+	int node_type;
 	int rc = 0;
 
 	if (down_interruptible(&rpadlpar_sem))
@@ -232,18 +327,27 @@ int dlpar_add_slot(char *drc_name)
 		goto exit;
 	}
 
-	dn = find_php_slot_vio_node(drc_name);
+	dn = find_newly_added_node(drc_name, &node_type);
 	if (!dn) {
-		dn = find_php_slot_pci_node(drc_name);
-		if (dn)
+		rc = -ENODEV;
+		goto exit;
+	}
+
+	switch (node_type) {
+		case NODE_TYPE_VIO:
+			/* Just add hotplug slot */
+			break;
+		case NODE_TYPE_SLOT:
 			rc = dlpar_add_pci_slot(drc_name, dn);
-		else {
-			rc = -ENODEV;
-			goto exit;
-		}
+			break;
+		case NODE_TYPE_PHB:
+			rc = dlpar_add_phb(dn);
+			break;
+		default:
+			printk("%s: unexpected node type\n", __FUNCTION__);
+			return -EIO;
 	}
 
-	/* Add hotplug slot for new VIOA or PCI */
 	if (!rc && rpaphp_add_slot(dn)) {
 		printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
 			__FUNCTION__, drc_name);
@@ -337,7 +441,8 @@ int dlpar_remove_slot(char *drc_name)
 		return -ERESTARTSYS;
 
 	if (!find_php_slot_vio_node(drc_name) &&
-	    !find_php_slot_pci_node(drc_name)) {
+	    !find_php_slot_pci_node(drc_name, "SLOT") &&
+	    !find_php_slot_pci_node(drc_name, "PHB")) {
 		rc = -ENODEV;
 		goto exit;
 	}
@@ -348,17 +453,18 @@ int dlpar_remove_slot(char *drc_name)
 		goto exit;
 	}
 	
-	switch (slot->dev_type) {
-		case PCI_DEV:
-			rc = dlpar_remove_pci_slot(slot, drc_name);
-			break;
-
-		case VIO_DEV:
-			rc = dlpar_remove_vio_slot(slot, drc_name);
-			break;
+	if (slot->type == PHB) {
+		rc = dlpar_remove_phb(slot);
+	} else {
+		switch (slot->dev_type) {
+			case PCI_DEV:
+				rc = dlpar_remove_pci_slot(slot, drc_name);
+				break;
 
-		default:
-			rc = -EIO;
+			case VIO_DEV:
+				rc = dlpar_remove_vio_slot(slot, drc_name);
+				break;
+		}
 	}
 exit:
 	up(&rpadlpar_sem);
diff -puN drivers/pci/hotplug/rpaphp_core.c~bk-pci drivers/pci/hotplug/rpaphp_core.c
--- 25/drivers/pci/hotplug/rpaphp_core.c~bk-pci	2004-10-06 20:35:45.569896704 -0700
+++ 25-akpm/drivers/pci/hotplug/rpaphp_core.c	2004-10-06 20:35:46.029826784 -0700
@@ -63,7 +63,6 @@ static int get_power_status(struct hotpl
 static int get_attention_status(struct hotplug_slot *slot, u8 * value);
 static int get_adapter_status(struct hotplug_slot *slot, u8 * value);
 static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value);
-static int rpaphp_disable_slot(struct pci_dev *dev);
 
 struct hotplug_slot_ops rpaphp_hotplug_slot_ops = {
 	.owner = THIS_MODULE,
@@ -212,32 +211,91 @@ int rpaphp_remove_slot(struct slot *slot
 	return deregister_slot(slot);
 }
 
-static int get_dn_properties(struct device_node *dn, int **indexes, int **names, 
-	int **types, int **power_domains)
+static int get_children_props(struct device_node *dn, int **drc_indexes,
+		int **drc_names, int **drc_types, int **drc_power_domains)
 {
-	*indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL);
+	int *indexes, *names;
+	int *types, *domains;
 
-	/* &names[1] contains NULL terminated slot names */
-	*names = (int *) get_property(dn, "ibm,drc-names", NULL);
+	indexes = (int *) get_property(dn, "ibm,drc-indexes", NULL);
+	names = (int *) get_property(dn, "ibm,drc-names", NULL);
+	types = (int *) get_property(dn, "ibm,drc-types", NULL);
+	domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL);
+
+	if (!indexes || !names || !types || !domains) {
+		/* Slot does not have dynamically-removable children */
+		return 1;
+	}
+	if (drc_indexes)
+		*drc_indexes = indexes;
+	if (drc_names)
+		/* &drc_names[1] contains NULL terminated slot names */
+		*drc_names = names;
+	if (drc_types)
+		/* &drc_types[1] contains NULL terminated slot types */
+		*drc_types = types;
+	if (drc_power_domains)
+		*drc_power_domains = domains;
 
-	/* &types[1] contains NULL terminated slot types */
-	*types = (int *) get_property(dn, "ibm,drc-types", NULL);
-
-	/* power_domains[1...n] are the slot power domains */
-	*power_domains = (int *) get_property(dn, "ibm,drc-power-domains", NULL);
-	
-	if (*indexes && *names && *types && *power_domains) 
-		return (1);
-	
-	return (0);
+	return 0;
+}
+
+/* To get the DRC props describing the current node, first obtain it's
+ * my-drc-index property.  Next obtain the DRC list from it's parent.  Use
+ * the my-drc-index for correlation, and obtain the requested properties.
+ */
+int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
+		char **drc_name, char **drc_type, int *drc_power_domain)
+{
+	int *indexes, *names;
+	int *types, *domains;
+	unsigned int *my_index;
+	char *name_tmp, *type_tmp;
+	int i, rc;
+
+	my_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
+	if (!my_index) {
+		/* Node isn't DLPAR/hotplug capable */
+		return 1;
+	}
+
+	rc = get_children_props(dn->parent, &indexes, &names, &types, &domains);
+	if (rc) {
+		return 1;
+	}
+
+	name_tmp = (char *) &names[1];
+	type_tmp = (char *) &types[1];
+
+	/* Iterate through parent properties, looking for my-drc-index */
+	for (i = 0; i < indexes[0]; i++) {
+		if ((unsigned int) indexes[i + 1] == *my_index) {
+			if (drc_name)
+                		*drc_name = name_tmp;
+			if (drc_type)
+				*drc_type = type_tmp;
+			if (drc_index)
+				*drc_index = *my_index;
+			if (drc_power_domain)
+				*drc_power_domain = domains[i+1];
+			return 0;
+		}
+		name_tmp += (strlen(name_tmp) + 1);
+		type_tmp += (strlen(type_tmp) + 1);
+	}
+
+	return 1;
 }
 
 static int is_php_dn(struct device_node *dn, int **indexes, int **names, int **types,
 	  int **power_domains)
 {
+	int rc;
+
 	if (!is_hotplug_capable(dn))
 		return (0);
-	if (!get_dn_properties(dn, indexes, names, types, power_domains))
+	rc = get_children_props(dn, indexes, names, types, power_domains);
+	if (rc)
 		return (0);
 	return (1);
 }
@@ -245,8 +303,7 @@ static int is_php_dn(struct device_node 
 static int is_dr_dn(struct device_node *dn, int **indexes, int **names, int **types,
 	  int **power_domains, int **my_drc_index)
 {
-	if (!is_hotplug_capable(dn))
-		return (0);
+	int rc;
 
 	*my_drc_index = (int *) get_property(dn, "ibm,my-drc-index", NULL);
 	if(!*my_drc_index) 		
@@ -255,7 +312,9 @@ static int is_dr_dn(struct device_node *
 	if (!dn->parent)
 		return (0);
 
-	return get_dn_properties(dn->parent, indexes, names, types, power_domains);
+	rc = get_children_props(dn->parent, indexes, names, types,
+				power_domains);
+	return (rc == 0);
 }
 
 static inline int is_vdevice_root(struct device_node *dn)
@@ -263,34 +322,10 @@ static inline int is_vdevice_root(struct
 	return !strcmp(dn->name, "vdevice");
 }
 
-char *rpaphp_get_drc_name(struct device_node *dn)
+int is_dlpar_type(const char *type_str)
 {
-	char *name, *ptr = NULL;
-	int *drc_names, *drc_indexes, i;
-	struct device_node *parent = dn->parent;	
-	u32 *my_drc_index;
-
-	if (!parent)
-		return NULL;
-
-	my_drc_index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
-	if (!my_drc_index)
-		return NULL;	
-
-	drc_names = (int *) get_property(parent, "ibm,drc-names", NULL);
-	drc_indexes = (int *) get_property(parent, "ibm,drc-indexes", NULL);
-	if (!drc_names || !drc_indexes)
-		return NULL;
-
-	name = (char *) &drc_names[1];
-	for (i = 0; i < drc_indexes[0]; i++, name += (strlen(name) + 1)) {
-		if (drc_indexes[i + 1] == *my_drc_index) {
-			ptr = (char *) name;
-			break;
-		}
-	}
-
-	return ptr;
+	/* Only register DLPAR-capable nodes of drc-type PHB or SLOT */
+	return (!strcmp(type_str, "PHB") || !strcmp(type_str, "SLOT"));
 }
 
 /****************************************************************
@@ -329,15 +364,18 @@ int rpaphp_add_slot(struct device_node *
 		for (i = 0; i < indexes[0]; i++,
 	     		name += (strlen(name) + 1), type += (strlen(type) + 1)) {
 
-			if ( slot_type == HOTPLUG || 
-				(slot_type == EMBEDDED && indexes[i + 1] == my_drc_index[0])) {
-				
+			if (slot_type == HOTPLUG ||
+			    (slot_type == EMBEDDED &&
+			     indexes[i + 1] == my_drc_index[0] &&
+			     is_dlpar_type(type))) {
 				if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name,
 					       power_domains[i + 1]))) {
 					retval = -ENOMEM;
 					goto exit;
 				}
-				if (slot_type == EMBEDDED)
+				if (!strcmp(type, "PHB"))
+					slot->type = PHB;
+				else if (slot_type == EMBEDDED)
 					slot->type = EMBEDDED;
 				else
 					slot->type = simple_strtoul(type, NULL, 10);
@@ -442,11 +480,6 @@ exit:
 	return retval;
 }
 
-static int rpaphp_disable_slot(struct pci_dev *dev)
-{
-	return disable_slot(rpaphp_find_hotplug_slot(dev));
-}
-
 static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
 	int retval = -EINVAL;
@@ -483,4 +516,4 @@ module_exit(rpaphp_exit);
 EXPORT_SYMBOL_GPL(rpaphp_add_slot);
 EXPORT_SYMBOL_GPL(rpaphp_remove_slot);
 EXPORT_SYMBOL_GPL(rpaphp_slot_head);
-EXPORT_SYMBOL_GPL(rpaphp_get_drc_name);
+EXPORT_SYMBOL_GPL(rpaphp_get_drc_props);
diff -puN drivers/pci/hotplug/rpaphp.h~bk-pci drivers/pci/hotplug/rpaphp.h
--- 25/drivers/pci/hotplug/rpaphp.h~bk-pci	2004-10-06 20:35:45.571896400 -0700
+++ 25-akpm/drivers/pci/hotplug/rpaphp.h	2004-10-06 20:35:46.027827088 -0700
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include "pci_hotplug.h"
 
+#define	PHB     2
 #define	HOTPLUG	1
 #define	EMBEDDED 0
 
@@ -129,7 +130,8 @@ extern struct hotplug_slot *rpaphp_find_
 /* rpaphp_core.c */
 extern int rpaphp_add_slot(struct device_node *dn);
 extern int rpaphp_remove_slot(struct slot *slot);
-extern char *rpaphp_get_drc_name(struct device_node *dn);
+extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
+		char **drc_name, char **drc_type, int *drc_power_domain);
 
 /* rpaphp_vio.c */
 extern int rpaphp_get_vio_adapter_status(struct slot *slot, int is_init, u8 * value);
diff -puN drivers/pci/hotplug/rpaphp_pci.c~bk-pci drivers/pci/hotplug/rpaphp_pci.c
--- 25/drivers/pci/hotplug/rpaphp_pci.c~bk-pci	2004-10-06 20:35:45.572896248 -0700
+++ 25-akpm/drivers/pci/hotplug/rpaphp_pci.c	2004-10-06 20:35:46.030826632 -0700
@@ -117,33 +117,40 @@ static int rpaphp_get_sensor_state(struc
 int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value)
 {
 	int state, rc;
-	*value = NOT_VALID;
+ 	struct device_node *child_dn;
+ 	struct pci_dev *child_dev;
 
+	*value = NOT_VALID;
 	rc = rpaphp_get_sensor_state(slot, &state);
 	if (rc)
 		goto exit;
-	if (state == PRESENT) {
+
+ 	if ((state == EMPTY) || (slot->type == PHB)) {
+ 		dbg("slot is empty\n");
+ 		*value = EMPTY;
+ 	}
+ 	else if (state == PRESENT) {
 		if (!is_init)
 			/* at run-time slot->state can be changed by */
 			/* config/unconfig adapter */
 			*value = slot->state;
 		else {
-			if (!slot->dn->child)
+ 			child_dn = slot->dn->child;
+ 			if (child_dn)
+ 				child_dev = rpaphp_find_pci_dev(child_dn);
+
+ 			if (child_dev)
+ 				*value = CONFIGURED;
+ 			else if (!child_dn)
 				dbg("%s: %s is not valid OFDT node\n",
 				    __FUNCTION__, slot->dn->full_name);
-			else if (rpaphp_find_pci_dev(slot->dn->child))
-				*value = CONFIGURED;
 			else {
 				err("%s: can't find pdev of adapter in slot[%s]\n", 
 					__FUNCTION__, slot->dn->full_name);
 				*value = NOT_CONFIGURED;
 			}
 		}
-	} else if (state == EMPTY) {
-		dbg("slot is empty\n");
-		*value = state;
 	}
-
 exit:
 	return rc;
 }
@@ -408,15 +415,52 @@ static int setup_pci_hotplug_slot_info(s
 	return 0;
 }
 
+static int set_phb_slot_name(struct slot *slot)
+{
+	struct device_node *dn;
+	struct pci_controller *phb;
+	struct pci_bus *bus;
+
+	dn = slot->dn;
+	if (!dn) {
+		return 1;
+	}
+	phb = dn->phb;
+	if (!phb) {
+		return 1;
+	}
+	bus = phb->bus;
+	if (!bus) {
+		return 1;
+	}
+
+	sprintf(slot->name, "%04x:%02x:%02x.%x", pci_domain_nr(bus),
+			bus->number, 0, 0);
+	return 0;
+}
+
 static int setup_pci_slot(struct slot *slot)
 {
-	slot->bridge = rpaphp_find_bridge_pdev(slot);
-	if (!slot->bridge) {	/* slot being added doesn't have pci_dev yet */
-		err("%s: no pci_dev for bridge dn %s\n", __FUNCTION__, slot->name);
-		goto exit_rc;
+	int rc;
+
+	if (slot->type == PHB) {
+		rc = set_phb_slot_name(slot);
+		if (rc) {
+			err("%s: failed to set phb slot name\n", __FUNCTION__);
+			goto exit_rc;
+		}
+	} else {
+		slot->bridge = rpaphp_find_bridge_pdev(slot);
+		if (!slot->bridge) {
+			/* slot being added doesn't have pci_dev yet */
+			err("%s: no pci_dev for bridge dn %s\n",
+					__FUNCTION__, slot->name);
+			goto exit_rc;
+		}
+		dbg("%s set slot->name to %s\n",  __FUNCTION__,
+				pci_name(slot->bridge));
+		strcpy(slot->name, pci_name(slot->bridge));
 	}
-	dbg("%s set slot->name to %s\n",  __FUNCTION__, pci_name(slot->bridge));
-	strcpy(slot->name, pci_name(slot->bridge));
 
 	/* find slot's pci_dev if it's not empty */
 	if (slot->hotplug_slot->info->adapter_status == EMPTY) {
@@ -470,10 +514,10 @@ int register_pci_slot(struct slot *slot)
 	int rc = 1;
 
 	slot->dev_type = PCI_DEV;
-	if (slot->type == EMBEDDED)
-		slot->removable = EMBEDDED;
+	if ((slot->type == EMBEDDED) || (slot->type == PHB))
+		slot->removable = 0;
 	else
-		slot->removable = HOTPLUG;
+		slot->removable = 1;
 	INIT_LIST_HEAD(&slot->dev.pci_funcs);
 	if (setup_pci_hotplug_slot_info(slot))
 		goto exit_rc;
diff -puN drivers/pci/hotplug/rpaphp_slot.c~bk-pci drivers/pci/hotplug/rpaphp_slot.c
--- 25/drivers/pci/hotplug/rpaphp_slot.c~bk-pci	2004-10-06 20:35:45.573896096 -0700
+++ 25-akpm/drivers/pci/hotplug/rpaphp_slot.c	2004-10-06 20:35:46.030826632 -0700
@@ -246,12 +246,7 @@ int rpaphp_get_power_status(struct slot 
 {
 	int rc = 0, level;
 	
-	if (slot->type == EMBEDDED) {
-		dbg("%s set to POWER_ON for EMBEDDED slot %s\n",
-			__FUNCTION__, slot->location);
-		*value = POWER_ON;
-	}
-	else {
+	if (slot->type == HOTPLUG) {
 		rc = rtas_get_power_level(slot->power_domain, &level);
 		if (!rc) {
 			dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n",
@@ -260,6 +255,10 @@ int rpaphp_get_power_status(struct slot 
 		} else
 			err("failed to get power-level for slot(%s), rc=0x%x\n",
 				slot->location, rc);
+	} else {
+		dbg("%s report POWER_ON for EMBEDDED or PHB slot %s\n",
+			__FUNCTION__, slot->location);
+		*value = (u8) POWER_ON;
 	}
 
 	return rc;
diff -puN drivers/pci/hotplug/rpaphp_vio.c~bk-pci drivers/pci/hotplug/rpaphp_vio.c
--- 25/drivers/pci/hotplug/rpaphp_vio.c~bk-pci	2004-10-06 20:35:45.575895792 -0700
+++ 25-akpm/drivers/pci/hotplug/rpaphp_vio.c	2004-10-06 20:35:46.031826480 -0700
@@ -74,8 +74,8 @@ int register_vio_slot(struct device_node
 	int rc = 1;
 	struct slot *slot = NULL;
 	
-	name = rpaphp_get_drc_name(dn);
-	if (!name)
+	rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL);
+	if (rc)
 		goto exit_rc;
 	index = (u32 *) get_property(dn, "ibm,my-drc-index", NULL);
 	if (!index)
diff -puN drivers/pci/hotplug/shpchp_core.c~bk-pci drivers/pci/hotplug/shpchp_core.c
--- 25/drivers/pci/hotplug/shpchp_core.c~bk-pci	2004-10-06 20:35:45.576895640 -0700
+++ 25-akpm/drivers/pci/hotplug/shpchp_core.c	2004-10-06 20:35:46.032826328 -0700
@@ -599,8 +599,8 @@ static int __init shpcd_init(void)
 
 	retval = shpchprm_init(PCI);
 	if (!retval) {
-		retval = pci_module_init(&shpc_driver);
-		dbg("%s: pci_module_init = %d\n", __FUNCTION__, retval);
+		retval = pci_register_driver(&shpc_driver);
+		dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
 		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
 	}
 
diff -puN drivers/pci/hotplug/shpchp_ctrl.c~bk-pci drivers/pci/hotplug/shpchp_ctrl.c
--- 25/drivers/pci/hotplug/shpchp_ctrl.c~bk-pci	2004-10-06 20:35:45.578895336 -0700
+++ 25-akpm/drivers/pci/hotplug/shpchp_ctrl.c	2004-10-06 20:35:46.037825568 -0700
@@ -1050,7 +1050,64 @@ static int is_bridge(struct pci_func * f
 /* The following routines constitute the bulk of the 
    hotplug controller logic
  */
+static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
+{ 
+	u32 rc = 0;
 
+	dbg("%s: change to speed %d\n", __FUNCTION__, speed);
+	down(&ctrl->crit_sect);
+	if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
+		err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
+		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",
+			  __FUNCTION__);
+		err("%s: Error code (%d)\n", __FUNCTION__, rc);
+		up(&ctrl->crit_sect);
+		return WRONG_BUS_FREQUENCY;
+	}
+	up(&ctrl->crit_sect);
+	return rc;
+}
+
+static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag, 
+enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
+{ 
+	u32 rc = 0;
+	
+	if (flag != 0) { /* Other slots on the same bus are occupied */
+		if ( asp < bsp ) {
+			err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp);
+			return WRONG_BUS_FREQUENCY;
+		}
+	} else {
+		/* Other slots on the same bus are empty */
+		if (msp == bsp) {
+		/* if adapter_speed >= bus_speed, do nothing */
+			if (asp < bsp) {
+				/* 
+				* Try to lower bus speed to accommodate the adapter if other slots 
+				* on the same controller are empty
+				*/
+				if ((rc = change_bus_speed(ctrl, pslot, asp)))
+					return rc;
+			} 
+		} else {
+			if (asp < msp) {
+				if ((rc = change_bus_speed(ctrl, pslot, asp)))
+					return rc;
+			} else {
+				if ((rc = change_bus_speed(ctrl, pslot, msp)))
+					return rc;
+			}
+		}
+	}
+	return rc;
+}
 
 /**
  * board_added - Called after a board has been added to the system.
@@ -1061,14 +1118,13 @@ static int is_bridge(struct pci_func * f
  */
 static u32 board_added(struct pci_func * func, struct controller * ctrl)
 {
-	u8 hp_slot, slot;
+	u8 hp_slot;
 	u8 slots_not_empty = 0;
 	int index;
 	u32 temp_register = 0xFFFFFFFF;
 	u32 retval, rc = 0;
 	struct pci_func *new_func = NULL;
-	struct pci_func *t_func = NULL;
-	struct slot *p_slot, *pslot;
+	struct slot *p_slot;
 	struct resource_lists res_lists;
 	enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
 	u8 pi, mode;
@@ -1132,258 +1188,72 @@ static u32 board_added(struct pci_func *
 	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
 
-	rc  = p_slot->hpc_ops->get_prog_int(p_slot, &pi);
-	if (rc) {
+	if ((rc  = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) {
 		err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__);
 		pi = 1;
 	}
+
+	/* Check if there are other slots or devices on the same bus */
+	if (!list_empty(&ctrl->pci_dev->subordinate->devices))
+		slots_not_empty = 1;
+
+	dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__, 
+		slots_not_empty, pi);
+	dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n", 
+		adapter_speed, bus_speed, max_bus_speed);
+
 	if (pi == 2) {
-		for ( slot = 0; slot < ctrl->num_slots; slot++) {
-			if (slot != hp_slot) {
-				pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset);
-				t_func = shpchp_slot_find(pslot->bus, pslot->device, 0);
-				slots_not_empty |= t_func->is_a_board;
-			}
+		dbg("%s: In PI = %d\n", __FUNCTION__, pi);
+		if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) {
+			err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__);
+			mode = 0;
 		}
 
 		switch (adapter_speed) {
-		case PCI_SPEED_133MHz_PCIX_533:	
+		case PCI_SPEED_133MHz_PCIX_533:
 		case PCI_SPEED_133MHz_PCIX_266:
-			if ((( bus_speed < 0xa ) || (bus_speed < 0xd)) && (max_bus_speed > bus_speed) &&
-				((max_bus_speed <= 0xa) || (max_bus_speed <= 0xd)) && (!slots_not_empty)) {
-			
-				/* Wait for exclusive access to hardware */
-				down(&ctrl->crit_sect);
-
-				rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-				if (rc) {
-					err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				
-				/* Wait for the command to complete */
-				wait_for_ctrl_irq (ctrl);
-		
-				rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-				if (rc) {
-					err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-					err("%s: Error code (%d)\n", __FUNCTION__, rc);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Done with exclusive hardware access */
-				up(&ctrl->crit_sect);
-			}
-			break;
+			if ((bus_speed != adapter_speed) &&
+			   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+				return rc;
+			break;	
 		case PCI_SPEED_133MHz_PCIX_ECC:
 		case PCI_SPEED_133MHz_PCIX:
-
-			rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode);
-
-			if (rc) {
-				err("%s: PI is 1 \n", __FUNCTION__);
-				return WRONG_BUS_FREQUENCY;
-			}
-
 			if (mode) { /* Bus - Mode 1 ECC */
-
-				if (bus_speed > 0x7)  {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x7) && (max_bus_speed <= 0x7) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x7) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			} else {
-				if (bus_speed > 0x4) {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x4) && (max_bus_speed <= 0x4) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x4) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			}
 			break;
 		case PCI_SPEED_66MHz_PCIX_ECC:
 		case PCI_SPEED_66MHz_PCIX:
-
-			rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode);
-
-			if (rc) {
-				err("%s: PI is 1 \n", __FUNCTION__);
-				return WRONG_BUS_FREQUENCY;
-			}
-
 			if (mode) { /* Bus - Mode 1 ECC */
-
-				if (bus_speed > 0x5)  {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x5) && (max_bus_speed <= 0x5) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x5) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			} else {
-				if (bus_speed > 0x2) {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-
-				if ((bus_speed < 0x2) && (max_bus_speed <= 0x2) &&
-					(bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						/* Done with exclusive hardware access */
-						up(&ctrl->crit_sect);				
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-				}
+				if ((bus_speed != 0x2) &&
+				   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+					return rc;
 			}
 			break;
 		case PCI_SPEED_66MHz:
-			if (bus_speed > 0x1) {
-				err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-				return WRONG_BUS_FREQUENCY;
-			}
-			if (bus_speed == 0x1)
-				;
-			if ((bus_speed == 0x0) && ( max_bus_speed == 0x1))  {
-				/* Wait for exclusive access to hardware */
-				down(&ctrl->crit_sect);
-
-				rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-				if (rc) {
-					err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				
-				/* Wait for the command to complete */
-				wait_for_ctrl_irq (ctrl);
-		
-				rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-				if (rc) {
-					err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-							  __FUNCTION__);
-					err("%s: Error code (%d)\n", __FUNCTION__, rc);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);				
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Done with exclusive hardware access */
-				up(&ctrl->crit_sect);
-			}
+			if ((bus_speed != 0x1) &&
+			   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed)))) 
+				return rc;
 			break;	
 		case PCI_SPEED_33MHz:
 			if (bus_speed > 0x0) {
-				err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-				return WRONG_BUS_FREQUENCY;
+				if (slots_not_empty == 0) {
+					if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed)))
+						return rc;
+				} else {
+					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
+					return WRONG_BUS_FREQUENCY;
+				}
 			}
 			break;
 		default:
@@ -1391,133 +1261,34 @@ static u32 board_added(struct pci_func *
 			return WRONG_BUS_FREQUENCY;
 		}
 	} else {
-		/* if adpater_speed == bus_speed, nothing to do here */
-		if (adapter_speed != bus_speed) {
-			for ( slot = 0; slot < ctrl->num_slots; slot++) {
-				if (slot != hp_slot) {
-					pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset);
-					t_func = shpchp_slot_find(pslot->bus, pslot->device, 0);
-					slots_not_empty |= t_func->is_a_board;
-				}
-			}
-
-			if (slots_not_empty != 0) { /* Other slots on the same bus are occupied */
-				if ( adapter_speed < bus_speed ) {
-					err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Do nothing if adapter_speed >= bus_speed */
-			}
-		}
-			
-		if ((adapter_speed != bus_speed) && (slots_not_empty == 0))  {
-			/* Other slots on the same bus are empty */
-			
-			rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed);
-			if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) {
-				err("%s: Can't get max bus operation speed\n", __FUNCTION__);
-				max_bus_speed = bus_speed;
-			}
-
-			if (max_bus_speed == bus_speed) {
-				/* if adapter_speed >= bus_speed, do nothing */
-				if (adapter_speed < bus_speed) {
-				/* 
-				 * Try to lower bus speed to accommodate the adapter if other slots 
-				 * on the same controller are empty
-				 */
-					
-					/* Wait for exclusive access to hardware */
-					down(&ctrl->crit_sect);
-
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed);
-					if (rc) {
-						err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-						up(&ctrl->crit_sect);
-						return WRONG_BUS_FREQUENCY;
-					}
-				
-					/* Wait for the command to complete */
-					wait_for_ctrl_irq (ctrl);
-		
-					rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-					if (rc) {
-						err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
-								  __FUNCTION__);
-						err("%s: Error code (%d)\n", __FUNCTION__, rc);
-						up(&ctrl->crit_sect);
-						return WRONG_BUS_FREQUENCY;
-					}
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-
-				} 
-			} else {
-				/* Wait for exclusive access to hardware */
-				down(&ctrl->crit_sect);
-
-				/* max_bus_speed != bus_speed. Note: max_bus_speed should be > than bus_speed */
-				if (adapter_speed < max_bus_speed) 
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed);
-				else  
-					rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-				
-				if (rc) {
-					err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-					return WRONG_BUS_FREQUENCY;
-				}
-				
-				/* Wait for the command to complete */
-				wait_for_ctrl_irq (ctrl);
-		
-				rc = p_slot->hpc_ops->check_cmd_status(ctrl);
-				if (rc) {
-					err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", 
-						__FUNCTION__);
-					err("%s: Error code (%d)\n", __FUNCTION__, rc);
-					/* Done with exclusive hardware access */
-					up(&ctrl->crit_sect);
-					return WRONG_BUS_FREQUENCY;
-				}
-				/* Done with exclusive hardware access */
-				up(&ctrl->crit_sect);
-
-			}
-		}
+		/* If adpater_speed == bus_speed, nothing to do here */
+		dbg("%s: In PI = %d\n", __FUNCTION__, pi);
+		if ((adapter_speed != bus_speed) &&
+		   ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+				return rc;
 	}
 
-	/* Wait for exclusive access to hardware */
 	down(&ctrl->crit_sect);
-
 	/* turn on board, blink green LED, turn off Amber LED */
-	rc = p_slot->hpc_ops->slot_enable(p_slot);
-	
-	if (rc) {
+	if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
 		err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
-		/* Done with exclusive hardware access */
 		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) {
+	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
 		err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
-		/* Done with exclusive hardware access */
 		up(&ctrl->crit_sect);
 		return rc;  
 	}
 
-	/* Done with exclusive hardware access */
 	up(&ctrl->crit_sect);
 
 	/* Wait for ~1 second */
 	dbg("%s: before long_delay\n", __FUNCTION__);
 	wait_for_ctrl_irq (ctrl);
-	dbg("%s: afterlong_delay\n", __FUNCTION__);
+	dbg("%s: after long_delay\n", __FUNCTION__);
 
 	dbg("%s: func status = %x\n", __FUNCTION__, func->status);
 	/* Check for a power fault */
diff -puN drivers/pci/hotplug/shpchp.h~bk-pci drivers/pci/hotplug/shpchp.h
--- 25/drivers/pci/hotplug/shpchp.h~bk-pci	2004-10-06 20:35:45.586894120 -0700
+++ 25-akpm/drivers/pci/hotplug/shpchp.h	2004-10-06 20:35:46.032826328 -0700
@@ -31,6 +31,7 @@
 
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 #include <asm/semaphore.h>
 #include <asm/io.h>		
 #include "pci_hotplug.h"
@@ -311,7 +312,7 @@ struct php_ctlr_state_s {
 	php_intr_callback_t presence_change_callback;
 	php_intr_callback_t power_fault_callback;
 	void *callback_instance_id;
-	void *creg;				/* Ptr to controller register space */
+	void __iomem *creg;			/* Ptr to controller register space */
 };
 /* Inline functions */
 
@@ -381,16 +382,14 @@ static inline int wait_for_ctrl_irq (str
 	dbg("%s : start\n",__FUNCTION__);
 
 	add_wait_queue(&ctrl->queue, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
 
 	if (!shpchp_poll_mode) {
 		/* Sleep for up to 1 second */
-		schedule_timeout(1*HZ);
+		msleep_interruptible(1000);
 	} else {
 		/* Sleep for up to 2 seconds */
-		schedule_timeout(2*HZ);
+		msleep_interruptible(2000);
 	}
-	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ctrl->queue, &wait);
 	if (signal_pending(current))
 		retval =  -EINTR;
diff -puN drivers/pci/hotplug/shpchp_hpc.c~bk-pci drivers/pci/hotplug/shpchp_hpc.c
--- 25/drivers/pci/hotplug/shpchp_hpc.c~bk-pci	2004-10-06 20:35:45.587893968 -0700
+++ 25-akpm/drivers/pci/hotplug/shpchp_hpc.c	2004-10-06 20:35:46.039825264 -0700
@@ -1158,7 +1158,7 @@ static irqreturn_t shpc_isr(int IRQ, voi
 					hp_slot, php_ctlr->callback_instance_id);
 			
 			/* Clear all slot events */
-			temp_dword = 0xe01fffff;
+			temp_dword = 0xe01f3fff;
 			dbg("%s: Clearing slot events, temp_dword = %x\n",
 				__FUNCTION__, temp_dword); 
 			writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
@@ -1492,8 +1492,7 @@ int shpc_init(struct controller * ctrl,
 		goto abort_free_ctlr;
 	}
 
-	php_ctlr->creg = (struct ctrl_reg *)
-		ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
+	php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
 	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);
@@ -1539,7 +1538,7 @@ int shpc_init(struct controller * ctrl,
 		slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
 			hp_slot, slot_reg);
-		tempdword = 0xffffffff;  
+		tempdword = 0xffff3fff;  
 		writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
 	}
 	
@@ -1592,7 +1591,7 @@ int shpc_init(struct controller * ctrl,
 		slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
 			hp_slot, slot_reg);
-		tempdword = 0xe01fffff;  
+		tempdword = 0xe01f3fff;  
 		writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
 	}
 	if (!shpchp_poll_mode) {
diff -puN drivers/pci/hotplug/shpchprm_acpi.c~bk-pci drivers/pci/hotplug/shpchprm_acpi.c
--- 25/drivers/pci/hotplug/shpchprm_acpi.c~bk-pci	2004-10-06 20:35:45.589893664 -0700
+++ 25-akpm/drivers/pci/hotplug/shpchprm_acpi.c	2004-10-06 20:35:46.040825112 -0700
@@ -1396,17 +1396,19 @@ static int configure_existing_function(
 static int bind_pci_resources_to_slots ( struct controller *ctrl)
 {
 	struct pci_func *func, new_func;
-	int busn = ctrl->bus;
+	int busn = ctrl->slot_bus;
 	int devn, funn;
 	u32	vid;
 
 	for (devn = 0; devn < 32; devn++) {
 		for (funn = 0; funn < 8; funn++) {
+			/*
 			if (devn == ctrl->device && funn == ctrl->function)
 				continue;
+			*/
 			/* find out if this entry is for an occupied slot */
 			vid = 0xFFFFFFFF;
-			pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
+			pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
 
 			if (vid != 0xFFFFFFFF) {
 				func = shpchp_slot_find(busn, devn, funn);
diff -puN drivers/pci/msi.c~bk-pci drivers/pci/msi.c
--- 25/drivers/pci/msi.c~bk-pci	2004-10-06 20:35:45.600891992 -0700
+++ 25-akpm/drivers/pci/msi.c	2004-10-06 20:35:46.041824960 -0700
@@ -66,7 +66,7 @@ static void msi_set_mask_bit(unsigned in
 		int		pos;
 		u32		mask_bits;
 
-		pos = entry->mask_base;
+		pos = (int)entry->mask_base;
 		pci_read_config_dword(entry->dev, pos, &mask_bits);
 		mask_bits &= ~(1);
 		mask_bits |= flag;
@@ -548,7 +548,7 @@ static int msi_capability_init(struct pc
 	dev->irq = vector;
 	entry->dev = dev;
 	if (is_mask_bit_support(control)) {
-		entry->mask_base = msi_mask_bits_reg(pos,
+		entry->mask_base = (void __iomem *)msi_mask_bits_reg(pos,
 				is_64bit_address(control));
 	}
 	/* Replace with MSI handler */
@@ -606,7 +606,7 @@ static int msix_capability_init(struct p
 	u32 phys_addr, table_offset;
  	u16 control;
 	u8 bir;
-	void *base;
+	void __iomem *base;
 
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
 	/* Request & Map MSI-X table region */
@@ -642,7 +642,7 @@ static int msix_capability_init(struct p
 		entry->msi_attrib.maskbit = 1;
 		entry->msi_attrib.default_vector = dev->irq;
 		entry->dev = dev;
-		entry->mask_base = (unsigned long)base;
+		entry->mask_base = base;
 		if (!head) {
 			entry->link.head = vector;
 			entry->link.tail = vector;
@@ -806,7 +806,7 @@ static int msi_free_vector(struct pci_de
 {
 	struct msi_desc *entry;
 	int head, entry_nr, type;
-	unsigned long base = 0L;
+	void __iomem *base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
@@ -857,7 +857,7 @@ static int msi_free_vector(struct pci_de
 			phys_addr = pci_resource_start (dev, bir);
 			phys_addr += (u32)(table_offset &
 				~PCI_MSIX_FLAGS_BIRMASK);
-			iounmap((void*)base);
+			iounmap(base);
 			release_mem_region(phys_addr,
 				nr_entries * PCI_MSIX_ENTRY_SIZE);
 		}
@@ -869,8 +869,8 @@ static int msi_free_vector(struct pci_de
 static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
 {
 	int vector = head, tail = 0;
-	int i = 0, j = 0, nr_entries = 0;
-	unsigned long base = 0L;
+	int i, j = 0, nr_entries = 0;
+	void __iomem *base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
@@ -1099,7 +1099,7 @@ void msi_remove_pci_irq_vectors(struct p
    	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
 		!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
 		int vector, head, tail = 0, warning = 0;
-		unsigned long base = 0L;
+		void __iomem *base = NULL;
 
 		vector = head = dev->irq;
 		while (head != tail) {
@@ -1129,7 +1129,7 @@ void msi_remove_pci_irq_vectors(struct p
 			phys_addr = pci_resource_start (dev, bir);
 			phys_addr += (u32)(table_offset &
 				~PCI_MSIX_FLAGS_BIRMASK);
-			iounmap((void*)base);
+			iounmap(base);
 			release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE *
 				multi_msix_capable(control));
 			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
diff -puN drivers/pci/msi.h~bk-pci drivers/pci/msi.h
--- 25/drivers/pci/msi.h~bk-pci	2004-10-06 20:35:45.602891688 -0700
+++ 25-akpm/drivers/pci/msi.h	2004-10-06 20:35:46.042824808 -0700
@@ -152,7 +152,7 @@ struct msi_desc {
 		__u16	tail;
 	}link;
 
-	unsigned long mask_base;
+	void __iomem *mask_base;
 	struct pci_dev *dev;
 };
 
diff -puN drivers/pci/pci.c~bk-pci drivers/pci/pci.c
--- 25/drivers/pci/pci.c~bk-pci	2004-10-06 20:35:45.603891536 -0700
+++ 25-akpm/drivers/pci/pci.c	2004-10-06 20:35:46.049823744 -0700
@@ -308,14 +308,12 @@ pci_set_power_state(struct pci_dev *dev,
  * (>= 64 bytes).
  */
 int
-pci_save_state(struct pci_dev *dev, u32 *buffer)
+pci_save_state(struct pci_dev *dev)
 {
 	int i;
-	if (buffer) {
-		/* XXX: 100% dword access ok here? */
-		for (i = 0; i < 16; i++)
-			pci_read_config_dword(dev, i * 4,&buffer[i]);
-	}
+	/* XXX: 100% dword access ok here? */
+	for (i = 0; i < 16; i++)
+		pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
 	return 0;
 }
 
@@ -326,27 +324,12 @@ pci_save_state(struct pci_dev *dev, u32 
  *
  */
 int 
-pci_restore_state(struct pci_dev *dev, u32 *buffer)
+pci_restore_state(struct pci_dev *dev)
 {
 	int i;
 
-	if (buffer) {
-		for (i = 0; i < 16; i++)
-			pci_write_config_dword(dev,i * 4, buffer[i]);
-	}
-	/*
-	 * otherwise, write the context information we know from bootup.
-	 * This works around a problem where warm-booting from Windows
-	 * combined with a D3(hot)->D0 transition causes PCI config
-	 * header data to be forgotten.
-	 */	
-	else {
-		for (i = 0; i < 6; i ++)
-			pci_write_config_dword(dev,
-					       PCI_BASE_ADDRESS_0 + (i * 4),
-					       dev->resource[i].start);
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-	}
+	for (i = 0; i < 16; i++)
+		pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]);
 	return 0;
 }
 
@@ -382,8 +365,13 @@ pci_enable_device_bars(struct pci_dev *d
 int
 pci_enable_device(struct pci_dev *dev)
 {
+	int err;
+
 	dev->is_enabled = 1;
-	return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
+	if ((err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1)))
+		return err;
+	pci_fixup_device(pci_fixup_enable, dev);
+	return 0;
 }
 
 /**
@@ -744,7 +732,7 @@ static int __devinit pci_init(void)
 {
 	struct pci_dev *dev = NULL;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_fixup_device(pci_fixup_final, dev);
 	}
 	return 0;
diff -puN drivers/pci/pci-driver.c~bk-pci drivers/pci/pci-driver.c
--- 25/drivers/pci/pci-driver.c~bk-pci	2004-10-06 20:35:45.604891384 -0700
+++ 25-akpm/drivers/pci/pci-driver.c	2004-10-06 20:35:46.047824048 -0700
@@ -14,27 +14,6 @@
  *  Registration of PCI drivers and handling of hot-pluggable devices.
  */
 
-/**
- * pci_match_one_device - Tell if a PCI device structure has a matching
- *                        PCI device id structure
- * @id: single PCI device id structure to match
- * @dev: the PCI device structure to match against
- * 
- * Returns the matching pci_device_id structure or %NULL if there is no match.
- */
-
-static inline const struct pci_device_id *
-pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
-{
-	if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
-	    (id->device == PCI_ANY_ID || id->device == dev->device) &&
-	    (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
-	    (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
-	    !((id->class ^ dev->class) & id->class_mask))
-		return id;
-	return NULL;
-}
-
 /*
  * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
  */
@@ -291,6 +270,19 @@ static int pci_device_remove(struct devi
 			drv->remove(pci_dev);
 		pci_dev->driver = NULL;
 	}
+
+#ifdef CONFIG_DEBUG_KERNEL
+	/*
+	 * If the driver decides to stop using the device, it should
+	 * call pci_disable_device().
+	 */
+	if (pci_dev->is_enabled) {
+		dev_warn(&pci_dev->dev, "Device was removed without properly "
+			 "calling pci_disable_device(). This may need fixing.\n");
+		/* WARN_ON(1); */
+	}
+#endif /* CONFIG_DEBUG_KERNEL */
+
 	pci_dev_put(pci_dev);
 	return 0;
 }
@@ -317,7 +309,7 @@ static int pci_device_suspend(struct dev
 	if (drv && drv->suspend)
 		i = drv->suspend(pci_dev, dev_state);
 		
-	pci_save_state(pci_dev, pci_dev->saved_config_space);
+	pci_save_state(pci_dev);
 	return i;
 }
 
@@ -329,7 +321,7 @@ static int pci_device_suspend(struct dev
 static void pci_default_resume(struct pci_dev *pci_dev)
 {
 	/* restore the PCI config space */
-	pci_restore_state(pci_dev, pci_dev->saved_config_space);
+	pci_restore_state(pci_dev);
 	/* if the device was enabled before suspend, reenable */
 	if (pci_dev->is_enabled)
 		pci_enable_device(pci_dev);
@@ -404,13 +396,13 @@ pci_populate_driver_dir(struct pci_drive
  * @drv: the driver structure to register
  * 
  * Adds the driver structure to the list of registered drivers.
- * Returns a negative value on error. The driver remains registered
- * even if no device was claimed during registration.
+ * Returns a negative value on error, otherwise 0. 
+ * If no error occured, the driver remains registered even if 
+ * no device was claimed during registration.
  */
-int
-pci_register_driver(struct pci_driver *drv)
+int pci_register_driver(struct pci_driver *drv)
 {
-	int count = 0;
+	int error;
 
 	/* initialize common driver fields */
 	drv->driver.name = drv->name;
@@ -422,13 +414,12 @@ pci_register_driver(struct pci_driver *d
 	pci_init_dynids(&drv->dynids);
 
 	/* register with core */
-	count = driver_register(&drv->driver);
+	error = driver_register(&drv->driver);
 
-	if (count >= 0) {
+	if (!error)
 		pci_populate_driver_dir(drv);
-	}
 
-	return count ? count : 1;
+	return error;
 }
 
 /**
@@ -513,16 +504,9 @@ static int pci_bus_match(struct device *
  */
 struct pci_dev *pci_dev_get(struct pci_dev *dev)
 {
-	struct device *tmp;
-
-	if (!dev)
-		return NULL;
-
-	tmp = get_device(&dev->dev);
-	if (tmp)        
-		return to_pci_dev(tmp);
-	else
-		return NULL;
+	if (dev)
+		get_device(&dev->dev);
+	return dev;
 }
 
 /**
diff -puN drivers/pci/pci.h~bk-pci drivers/pci/pci.h
--- 25/drivers/pci/pci.h~bk-pci	2004-10-06 20:35:45.606891080 -0700
+++ 25-akpm/drivers/pci/pci.h	2004-10-06 20:35:46.049823744 -0700
@@ -63,3 +63,24 @@ extern spinlock_t pci_bus_lock;
 
 extern int pciehp_msi_quirk;
 extern struct device_attribute pci_dev_attrs[];
+
+/**
+ * pci_match_one_device - Tell if a PCI device structure has a matching
+ *                        PCI device id structure
+ * @id: single PCI device id structure to match
+ * @dev: the PCI device structure to match against
+ * 
+ * Returns the matching pci_device_id structure or %NULL if there is no match.
+ */
+static inline const struct pci_device_id *
+pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
+{
+	if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
+	    (id->device == PCI_ANY_ID || id->device == dev->device) &&
+	    (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
+	    (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
+	    !((id->class ^ dev->class) & id->class_mask))
+		return id;
+	return NULL;
+}
+
diff -puN drivers/pci/pci.ids~bk-pci drivers/pci/pci.ids
--- 25/drivers/pci/pci.ids~bk-pci	2004-10-06 20:35:45.609890624 -0700
+++ 25-akpm/drivers/pci/pci.ids	2004-10-06 20:35:46.057822528 -0700
@@ -8429,9 +8429,9 @@
 	84e6  460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB)
 	84ea  460GX - 84460GX AGP Bridge (GXB function 1)
 	8500  IXP4xx Family  Network Processor (IXP420, 421, 422, 425 and IXC1100)
-	9000  Intel IXP2000 Family Network Processor
-	9001  Intel IXP2400 Network Processor
-	9004  Intel IXP2800 Network Processor
+	9000  IXP2000 Family Network Processor
+	9001  IXP2400 Network Processor
+	9004  IXP2800 Network Processor
 	9621  Integrated RAID
 	9622  Integrated RAID
 	9641  Integrated RAID
@@ -8440,7 +8440,7 @@
 # observed, and documented in Intel revision note; new mask of 1011:0026
 	b154  21154 PCI-to-PCI Bridge
 	b555  21555 Non transparent PCI-to-PCI Bridge
-		1331 0030  Radisys ENP-2611
+		1331 0030  ENP-2611
 		4c53 1050  CT7 mainboard
 		4c53 1051  CE7 mainboard
 		e4bf 1000  CC8-1-BLUES
diff -puN drivers/pci/probe.c~bk-pci drivers/pci/probe.c
--- 25/drivers/pci/probe.c~bk-pci	2004-10-06 20:35:45.610890472 -0700
+++ 25-akpm/drivers/pci/probe.c	2004-10-06 20:35:46.058822376 -0700
@@ -750,6 +750,7 @@ unsigned int __devinit pci_do_scan_bus(s
 
 struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
 {
+	int error;
 	struct pci_bus *b;
 	struct device *dev;
 
@@ -769,9 +770,7 @@ struct pci_bus * __devinit pci_scan_bus_
 	if (pci_find_bus(pci_domain_nr(b), bus)) {
 		/* If we already got to this bus through a different bridge, ignore it */
 		DBG("PCI: Bus %02x already known\n", bus);
-		kfree(dev);
-		kfree(b);
-		return NULL;
+		goto err_out;
 	}
 	list_add_tail(&b->node, &pci_root_buses);
 
@@ -779,15 +778,23 @@ struct pci_bus * __devinit pci_scan_bus_
 	dev->parent = parent;
 	dev->release = pci_release_bus_bridge_dev;
 	sprintf(dev->bus_id, "pci%04x:%02x", pci_domain_nr(b), bus);
-	device_register(dev);
+	error = device_register(dev);
+	if (error)
+		goto dev_reg_err;
 	b->bridge = get_device(dev);
 
 	b->class_dev.class = &pcibus_class;
 	sprintf(b->class_dev.class_id, "%04x:%02x", pci_domain_nr(b), bus);
-	class_device_register(&b->class_dev);
-	class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
-
-	sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
+	error = class_device_register(&b->class_dev);
+	if (error)
+		goto class_dev_reg_err;
+	error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity);
+	if (error)
+		goto class_dev_create_file_err;
+
+	error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge");
+	if (error)
+		goto sys_create_link_err;
 
 	b->number = b->secondary = bus;
 	b->resource[0] = &ioport_resource;
@@ -798,6 +805,19 @@ struct pci_bus * __devinit pci_scan_bus_
 	pci_bus_add_devices(b);
 
 	return b;
+
+sys_create_link_err:
+	class_device_remove_file(&b->class_dev, &class_device_attr_cpuaffinity);
+class_dev_create_file_err:
+	class_device_unregister(&b->class_dev);
+class_dev_reg_err:
+	device_unregister(dev);
+dev_reg_err:
+	list_del(&b->node);
+err_out:
+	kfree(dev);
+	kfree(b);
+	return NULL;
 }
 EXPORT_SYMBOL(pci_scan_bus_parented);
 
diff -puN drivers/pci/proc.c~bk-pci drivers/pci/proc.c
--- 25/drivers/pci/proc.c~bk-pci	2004-10-06 20:35:45.611890320 -0700
+++ 25-akpm/drivers/pci/proc.c	2004-10-06 20:35:46.059822224 -0700
@@ -379,7 +379,7 @@ static struct seq_operations proc_bus_pc
 	.show	= show_device
 };
 
-struct proc_dir_entry *proc_bus_pci_dir;
+static struct proc_dir_entry *proc_bus_pci_dir;
 
 int pci_proc_attach_device(struct pci_dev *dev)
 {
@@ -599,7 +599,7 @@ static int __init pci_proc_init(void)
 	if (entry)
 		entry->proc_fops = &proc_bus_pci_dev_operations;
 	proc_initialized = 1;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_proc_attach_device(dev);
 	}
 	legacy_proc_init();
@@ -612,6 +612,5 @@ __initcall(pci_proc_init);
 EXPORT_SYMBOL(pci_proc_attach_device);
 EXPORT_SYMBOL(pci_proc_attach_bus);
 EXPORT_SYMBOL(pci_proc_detach_bus);
-EXPORT_SYMBOL(proc_bus_pci_dir);
 #endif
 
diff -puN drivers/pci/quirks.c~bk-pci drivers/pci/quirks.c
--- 25/drivers/pci/quirks.c~bk-pci	2004-10-06 20:35:45.613890016 -0700
+++ 25-akpm/drivers/pci/quirks.c	2004-10-06 20:35:46.060822072 -0700
@@ -30,7 +30,7 @@ static void __devinit quirk_passive_rele
 
 	/* We have to make sure a particular bit is set in the PIIX3
 	   ISA bridge, so we have to go out and find it. */
-	while ((d = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
+	while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
 		pci_read_config_byte(d, 0x82, &dlc);
 		if (!(dlc & 1<<1)) {
 			printk(KERN_ERR "PCI: PIIX3: Enabling Passive Release on %s\n", pci_name(d));
@@ -116,21 +116,21 @@ static void __devinit quirk_vialatency(s
 	/* Ok we have a potential problem chipset here. Now see if we have
 	   a buggy southbridge */
 	   
-	p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
+	p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, NULL);
 	if (p!=NULL) {
 		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
 		/* 0x40 - 0x4f == 686B, 0x10 - 0x2f == 686A; thanks Dan Hollis */
 		/* Check for buggy part revisions */
-		if (rev < 0x40 || rev > 0x42) 
-			return;
+		if (rev < 0x40 || rev > 0x42)
+			goto exit;
 	} else {
-		p = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
+		p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
 		if (p==NULL)	/* No problem parts */
-			return;
+			goto exit;
 		pci_read_config_byte(p, PCI_CLASS_REVISION, &rev);
 		/* Check for buggy part revisions */
 		if (rev < 0x10 || rev > 0x12) 
-			return;
+			goto exit;
 	}
 	
 	/*
@@ -153,6 +153,8 @@ static void __devinit quirk_vialatency(s
 	busarb |= (1<<4);
 	pci_write_config_byte(dev, 0x76, busarb);
 	printk(KERN_INFO "Applying VIA southbridge workaround.\n");
+exit:
+	pci_dev_put(p);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8363_0,	quirk_vialatency );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8371_1,	quirk_vialatency );
@@ -491,9 +493,9 @@ static void __devinit quirk_via_irqpic(s
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
 	}
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic );
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic );
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_2,	quirk_via_irqpic );
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_5,	quirk_via_irqpic );
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_6,	quirk_via_irqpic );
 
 
 /*
@@ -992,7 +994,7 @@ static void pci_do_fixups(struct pci_dev
 	while (f < end) {
 		if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
  		    (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
-			pr_debug(KERN_INFO "PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev));
+			pr_debug("PCI: Calling quirk %p for %s\n", f->hook, pci_name(dev));
 			f->hook(dev);
 		}
 		f++;
@@ -1003,6 +1005,9 @@ extern struct pci_fixup __start_pci_fixu
 extern struct pci_fixup __end_pci_fixups_header[];
 extern struct pci_fixup __start_pci_fixups_final[];
 extern struct pci_fixup __end_pci_fixups_final[];
+extern struct pci_fixup __start_pci_fixups_enable[];
+extern struct pci_fixup __end_pci_fixups_enable[];
+
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
 {
@@ -1018,6 +1023,12 @@ void pci_fixup_device(enum pci_fixup_pas
 		start = __start_pci_fixups_final;
 		end = __end_pci_fixups_final;
 		break;
+
+	case pci_fixup_enable:
+		start = __start_pci_fixups_enable;
+		end = __end_pci_fixups_enable;
+		break;
+
 	default:
 		/* stupid compiler warning, you would think with an enum... */
 		return;
diff -puN drivers/pci/search.c~bk-pci drivers/pci/search.c
--- 25/drivers/pci/search.c~bk-pci	2004-10-06 20:35:45.614889864 -0700
+++ 25-akpm/drivers/pci/search.c	2004-10-06 20:35:46.062821768 -0700
@@ -1,16 +1,17 @@
 /*
  * 	PCI searching functions.
  *
- *	Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
- *				David Mosberger-Tang
- *	Copyright 1997 -- 2000 Martin Mares <mj@ucw.cz>
- *	Copyright 2003 -- Greg Kroah-Hartman <greg@kroah.com>
+ *	Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter,
+ *					David Mosberger-Tang
+ *	Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz>
+ *	Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com>
  */
 
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include "pci.h"
 
 spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
 
@@ -156,10 +157,11 @@ struct pci_dev * pci_get_slot(struct pci
  * the pci device returned by this function can disappear at any moment in
  * time.
  */
-struct pci_dev *
-pci_find_subsys(unsigned int vendor, unsigned int device,
-		unsigned int ss_vendor, unsigned int ss_device,
-		const struct pci_dev *from)
+static struct pci_dev * pci_find_subsys(unsigned int vendor,
+				        unsigned int device,
+					unsigned int ss_vendor,
+					unsigned int ss_device,
+					const struct pci_dev *from)
 {
 	struct list_head *n;
 	struct pci_dev *dev;
@@ -257,12 +259,6 @@ exit:
  * @from: Previous PCI device found in search, or %NULL for new search.
  *
  * Iterates through the list of known PCI devices.  If a PCI device is
- * found with a matching @vendor and @device, a pointer to its device structure is
- * returned.  Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL to the @from argument.
- * Otherwise if @from is not %NULL, searches continue from next device on the global list.
- *
- * Iterates through the list of known PCI devices.  If a PCI device is
  * found with a matching @vendor and @device, the reference count to the
  * device is incremented and a pointer to its device structure is returned.
  * Otherwise, %NULL is returned.  A new search is initiated by passing %NULL
@@ -312,25 +308,26 @@ exit:
 	return dev;
 }
 
-
 /**
- * pci_find_class - begin or continue searching for a PCI device by class
+ * pci_get_class - begin or continue searching for a PCI device by class
  * @class: search for a PCI device with this class designation
  * @from: Previous PCI device found in search, or %NULL for new search.
  *
  * Iterates through the list of known PCI devices.  If a PCI device is
- * found with a matching @class, a pointer to its device structure is
- * returned.  Otherwise, %NULL is returned.
+ * found with a matching @class, the reference count to the device is
+ * incremented and a pointer to its device structure is returned.
+ * Otherwise, %NULL is returned.
  * A new search is initiated by passing %NULL to the @from argument.
  * Otherwise if @from is not %NULL, searches continue from next device
- * on the global list.
+ * on the global list.  The reference count for @from is always decremented
+ * if it is not %NULL.
  */
-struct pci_dev *
-pci_find_class(unsigned int class, const struct pci_dev *from)
+struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
 {
 	struct list_head *n;
 	struct pci_dev *dev;
 
+	WARN_ON(in_interrupt());
 	spin_lock(&pci_bus_lock);
 	n = from ? from->global_list.next : pci_devices.next;
 
@@ -342,16 +339,50 @@ pci_find_class(unsigned int class, const
 	}
 	dev = NULL;
 exit:
+	pci_dev_put(from);
+	dev = pci_dev_get(dev);
 	spin_unlock(&pci_bus_lock);
 	return dev;
 }
 
+/**
+ * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
+ * @ids: A pointer to a null terminated list of struct pci_device_id structures
+ * that describe the type of PCI device the caller is trying to find.
+ *
+ * Obvious fact: You do not have a reference to any device that might be found
+ * by this function, so if that device is removed from the system right after
+ * this function is finished, the value will be stale.  Use this function to
+ * find devices that are usually built into a system, or for a general hint as
+ * to if another device happens to be present at this specific moment in time.
+ */
+int pci_dev_present(const struct pci_device_id *ids)
+{
+	struct pci_dev *dev;
+	int found = 0;
+
+	WARN_ON(in_interrupt());
+	spin_lock(&pci_bus_lock);
+	while (ids->vendor || ids->subvendor || ids->class_mask) {
+		list_for_each_entry(dev, &pci_devices, global_list) {
+			if (pci_match_one_device(ids, dev)) {
+				found = 1;
+				goto exit;
+			}
+		}
+		ids++;
+	}
+exit:				
+	spin_unlock(&pci_bus_lock);
+	return found;
+}
+EXPORT_SYMBOL(pci_dev_present);
+
 EXPORT_SYMBOL(pci_find_bus);
-EXPORT_SYMBOL(pci_find_class);
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
-EXPORT_SYMBOL(pci_find_subsys);
 EXPORT_SYMBOL(pci_get_device);
 EXPORT_SYMBOL(pci_get_subsys);
 EXPORT_SYMBOL(pci_get_slot);
+EXPORT_SYMBOL(pci_get_class);
diff -puN drivers/pci/setup-bus.c~bk-pci drivers/pci/setup-bus.c
--- 25/drivers/pci/setup-bus.c~bk-pci	2004-10-06 20:35:45.615889712 -0700
+++ 25-akpm/drivers/pci/setup-bus.c	2004-10-06 20:35:46.063821616 -0700
@@ -533,16 +533,16 @@ EXPORT_SYMBOL(pci_bus_assign_resources);
 void __init
 pci_assign_unassigned_resources(void)
 {
-	struct list_head *ln;
+	struct pci_bus *bus;
 
 	/* Depth first, calculate sizes and alignments of all
 	   subordinate buses. */
-	list_for_each(ln, &pci_root_buses) {
-		pci_bus_size_bridges(pci_bus_b(ln));
+	list_for_each_entry(bus, &pci_root_buses, node) {
+		pci_bus_size_bridges(bus);
 	}
 	/* Depth last, allocate resources and update the hardware. */
-	list_for_each(ln, &pci_root_buses) {
-		pci_bus_assign_resources(pci_bus_b(ln));
-		pci_enable_bridges(pci_bus_b(ln));
+	list_for_each_entry(bus, &pci_root_buses, node) {
+		pci_bus_assign_resources(bus);
+		pci_enable_bridges(bus);
 	}
 }
diff -puN drivers/pci/setup-irq.c~bk-pci drivers/pci/setup-irq.c
--- 25/drivers/pci/setup-irq.c~bk-pci	2004-10-06 20:35:45.617889408 -0700
+++ 25-akpm/drivers/pci/setup-irq.c	2004-10-06 20:35:46.063821616 -0700
@@ -65,7 +65,7 @@ pci_fixup_irqs(u8 (*swizzle)(struct pci_
 	       int (*map_irq)(struct pci_dev *, u8, u8))
 {
 	struct pci_dev *dev = NULL;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pdev_fixup_irq(dev, swizzle, map_irq);
 	}
 }
diff -puN drivers/pcmcia/yenta_socket.c~bk-pci drivers/pcmcia/yenta_socket.c
--- 25/drivers/pcmcia/yenta_socket.c~bk-pci	2004-10-06 20:35:45.631887280 -0700
+++ 25-akpm/drivers/pcmcia/yenta_socket.c	2004-10-06 20:35:46.064821464 -0700
@@ -1023,9 +1023,9 @@ static int yenta_dev_suspend (struct pci
 			socket->type->save_state(socket);
 
 		/* FIXME: pci_save_state needs to have a better interface */
-		pci_save_state(dev, socket->saved_state);
-		pci_read_config_dword(dev, 16*4, &socket->saved_state[16]);
-		pci_read_config_dword(dev, 17*4, &socket->saved_state[17]);
+		pci_save_state(dev);
+		pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
+		pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
 		pci_set_power_state(dev, 3);
 	}
 
@@ -1040,9 +1040,9 @@ static int yenta_dev_resume (struct pci_
 	if (socket) {
 		pci_set_power_state(dev, 0);
 		/* FIXME: pci_restore_state needs to have a better interface */
-		pci_restore_state(dev, socket->saved_state);
-		pci_write_config_dword(dev, 16*4, socket->saved_state[16]);
-		pci_write_config_dword(dev, 17*4, socket->saved_state[17]);
+		pci_restore_state(dev);
+		pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
+		pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
 
 		if (socket->type && socket->type->restore_state)
 			socket->type->restore_state(socket);
diff -puN drivers/pcmcia/yenta_socket.h~bk-pci drivers/pcmcia/yenta_socket.h
--- 25/drivers/pcmcia/yenta_socket.h~bk-pci	2004-10-06 20:35:45.632887128 -0700
+++ 25-akpm/drivers/pcmcia/yenta_socket.h	2004-10-06 20:35:46.064821464 -0700
@@ -120,7 +120,7 @@ struct yenta_socket {
 	unsigned int private[8];
 
 	/* PCI saved state */
-	u32 saved_state[18];
+	u32 saved_state[2];
 };
 
 
diff -puN drivers/pnp/system.c~bk-pci drivers/pnp/system.c
--- 25/drivers/pnp/system.c~bk-pci	2004-10-06 20:35:45.640885912 -0700
+++ 25-akpm/drivers/pnp/system.c	2004-10-06 20:35:46.065821312 -0700
@@ -104,4 +104,8 @@ static int __init pnp_system_init(void)
 	return pnp_register_driver(&system_pnp_driver);
 }
 
-subsys_initcall(pnp_system_init);
+/**
+ * Reserve motherboard resources after PCI claim BARs,
+ * but before PCI assign resources for uninitialized PCI devices
+ */
+fs_initcall(pnp_system_init);
diff -puN drivers/scsi/eata.c~bk-pci drivers/scsi/eata.c
--- 25/drivers/scsi/eata.c~bk-pci	2004-10-06 20:35:45.660882872 -0700
+++ 25-akpm/drivers/scsi/eata.c	2004-10-06 20:35:46.067821008 -0700
@@ -1005,7 +1005,7 @@ static struct pci_dev *get_pci_dev(unsig
    unsigned int addr;
    struct pci_dev *dev = NULL;
 
-   while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
       addr = pci_resource_start (dev, 0);
 
 #if defined(DEBUG_PCI_DETECT)
@@ -1013,6 +1013,11 @@ static struct pci_dev *get_pci_dev(unsig
              driver_name, dev->bus->number, dev->devfn, addr);
 #endif
 
+      /* we are in so much trouble for a pci hotplug system with this driver
+       * anyway, so doing this at least lets people unload the driver and not
+       * cause memory problems, but in general this is a bad thing to do (this
+       * driver needs to be converted to the proper PCI api someday... */
+      pci_dev_put(dev);
       if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev;
       }
 
@@ -1027,7 +1032,7 @@ static void enable_pci_ports(void) {
 
    struct pci_dev *dev = NULL;
 
-   while((dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
+   while((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) {
 
 #if defined(DEBUG_PCI_DETECT)
       printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n",
@@ -1454,7 +1459,7 @@ static void add_pci_ports(void) {
 
    for (k = 0; k < MAX_PCI; k++) {
 
-      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
+      if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;
 
       if (pci_enable_device (dev)) {
 
@@ -1478,6 +1483,7 @@ static void add_pci_ports(void) {
              addr + PCI_BASE_ADDRESS_0;
       }
 
+   pci_dev_put(dev);
 #endif /* end CONFIG_PCI */
 
    return;
diff -puN drivers/scsi/ipr.c~bk-pci drivers/scsi/ipr.c
--- 25/drivers/scsi/ipr.c~bk-pci	2004-10-06 20:35:45.662882568 -0700
+++ 25-akpm/drivers/scsi/ipr.c	2004-10-06 20:35:46.071820400 -0700
@@ -4935,7 +4935,7 @@ static int ipr_reset_restore_cfg_space(s
 	int rc;
 
 	ENTER;
-	rc = pci_restore_state(ioa_cfg->pdev, ioa_cfg->pci_cfg_buf);
+	rc = pci_restore_state(ioa_cfg->pdev);
 
 	if (rc != PCIBIOS_SUCCESSFUL) {
 		ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
@@ -5749,7 +5749,7 @@ static int __devinit ipr_probe_ioa(struc
 	}
 
 	/* Save away PCI config space for use following IOA reset */
-	rc = pci_save_state(pdev, ioa_cfg->pci_cfg_buf);
+	rc = pci_save_state(pdev);
 
 	if (rc != PCIBIOS_SUCCESSFUL) {
 		dev_err(&pdev->dev, "Failed to save PCI config space\n");
diff -puN drivers/scsi/ipr.h~bk-pci drivers/scsi/ipr.h
--- 25/drivers/scsi/ipr.h~bk-pci	2004-10-06 20:35:45.664882264 -0700
+++ 25-akpm/drivers/scsi/ipr.h	2004-10-06 20:35:46.073820096 -0700
@@ -889,7 +889,6 @@ struct ipr_ioa_cfg {
 	unsigned long ioa_mailbox;
 	struct ipr_interrupts regs;
 
-	u32 pci_cfg_buf[64];
 	u16 saved_pcix_cmd_reg;
 	u16 reset_retries;
 
diff -puN drivers/scsi/megaraid/megaraid_mbox.c~bk-pci drivers/scsi/megaraid/megaraid_mbox.c
--- 25/drivers/scsi/megaraid/megaraid_mbox.c~bk-pci	2004-10-06 20:35:45.675880592 -0700
+++ 25-akpm/drivers/scsi/megaraid/megaraid_mbox.c	2004-10-06 20:35:46.076819640 -0700
@@ -1554,12 +1554,12 @@ mbox_post_cmd(adapter_t *adapter, scb_t 
 
 	if (scb->dma_direction == PCI_DMA_TODEVICE) {
 		if (!scb->scp->use_sg) {	// sg list not used
-			pci_dma_sync_single(adapter->pdev, ccb->buf_dma_h,
+			pci_dma_sync_single_for_cpu(adapter->pdev, ccb->buf_dma_h,
 					scb->scp->request_bufflen,
 					PCI_DMA_TODEVICE);
 		}
 		else {
-			pci_dma_sync_sg(adapter->pdev, scb->scp->request_buffer,
+			pci_dma_sync_sg_for_cpu(adapter->pdev, scb->scp->request_buffer,
 				scb->scp->use_sg, PCI_DMA_TODEVICE);
 		}
 	}
@@ -2332,7 +2332,7 @@ megaraid_mbox_sync_scb(adapter_t *adapte
 
 	case MRAID_DMA_WBUF:
 		if (scb->dma_direction == PCI_DMA_FROMDEVICE) {
-			pci_dma_sync_single(adapter->pdev,
+			pci_dma_sync_single_for_cpu(adapter->pdev,
 					ccb->buf_dma_h,
 					scb->scp->request_bufflen,
 					PCI_DMA_FROMDEVICE);
@@ -2345,7 +2345,7 @@ megaraid_mbox_sync_scb(adapter_t *adapte
 
 	case MRAID_DMA_WSG:
 		if (scb->dma_direction == PCI_DMA_FROMDEVICE) {
-			pci_dma_sync_sg(adapter->pdev,
+			pci_dma_sync_sg_for_cpu(adapter->pdev,
 					scb->scp->request_buffer,
 					scb->scp->use_sg, PCI_DMA_FROMDEVICE);
 		}
diff -puN drivers/scsi/nsp32.c~bk-pci drivers/scsi/nsp32.c
--- 25/drivers/scsi/nsp32.c~bk-pci	2004-10-06 20:35:45.677880288 -0700
+++ 25-akpm/drivers/scsi/nsp32.c	2004-10-06 20:35:46.078819336 -0700
@@ -3439,11 +3439,10 @@ static int nsp32_prom_read_bit(nsp32_hw_
 static int nsp32_suspend(struct pci_dev *pdev, u32 state)
 {
 	struct Scsi_Host *host = pci_get_drvdata(pdev);
-	nsp32_hw_data    *data = (nsp32_hw_data *)host->hostdata;
 
 	nsp32_msg(KERN_INFO, "pci-suspend: pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host);
 
-	pci_save_state     (pdev, data->PciState);
+	pci_save_state     (pdev);
 	pci_disable_device (pdev);
 	pci_set_power_state(pdev, state);
 
@@ -3461,7 +3460,7 @@ static int nsp32_resume(struct pci_dev *
 
 	pci_set_power_state(pdev, 0);
 	pci_enable_wake    (pdev, 0, 0);
-	pci_restore_state  (pdev, data->PciState);
+	pci_restore_state  (pdev);
 
 	reg = nsp32_read2(data->BaseAddress, INDEX_REG);
 
diff -puN drivers/scsi/nsp32.h~bk-pci drivers/scsi/nsp32.h
--- 25/drivers/scsi/nsp32.h~bk-pci	2004-10-06 20:35:45.678880136 -0700
+++ 25-akpm/drivers/scsi/nsp32.h	2004-10-06 20:35:46.079819184 -0700
@@ -605,9 +605,6 @@ typedef struct _nsp32_hw_data {
 	unsigned char msginbuf [MSGINBUF_MAX];	/* megin buffer     */
 	char	      msgin_len;		/* msginbuf length  */
 
-#ifdef CONFIG_PM
-	u32           PciState[16];     /* save PCI state to this area */
-#endif
 } nsp32_hw_data;
 
 /*
diff -puN drivers/usb/core/hcd.h~bk-pci drivers/usb/core/hcd.h
--- 25/drivers/usb/core/hcd.h~bk-pci	2004-10-06 20:35:45.691878160 -0700
+++ 25-akpm/drivers/usb/core/hcd.h	2004-10-06 20:35:46.081818880 -0700
@@ -81,7 +81,6 @@ struct usb_hcd {	/* usb_bus.hcpriv point
 
 #ifdef	CONFIG_PCI
 	int			region;		/* pci region for regs */
-	u32			pci_state [16];	/* for PM state save */
 #endif
 
 #define HCD_BUFFER_POOLS	4
diff -puN drivers/usb/core/hcd-pci.c~bk-pci drivers/usb/core/hcd-pci.c
--- 25/drivers/usb/core/hcd-pci.c~bk-pci	2004-10-06 20:35:45.692878008 -0700
+++ 25-akpm/drivers/usb/core/hcd-pci.c	2004-10-06 20:35:46.080819032 -0700
@@ -305,7 +305,7 @@ int usb_hcd_pci_suspend (struct pci_dev 
 					retval);
 		else {
 			hcd->state = HCD_STATE_SUSPENDED;
-			pci_save_state (dev, hcd->pci_state);
+			pci_save_state (dev);
 #ifdef	CONFIG_USB_SUSPEND
 			pci_enable_wake (dev, state, hcd->remote_wakeup);
 			pci_enable_wake (dev, 4, hcd->remote_wakeup);
@@ -365,7 +365,7 @@ int usb_hcd_pci_resume (struct pci_dev *
 		return retval;
 	}
 	pci_set_master (dev);
-	pci_restore_state (dev, hcd->pci_state);
+	pci_restore_state (dev);
 #ifdef	CONFIG_USB_SUSPEND
 	pci_enable_wake (dev, dev->current_state, 0);
 	pci_enable_wake (dev, 4, 0);
diff -puN drivers/usb/gadget/goku_udc.c~bk-pci drivers/usb/gadget/goku_udc.c
--- 25/drivers/usb/gadget/goku_udc.c~bk-pci	2004-10-06 20:35:45.705876032 -0700
+++ 25-akpm/drivers/usb/gadget/goku_udc.c	2004-10-06 20:35:46.082818728 -0700
@@ -1976,7 +1976,7 @@ static struct pci_driver goku_pci_driver
 
 static int __init init (void)
 {
-	return pci_module_init (&goku_pci_driver);
+	return pci_register_driver (&goku_pci_driver);
 }
 module_init (init);
 
diff -puN drivers/usb/gadget/net2280.c~bk-pci drivers/usb/gadget/net2280.c
--- 25/drivers/usb/gadget/net2280.c~bk-pci	2004-10-06 20:35:45.707875728 -0700
+++ 25-akpm/drivers/usb/gadget/net2280.c	2004-10-06 20:35:46.084818424 -0700
@@ -2935,7 +2935,7 @@ static int __init init (void)
 {
 	if (!use_dma)
 		use_dma_chaining = 0;
-	return pci_module_init (&net2280_pci_driver);
+	return pci_register_driver (&net2280_pci_driver);
 }
 module_init (init);
 
diff -puN drivers/usb/host/ehci-hcd.c~bk-pci drivers/usb/host/ehci-hcd.c
--- 25/drivers/usb/host/ehci-hcd.c~bk-pci	2004-10-06 20:35:45.724873144 -0700
+++ 25-akpm/drivers/usb/host/ehci-hcd.c	2004-10-06 20:35:46.085818272 -0700
@@ -1092,7 +1092,7 @@ static int __init init (void) 
 		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
 		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
 
-	return pci_module_init (&ehci_pci_driver);
+	return pci_register_driver (&ehci_pci_driver);
 }
 module_init (init);
 
diff -puN drivers/usb/host/ohci-pci.c~bk-pci drivers/usb/host/ohci-pci.c
--- 25/drivers/usb/host/ohci-pci.c~bk-pci	2004-10-06 20:35:45.725872992 -0700
+++ 25-akpm/drivers/usb/host/ohci-pci.c	2004-10-06 20:35:46.086818120 -0700
@@ -279,7 +279,7 @@ static int __init ohci_hcd_pci_init (voi
 
 	pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
 		sizeof (struct ed), sizeof (struct td));
-	return pci_module_init (&ohci_pci_driver);
+	return pci_register_driver (&ohci_pci_driver);
 }
 module_init (ohci_hcd_pci_init);
 
diff -puN drivers/usb/host/uhci-hcd.c~bk-pci drivers/usb/host/uhci-hcd.c
--- 25/drivers/usb/host/uhci-hcd.c~bk-pci	2004-10-06 20:35:45.727872688 -0700
+++ 25-akpm/drivers/usb/host/uhci-hcd.c	2004-10-06 20:35:46.088817816 -0700
@@ -2534,7 +2534,7 @@ static int __init uhci_hcd_init(void)
 	if (!uhci_up_cachep)
 		goto up_failed;
 
-	retval = pci_module_init(&uhci_pci_driver);
+	retval = pci_register_driver(&uhci_pci_driver);
 	if (retval)
 		goto init_failed;
 
diff -puN drivers/video/i810/i810.h~bk-pci drivers/video/i810/i810.h
--- 25/drivers/video/i810/i810.h~bk-pci	2004-10-06 20:35:45.743870256 -0700
+++ 25-akpm/drivers/video/i810/i810.h	2004-10-06 20:35:46.088817816 -0700
@@ -254,7 +254,6 @@ struct i810fb_par {
 	drm_agp_t                *drm_agp;
 	atomic_t                 use_count;
 	u32 pseudo_palette[17];
-	u32 pci_state[16];
 	unsigned long mmio_start_phys;
 	u8 *mmio_start_virtual;
 	u32 pitch;
diff -puN drivers/video/i810/i810_main.c~bk-pci drivers/video/i810/i810_main.c
--- 25/drivers/video/i810/i810_main.c~bk-pci	2004-10-06 20:35:45.744870104 -0700
+++ 25-akpm/drivers/video/i810/i810_main.c	2004-10-06 20:35:46.090817512 -0700
@@ -1517,7 +1517,7 @@ static int i810fb_suspend(struct pci_dev
 		par->drm_agp->unbind_memory(par->i810_gtt.i810_cursor_memory);
 		pci_disable_device(dev);
 	}
-	pci_save_state(dev, par->pci_state);
+	pci_save_state(dev);
 	pci_set_power_state(dev, state);
 
 	return 0;
@@ -1531,7 +1531,7 @@ static int i810fb_resume(struct pci_dev 
 	if (par->cur_state == 0)
 		return 0;
 
-	pci_restore_state(dev, par->pci_state);
+	pci_restore_state(dev);
 	pci_set_power_state(dev, 0);
 	pci_enable_device(dev);
 	par->drm_agp->bind_memory(par->i810_gtt.i810_fb_memory, 
@@ -1995,10 +1995,7 @@ int __init i810fb_init(void)
 		return -ENODEV;
 	i810fb_setup(option);
 
-	if (pci_register_driver(&i810fb_driver) > 0)
-		return 0;
-	pci_unregister_driver(&i810fb_driver);
-	return -ENODEV;
+	return pci_register_driver(&i810fb_driver);
 }
 #endif 
 
@@ -2013,10 +2010,7 @@ int __init i810fb_init(void)
 	hsync1 *= 1000;
 	hsync2 *= 1000;
 
-	if (pci_register_driver(&i810fb_driver) > 0)
-		return 0;
-	pci_unregister_driver(&i810fb_driver);
-	return -ENODEV;
+	return pci_register_driver(&i810fb_driver);
 }
 
 MODULE_PARM(vram, "i");
diff -puN drivers/video/riva/fbdev.c~bk-pci drivers/video/riva/fbdev.c
--- 25/drivers/video/riva/fbdev.c~bk-pci	2004-10-06 20:35:45.758867976 -0700
+++ 25-akpm/drivers/video/riva/fbdev.c	2004-10-06 20:35:46.092817208 -0700
@@ -2147,10 +2147,7 @@ int __devinit rivafb_init(void)
 		return -ENODEV;
 	rivafb_setup(option);
 #endif
-	if (pci_register_driver(&rivafb_driver) > 0)
-		return 0;
-	pci_unregister_driver(&rivafb_driver);
-	return -ENODEV;
+	return pci_register_driver(&rivafb_driver);
 }
 
 
diff -puN include/asm-generic/vmlinux.lds.h~bk-pci include/asm-generic/vmlinux.lds.h
--- 25/include/asm-generic/vmlinux.lds.h~bk-pci	2004-10-06 20:35:45.767866608 -0700
+++ 25-akpm/include/asm-generic/vmlinux.lds.h	2004-10-06 20:35:46.092817208 -0700
@@ -24,6 +24,9 @@
 		VMLINUX_SYMBOL(__start_pci_fixups_final) = .;		\
 		*(.pci_fixup_final)					\
 		VMLINUX_SYMBOL(__end_pci_fixups_final) = .;		\
+		VMLINUX_SYMBOL(__start_pci_fixups_enable) = .;		\
+		*(.pci_fixup_enable)					\
+		VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;		\
 	}								\
 									\
 	/* Kernel symbol table: Normal symbols */			\
diff -puN include/asm-ppc64/pci-bridge.h~bk-pci include/asm-ppc64/pci-bridge.h
--- 25/include/asm-ppc64/pci-bridge.h~bk-pci	2004-10-06 20:35:45.774865544 -0700
+++ 25-akpm/include/asm-ppc64/pci-bridge.h	2004-10-06 20:35:46.093817056 -0700
@@ -34,6 +34,7 @@ struct pci_controller {
 	char what[8];                     /* Eye catcher      */
 	enum phb_types type;              /* Type of hardware */
 	struct pci_bus *bus;
+	char is_dynamic;
 	void *arch_data;
 	struct list_head list_node;
 
@@ -47,6 +48,7 @@ struct pci_controller {
 	 * the PCI memory space in the CPU bus space
 	 */
 	unsigned long pci_mem_offset;
+	unsigned long pci_io_size;
 
 	struct pci_ops *ops;
 	volatile unsigned int *cfg_addr;
@@ -88,7 +90,9 @@ static inline struct device_node *pci_de
 }
 
 extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
-					 struct device_node *dev, int primary);
+					 struct device_node *dev);
+
+extern int pcibios_remove_root_bus(struct pci_controller *phb);
 
 /* Use this macro after the PCI bus walk for max performance when it
  * is known that sysdata is correct.
diff -puN include/asm-ppc64/pci.h~bk-pci include/asm-ppc64/pci.h
--- 25/include/asm-ppc64/pci.h~bk-pci	2004-10-06 20:35:45.775865392 -0700
+++ 25-akpm/include/asm-ppc64/pci.h	2004-10-06 20:35:46.093817056 -0700
@@ -229,6 +229,8 @@ remap_bus_range(struct pci_bus *bus);
 extern void
 pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus);
 
+extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+
 extern int pci_read_irq_line(struct pci_dev *dev);
 
 extern void pcibios_add_platform_entries(struct pci_dev *dev);
diff -puN include/linux/pci.h~bk-pci include/linux/pci.h
--- 25/include/linux/pci.h~bk-pci	2004-10-06 20:35:45.777865088 -0700
+++ 25-akpm/include/linux/pci.h	2004-10-06 20:35:46.101815840 -0700
@@ -1,5 +1,5 @@
 /*
- *	$Id: pci.h,v 1.87 1998/10/11 15:13:12 mj Exp $
+ *	pci.h
  *
  *	PCI defines and function prototypes
  *	Copyright 1994, Drew Eckhardt
@@ -676,6 +676,12 @@ struct pci_driver {
 	.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
 	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
 
+/* 
+ * pci_module_init is obsolete, this stays here till we fix up all usages of it
+ * in the tree.
+ */
+#define pci_module_init	pci_register_driver
+
 /* these external functions are only available when PCI support is enabled */
 #ifdef CONFIG_PCI
 
@@ -721,10 +727,6 @@ extern void pci_remove_bus_device(struct
 
 struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
 struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
-struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device,
-				 unsigned int ss_vendor, unsigned int ss_device,
-				 const struct pci_dev *from);
-struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
@@ -735,6 +737,8 @@ struct pci_dev *pci_get_subsys (unsigned
 				unsigned int ss_vendor, unsigned int ss_device,
 				struct pci_dev *from);
 struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
+struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
+int pci_dev_present(const struct pci_device_id *ids);
 
 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
@@ -781,8 +785,8 @@ int pci_set_consistent_dma_mask(struct p
 int pci_assign_resource(struct pci_dev *dev, int i);
 
 /* Power management related routines */
-int pci_save_state(struct pci_dev *dev, u32 *buffer);
-int pci_restore_state(struct pci_dev *dev, u32 *buffer);
+int pci_save_state(struct pci_dev *dev);
+int pci_restore_state(struct pci_dev *dev);
 int pci_set_power_state(struct pci_dev *dev, int state);
 int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
 
@@ -862,10 +866,6 @@ extern void msi_remove_pci_irq_vectors(s
 
 #include <asm/pci.h>
 
-/* Backwards compat, remove in 2.7.x */
-#define pci_dma_sync_single	pci_dma_sync_single_for_cpu
-#define pci_dma_sync_sg		pci_dma_sync_sg_for_cpu
-
 /*
  *  If the system does not have PCI, clearly these return errors.  Define
  *  these as simple inline functions to avoid hair in drivers.
@@ -884,16 +884,9 @@ _PCI_NOP_ALL(write,)
 static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
 { return NULL; }
 
-static inline struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from)
-{ return NULL; }
-
 static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
 { return NULL; }
 
-static inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int device,
-unsigned int ss_vendor, unsigned int ss_device, const struct pci_dev *from)
-{ return NULL; }
-
 static inline struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from)
 { return NULL; }
 
@@ -901,10 +894,15 @@ static inline struct pci_dev *pci_get_su
 unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from)
 { return NULL; }
 
+static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
+{ return NULL; }
+
+#define pci_dev_present(ids)	(0)
+#define pci_dev_put(dev)	do { } while (0)
+
 static inline void pci_set_master(struct pci_dev *dev) { }
 static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
 static inline void pci_disable_device(struct pci_dev *dev) { }
-static inline int pci_module_init(struct pci_driver *drv) { return -ENODEV; }
 static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
 static inline int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; }
 static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
@@ -915,8 +913,8 @@ static inline int pci_find_ext_capabilit
 static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
 
 /* Power management related routines */
-static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; }
-static inline int pci_restore_state(struct pci_dev *dev, u32 *buffer) { return 0; }
+static inline int pci_save_state(struct pci_dev *dev) { return 0; }
+static inline int pci_restore_state(struct pci_dev *dev) { return 0; }
 static inline int pci_set_power_state(struct pci_dev *dev, int state) { return 0; }
 static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) { return 0; }
 
@@ -925,19 +923,6 @@ static inline int pci_enable_wake(struct
 #else
 
 /*
- * a helper function which helps ensure correct pci_driver
- * setup and cleanup for commonly-encountered hotplug/modular cases
- *
- * This MUST stay in a header, as it checks for -DMODULE
- */
-static inline int pci_module_init(struct pci_driver *drv)
-{
-	int rc = pci_register_driver (drv);
-
-	return rc < 0 ? rc : 0;
-}
-
-/*
  * PCI domain support.  Sometimes called PCI segment (eg by ACPI),
  * a PCI domain is defined to be a set of PCI busses which share
  * configuration space.
@@ -1010,6 +995,7 @@ struct pci_fixup {
 enum pci_fixup_pass {
 	pci_fixup_header,	/* Called immediately after reading configuration header */
 	pci_fixup_final,	/* Final phase of device fixups */
+	pci_fixup_enable,	/* pci_enable_device() time */
 };
 
 /* Anonymous variables would be nice... */
@@ -1023,6 +1009,12 @@ enum pci_fixup_pass {
 	__attribute__((__section__(".pci_fixup_final"))) = {				\
 		vendor, device, hook };
 
+#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)				\
+	static struct pci_fixup __pci_fixup_##vendor##device##hook __attribute_used__	\
+	__attribute__((__section__(".pci_fixup_enable"))) = {				\
+		vendor, device, hook };
+
+
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
 
 extern int pci_pci_problems;
diff -puN sound/core/init.c~bk-pci sound/core/init.c
--- 25/sound/core/init.c~bk-pci	2004-10-06 20:35:45.778864936 -0700
+++ 25-akpm/sound/core/init.c	2004-10-06 20:35:46.102815688 -0700
@@ -801,7 +801,7 @@ int snd_card_pci_resume(struct pci_dev *
 	if (card->power_state == SNDRV_CTL_POWER_D0)
 		return 0;
 	/* restore the PCI config space */
-	pci_restore_state(dev, dev->saved_config_space);
+	pci_restore_state(dev);
 	/* FIXME: correct state value? */
 	return card->pm_resume(card, 0);
 }
diff -puN sound/oss/ali5455.c~bk-pci sound/oss/ali5455.c
--- 25/sound/oss/ali5455.c~bk-pci	2004-10-06 20:35:45.796862200 -0700
+++ 25-akpm/sound/oss/ali5455.c	2004-10-06 20:35:46.105815232 -0700
@@ -311,7 +311,6 @@ struct ali_card {
 	u16 pci_id;
 #ifdef CONFIG_PM
 	u16 pm_suspended;
-	u32 pm_save_state[64 / sizeof(u32)];
 	int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97];
 #endif
 	/* soundcore stuff */
@@ -3576,7 +3575,7 @@ static int ali_pm_suspend(struct pci_dev
 			}
 		}
 	}
-	pci_save_state(dev, card->pm_save_state);	/* XXX do we need this? */
+	pci_save_state(dev);	/* XXX do we need this? */
 	pci_disable_device(dev);	/* disable busmastering */
 	pci_set_power_state(dev, 3);	/* Zzz. */
 	return 0;
@@ -3588,7 +3587,7 @@ static int ali_pm_resume(struct pci_dev 
 	int num_ac97, i = 0;
 	struct ali_card *card = pci_get_drvdata(dev);
 	pci_enable_device(dev);
-	pci_restore_state(dev, card->pm_save_state);
+	pci_restore_state(dev);
 	/* observation of a toshiba portege 3440ct suggests that the 
 	   hardware has to be more or less completely reinitialized from
 	   scratch after an apm suspend.  Works For Me.   -dan */
@@ -3714,11 +3713,7 @@ static int __init ali_init_module(void)
 			controller_pcmout_share_spdif_locked = 0;
 		}
 	}
-	if (!pci_register_driver(&ali_pci_driver)) {
-		pci_unregister_driver(&ali_pci_driver);
-		return -ENODEV;
-	}
-	return 0;
+	return pci_register_driver(&ali_pci_driver);
 }
 
 static void __exit ali_cleanup_module(void)
diff -puN sound/oss/esssolo1.c~bk-pci sound/oss/esssolo1.c
--- 25/sound/oss/esssolo1.c~bk-pci	2004-10-06 20:35:45.801861440 -0700
+++ 25-akpm/sound/oss/esssolo1.c	2004-10-06 20:35:46.107814928 -0700
@@ -2451,11 +2451,7 @@ static struct pci_driver solo1_driver = 
 static int __init init_solo1(void)
 {
 	printk(KERN_INFO "solo1: version v0.20 time " __TIME__ " " __DATE__ "\n");
-	if (!pci_register_driver(&solo1_driver)) {
-		pci_unregister_driver(&solo1_driver);
-                return -ENODEV;
-	}
-	return 0;
+	return pci_register_driver(&solo1_driver);
 }
 
 /* --------------------------------------------------------------------- */
diff -puN sound/oss/forte.c~bk-pci sound/oss/forte.c
--- 25/sound/oss/forte.c~bk-pci	2004-10-06 20:35:45.802861288 -0700
+++ 25-akpm/sound/oss/forte.c	2004-10-06 20:35:46.108814776 -0700
@@ -2111,12 +2111,7 @@ forte_init_module (void)
 {
 	printk (KERN_INFO PFX DRIVER_VERSION "\n");
 
-	if (!pci_register_driver (&forte_pci_driver)) {
-		pci_unregister_driver (&forte_pci_driver);
-		return -ENODEV;
-	}
-
-	return 0;
+	return pci_register_driver (&forte_pci_driver);
 }
 
 
diff -puN sound/oss/i810_audio.c~bk-pci sound/oss/i810_audio.c
--- 25/sound/oss/i810_audio.c~bk-pci	2004-10-06 20:35:45.804860984 -0700
+++ 25-akpm/sound/oss/i810_audio.c	2004-10-06 20:35:46.111814320 -0700
@@ -406,7 +406,6 @@ struct i810_card {
 	u16 pci_id_internal; /* used to access card_cap[] */
 #ifdef CONFIG_PM	
 	u16 pm_suspended;
-	u32 pm_save_state[64/sizeof(u32)];
 	int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97];
 #endif
 	/* soundcore stuff */
@@ -3385,7 +3384,7 @@ static int i810_pm_suspend(struct pci_de
 			}
 		}
 	}
-	pci_save_state(dev,card->pm_save_state); /* XXX do we need this? */
+	pci_save_state(dev); /* XXX do we need this? */
 	pci_disable_device(dev); /* disable busmastering */
 	pci_set_power_state(dev,3); /* Zzz. */
 
@@ -3398,7 +3397,7 @@ static int i810_pm_resume(struct pci_dev
 	int num_ac97,i=0;
 	struct i810_card *card=pci_get_drvdata(dev);
 	pci_enable_device(dev);
-	pci_restore_state (dev,card->pm_save_state);
+	pci_restore_state (dev);
 
 	/* observation of a toshiba portege 3440ct suggests that the 
 	   hardware has to be more or less completely reinitialized from
@@ -3484,13 +3483,15 @@ static struct pci_driver i810_pci_driver
 
 static int __init i810_init_module (void)
 {
+	int retval;
+
 	printk(KERN_INFO "Intel 810 + AC97 Audio, version "
 	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
-	if (!pci_register_driver(&i810_pci_driver)) {
-		pci_unregister_driver(&i810_pci_driver);
-                return -ENODEV;
-	}
+	retval = pci_register_driver(&i810_pci_driver);
+	if (retval)
+		return retval;
+
 	if(ftsodell != 0) {
 		printk("i810_audio: ftsodell is now a deprecated option.\n");
 	}
diff -puN sound/oss/maestro3.c~bk-pci sound/oss/maestro3.c
--- 25/sound/oss/maestro3.c~bk-pci	2004-10-06 20:35:45.806860680 -0700
+++ 25-akpm/sound/oss/maestro3.c	2004-10-06 20:35:46.114813864 -0700
@@ -2940,8 +2940,7 @@ static int __init m3_init_module(void)
         return -ENODEV; /* ? */
     }
 
-    if (!pci_register_driver(&m3_pci_driver)) {
-        pci_unregister_driver(&m3_pci_driver);
+    if (pci_register_driver(&m3_pci_driver)) {
         unregister_reboot_notifier(&m3_reboot_nb);
         return -ENODEV;
     }
diff -puN sound/oss/trident.c~bk-pci sound/oss/trident.c
--- 25/sound/oss/trident.c~bk-pci	2004-10-06 20:35:45.808860376 -0700
+++ 25-akpm/sound/oss/trident.c	2004-10-06 20:35:46.117813408 -0700
@@ -4594,11 +4594,7 @@ trident_init_module(void)
 	       "5050 PCI Audio, version " DRIVER_VERSION ", " __TIME__ " " 
 	       __DATE__ "\n");
 
-	if (!pci_register_driver(&trident_pci_driver)) {
-		pci_unregister_driver(&trident_pci_driver);
-		return -ENODEV;
-	}
-	return 0;
+	return pci_register_driver(&trident_pci_driver);
 }
 
 static void __exit
diff -puN sound/oss/via82cxxx_audio.c~bk-pci sound/oss/via82cxxx_audio.c
--- 25/sound/oss/via82cxxx_audio.c~bk-pci	2004-10-06 20:35:45.810860072 -0700
+++ 25-akpm/sound/oss/via82cxxx_audio.c	2004-10-06 20:35:46.120812952 -0700
@@ -3622,12 +3622,10 @@ static int __init init_via82cxxx_audio(v
 	}
 
 	rc = pci_register_driver (&via_driver);
-	if (rc < 1) {
-		if (rc == 0)
-			pci_unregister_driver (&via_driver);
+	if (rc) {
 		via_cleanup_proc ();
-		DPRINTK ("EXIT, returning -ENODEV\n");
-		return -ENODEV;
+		DPRINTK ("EXIT, returning %d\n", rc);
+		return rc;
 	}
 
 	DPRINTK ("EXIT, returning 0\n");
_
