summary refs log tree commit diff
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-07 19:23:44 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-07 19:23:44 -0800
commit78149df6d565c36675463352d0bfe0000b02b7a7 (patch)
tree9a9269d8c037ef66cf3f3d060bbbcc1053562d70 /drivers/pci
parentc96e2c92072d3e78954c961f53d8c7352f7abbd7 (diff)
parent14719f325e1cd4ff757587e9a221ebaf394563ee (diff)
downloadlinux-78149df6d565c36675463352d0bfe0000b02b7a7.tar.gz
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (41 commits)
  Revert "PCI: remove duplicate device id from ata_piix"
  msi: Make MSI useable more architectures
  msi: Kill the msi_desc array.
  msi: Remove attach_msi_entry.
  msi: Fix msi_remove_pci_irq_vectors.
  msi: Remove msi_lock.
  msi: Kill msi_lookup_irq
  MSI: Combine pci_(save|restore)_msi/msix_state
  MSI: Remove pci_scan_msi_device()
  MSI: Replace pci_msi_quirk with calls to pci_no_msi()
  PCI: remove duplicate device id from ipr
  PCI: remove duplicate device id from ata_piix
  PCI: power management: remove noise on non-manageable hw
  PCI: cleanup MSI code
  PCI: make isa_bridge Alpha-only
  PCI: remove quirk_sis_96x_compatible()
  PCI: Speed up the Intel SMBus unhiding quirk
  PCI Quirk: 1k I/O space IOBL_ADR fix on P64H2
  shpchp: delete trailing whitespace
  shpchp: remove DBG_XXX_ROUTINE
  ...
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/Kconfig9
-rw-r--r--drivers/pci/hotplug/pciehp.h194
-rw-r--r--drivers/pci/hotplug/pciehp_core.c292
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c223
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c827
-rw-r--r--drivers/pci/hotplug/shpchp.h4
-rw-r--r--drivers/pci/hotplug/shpchp_core.c4
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c20
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c185
-rw-r--r--drivers/pci/msi.c325
-rw-r--r--drivers/pci/pci-driver.c3
-rw-r--r--drivers/pci/pci.c171
-rw-r--r--drivers/pci/pci.h14
-rw-r--r--drivers/pci/probe.c70
-rw-r--r--drivers/pci/quirks.c113
-rw-r--r--drivers/pci/search.c38
16 files changed, 966 insertions, 1526 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index adce4204d87d..be92695a7833 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -145,15 +145,6 @@ config HOTPLUG_PCI_SHPC
 
 	  When in doubt, say N.
 
-config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
-	bool "Use polling mechanism for hot-plug events (for testing purpose)"
-	depends on HOTPLUG_PCI_SHPC
-	help
-	  Say Y here if you want to use the polling mechanism for hot-plug 
-	  events for early platform testing.
-
-	  When in doubt, say N.
-
 config HOTPLUG_PCI_RPA
 	tristate "RPA PCI Hotplug driver"
 	depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 4fb12fcda563..d19fcae8a7c0 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -44,15 +44,20 @@ extern int pciehp_poll_time;
 extern int pciehp_debug;
 extern int pciehp_force;
 
-/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
-#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
-
+#define dbg(format, arg...)						\
+	do {								\
+		if (pciehp_debug)					\
+			printk("%s: " format, MY_NAME , ## arg);	\
+	} while (0)
+#define err(format, arg...)						\
+	printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...)						\
+	printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+#define warn(format, arg...)						\
+	printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
+#define SLOT_NAME_SIZE 10
 struct slot {
-	struct slot *next;
 	u8 bus;
 	u8 device;
 	u32 number;
@@ -63,6 +68,8 @@ struct slot {
 	struct hpc_ops *hpc_ops;
 	struct hotplug_slot *hotplug_slot;
 	struct list_head	slot_list;
+	char name[SLOT_NAME_SIZE];
+	unsigned long last_emi_toggle;
 };
 
 struct event_info {
@@ -70,34 +77,15 @@ struct event_info {
 	u8 hp_slot;
 };
 
-typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
-
-struct php_ctlr_state_s {
-	struct php_ctlr_state_s *pnext;
-	struct pci_dev *pci_dev;
-	unsigned int irq;
-	unsigned long flags;				/* spinlock's */
-	u32 slot_device_offset;
-	u32 num_slots;
-    	struct timer_list	int_poll_timer;		/* Added for poll event */
-	php_intr_callback_t 	attention_button_callback;
-	php_intr_callback_t 	switch_change_callback;
-	php_intr_callback_t 	presence_change_callback;
-	php_intr_callback_t 	power_fault_callback;
-	void 			*callback_instance_id;
-	struct ctrl_reg 	*creg;				/* Ptr to controller register space */
-};
-
 #define MAX_EVENTS		10
 struct controller {
 	struct controller *next;
 	struct mutex crit_sect;		/* critical section mutex */
 	struct mutex ctrl_lock;		/* controller lock */
-	struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
 	int num_slots;			/* Number of slots on ctlr */
 	int slot_num_inc;		/* 1 or -1 */
 	struct pci_dev *pci_dev;
-	struct pci_bus *pci_bus;
+	struct list_head slot_list;
 	struct event_info event_queue[MAX_EVENTS];
 	struct slot *slot;
 	struct hpc_ops *hpc_ops;
@@ -112,6 +100,8 @@ struct controller {
 	u8 ctrlcap;
 	u16 vendor_id;
 	u8 cap_base;
+	struct timer_list poll_timer;
+	volatile int cmd_busy;
 };
 
 #define INT_BUTTON_IGNORE		0
@@ -131,8 +121,6 @@ struct controller {
 #define POWERON_STATE			3
 #define POWEROFF_STATE			4
 
-#define PCI_TO_PCI_BRIDGE_CLASS		0x00060400
-
 /* Error messages */
 #define INTERLOCK_OPEN			0x00000002
 #define ADD_NOT_SUPPORTED		0x00000003
@@ -144,10 +132,6 @@ struct controller {
 #define WRONG_BUS_FREQUENCY		0x0000000D
 #define POWER_FAILURE			0x0000000E
 
-#define REMOVE_NOT_SUPPORTED		0x00000003
-
-#define DISABLE_CARD			1
-
 /* Field definitions in Slot Capabilities Register */
 #define ATTN_BUTTN_PRSN	0x00000001
 #define	PWR_CTRL_PRSN	0x00000002
@@ -155,6 +139,7 @@ struct controller {
 #define ATTN_LED_PRSN	0x00000008
 #define PWR_LED_PRSN	0x00000010
 #define HP_SUPR_RM_SUP	0x00000020
+#define EMI_PRSN	0x00020000
 
 #define ATTN_BUTTN(cap)		(cap & ATTN_BUTTN_PRSN)
 #define POWER_CTRL(cap)		(cap & PWR_CTRL_PRSN)
@@ -162,130 +147,65 @@ struct controller {
 #define ATTN_LED(cap)		(cap & ATTN_LED_PRSN)
 #define PWR_LED(cap)		(cap & PWR_LED_PRSN) 
 #define HP_SUPR_RM(cap)		(cap & HP_SUPR_RM_SUP)
-
-/*
- * error Messages
- */
-#define msg_initialization_err	"Initialization failure, error=%d\n"
-#define msg_button_on		"PCI slot #%s - powering on due to button press.\n"
-#define msg_button_off		"PCI slot #%s - powering off due to button press.\n"
-#define msg_button_cancel	"PCI slot #%s - action canceled due to button press.\n"
-#define msg_button_ignore	"PCI slot #%s - button press ignored.  (action in progress...)\n"
-
-/* controller functions */
-extern int	pciehp_event_start_thread	(void);
-extern void	pciehp_event_stop_thread	(void);
-extern int	pciehp_enable_slot		(struct slot *slot);
-extern int	pciehp_disable_slot		(struct slot *slot);
-
-extern u8	pciehp_handle_attention_button	(u8 hp_slot, void *inst_id);
-extern u8	pciehp_handle_switch_change	(u8 hp_slot, void *inst_id);
-extern u8	pciehp_handle_presence_change	(u8 hp_slot, void *inst_id);
-extern u8	pciehp_handle_power_fault	(u8 hp_slot, void *inst_id);
-/* extern void	long_delay (int delay); */
-
-/* pci functions */
-extern int	pciehp_configure_device		(struct slot *p_slot);
-extern int	pciehp_unconfigure_device	(struct slot *p_slot);
-
-
+#define EMI(cap)		(cap & EMI_PRSN)
+
+extern int pciehp_event_start_thread(void);
+extern void pciehp_event_stop_thread(void);
+extern int pciehp_enable_slot(struct slot *slot);
+extern int pciehp_disable_slot(struct slot *slot);
+extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
+extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
+extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
+extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
+extern int pciehp_configure_device(struct slot *p_slot);
+extern int pciehp_unconfigure_device(struct slot *p_slot);
+int pcie_init(struct controller *ctrl, struct pcie_device *dev);
 
 /* Global variables */
 extern struct controller *pciehp_ctrl_list;
 
-/* Inline functions */
-
 static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
 {
-	struct slot *p_slot, *tmp_slot = NULL;
-
-	p_slot = ctrl->slot;
+	struct slot *slot;
 
-	while (p_slot && (p_slot->device != device)) {
-		tmp_slot = p_slot;
-		p_slot = p_slot->next;
+	list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
+		if (slot->device == device)
+			return slot;
 	}
-	if (p_slot == NULL) {
-		err("ERROR: pciehp_find_slot device=0x%x\n", device);
-		p_slot = tmp_slot;
-	}
-
-	return p_slot;
-}
-
-static inline int wait_for_ctrl_irq(struct controller *ctrl)
-{
-	int retval = 0;
-
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(&ctrl->queue, &wait);
-	if (!pciehp_poll_mode)
-		/* Sleep for up to 1 second */
-		msleep_interruptible(1000);
-	else
-		msleep_interruptible(2500);
-	
-	remove_wait_queue(&ctrl->queue, &wait);
-	if (signal_pending(current))
-		retval =  -EINTR;
-
-	return retval;
-}
-
-#define SLOT_NAME_SIZE 10
 
-static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
-{
-	snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
+	err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
+	return NULL;
 }
 
-enum php_ctlr_type {
-	PCI,
-	ISA,
-	ACPI
-};
-
-int pcie_init(struct controller *ctrl, struct pcie_device *dev);
-
-/* This has no meaning for PCI Express, as there is only 1 slot per port */
-int pcie_get_ctlr_slot_config(struct controller *ctrl,
-		int *num_ctlr_slots,
-		int *first_device_num,
-		int *physical_slot_num,
-		u8 *ctrlcap);
-
 struct hpc_ops {
-	int	(*power_on_slot)	(struct slot *slot);
-	int	(*power_off_slot)	(struct slot *slot);
-	int	(*get_power_status)	(struct slot *slot, u8 *status);
-	int	(*get_attention_status)	(struct slot *slot, u8 *status);
-	int	(*set_attention_status)	(struct slot *slot, u8 status);
-	int	(*get_latch_status)	(struct slot *slot, u8 *status);
-	int	(*get_adapter_status)	(struct slot *slot, u8 *status);
-
-	int	(*get_max_bus_speed)	(struct slot *slot, enum pci_bus_speed *speed);
-	int	(*get_cur_bus_speed)	(struct slot *slot, enum pci_bus_speed *speed);
-
-	int	(*get_max_lnk_width)	(struct slot *slot, enum pcie_link_width *value);
-	int	(*get_cur_lnk_width)	(struct slot *slot, enum pcie_link_width *value);
-	
-	int	(*query_power_fault)	(struct slot *slot);
-	void	(*green_led_on)		(struct slot *slot);
-	void	(*green_led_off)	(struct slot *slot);
-	void	(*green_led_blink)	(struct slot *slot);
-	void	(*release_ctlr)		(struct controller *ctrl);
-	int	(*check_lnk_status)	(struct controller *ctrl);
+	int (*power_on_slot)(struct slot *slot);
+	int (*power_off_slot)(struct slot *slot);
+	int (*get_power_status)(struct slot *slot, u8 *status);
+	int (*get_attention_status)(struct slot *slot, u8 *status);
+	int (*set_attention_status)(struct slot *slot, u8 status);
+	int (*get_latch_status)(struct slot *slot, u8 *status);
+	int (*get_adapter_status)(struct slot *slot, u8 *status);
+	int (*get_emi_status)(struct slot *slot, u8 *status);
+	int (*toggle_emi)(struct slot *slot);
+	int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+	int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+	int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val);
+	int (*get_cur_lnk_width)(struct slot *slot, enum pcie_link_width *val);
+	int (*query_power_fault)(struct slot *slot);
+	void (*green_led_on)(struct slot *slot);
+	void (*green_led_off)(struct slot *slot);
+	void (*green_led_blink)(struct slot *slot);
+	void (*release_ctlr)(struct controller *ctrl);
+	int (*check_lnk_status)(struct controller *ctrl);
 };
 
-
 #ifdef CONFIG_ACPI
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/actypes.h>
 #include <linux/pci-acpi.h>
 
-#define pciehp_get_hp_hw_control_from_firmware(dev) \
+#define pciehp_get_hp_hw_control_from_firmware(dev)			\
 	pciehp_acpi_get_hp_hw_control_from_firmware(dev)
 static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
 			struct hotplug_params *hpp)
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index f13f31323e85..a92eda6e02f6 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -34,6 +34,7 @@
 #include <linux/pci.h>
 #include "pciehp.h"
 #include <linux/interrupt.h>
+#include <linux/time.h>
 
 /* Global variables */
 int pciehp_debug;
@@ -87,6 +88,95 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
   	.get_cur_bus_speed =	get_cur_bus_speed,
 };
 
+/*
+ * Check the status of the Electro Mechanical Interlock (EMI)
+ */
+static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value)
+{
+	struct slot *slot = hotplug_slot->private;
+	return (slot->hpc_ops->get_emi_status(slot, value));
+}
+
+/*
+ * sysfs interface for the Electro Mechanical Interlock (EMI)
+ * 1 == locked, 0 == unlocked
+ */
+static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf)
+{
+	int retval;
+	u8 value;
+
+	retval = get_lock_status(slot, &value);
+	if (retval)
+		goto lock_read_exit;
+	retval = sprintf (buf, "%d\n", value);
+
+lock_read_exit:
+	return retval;
+}
+
+/*
+ * Change the status of the Electro Mechanical Interlock (EMI)
+ * This is a toggle - in addition there must be at least 1 second
+ * in between toggles.
+ */
+static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status)
+{
+	struct slot *slot = hotplug_slot->private;
+	int retval;
+	u8 value;
+
+	mutex_lock(&slot->ctrl->crit_sect);
+
+	/* has it been >1 sec since our last toggle? */
+	if ((get_seconds() - slot->last_emi_toggle) < 1)
+		return -EINVAL;
+
+	/* see what our current state is */
+	retval = get_lock_status(hotplug_slot, &value);
+	if (retval || (value == status))
+		goto set_lock_exit;
+
+	slot->hpc_ops->toggle_emi(slot);
+set_lock_exit:
+	mutex_unlock(&slot->ctrl->crit_sect);
+	return 0;
+}
+
+/*
+ * sysfs interface which allows the user to toggle the Electro Mechanical
+ * Interlock.  Valid values are either 0 or 1.  0 == unlock, 1 == lock
+ */
+static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
+		size_t count)
+{
+	unsigned long llock;
+	u8 lock;
+	int retval = 0;
+
+	llock = simple_strtoul(buf, NULL, 10);
+	lock = (u8)(llock & 0xff);
+
+	switch (lock) {
+		case 0:
+		case 1:
+			retval = set_lock_status(slot, lock);
+			break;
+		default:
+			err ("%d is an invalid lock value\n", lock);
+			retval = -EINVAL;
+	}
+	if (retval)
+		return retval;
+	return count;
+}
+
+static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
+	.attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = lock_read_file,
+	.store = lock_write_file
+};
+
 /**
  * release_slot - free up the memory used by a slot
  * @hotplug_slot: slot to free
@@ -98,148 +188,108 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
 	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
 	kfree(slot->hotplug_slot->info);
-	kfree(slot->hotplug_slot->name);
 	kfree(slot->hotplug_slot);
 	kfree(slot);
 }
 
+static void make_slot_name(struct slot *slot)
+{
+	snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d",
+		 slot->bus, slot->number);
+}
+
 static int init_slots(struct controller *ctrl)
 {
 	struct slot *slot;
-	struct hpc_ops *hpc_ops;
 	struct hotplug_slot *hotplug_slot;
-	struct hotplug_slot_info *hotplug_slot_info;
-	u8 number_of_slots;
-	u8 slot_device;
-	u32 slot_number;
-	int result = -ENOMEM;
+	struct hotplug_slot_info *info;
+	int retval = -ENOMEM;
+	int i;
 
-	number_of_slots = ctrl->num_slots;
-	slot_device = ctrl->slot_device_offset;
-	slot_number = ctrl->first_slot;
-
-	while (number_of_slots) {
+	for (i = 0; i < ctrl->num_slots; i++) {
 		slot = kzalloc(sizeof(*slot), GFP_KERNEL);
 		if (!slot)
 			goto error;
 
-		slot->hotplug_slot =
-				kzalloc(sizeof(*(slot->hotplug_slot)),
-						GFP_KERNEL);
-		if (!slot->hotplug_slot)
+		hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL);
+		if (!hotplug_slot)
 			goto error_slot;
-		hotplug_slot = slot->hotplug_slot;
+		slot->hotplug_slot = hotplug_slot;
 
-		hotplug_slot->info =
-			kzalloc(sizeof(*(hotplug_slot->info)),
-						GFP_KERNEL);
-		if (!hotplug_slot->info)
+		info = kzalloc(sizeof(*info), GFP_KERNEL);
+		if (!info)
 			goto error_hpslot;
-		hotplug_slot_info = hotplug_slot->info;
-		hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL);
-		if (!hotplug_slot->name)
-			goto error_info;
+		hotplug_slot->info = info;
 
-		slot->ctrl = ctrl;
-		slot->bus = ctrl->slot_bus;
-		slot->device = slot_device;
-		slot->hpc_ops = hpc_ops = ctrl->hpc_ops;
+		hotplug_slot->name = slot->name;
 
+		slot->hp_slot = i;
+		slot->ctrl = ctrl;
+		slot->bus = ctrl->pci_dev->subordinate->number;
+		slot->device = ctrl->slot_device_offset + i;
+		slot->hpc_ops = ctrl->hpc_ops;
 		slot->number = ctrl->first_slot;
-		slot->hp_slot = slot_device - ctrl->slot_device_offset;
 
 		/* register this slot with the hotplug pci core */
 		hotplug_slot->private = slot;
 		hotplug_slot->release = &release_slot;
-		make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot);
+		make_slot_name(slot);
 		hotplug_slot->ops = &pciehp_hotplug_slot_ops;
 
-		hpc_ops->get_power_status(slot,
-			&(hotplug_slot_info->power_status));
-		hpc_ops->get_attention_status(slot,
-			&(hotplug_slot_info->attention_status));
-		hpc_ops->get_latch_status(slot,
-			&(hotplug_slot_info->latch_status));
-		hpc_ops->get_adapter_status(slot,
-			&(hotplug_slot_info->adapter_status));
+		get_power_status(hotplug_slot, &info->power_status);
+		get_attention_status(hotplug_slot, &info->attention_status);
+		get_latch_status(hotplug_slot, &info->latch_status);
+		get_adapter_status(hotplug_slot, &info->adapter_status);
 
 		dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
-			"slot_device_offset=%x\n",
-			slot->bus, slot->device, slot->hp_slot, slot->number,
-			ctrl->slot_device_offset);
-		result = pci_hp_register(hotplug_slot);
-		if (result) {
-			err ("pci_hp_register failed with error %d\n", result);
-			goto error_name;
+		    "slot_device_offset=%x\n", slot->bus, slot->device,
+		    slot->hp_slot, slot->number, ctrl->slot_device_offset);
+		retval = pci_hp_register(hotplug_slot);
+		if (retval) {
+			err ("pci_hp_register failed with error %d\n", retval);
+			goto error_info;
+		}
+		/* create additional sysfs entries */
+		if (EMI(ctrl->ctrlcap)) {
+			retval = sysfs_create_file(&hotplug_slot->kobj,
+				&hotplug_slot_attr_lock.attr);
+			if (retval) {
+				pci_hp_deregister(hotplug_slot);
+				err("cannot create additional sysfs entries\n");
+				goto error_info;
+			}
 		}
 
-		slot->next = ctrl->slot;
-		ctrl->slot = slot;
-
-		number_of_slots--;
-		slot_device++;
-		slot_number += ctrl->slot_num_inc;
+		list_add(&slot->slot_list, &ctrl->slot_list);
 	}
 
 	return 0;
-
-error_name:
-	kfree(hotplug_slot->name);
 error_info:
-	kfree(hotplug_slot_info);
+	kfree(info);
 error_hpslot:
 	kfree(hotplug_slot);
 error_slot:
 	kfree(slot);
 error:
-	return result;
-}
-
-
-static int cleanup_slots (struct controller * ctrl)
-{
-	struct slot *old_slot, *next_slot;
-
-	old_slot = ctrl->slot;
-	ctrl->slot = NULL;
-
-	while (old_slot) {
-		next_slot = old_slot->next;
-		pci_hp_deregister (old_slot->hotplug_slot);
-		old_slot = next_slot;
-	}
-
-
-	return(0);
+	return retval;
 }
 
-static int get_ctlr_slot_config(struct controller *ctrl)
+static void cleanup_slots(struct controller *ctrl)
 {
-	int num_ctlr_slots;		/* Not needed; PCI Express has 1 slot per port*/
-	int first_device_num;		/* Not needed */
-	int physical_slot_num;
-	u8 ctrlcap;			
-	int rc;
+	struct list_head *tmp;
+	struct list_head *next;
+	struct slot *slot;
 
-	rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap);
-	if (rc) {
-		err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device);
-		return (-1);
+	list_for_each_safe(tmp, next, &ctrl->slot_list) {
+		slot = list_entry(tmp, struct slot, slot_list);
+		list_del(&slot->slot_list);
+		if (EMI(ctrl->ctrlcap))
+			sysfs_remove_file(&slot->hotplug_slot->kobj,
+				&hotplug_slot_attr_lock.attr);
+		pci_hp_deregister(slot->hotplug_slot);
 	}
-
-	ctrl->num_slots = num_ctlr_slots;	/* PCI Express has 1 slot per port */
-	ctrl->slot_device_offset = first_device_num;
-	ctrl->first_slot = physical_slot_num;
-	ctrl->ctrlcap = ctrlcap; 	
-
-	dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n",
-		__FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap, 
-		ctrl->bus, ctrl->device);
-
-	return (0);
 }
 
-
 /*
  * set_attention_status - Turns the Amber LED for a slot on, off or blink
  */
@@ -378,8 +428,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
 	int rc;
 	struct controller *ctrl;
 	struct slot *t_slot;
-	int first_device_num = 0 ;	/* first PCI device number supported by this PCIE */  
-	int num_ctlr_slots;		/* number of slots supported by this HPC */
 	u8 value;
 	struct pci_dev *pdev;
 	
@@ -388,6 +436,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
 		err("%s : out of memory\n", __FUNCTION__);
 		goto err_out_none;
 	}
+	INIT_LIST_HEAD(&ctrl->slot_list);
 
 	pdev = dev->port;
 	ctrl->pci_dev = pdev;
@@ -400,13 +449,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
 
 	pci_set_drvdata(pdev, ctrl);
 
-	ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
-	if (!ctrl->pci_bus) {
-		err("%s: out of memory\n", __FUNCTION__);
-		rc = -ENOMEM;
-		goto err_out_unmap_mmio_region;
-	}
-	memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
 	ctrl->bus = pdev->bus->number;  /* ctrl bus */
 	ctrl->slot_bus = pdev->subordinate->number;  /* bus controlled by this HPC */
 
@@ -415,26 +457,14 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
 	dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__,
 		ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
 
-	/*
-	 *	Save configuration headers for this and subordinate PCI buses
-	 */
-
-	rc = get_ctlr_slot_config(ctrl);
-	if (rc) {
-		err(msg_initialization_err, rc);
-		goto err_out_free_ctrl_bus;
-	}
-	first_device_num = ctrl->slot_device_offset;
-	num_ctlr_slots = ctrl->num_slots; 
-
 	/* Setup the slot information structures */
 	rc = init_slots(ctrl);
 	if (rc) {
-		err(msg_initialization_err, 6);
-		goto err_out_free_ctrl_slot;
+		err("%s: slot initialization failed\n", PCIE_MODULE_NAME);
+		goto err_out_release_ctlr;
 	}
 
-	t_slot = pciehp_find_slot(ctrl, first_device_num);
+	t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
 
 	/*	Finish setting up the hot plug ctrl device */
 	ctrl->next_event = 0;
@@ -447,32 +477,18 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
 		pciehp_ctrl_list = ctrl;
 	}
 
-	/* Wait for exclusive access to hardware */
-	mutex_lock(&ctrl->ctrl_lock);
-
 	t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
-	
 	if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
 		rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
-		if (rc) {
-			/* Done with exclusive hardware access */
-			mutex_unlock(&ctrl->ctrl_lock);
+		if (rc)
 			goto err_out_free_ctrl_slot;
-		} else
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (ctrl);
 	}
 
-	/* Done with exclusive hardware access */
-	mutex_unlock(&ctrl->ctrl_lock);
-
 	return 0;
 
 err_out_free_ctrl_slot:
 	cleanup_slots(ctrl);
-err_out_free_ctrl_bus:
-	kfree(ctrl->pci_bus);
-err_out_unmap_mmio_region:
+err_out_release_ctlr:
 	ctrl->hpc_ops->release_ctlr(ctrl);
 err_out_free_ctrl:
 	kfree(ctrl);
@@ -506,8 +522,6 @@ static void __exit unload_pciehpd(void)
 	while (ctrl) {
 		cleanup_slots(ctrl);
 
-		kfree (ctrl->pci_bus);
-
 		ctrl->hpc_ops->release_ctlr(ctrl);
 
 		tctrl = ctrl;
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 372c63e35aa9..4283ef56dbd9 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -48,9 +48,8 @@ static inline char *slot_name(struct slot *p_slot)
 	return p_slot->hotplug_slot->name;
 }
 
-u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
+u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u8 rc = 0;
 	u8 getstatus;
@@ -101,9 +100,8 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
 
 }
 
-u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
+u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u8 rc = 0;
 	u8 getstatus;
@@ -143,9 +141,8 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
 	return rc;
 }
 
-u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
+u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u8 presence_save, rc = 0;
 	struct event_info *taskInfo;
@@ -187,9 +184,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
 	return rc;
 }
 
-u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
+u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
 {
-	struct controller *ctrl = (struct controller *) inst_id;
 	struct slot *p_slot;
 	u8 rc = 0;
 	struct event_info *taskInfo;
@@ -233,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
 
 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 {
-	/* Wait for exclusive access to hardware */
-	mutex_lock(&ctrl->ctrl_lock);
-
 	/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
 	if (POWER_CTRL(ctrl->ctrlcap)) {
 		if (pslot->hpc_ops->power_off_slot(pslot)) {   
-			err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__);
-			mutex_unlock(&ctrl->ctrl_lock);
+			err("%s: Issue of Slot Power Off command failed\n",
+			    __FUNCTION__);
 			return;
 		}
-		wait_for_ctrl_irq (ctrl);
 	}
 
-	if (PWR_LED(ctrl->ctrlcap)) {
+	if (PWR_LED(ctrl->ctrlcap))
 		pslot->hpc_ops->green_led_off(pslot);   
-		wait_for_ctrl_irq (ctrl);
-	}
 
-	if (ATTN_LED(ctrl->ctrlcap)) { 
-		if (pslot->hpc_ops->set_attention_status(pslot, 1)) {   
-			err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__);
-			mutex_unlock(&ctrl->ctrl_lock);
+	if (ATTN_LED(ctrl->ctrlcap)) {
+		if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
+			err("%s: Issue of Set Attention Led command failed\n",
+			    __FUNCTION__);
 			return;
 		}
-		wait_for_ctrl_irq (ctrl);
 	}
-
-	/* Done with exclusive hardware access */
-	mutex_unlock(&ctrl->ctrl_lock);
 }
 
 /**
@@ -274,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
 static int board_added(struct slot *p_slot)
 {
 	u8 hp_slot;
-	int rc = 0;
+	int retval = 0;
 	struct controller *ctrl = p_slot->ctrl;
 
 	hp_slot = p_slot->device - ctrl->slot_device_offset;
@@ -283,53 +269,38 @@ static int board_added(struct slot *p_slot)
 			__FUNCTION__, p_slot->device,
 			ctrl->slot_device_offset, hp_slot);
 
-	/* Wait for exclusive access to hardware */
-	mutex_lock(&ctrl->ctrl_lock);
-
 	if (POWER_CTRL(ctrl->ctrlcap)) {
 		/* Power on slot */
-		rc = p_slot->hpc_ops->power_on_slot(p_slot);
-		if (rc) {
-			mutex_unlock(&ctrl->ctrl_lock);
-			return -1;
-		}
-
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
+		retval = p_slot->hpc_ops->power_on_slot(p_slot);
+		if (retval)
+			return retval;
 	}
 	
-	if (PWR_LED(ctrl->ctrlcap)) {
+	if (PWR_LED(ctrl->ctrlcap))
 		p_slot->hpc_ops->green_led_blink(p_slot);
-			
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
-	}
-
-	/* Done with exclusive hardware access */
-	mutex_unlock(&ctrl->ctrl_lock);
 
 	/* Wait for ~1 second */
-	wait_for_ctrl_irq (ctrl);
+	msleep(1000);
 
-	/*  Check link training status */
-	rc = p_slot->hpc_ops->check_lnk_status(ctrl);  
-	if (rc) {
+	/* Check link training status */
+	retval = p_slot->hpc_ops->check_lnk_status(ctrl);
+	if (retval) {
 		err("%s: Failed to check link status\n", __FUNCTION__);
 		set_slot_off(ctrl, p_slot);
-		return rc;
+		return retval;
 	}
 
 	/* Check for a power fault */
 	if (p_slot->hpc_ops->query_power_fault(p_slot)) {
 		dbg("%s: power fault detected\n", __FUNCTION__);
-		rc = POWER_FAILURE;
+		retval = POWER_FAILURE;
 		goto err_exit;
 	}
 
-	rc = pciehp_configure_device(p_slot);
-	if (rc) {
+	retval = pciehp_configure_device(p_slot);
+	if (retval) {
 		err("Cannot add device 0x%x:%x\n", p_slot->bus,
-				p_slot->device);
+		    p_slot->device);
 		goto err_exit;
 	}
 
@@ -338,26 +309,16 @@ static int board_added(struct slot *p_slot)
 	 */
 	if (pcie_mch_quirk)
 		pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
-	if (PWR_LED(ctrl->ctrlcap)) {
-		/* Wait for exclusive access to hardware */
-  		mutex_lock(&ctrl->ctrl_lock);
-
+	if (PWR_LED(ctrl->ctrlcap))
   		p_slot->hpc_ops->green_led_on(p_slot);
-  
-  		/* Wait for the command to complete */
-  		wait_for_ctrl_irq (ctrl);
-  	
-  		/* Done with exclusive hardware access */
-  		mutex_unlock(&ctrl->ctrl_lock);
-  	}
+
 	return 0;
 
 err_exit:
 	set_slot_off(ctrl, p_slot);
-	return -1;
+	return retval;
 }
 
-
 /**
  * remove_board - Turns off slot and LED's
  *
@@ -366,44 +327,32 @@ static int remove_board(struct slot *p_slot)
 {
 	u8 device;
 	u8 hp_slot;
-	int rc;
+	int retval = 0;
 	struct controller *ctrl = p_slot->ctrl;
 
-	if (pciehp_unconfigure_device(p_slot))
-		return 1;
+	retval = pciehp_unconfigure_device(p_slot);
+	if (retval)
+		return retval;
 
 	device = p_slot->device;
-
 	hp_slot = p_slot->device - ctrl->slot_device_offset;
 	p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
 	dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
 
-	/* Wait for exclusive access to hardware */
-	mutex_lock(&ctrl->ctrl_lock);
-
 	if (POWER_CTRL(ctrl->ctrlcap)) {
 		/* power off slot */
-		rc = p_slot->hpc_ops->power_off_slot(p_slot);
-		if (rc) {
-			err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
-			mutex_unlock(&ctrl->ctrl_lock);
-			return rc;
+		retval = p_slot->hpc_ops->power_off_slot(p_slot);
+		if (retval) {
+			err("%s: Issue of Slot Disable command failed\n",
+			    __FUNCTION__);
+			return retval;
 		}
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
 	}
 
-	if (PWR_LED(ctrl->ctrlcap)) {
+	if (PWR_LED(ctrl->ctrlcap))
 		/* turn off Green LED */
 		p_slot->hpc_ops->green_led_off(p_slot);
-	
-		/* Wait for the command to complete */
-		wait_for_ctrl_irq (ctrl);
-	}
-
-	/* Done with exclusive hardware access */
-	mutex_unlock(&ctrl->ctrl_lock);
 
 	return 0;
 }
@@ -448,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot)
 		dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
 				p_slot->bus, p_slot->device);
 
-		if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
-			/* Wait for exclusive access to hardware */
-			mutex_lock(&p_slot->ctrl->ctrl_lock);
-
+		if (pciehp_enable_slot(p_slot) &&
+		    PWR_LED(p_slot->ctrl->ctrlcap))
 			p_slot->hpc_ops->green_led_off(p_slot);
 
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (p_slot->ctrl);
-
-			/* Done with exclusive hardware access */
-			mutex_unlock(&p_slot->ctrl->ctrl_lock);
-		}
 		p_slot->state = STATIC_STATE;
 	}
 
@@ -498,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
 		dbg("%s: adding bus:device(%x:%x)\n",
 				__FUNCTION__, p_slot->bus, p_slot->device);
 
-		if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
-			/* Wait for exclusive access to hardware */
-			mutex_lock(&p_slot->ctrl->ctrl_lock);
-
+		if (pciehp_enable_slot(p_slot) &&
+		    PWR_LED(p_slot->ctrl->ctrlcap))
 			p_slot->hpc_ops->green_led_off(p_slot);
 
-			/* Wait for the command to complete */
-			wait_for_ctrl_irq (p_slot->ctrl);
-
-			/* Done with exclusive hardware access */
-			mutex_unlock(&p_slot->ctrl->ctrl_lock);
-		}
 		p_slot->state = STATIC_STATE;
 	}
 
@@ -620,46 +553,24 @@ static void interrupt_event_handler(struct controller *ctrl)
 
 					switch (p_slot->state) {
 					case BLINKINGOFF_STATE:
-						/* Wait for exclusive access to hardware */
-						mutex_lock(&ctrl->ctrl_lock);
-						
-						if (PWR_LED(ctrl->ctrlcap)) {
+						if (PWR_LED(ctrl->ctrlcap))
 							p_slot->hpc_ops->green_led_on(p_slot);
-							/* Wait for the command to complete */
-							wait_for_ctrl_irq (ctrl);
-						}
-						if (ATTN_LED(ctrl->ctrlcap)) {
-							p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-							/* Wait for the command to complete */
-							wait_for_ctrl_irq (ctrl);
-						}
-						/* Done with exclusive hardware access */
-						mutex_unlock(&ctrl->ctrl_lock);
+						if (ATTN_LED(ctrl->ctrlcap))
+							p_slot->hpc_ops->set_attention_status(p_slot, 0);
 						break;
 					case BLINKINGON_STATE:
-						/* Wait for exclusive access to hardware */
-						mutex_lock(&ctrl->ctrl_lock);
-
-						if (PWR_LED(ctrl->ctrlcap)) {
+						if (PWR_LED(ctrl->ctrlcap))
 							p_slot->hpc_ops->green_led_off(p_slot);
-							/* Wait for the command to complete */
-							wait_for_ctrl_irq (ctrl);
-						}
-						if (ATTN_LED(ctrl->ctrlcap)){
-							p_slot->hpc_ops->set_attention_status(p_slot, 0);
-							/* Wait for the command to complete */
-							wait_for_ctrl_irq (ctrl);
-						}
-						/* Done with exclusive hardware access */
-						mutex_unlock(&ctrl->ctrl_lock);
 
+						if (ATTN_LED(ctrl->ctrlcap))
+							p_slot->hpc_ops->set_attention_status(p_slot, 0);
 						break;
 					default:
 						warn("Not a valid state\n");
 						return;
 					}
-					info(msg_button_cancel, slot_name(p_slot));
+					info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot));
 					p_slot->state = STATIC_STATE;
 				}
 				/* ***********Button Pressed (No action on 1st press...) */
@@ -672,34 +583,21 @@ static void interrupt_event_handler(struct controller *ctrl)
 							/* slot is on */
 							dbg("slot is on\n");
 							p_slot->state = BLINKINGOFF_STATE;
-							info(msg_button_off, slot_name(p_slot));
+							info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot));
 						} else {
 							/* slot is off */
 							dbg("slot is off\n");
 							p_slot->state = BLINKINGON_STATE;
-							info(msg_button_on, slot_name(p_slot));
+							info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot));
 						}
 
-						/* Wait for exclusive access to hardware */
-						mutex_lock(&ctrl->ctrl_lock);
-
 						/* blink green LED and turn off amber */
-						if (PWR_LED(ctrl->ctrlcap)) {
+						if (PWR_LED(ctrl->ctrlcap))
 							p_slot->hpc_ops->green_led_blink(p_slot);
-							/* Wait for the command to complete */
-							wait_for_ctrl_irq (ctrl);
-						}
 
-						if (ATTN_LED(ctrl->ctrlcap)) {
+						if (ATTN_LED(ctrl->ctrlcap))
 							p_slot->hpc_ops->set_attention_status(p_slot, 0);
 
-							/* Wait for the command to complete */
-							wait_for_ctrl_irq (ctrl);
-						}
-
-						/* Done with exclusive hardware access */
-						mutex_unlock(&ctrl->ctrl_lock);
-
 						init_timer(&p_slot->task_event);
 						p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
 						p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
@@ -712,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl)
 				else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
 					if (POWER_CTRL(ctrl->ctrlcap)) {
 						dbg("power fault\n");
-						/* Wait for exclusive access to hardware */
-						mutex_lock(&ctrl->ctrl_lock);
-
-						if (ATTN_LED(ctrl->ctrlcap)) {
+						if (ATTN_LED(ctrl->ctrlcap))
 							p_slot->hpc_ops->set_attention_status(p_slot, 1);
-							wait_for_ctrl_irq (ctrl);
-						}
 
-						if (PWR_LED(ctrl->ctrlcap)) {
+						if (PWR_LED(ctrl->ctrlcap))
 							p_slot->hpc_ops->green_led_off(p_slot);
-							wait_for_ctrl_irq (ctrl);
-						}
-
-						/* Done with exclusive hardware access */
-						mutex_unlock(&ctrl->ctrl_lock);
 					}
 				}
 				/***********SURPRISE REMOVAL********************/
@@ -754,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl)
 	}
 }
 
-
 int pciehp_enable_slot(struct slot *p_slot)
 {
 	u8 getstatus = 0;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 25d3aadfddbf..fbc64aa2dd68 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -35,6 +35,7 @@
 #include <linux/timer.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/time.h>
 
 #include "../pci.h"
 #include "pciehp.h"
@@ -105,34 +106,30 @@ enum ctrl_offsets {
 	ROOTCTRL	=	offsetof(struct ctrl_reg, root_ctrl),
 	ROOTSTATUS	=	offsetof(struct ctrl_reg, root_status),
 };
-static int pcie_cap_base = 0;		/* Base of the PCI Express capability item structure */ 
-
-#define PCIE_CAP_ID(cb)	( cb + PCIECAPID )
-#define NXT_CAP_PTR(cb)	( cb + NXTCAPPTR )
-#define CAP_REG(cb)	( cb + CAPREG )
-#define DEV_CAP(cb)	( cb + DEVCAP )
-#define DEV_CTRL(cb)	( cb + DEVCTRL )
-#define DEV_STATUS(cb)	( cb + DEVSTATUS )
-#define LNK_CAP(cb)	( cb + LNKCAP )
-#define LNK_CTRL(cb)	( cb + LNKCTRL )
-#define LNK_STATUS(cb)	( cb + LNKSTATUS )
-#define SLOT_CAP(cb)	( cb + SLOTCAP )
-#define SLOT_CTRL(cb)	( cb + SLOTCTRL )
-#define SLOT_STATUS(cb)	( cb + SLOTSTATUS )
-#define ROOT_CTRL(cb)	( cb + ROOTCTRL )
-#define ROOT_STATUS(cb)	( cb + ROOTSTATUS )
-
-#define hp_register_read_word(pdev, reg , value)		\
-	pci_read_config_word(pdev, reg, &value)
-
-#define hp_register_read_dword(pdev, reg , value)		\
-	pci_read_config_dword(pdev, reg, &value)
- 
-#define hp_register_write_word(pdev, reg , value)		\
-	pci_write_config_word(pdev, reg, value)
-
-#define hp_register_dwrite_word(pdev, reg , value)		\
-	pci_write_config_dword(pdev, reg, value)
+
+static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
+{
+	struct pci_dev *dev = ctrl->pci_dev;
+	return pci_read_config_word(dev, ctrl->cap_base + reg, value);
+}
+
+static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
+{
+	struct pci_dev *dev = ctrl->pci_dev;
+	return pci_read_config_dword(dev, ctrl->cap_base + reg, value);
+}
+
+static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
+{
+	struct pci_dev *dev = ctrl->pci_dev;
+	return pci_write_config_word(dev, ctrl->cap_base + reg, value);
+}
+
+static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
+{
+	struct pci_dev *dev = ctrl->pci_dev;
+	return pci_write_config_dword(dev, ctrl->cap_base + reg, value);
+}
 
 /* Field definitions in PCI Express Capabilities Register */
 #define CAP_VER			0x000F
@@ -196,6 +193,7 @@ static int pcie_cap_base = 0;		/* Base of the PCI Express capability item struct
 #define ATTN_LED_CTRL			0x00C0
 #define PWR_LED_CTRL			0x0300
 #define PWR_CTRL			0x0400
+#define EMI_CTRL			0x0800
 
 /* Attention indicator and Power indicator states */
 #define LED_ON		0x01
@@ -206,6 +204,10 @@ static int pcie_cap_base = 0;		/* Base of the PCI Express capability item struct
 #define POWER_ON	0
 #define POWER_OFF	0x0400
 
+/* EMI Status defines */
+#define EMI_DISENGAGED	0
+#define EMI_ENGAGED	1
+
 /* Field definitions in Slot Status Register */
 #define ATTN_BUTTN_PRESSED	0x0001
 #define PWR_FAULT_DETECTED	0x0002
@@ -214,114 +216,117 @@ static int pcie_cap_base = 0;		/* Base of the PCI Express capability item struct
 #define CMD_COMPLETED		0x0010
 #define MRL_STATE		0x0020
 #define PRSN_STATE		0x0040
+#define EMI_STATE		0x0080
+#define EMI_STATUS_BIT		7
 
 static spinlock_t hpc_event_lock;
 
 DEFINE_DBG_BUFFER		/* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
 static int ctlr_seq_num = 0;	/* Controller sequence # */
-static spinlock_t list_lock;
-
-static irqreturn_t pcie_isr(int IRQ, void *dev_id);
 
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
+static irqreturn_t pcie_isr(int irq, void *dev_id);
+static void start_int_poll_timer(struct controller *ctrl, int sec);
 
 /* This is the interrupt polling timeout function. */
-static void int_poll_timeout(unsigned long lphp_ctlr)
+static void int_poll_timeout(unsigned long data)
 {
-	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
+	struct controller *ctrl = (struct controller *)data;
 
 	DBG_ENTER_ROUTINE
 
-	if ( !php_ctlr ) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return;
-	}
-
 	/* Poll for interrupt events.  regs == NULL => polling */
-	pcie_isr( 0, (void *)php_ctlr );
-
-	init_timer(&php_ctlr->int_poll_timer);
+	pcie_isr(0, ctrl);
 
+	init_timer(&ctrl->poll_timer);
 	if (!pciehp_poll_time)
 		pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
 
-	start_int_poll_timer(php_ctlr, pciehp_poll_time);  
-	
-	return;
+	start_int_poll_timer(ctrl, pciehp_poll_time);
 }
 
 /* This function starts the interrupt polling timer. */
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
+static void start_int_poll_timer(struct controller *ctrl, int sec)
 {
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return;
-	}
+	/* Clamp to sane value */
+	if ((sec <= 0) || (sec > 60))
+        	sec = 2;
+
+	ctrl->poll_timer.function = &int_poll_timeout;
+	ctrl->poll_timer.data = (unsigned long)ctrl;
+	ctrl->poll_timer.expires = jiffies + sec * HZ;
+	add_timer(&ctrl->poll_timer);
+}
 
-	if ( ( seconds <= 0 ) || ( seconds > 60 ) )
-        	seconds = 2;            /* Clamp to sane value */
+static inline int pcie_wait_cmd(struct controller *ctrl)
+{
+	int retval = 0;
+	unsigned int msecs = pciehp_poll_mode ? 2500 : 1000;
+	unsigned long timeout = msecs_to_jiffies(msecs);
+	int rc;
 
-	php_ctlr->int_poll_timer.function = &int_poll_timeout;
-	php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;    /* Instance data */
-	php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
-	add_timer(&php_ctlr->int_poll_timer);
+	rc = wait_event_interruptible_timeout(ctrl->queue,
+					      !ctrl->cmd_busy, timeout);
+	if (!rc)
+		dbg("Command not completed in 1000 msec\n");
+	else if (rc < 0) {
+		retval = -EINTR;
+		info("Command was interrupted by a signal\n");
+	}
 
-	return;
+	return retval;
 }
 
 static int pcie_write_cmd(struct slot *slot, u16 cmd)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	int retval = 0;
 	u16 slot_status;
 
 	DBG_ENTER_ROUTINE 
-	
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
 
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
+	mutex_lock(&ctrl->ctrl_lock);
+
+	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (retval) {
-			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
-			return retval;
-		}
-	
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
+		goto out;
+	}
+
 	if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { 
-		/* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue 
-		   the next command according to spec.  Just print out the error message */
-		dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
+		/* After 1 sec and CMD_COMPLETED still not set, just
+		   proceed forward to issue the next command according
+		   to spec.  Just print out the error message */
+		dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
+		    __FUNCTION__);
 	}
 
-	retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
+	ctrl->cmd_busy = 1;
+	retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE));
 	if (retval) {
-		err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
-		return retval;
+		err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
+		goto out;
 	}
 
+	/*
+	 * Wait for command completion.
+	 */
+	retval = pcie_wait_cmd(ctrl);
+ out:
+	mutex_unlock(&ctrl->ctrl_lock);
 	DBG_LEAVE_ROUTINE 
 	return retval;
 }
 
 static int hpc_check_lnk_status(struct controller *ctrl)
 {
-	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
 	u16 lnk_status;
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-	
-	retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status);
-
+	retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
 	if (retval) {
-		err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -340,26 +345,21 @@ static int hpc_check_lnk_status(struct controller *ctrl)
 
 static int hpc_get_attention_status(struct slot *slot, u8 *status)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_ctrl;
 	u8 atten_led_state;
 	int retval = 0;
 	
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
-
+	retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (retval) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return retval;
 	}
 
-	dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
+	dbg("%s: SLOTCTRL %x, value read %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
 
 	atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
 
@@ -385,27 +385,22 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
 	return 0;
 }
 
-static int hpc_get_power_status(struct slot * slot, u8 *status)
+static int hpc_get_power_status(struct slot *slot, u8 *status)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_ctrl;
 	u8 pwr_state;
 	int	retval = 0;
 	
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
-
+	retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (retval) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return retval;
 	}
-	dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
+	dbg("%s: SLOTCTRL %x value read %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
 
 	pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
 
@@ -428,21 +423,15 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
 
 static int hpc_get_latch_status(struct slot *slot, u8 *status)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_status;
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
-
+	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (retval) {
-		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -454,22 +443,16 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
 
 static int hpc_get_adapter_status(struct slot *slot, u8 *status)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_status;
 	u8 card_state;
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
-
+	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (retval) {
-		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
 		return retval;
 	}
 	card_state = (u8)((slot_status & PRSN_STATE) >> 6);
@@ -479,24 +462,18 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
 	return 0;
 }
 
-static int hpc_query_power_fault(struct slot * slot)
+static int hpc_query_power_fault(struct slot *slot)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_status;
 	u8 pwr_fault;
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
-
+	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (retval) {
-		err("%s : Cannot check for power fault\n", __FUNCTION__);
+		err("%s: Cannot check for power fault\n", __FUNCTION__);
 		return retval;
 	}
 	pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
@@ -505,28 +482,63 @@ static int hpc_query_power_fault(struct slot * slot)
 	return pwr_fault;
 }
 
-static int hpc_set_attention_status(struct slot *slot, u8 value)
+static int hpc_get_emi_status(struct slot *slot, u8 *status)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
+	u16 slot_status;
+	int retval = 0;
+
+	DBG_ENTER_ROUTINE
+
+	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
+	if (retval) {
+		err("%s : Cannot check EMI status\n", __FUNCTION__);
+		return retval;
+	}
+	*status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT;
+
+	DBG_LEAVE_ROUTINE
+	return retval;
+}
+
+static int hpc_toggle_emi(struct slot *slot)
+{
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd = 0;
 	u16 slot_ctrl;
 	int rc = 0;
 
 	DBG_ENTER_ROUTINE
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
+	rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
+	if (rc) {
+		err("%s : hp_register_read_word SLOT_CTRL failed\n",
+			__FUNCTION__);
+		return rc;
 	}
 
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
+	slot_cmd = (slot_ctrl | EMI_CTRL);
+	if (!pciehp_poll_mode)
+		slot_cmd = slot_cmd | HP_INTR_ENABLE;
 
+	pcie_write_cmd(slot, slot_cmd);
+	slot->last_emi_toggle = get_seconds();
+	DBG_LEAVE_ROUTINE
+	return rc;
+}
+
+static int hpc_set_attention_status(struct slot *slot, u8 value)
+{
+	struct controller *ctrl = slot->ctrl;
+	u16 slot_cmd = 0;
+	u16 slot_ctrl;
+	int rc = 0;
+
+	DBG_ENTER_ROUTINE
+
+	rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return rc;
 	}
 
@@ -547,7 +559,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
 		slot_cmd = slot_cmd | HP_INTR_ENABLE; 
 
 	pcie_write_cmd(slot, slot_cmd);
-	dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+	dbg("%s: SLOTCTRL %x write cmd %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 	
 	DBG_LEAVE_ROUTINE
 	return rc;
@@ -556,27 +569,16 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
 
 static void hpc_set_green_led_on(struct slot *slot)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 slot_ctrl;
 	int rc = 0;
        	
 	DBG_ENTER_ROUTINE
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return ;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return ;
-	}
-
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
-
+	rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return;
 	}
 	slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
@@ -585,34 +587,24 @@ static void hpc_set_green_led_on(struct slot *slot)
 
 	pcie_write_cmd(slot, slot_cmd);
 
-	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+	dbg("%s: SLOTCTRL %x write cmd %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 	DBG_LEAVE_ROUTINE
 	return;
 }
 
 static void hpc_set_green_led_off(struct slot *slot)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 slot_ctrl;
 	int rc = 0;
 
 	DBG_ENTER_ROUTINE
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return ;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return ;
-	}
-
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
-
+	rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return;
 	}
 
@@ -621,7 +613,8 @@ static void hpc_set_green_led_off(struct slot *slot)
 	if (!pciehp_poll_mode)
 		slot_cmd = slot_cmd | HP_INTR_ENABLE; 
 	pcie_write_cmd(slot, slot_cmd);
-	dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+	dbg("%s: SLOTCTRL %x write cmd %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 
 	DBG_LEAVE_ROUTINE
 	return;
@@ -629,27 +622,16 @@ static void hpc_set_green_led_off(struct slot *slot)
 
 static void hpc_set_green_led_blink(struct slot *slot)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 slot_ctrl;
 	int rc = 0; 
 	
 	DBG_ENTER_ROUTINE
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return ;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return ;
-	}
-
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
-
+	rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return;
 	}
 
@@ -659,126 +641,54 @@ static void hpc_set_green_led_blink(struct slot *slot)
 		slot_cmd = slot_cmd | HP_INTR_ENABLE; 
 	pcie_write_cmd(slot, slot_cmd);
 
-	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+	dbg("%s: SLOTCTRL %x write cmd %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 	DBG_LEAVE_ROUTINE
 	return;
 }
 
-int pcie_get_ctlr_slot_config(struct controller *ctrl,
-	int *num_ctlr_slots,	/* number of slots in this HPC; only 1 in PCIE  */	
-	int *first_device_num,	/* PCI dev num of the first slot in this PCIE	*/
-	int *physical_slot_num,	/* phy slot num of the first slot in this PCIE	*/
-	u8 *ctrlcap)
-{
-	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
-	u32 slot_cap;
-	int rc = 0;
-	
-	DBG_ENTER_ROUTINE 
-
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	*first_device_num = 0;
-	*num_ctlr_slots = 1; 
-
-	rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
-
-	if (rc) {
-		err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
-		return -1;
-	}
-	
-	*physical_slot_num = slot_cap >> 19;
-	dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);
-	
-	*ctrlcap = slot_cap & 0x0000007f;
-
-	DBG_LEAVE_ROUTINE 
-	return 0;
-}
-
 static void hpc_release_ctlr(struct controller *ctrl)
 {
-	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
-	struct php_ctlr_state_s *p, *p_prev;
-
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return ;
-	}
-
-	if (pciehp_poll_mode) {
-	    del_timer(&php_ctlr->int_poll_timer);
-	} else {	
-		if (php_ctlr->irq) {
-			free_irq(php_ctlr->irq, ctrl);
-			php_ctlr->irq = 0;
-		}
-	}
-	if (php_ctlr->pci_dev) 
-		php_ctlr->pci_dev = NULL;
-
-	spin_lock(&list_lock);
-	p = php_ctlr_list_head;
-	p_prev = NULL;
-	while (p) {
-		if (p == php_ctlr) {
-			if (p_prev)
-				p_prev->pnext = p->pnext;
-			else
-				php_ctlr_list_head = p->pnext;
-			break;
-		} else {
-			p_prev = p;
-			p = p->pnext;
-		}
-	}
-	spin_unlock(&list_lock);
-
-	kfree(php_ctlr);
+	if (pciehp_poll_mode)
+		del_timer(&ctrl->poll_timer);
+	else
+		free_irq(ctrl->pci_dev->irq, ctrl);
 
 	DBG_LEAVE_ROUTINE
-			  
 }
 
 static int hpc_power_on_slot(struct slot * slot)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 slot_ctrl, slot_status;
-
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
 	dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
 
 	/* Clear sticky power-fault bit from previous power failures */
-	hp_register_read_word(php_ctlr->pci_dev,
-			SLOT_STATUS(slot->ctrl->cap_base), slot_status);
+	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
+	if (retval) {
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
+		return retval;
+	}
 	slot_status &= PWR_FAULT_DETECTED;
-	if (slot_status)
-		hp_register_write_word(php_ctlr->pci_dev,
-			SLOT_STATUS(slot->ctrl->cap_base), slot_status);
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
+	if (slot_status) {
+		retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status);
+		if (retval) {
+			err("%s: Cannot write to SLOTSTATUS register\n",
+			    __FUNCTION__);
+			return retval;
+		}
+	}
 
+	retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (retval) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -798,7 +708,8 @@ static int hpc_power_on_slot(struct slot * slot)
 		err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
 		return -1;
 	}
-	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+	dbg("%s: SLOTCTRL %x write cmd %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 
 	DBG_LEAVE_ROUTINE
 
@@ -807,29 +718,18 @@ static int hpc_power_on_slot(struct slot * slot)
 
 static int hpc_power_off_slot(struct slot * slot)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	u16 slot_cmd;
 	u16 slot_ctrl;
-
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
 	dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
-	slot->hp_slot = 0;
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
-	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
 
+	retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (retval) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -854,47 +754,25 @@ static int hpc_power_off_slot(struct slot * slot)
 		err("%s: Write command failed!\n", __FUNCTION__);
 		return -1;
 	}
-	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
+	dbg("%s: SLOTCTRL %x write cmd %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);
 
 	DBG_LEAVE_ROUTINE
 
 	return retval;
 }
 
-static irqreturn_t pcie_isr(int IRQ, void *dev_id)
+static irqreturn_t pcie_isr(int irq, void *dev_id)
 {
-	struct controller *ctrl = NULL;
-	struct php_ctlr_state_s *php_ctlr;
-	u8 schedule_flag = 0;
+	struct controller *ctrl = (struct controller *)dev_id;
 	u16 slot_status, intr_detect, intr_loc;
 	u16 temp_word;
 	int hp_slot = 0;	/* only 1 slot per PCI Express port */
 	int rc = 0;
 
-	if (!dev_id)
-		return IRQ_NONE;
-
-	if (!pciehp_poll_mode) { 
-		ctrl = dev_id;
-		php_ctlr = ctrl->hpc_ctlr_handle;
-	} else {
-		php_ctlr = dev_id;
-		ctrl = (struct controller *)php_ctlr->callback_instance_id;
-	}
-
-	if (!ctrl) {
-		dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id);
-		return IRQ_NONE;
-	}
-	
-	if (!php_ctlr) {
-		dbg("%s: php_ctlr == NULL\n", __FUNCTION__);
-		return IRQ_NONE;
-	}
-
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
+	rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
 		return IRQ_NONE;
 	}
 
@@ -910,33 +788,38 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id)
 	dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
 	/* Mask Hot-plug Interrupt Enable */
 	if (!pciehp_poll_mode) {
-		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
+		rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
 		if (rc) {
-			err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+			err("%s: Cannot read SLOT_CTRL register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
 
-		dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
+		dbg("%s: pciehp_readw(SLOTCTRL) with value %x\n",
+		    __FUNCTION__, temp_word);
 		temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
-
-		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
+		rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
 		if (rc) {
-			err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
+			err("%s: Cannot write to SLOTCTRL register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
-		
-		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
+
+		rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 		if (rc) {
-			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+			err("%s: Cannot read SLOT_STATUS register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
-		dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); 
+		dbg("%s: pciehp_readw(SLOTSTATUS) with value %x\n",
+		    __FUNCTION__, slot_status);
 		
 		/* Clear command complete interrupt caused by this write */
 		temp_word = 0x1f;
-		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
+		rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
 		if (rc) {
-			err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+			err("%s: Cannot write to SLOTSTATUS register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
 	}
@@ -945,60 +828,65 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id)
 		/* 
 		 * Command Complete Interrupt Pending 
 		 */
+		ctrl->cmd_busy = 0;
 		wake_up_interruptible(&ctrl->queue);
 	}
 
-	if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED))
-		schedule_flag += php_ctlr->switch_change_callback(
-			hp_slot, php_ctlr->callback_instance_id);
-	if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED))
-		schedule_flag += php_ctlr->attention_button_callback(
-			hp_slot, php_ctlr->callback_instance_id);
-	if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED))
-		schedule_flag += php_ctlr->presence_change_callback(
-			hp_slot , php_ctlr->callback_instance_id);
-	if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED))
-		schedule_flag += php_ctlr->power_fault_callback(
-			hp_slot, php_ctlr->callback_instance_id);
+	if (intr_loc & MRL_SENS_CHANGED)
+		pciehp_handle_switch_change(hp_slot, ctrl);
+
+	if (intr_loc & ATTN_BUTTN_PRESSED)
+		pciehp_handle_attention_button(hp_slot, ctrl);
+
+	if (intr_loc & PRSN_DETECT_CHANGED)
+		pciehp_handle_presence_change(hp_slot, ctrl);
+
+	if (intr_loc & PWR_FAULT_DETECTED)
+		pciehp_handle_power_fault(hp_slot, ctrl);
 
 	/* Clear all events after serving them */
 	temp_word = 0x1F;
-	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
+	rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
 	if (rc) {
-		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
 		return IRQ_NONE;
 	}
 	/* Unmask Hot-plug Interrupt Enable */
 	if (!pciehp_poll_mode) {
-		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
+		rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
 		if (rc) {
-			err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+			err("%s: Cannot read SLOTCTRL register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
 
 		dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
 		temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
 
-		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
+		rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
 		if (rc) {
-			err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
+			err("%s: Cannot write to SLOTCTRL register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
-	
-		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
+
+		rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 		if (rc) {
-			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+			err("%s: Cannot read SLOT_STATUS register\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
 		
 		/* Clear command complete interrupt caused by this write */
 		temp_word = 0x1F;
-		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
+		rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
 		if (rc) {
-			err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+			err("%s: Cannot write to SLOTSTATUS failed\n",
+			    __FUNCTION__);
 			return IRQ_NONE;
 		}
-		dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); 
+		dbg("%s: pciehp_writew(SLOTSTATUS) with value %x\n",
+		    __FUNCTION__, temp_word);
 	}
 	
 	return IRQ_HANDLED;
@@ -1006,27 +894,16 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id)
 
 static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	enum pcie_link_speed lnk_speed;
 	u32	lnk_cap;
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
-
+	retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
 	if (retval) {
-		err("%s : hp_register_read_dword  LNK_CAP failed\n", __FUNCTION__);
+		err("%s: Cannot read LNKCAP register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -1047,27 +924,16 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
 
 static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	enum pcie_link_width lnk_wdth;
 	u32	lnk_cap;
 	int retval = 0;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
-
+	retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
 	if (retval) {
-		err("%s : hp_register_read_dword  LNK_CAP failed\n", __FUNCTION__);
+		err("%s: Cannot read LNKCAP register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -1109,27 +975,16 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value
 
 static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
 	int retval = 0;
 	u16 lnk_status;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
-
+	retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
 	if (retval) {
-		err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__);
 		return retval;
 	}
 
@@ -1150,27 +1005,16 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
 
 static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value)
 {
-	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+	struct controller *ctrl = slot->ctrl;
 	enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
 	int retval = 0;
 	u16 lnk_status;
 
 	DBG_ENTER_ROUTINE 
 
-	if (!php_ctlr) {
-		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
-		return -1;
-	}
-
-	if (slot->hp_slot >= php_ctlr->num_slots) {
-		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
-		return -1;
-	}
-
-	retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
-
+	retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
 	if (retval) {
-		err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__);
 		return retval;
 	}
 	
@@ -1218,6 +1062,8 @@ static struct hpc_ops pciehp_hpc_ops = {
 	.get_attention_status		= hpc_get_attention_status,
 	.get_latch_status		= hpc_get_latch_status,
 	.get_adapter_status		= hpc_get_adapter_status,
+	.get_emi_status			= hpc_get_emi_status,
+	.toggle_emi			= hpc_toggle_emi,
 
 	.get_max_bus_speed		= hpc_get_max_lnk_speed,
 	.get_cur_bus_speed		= hpc_get_cur_lnk_speed,
@@ -1305,38 +1151,24 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
 
 int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 {
-	struct php_ctlr_state_s *php_ctlr, *p;
-	void *instance_id = ctrl;
 	int rc;
 	static int first = 1;
 	u16 temp_word;
 	u16 cap_reg;
 	u16 intr_enable = 0;
 	u32 slot_cap;
-	int cap_base, saved_cap_base;
+	int cap_base;
 	u16 slot_status, slot_ctrl;
 	struct pci_dev *pdev;
 
 	DBG_ENTER_ROUTINE
 	
-	spin_lock_init(&list_lock);	
-	php_ctlr = kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
-
-	if (!php_ctlr) {	/* allocate controller state data */
-		err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
-		goto abort;
-	}
-
-	memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
-	
 	pdev = dev->port;
-	php_ctlr->pci_dev = pdev;	/* save pci_dev in context */
+	ctrl->pci_dev = pdev;	/* save pci_dev in context */
 
 	dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
 			__FUNCTION__, pdev->vendor, pdev->device);
 
-	saved_cap_base = pcie_cap_base;
-
 	if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) {
 		dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
 		goto abort_free_ctlr;
@@ -1344,14 +1176,15 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 
 	ctrl->cap_base = cap_base;
 
-	dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
+	dbg("%s: pcie_cap_base %x\n", __FUNCTION__, cap_base);
 
-	rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg);
+	rc = pciehp_readw(ctrl, CAPREG, &cap_reg);
 	if (rc) {
-		err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
+		err("%s: Cannot read CAPREG register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
-	dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg);
+	dbg("%s: CAPREG offset %x cap_reg %x\n",
+	    __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg);
 
 	if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040)
 		&& ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
@@ -1359,31 +1192,34 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 		goto abort_free_ctlr;
 	}
 
-	rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
+	rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap);
 	if (rc) {
-		err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCAP register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
-	dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap);
+	dbg("%s: SLOTCAP offset %x slot_cap %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap);
 
 	if (!(slot_cap & HP_CAP)) {
 		dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
 	/* For debugging purpose */
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
+	rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
-	dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status);
+	dbg("%s: SLOTSTATUS offset %x slot_status %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status);
 
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
+	rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
-	dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
+	dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
 
 	if (first) {
 		spin_lock_init(&hpc_event_lock);
@@ -1405,69 +1241,64 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 	/* setup wait queue */
 	init_waitqueue_head(&ctrl->queue);
 
-	/* find the IRQ */
-	php_ctlr->irq = dev->irq;
-
-	/* Save interrupt callback info */
-	php_ctlr->attention_button_callback = pciehp_handle_attention_button;
-	php_ctlr->switch_change_callback = pciehp_handle_switch_change;
-	php_ctlr->presence_change_callback = pciehp_handle_presence_change;
-	php_ctlr->power_fault_callback = pciehp_handle_power_fault;
-	php_ctlr->callback_instance_id = instance_id;
-
 	/* return PCI Controller Info */
-	php_ctlr->slot_device_offset = 0;
-	php_ctlr->num_slots = 1;
+	ctrl->slot_device_offset = 0;
+	ctrl->num_slots = 1;
+	ctrl->first_slot = slot_cap >> 19;
+	ctrl->ctrlcap = slot_cap & 0x0000007f;
 
 	/* Mask Hot-plug Interrupt Enable */
-	rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
+	rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
 
-	dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
+	dbg("%s: SLOTCTRL %x value read %x\n",
+	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word);
 	temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
 
-	rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
+	rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
 	if (rc) {
-		err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
 
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
+	rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
 
 	temp_word = 0x1F; /* Clear all events */
-	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
+	rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
 	if (rc) {
-		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
 		goto abort_free_ctlr;
 	}
 
-	if (pciehp_poll_mode)  {/* Install interrupt polling code */
-		/* Install and start the interrupt polling timer */
-		init_timer(&php_ctlr->int_poll_timer);
-		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
+	if (pciehp_poll_mode) {
+		/* Install interrupt polling timer. Start with 10 sec delay */
+		init_timer(&ctrl->poll_timer);
+		start_int_poll_timer(ctrl, 10);
 	} else {
 		/* Installs the interrupt handler */
-		rc = request_irq(php_ctlr->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
-		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
+		rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED,
+				 MY_NAME, (void *)ctrl);
+		dbg("%s: request_irq %d for hpc%d (returns %d)\n",
+		    __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc);
 		if (rc) {
-			err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
+			err("Can't get irq %d for the hotplug controller\n",
+			    ctrl->pci_dev->irq);
 			goto abort_free_ctlr;
 		}
 	}
-
 	dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
 		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
 
-	rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
+	rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
 		goto abort_free_irq;
 	}
 
@@ -1491,21 +1322,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 	}
 
 	/* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
-	rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
+	rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
 	if (rc) {
-		err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
+		err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__);
 		goto abort_free_irq;
 	}
-	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
+	rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
 	if (rc) {
-		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);
 		goto abort_disable_intr;
 	}
 	
 	temp_word =  0x1F; /* Clear all events */
-	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
+	rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);
 	if (rc) {
-		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
+		err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);
 		goto abort_disable_intr;
 	}
 	
@@ -1518,24 +1349,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 			goto abort_disable_intr;
 	}
 
-	/*  Add this HPC instance into the HPC list */
-	spin_lock(&list_lock);
-	if (php_ctlr_list_head == 0) {
-		php_ctlr_list_head = php_ctlr;
-		p = php_ctlr_list_head;
-		p->pnext = NULL;
-	} else {
-		p = php_ctlr_list_head;
-
-		while (p->pnext)
-			p = p->pnext;
-
-		p->pnext = php_ctlr;
-	}
-	spin_unlock(&list_lock);
-
 	ctlr_seq_num++;
-	ctrl->hpc_ctlr_handle = php_ctlr;
 	ctrl->hpc_ops = &pciehp_hpc_ops;
 
 	DBG_LEAVE_ROUTINE
@@ -1543,24 +1357,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
 
 	/* We end up here for the many possible ways to fail this API.  */
 abort_disable_intr:
-	rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
+	rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
 	if (!rc) {
 		temp_word &= ~(intr_enable | HP_INTR_ENABLE);
-		rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
+		rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);
 	}
 	if (rc)
 		err("%s : disabling interrupts failed\n", __FUNCTION__);
 
 abort_free_irq:
 	if (pciehp_poll_mode)
-		del_timer_sync(&php_ctlr->int_poll_timer);
+		del_timer_sync(&ctrl->poll_timer);
 	else
-		free_irq(php_ctlr->irq, ctrl);
+		free_irq(ctrl->pci_dev->irq, ctrl);
 
 abort_free_ctlr:
-	pcie_cap_base = saved_cap_base;
-	kfree(php_ctlr);
-abort:
 	DBG_LEAVE_ROUTINE
 	return -1;
 }
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 3ca6a4f574b3..01d31a1f697c 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -106,7 +106,7 @@ struct controller {
 };
 
 /* Define AMD SHPC ID  */
-#define PCI_DEVICE_ID_AMD_GOLAM_7450	0x7450 
+#define PCI_DEVICE_ID_AMD_GOLAM_7450	0x7450
 #define PCI_DEVICE_ID_AMD_POGO_7458	0x7458
 
 /* AMD PCIX bridge registers */
@@ -221,7 +221,7 @@ enum ctrl_offsets {
 };
 
 static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
-{ 
+{
 	return hotplug_slot->private;
 }
 
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 590cd3cbe010..5f4bc08a633a 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -401,10 +401,6 @@ static int __init shpcd_init(void)
 {
 	int retval = 0;
 
-#ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
-	shpchp_poll_mode = 1;
-#endif
-
 	retval = pci_register_driver(&shpc_driver);
 	dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
 	info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 6bb84734cd6c..b746bd265bc6 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -64,7 +64,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
 
 	/* Attention Button Change */
 	dbg("shpchp:  Attention button interrupt received.\n");
-	
+
 	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
 
@@ -128,7 +128,7 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
 
 	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
 
-	/* 
+	/*
 	 * Save the presence state
 	 */
 	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
@@ -184,12 +184,12 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
 	return 1;
 }
 
-/* The following routines constitute the bulk of the 
+/* The following routines constitute the bulk of the
    hotplug controller logic
  */
 static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
 		enum pci_bus_speed speed)
-{ 
+{
 	int rc = 0;
 
 	dbg("%s: change to speed %d\n", __FUNCTION__, speed);
@@ -204,7 +204,7 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
 static int 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)
-{ 
+{
 	int rc = 0;
 
 	/*
@@ -257,23 +257,23 @@ static int board_added(struct slot *p_slot)
 		err("%s: Failed to power on slot\n", __FUNCTION__);
 		return -1;
 	}
-	
+
 	if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
 		if (slots_not_empty)
 			return WRONG_BUS_FREQUENCY;
-		
+
 		if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
 			err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
 			return WRONG_BUS_FREQUENCY;
 		}
-		
+
 		/* turn on board, blink green LED, turn off Amber LED */
 		if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
 			err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
 			return rc;
 		}
 	}
- 
+
 	rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp);
 	if (rc) {
 		err("%s: Can't get adapter speed or bus mode mismatch\n",
@@ -378,7 +378,7 @@ static int remove_board(struct slot *p_slot)
 		err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
 		return rc;
 	}
-	
+
 	rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
 	if (rc) {
 		err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index b7bede4b7c27..5183a45d45b5 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -35,38 +35,6 @@
 
 #include "shpchp.h"
 
-#ifdef DEBUG
-#define DBG_K_TRACE_ENTRY      ((unsigned int)0x00000001)	/* On function entry */
-#define DBG_K_TRACE_EXIT       ((unsigned int)0x00000002)	/* On function exit */
-#define DBG_K_INFO             ((unsigned int)0x00000004)	/* Info messages */
-#define DBG_K_ERROR            ((unsigned int)0x00000008)	/* Error messages */
-#define DBG_K_TRACE            (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
-#define DBG_K_STANDARD         (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
-/* Redefine this flagword to set debug level */
-#define DEBUG_LEVEL            DBG_K_STANDARD
-
-#define DEFINE_DBG_BUFFER     char __dbg_str_buf[256];
-
-#define DBG_PRINT( dbg_flags, args... )              \
-	do {                                             \
-	  if ( DEBUG_LEVEL & ( dbg_flags ) )             \
-	  {                                              \
-	    int len;                                     \
-	    len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
-		  __FILE__, __LINE__, __FUNCTION__ );    \
-	    sprintf( __dbg_str_buf + len, args );        \
-	    printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
-	  }                                              \
-	} while (0)
-
-#define DBG_ENTER_ROUTINE	DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
-#define DBG_LEAVE_ROUTINE	DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
-#else
-#define DEFINE_DBG_BUFFER
-#define DBG_ENTER_ROUTINE
-#define DBG_LEAVE_ROUTINE
-#endif				/* DEBUG */
-
 /* Slot Available Register I field definition */
 #define SLOT_33MHZ		0x0000001f
 #define SLOT_66MHZ_PCIX		0x00001f00
@@ -211,7 +179,6 @@
 #define SLOT_EVENT_LATCH	0x2
 #define SLOT_SERR_INT_MASK	0x3
 
-DEFINE_DBG_BUFFER		/* Debug string buffer for entire HPC defined here */
 static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
 
 static irqreturn_t shpc_isr(int irq, void *dev_id);
@@ -268,8 +235,6 @@ static void int_poll_timeout(unsigned long data)
 {
 	struct controller *ctrl = (struct controller *)data;
 
-	DBG_ENTER_ROUTINE
-
 	/* Poll for interrupt events.  regs == NULL => polling */
 	shpc_isr(0, ctrl);
 
@@ -278,8 +243,6 @@ static void int_poll_timeout(unsigned long data)
 		shpchp_poll_time = 2; /* default polling interval is 2 sec */
 
 	start_int_poll_timer(ctrl, shpchp_poll_time);
-
-	DBG_LEAVE_ROUTINE
 }
 
 /*
@@ -353,8 +316,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
 	int retval = 0;
 	u16 temp_word;
 
-	DBG_ENTER_ROUTINE 
-
 	mutex_lock(&slot->ctrl->cmd_lock);
 
 	if (!shpc_poll_ctrl_busy(ctrl)) {
@@ -368,9 +329,9 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
 	++t_slot;
 	temp_word =  (t_slot << 8) | (cmd & 0xFF);
 	dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd);
-	
+
 	/* To make sure the Controller Busy bit is 0 before we send out the
-	 * command. 
+	 * command.
 	 */
 	shpc_writew(ctrl, CMD, temp_word);
 
@@ -389,20 +350,14 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
 	}
  out:
 	mutex_unlock(&slot->ctrl->cmd_lock);
-
-	DBG_LEAVE_ROUTINE 
 	return retval;
 }
 
 static int hpc_check_cmd_status(struct controller *ctrl)
 {
-	u16 cmd_status;
 	int retval = 0;
+	u16 cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F;
 
-	DBG_ENTER_ROUTINE 
-
-	cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F;
-	
 	switch (cmd_status >> 1) {
 	case 0:
 		retval = 0;
@@ -423,7 +378,6 @@ static int hpc_check_cmd_status(struct controller *ctrl)
 		retval = cmd_status;
 	}
 
-	DBG_LEAVE_ROUTINE 
 	return retval;
 }
 
@@ -431,13 +385,8 @@ static int hpc_check_cmd_status(struct controller *ctrl)
 static int hpc_get_attention_status(struct slot *slot, u8 *status)
 {
 	struct controller *ctrl = slot->ctrl;
-	u32 slot_reg;
-	u8 state;
-	
-	DBG_ENTER_ROUTINE 
-
-	slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
-	state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT;
+	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
+	u8 state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT;
 
 	switch (state) {
 	case ATN_LED_STATE_ON:
@@ -454,20 +403,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
 		break;
 	}
 
-	DBG_LEAVE_ROUTINE 
 	return 0;
 }
 
 static int hpc_get_power_status(struct slot * slot, u8 *status)
 {
 	struct controller *ctrl = slot->ctrl;
-	u32 slot_reg;
-	u8 state;
-	
-	DBG_ENTER_ROUTINE 
-
-	slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
-	state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT;
+	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
+	u8 state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT;
 
 	switch (state) {
 	case SLOT_STATE_PWRONLY:
@@ -484,7 +427,6 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
 		break;
 	}
 
-	DBG_LEAVE_ROUTINE 
 	return 0;
 }
 
@@ -492,30 +434,21 @@ static int hpc_get_power_status(struct slot * slot, u8 *status)
 static int hpc_get_latch_status(struct slot *slot, u8 *status)
 {
 	struct controller *ctrl = slot->ctrl;
-	u32 slot_reg;
-
-	DBG_ENTER_ROUTINE 
+	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
 
-	slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
 	*status = !!(slot_reg & MRL_SENSOR);	/* 0 -> close; 1 -> open */
 
-	DBG_LEAVE_ROUTINE 
 	return 0;
 }
 
 static int hpc_get_adapter_status(struct slot *slot, u8 *status)
 {
 	struct controller *ctrl = slot->ctrl;
-	u32 slot_reg;
-	u8 state;
-
-	DBG_ENTER_ROUTINE 
+	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
+	u8 state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT;
 
-	slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
-	state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT;
 	*status = (state != 0x3) ? 1 : 0;
 
-	DBG_LEAVE_ROUTINE 
 	return 0;
 }
 
@@ -523,11 +456,8 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
 {
 	struct controller *ctrl = slot->ctrl;
 
-	DBG_ENTER_ROUTINE 
-
 	*prog_int = shpc_readb(ctrl, PROG_INTERFACE);
 
-	DBG_LEAVE_ROUTINE 
 	return 0;
 }
 
@@ -539,8 +469,6 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
 	u8 m66_cap  = !!(slot_reg & MHZ66_CAP);
 	u8 pi, pcix_cap;
 
-	DBG_ENTER_ROUTINE 
-
 	if ((retval = hpc_get_prog_int(slot, &pi)))
 		return retval;
 
@@ -582,21 +510,15 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
 	}
 
 	dbg("Adapter speed = %d\n", *value);
-	DBG_LEAVE_ROUTINE 
 	return retval;
 }
 
 static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
 {
-	struct controller *ctrl = slot->ctrl;
-	u16 sec_bus_status;
-	u8 pi;
 	int retval = 0;
-
-	DBG_ENTER_ROUTINE 
-
-	pi = shpc_readb(ctrl, PROG_INTERFACE);
-	sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG);
+	struct controller *ctrl = slot->ctrl;
+	u16 sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG);
+	u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
 
 	if (pi == 2) {
 		*mode = (sec_bus_status & 0x0100) >> 8;
@@ -605,21 +527,14 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
 	}
 
 	dbg("Mode 1 ECC cap = %d\n", *mode);
-	
-	DBG_LEAVE_ROUTINE 
 	return retval;
 }
 
 static int hpc_query_power_fault(struct slot * slot)
 {
 	struct controller *ctrl = slot->ctrl;
-	u32 slot_reg;
-
-	DBG_ENTER_ROUTINE 
-
-	slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
+	u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
 
-	DBG_LEAVE_ROUTINE
 	/* Note: Logic 0 => fault */
 	return !(slot_reg & POWER_FAULT);
 }
@@ -629,7 +544,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
 	u8 slot_cmd = 0;
 
 	switch (value) {
-		case 0 :	
+		case 0 :
 			slot_cmd = SET_ATTN_OFF;	/* OFF */
 			break;
 		case 1:
@@ -666,8 +581,6 @@ static void hpc_release_ctlr(struct controller *ctrl)
 	int i;
 	u32 slot_reg, serr_int;
 
-	DBG_ENTER_ROUTINE 
-
 	/*
 	 * Mask event interrupts and SERRs of all slots
 	 */
@@ -708,61 +621,43 @@ static void hpc_release_ctlr(struct controller *ctrl)
 	 */
 	if (atomic_dec_and_test(&shpchp_num_controllers))
 		destroy_workqueue(shpchp_wq);
-
-	DBG_LEAVE_ROUTINE
 }
 
 static int hpc_power_on_slot(struct slot * slot)
 {
 	int retval;
 
-	DBG_ENTER_ROUTINE 
-
 	retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR);
-	if (retval) {
+	if (retval)
 		err("%s: Write command failed!\n", __FUNCTION__);
-		return retval;
-	}
-
-	DBG_LEAVE_ROUTINE
 
-	return 0;
+	return retval;
 }
 
 static int hpc_slot_enable(struct slot * slot)
 {
 	int retval;
 
-	DBG_ENTER_ROUTINE 
-
 	/* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */
 	retval = shpc_write_cmd(slot, slot->hp_slot,
 			SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF);
-	if (retval) {
+	if (retval)
 		err("%s: Write command failed!\n", __FUNCTION__);
-		return retval;
-	}
 
-	DBG_LEAVE_ROUTINE
-	return 0;
+	return retval;
 }
 
 static int hpc_slot_disable(struct slot * slot)
 {
 	int retval;
 
-	DBG_ENTER_ROUTINE 
-
 	/* Slot - Disable, Power Indicator - Off, Attention Indicator - On */
 	retval = shpc_write_cmd(slot, slot->hp_slot,
 			SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON);
-	if (retval) {
+	if (retval)
 		err("%s: Write command failed!\n", __FUNCTION__);
-		return retval;
-	}
 
-	DBG_LEAVE_ROUTINE
-	return 0;
+	return retval;
 }
 
 static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
@@ -771,8 +666,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
 	struct controller *ctrl = slot->ctrl;
 	u8 pi, cmd;
 
-	DBG_ENTER_ROUTINE 
-
 	pi = shpc_readb(ctrl, PROG_INTERFACE);
 	if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX))
 		return -EINVAL;
@@ -828,7 +721,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
 	if (retval)
 		err("%s: Write command failed!\n", __FUNCTION__);
 
-	DBG_LEAVE_ROUTINE
 	return retval;
 }
 
@@ -843,7 +735,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
 	if (!intr_loc)
 		return IRQ_NONE;
 
-	dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); 
+	dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
 
 	if(!shpchp_poll_mode) {
 		/*
@@ -856,12 +748,12 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
 		shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
 
 		intr_loc2 = shpc_readl(ctrl, INTR_LOC);
-		dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 
+		dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
 	}
 
 	if (intr_loc & CMD_INTR_PENDING) {
-		/* 
-		 * Command Complete Interrupt Pending 
+		/*
+		 * Command Complete Interrupt Pending
 		 * RO only - clear by writing 1 to the Command Completion
 		 * Detect bit in Controller SERR-INT register
 		 */
@@ -875,7 +767,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
 	if (!(intr_loc & ~CMD_INTR_PENDING))
 		goto out;
 
-	for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { 
+	for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
 		/* To find out which slot has interrupt pending */
 		if (!(intr_loc & SLOT_INTR_PENDING(hp_slot)))
 			continue;
@@ -907,7 +799,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
 		serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
 		shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
 	}
-	
+
 	return IRQ_HANDLED;
 }
 
@@ -920,8 +812,6 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 	u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1);
 	u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2);
 
-	DBG_ENTER_ROUTINE 
-
 	if (pi == 2) {
 		if (slot_avail2 & SLOT_133MHZ_PCIX_533)
 			bus_speed = PCI_SPEED_133MHz_PCIX_533;
@@ -954,7 +844,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 
 	*value = bus_speed;
 	dbg("Max bus speed = %d\n", bus_speed);
-	DBG_LEAVE_ROUTINE 
+
 	return retval;
 }
 
@@ -967,8 +857,6 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 	u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
 	u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7);
 
-	DBG_ENTER_ROUTINE 
-
 	if ((pi == 1) && (speed_mode > 4)) {
 		*value = PCI_SPEED_UNKNOWN;
 		return -ENODEV;
@@ -1024,7 +912,6 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
 	}
 
 	dbg("Current bus speed = %d\n", bus_speed);
-	DBG_LEAVE_ROUTINE 
 	return retval;
 }
 
@@ -1032,7 +919,7 @@ static struct hpc_ops shpchp_hpc_ops = {
 	.power_on_slot			= hpc_power_on_slot,
 	.slot_enable			= hpc_slot_enable,
 	.slot_disable			= hpc_slot_disable,
-	.set_bus_speed_mode		= hpc_set_bus_speed_mode,	  
+	.set_bus_speed_mode		= hpc_set_bus_speed_mode,
 	.set_attention_status	= hpc_set_attention_status,
 	.get_power_status		= hpc_get_power_status,
 	.get_attention_status	= hpc_get_attention_status,
@@ -1049,7 +936,7 @@ static struct hpc_ops shpchp_hpc_ops = {
 	.green_led_on			= hpc_set_green_led_on,
 	.green_led_off			= hpc_set_green_led_off,
 	.green_led_blink		= hpc_set_green_led_blink,
-	
+
 	.release_ctlr			= hpc_release_ctlr,
 };
 
@@ -1061,8 +948,6 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 	u32 tempdword, slot_reg, slot_config;
 	u8 i;
 
-	DBG_ENTER_ROUTINE
-
 	ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
 
 	if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
@@ -1108,9 +993,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 		ctrl->mmio_size = 0x24 + 0x4 * num_slots;
 	}
 
-	info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, 
+	info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor,
 		pdev->subsystem_device);
-	
+
 	rc = pci_enable_device(pdev);
 	if (rc) {
 		err("%s: pci_enable_device failed\n", __FUNCTION__);
@@ -1172,7 +1057,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 		slot_reg &= ~SLOT_REG_RSVDZ_MASK;
 		shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
 	}
-	
+
 	if (shpchp_poll_mode) {
 		/* Install interrupt polling timer. Start with 10 sec delay */
 		init_timer(&ctrl->poll_timer);
@@ -1184,7 +1069,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 			info("Can't get msi for the hotplug controller\n");
 			info("Use INTx for the hotplug controller\n");
 		}
-		
+
 		rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
 				 MY_NAME, (void *)ctrl);
 		dbg("%s: request_irq %d for hpc%d (returns %d)\n",
@@ -1235,13 +1120,11 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 		dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
 	}
 
-	DBG_LEAVE_ROUTINE
 	return 0;
 
 	/* We end up here for the many possible ways to fail this API.  */
 abort_iounmap:
 	iounmap(ctrl->creg);
 abort:
-	DBG_LEAVE_ROUTINE
 	return rc;
 }
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index ed3f7e1a563c..68555c11f556 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -24,8 +24,6 @@
 #include "pci.h"
 #include "msi.h"
 
-static DEFINE_SPINLOCK(msi_lock);
-static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static struct kmem_cache* msi_cachep;
 
 static int pci_msi_enable = 1;
@@ -44,13 +42,13 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
 {
 	struct msi_desc *entry;
 
-	entry = msi_desc[irq];
+	entry = get_irq_msi(irq);
 	BUG_ON(!entry || !entry->dev);
 	switch (entry->msi_attrib.type) {
 	case PCI_CAP_ID_MSI:
 		if (entry->msi_attrib.maskbit) {
-			int		pos;
-			u32		mask_bits;
+			int pos;
+			u32 mask_bits;
 
 			pos = (long)entry->mask_base;
 			pci_read_config_dword(entry->dev, pos, &mask_bits);
@@ -74,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
 
 void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-	struct msi_desc *entry = get_irq_data(irq);
+	struct msi_desc *entry = get_irq_msi(irq);
 	switch(entry->msi_attrib.type) {
 	case PCI_CAP_ID_MSI:
 	{
@@ -113,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 
 void write_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-	struct msi_desc *entry = get_irq_data(irq);
+	struct msi_desc *entry = get_irq_msi(irq);
 	switch (entry->msi_attrib.type) {
 	case PCI_CAP_ID_MSI:
 	{
@@ -162,6 +160,7 @@ void unmask_msi_irq(unsigned int irq)
 }
 
 static int msi_free_irq(struct pci_dev* dev, int irq);
+
 static int msi_init(void)
 {
 	static int status = -ENOMEM;
@@ -169,13 +168,6 @@ static int msi_init(void)
 	if (!status)
 		return status;
 
-	if (pci_msi_quirk) {
-		pci_msi_enable = 0;
-		printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n");
-		status = -EINVAL;
-		return status;
-	}
-
 	status = msi_cache_init();
 	if (status < 0) {
 		pci_msi_enable = 0;
@@ -200,46 +192,6 @@ static struct msi_desc* alloc_msi_entry(void)
 	return entry;
 }
 
-static void attach_msi_entry(struct msi_desc *entry, int irq)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	msi_desc[irq] = entry;
-	spin_unlock_irqrestore(&msi_lock, flags);
-}
-
-static int create_msi_irq(void)
-{
-	struct msi_desc *entry;
-	int irq;
-
-	entry = alloc_msi_entry();
-	if (!entry)
-		return -ENOMEM;
-
-	irq = create_irq();
-	if (irq < 0) {
-		kmem_cache_free(msi_cachep, entry);
-		return -EBUSY;
-	}
-
-	set_irq_data(irq, entry);
-
-	return irq;
-}
-
-static void destroy_msi_irq(unsigned int irq)
-{
-	struct msi_desc *entry;
-
-	entry = get_irq_data(irq);
-	set_irq_chip(irq, NULL);
-	set_irq_data(irq, NULL);
-	destroy_irq(irq);
-	kmem_cache_free(msi_cachep, entry);
-}
-
 static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
 {
 	u16 control;
@@ -278,36 +230,8 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
 	pci_intx(dev, 1);  /* enable intx */
 }
 
-static int msi_lookup_irq(struct pci_dev *dev, int type)
-{
-	int irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	for (irq = 0; irq < NR_IRQS; irq++) {
-		if (!msi_desc[irq] || msi_desc[irq]->dev != dev ||
-			msi_desc[irq]->msi_attrib.type != type ||
-			msi_desc[irq]->msi_attrib.default_irq != dev->irq)
-			continue;
-		spin_unlock_irqrestore(&msi_lock, flags);
-		/* This pre-assigned MSI irq for this device
-		   already exits. Override dev->irq with this irq */
-		dev->irq = irq;
-		return 0;
-	}
-	spin_unlock_irqrestore(&msi_lock, flags);
-
-	return -EACCES;
-}
-
-void pci_scan_msi_device(struct pci_dev *dev)
-{
-	if (!dev)
-		return;
-}
-
 #ifdef CONFIG_PM
-int pci_save_msi_state(struct pci_dev *dev)
+static int __pci_save_msi_state(struct pci_dev *dev)
 {
 	int pos, i = 0;
 	u16 control;
@@ -345,7 +269,7 @@ int pci_save_msi_state(struct pci_dev *dev)
 	return 0;
 }
 
-void pci_restore_msi_state(struct pci_dev *dev)
+static void __pci_restore_msi_state(struct pci_dev *dev)
 {
 	int i = 0, pos;
 	u16 control;
@@ -373,14 +297,16 @@ void pci_restore_msi_state(struct pci_dev *dev)
 	kfree(save_state);
 }
 
-int pci_save_msix_state(struct pci_dev *dev)
+static int __pci_save_msix_state(struct pci_dev *dev)
 {
 	int pos;
-	int temp;
 	int irq, head, tail = 0;
 	u16 control;
 	struct pci_cap_saved_state *save_state;
 
+	if (!dev->msix_enabled)
+		return 0;
+
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
 	if (pos <= 0 || dev->no_msi)
 		return 0;
@@ -398,38 +324,46 @@ int pci_save_msix_state(struct pci_dev *dev)
 	*((u16 *)&save_state->data[0]) = control;
 
 	/* save the table */
-	temp = dev->irq;
-	if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
-		kfree(save_state);
-		return -EINVAL;
-	}
-
-	irq = head = dev->irq;
+	irq = head = dev->first_msi_irq;
 	while (head != tail) {
 		struct msi_desc *entry;
 
-		entry = msi_desc[irq];
+		entry = get_irq_msi(irq);
 		read_msi_msg(irq, &entry->msg_save);
 
-		tail = msi_desc[irq]->link.tail;
+		tail = entry->link.tail;
 		irq = tail;
 	}
-	dev->irq = temp;
 
 	save_state->cap_nr = PCI_CAP_ID_MSIX;
 	pci_add_saved_cap(dev, save_state);
 	return 0;
 }
 
-void pci_restore_msix_state(struct pci_dev *dev)
+int pci_save_msi_state(struct pci_dev *dev)
+{
+	int rc;
+
+	rc = __pci_save_msi_state(dev);
+	if (rc)
+		return rc;
+
+	rc = __pci_save_msix_state(dev);
+
+	return rc;
+}
+
+static void __pci_restore_msix_state(struct pci_dev *dev)
 {
 	u16 save;
 	int pos;
 	int irq, head, tail = 0;
 	struct msi_desc *entry;
-	int temp;
 	struct pci_cap_saved_state *save_state;
 
+	if (!dev->msix_enabled)
+		return;
+
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
 	if (!save_state)
 		return;
@@ -442,23 +376,25 @@ void pci_restore_msix_state(struct pci_dev *dev)
 		return;
 
 	/* route the table */
-	temp = dev->irq;
-	if (msi_lookup_irq(dev, PCI_CAP_ID_MSIX))
-		return;
-	irq = head = dev->irq;
+	irq = head = dev->first_msi_irq;
 	while (head != tail) {
-		entry = msi_desc[irq];
+		entry = get_irq_msi(irq);
 		write_msi_msg(irq, &entry->msg_save);
 
-		tail = msi_desc[irq]->link.tail;
+		tail = entry->link.tail;
 		irq = tail;
 	}
-	dev->irq = temp;
 
 	pci_write_config_word(dev, msi_control_reg(pos), save);
 	enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
 }
-#endif
+
+void pci_restore_msi_state(struct pci_dev *dev)
+{
+	__pci_restore_msi_state(dev);
+	__pci_restore_msix_state(dev);
+}
+#endif	/* CONFIG_PM */
 
 /**
  * msi_capability_init - configure device's MSI capability structure
@@ -471,7 +407,6 @@ void pci_restore_msix_state(struct pci_dev *dev)
  **/
 static int msi_capability_init(struct pci_dev *dev)
 {
-	int status;
 	struct msi_desc *entry;
 	int pos, irq;
 	u16 control;
@@ -479,13 +414,10 @@ static int msi_capability_init(struct pci_dev *dev)
    	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
 	/* MSI Entry Initialization */
-	irq = create_msi_irq();
-	if (irq < 0)
-		return irq;
+	entry = alloc_msi_entry();
+	if (!entry)
+		return -ENOMEM;
 
-	entry = get_irq_data(irq);
-	entry->link.head = irq;
-	entry->link.tail = irq;
 	entry->msi_attrib.type = PCI_CAP_ID_MSI;
 	entry->msi_attrib.is_64 = is_64bit_address(control);
 	entry->msi_attrib.entry_nr = 0;
@@ -511,13 +443,16 @@ static int msi_capability_init(struct pci_dev *dev)
 			maskbits);
 	}
 	/* Configure MSI capability structure */
-	status = arch_setup_msi_irq(irq, dev);
-	if (status < 0) {
-		destroy_msi_irq(irq);
-		return status;
+	irq = arch_setup_msi_irq(dev, entry);
+	if (irq < 0) {
+		kmem_cache_free(msi_cachep, entry);
+		return irq;
 	}
+	entry->link.head = irq;
+	entry->link.tail = irq;
+	dev->first_msi_irq = irq;
+	set_irq_msi(irq, entry);
 
-	attach_msi_entry(entry, irq);
 	/* Set MSI enabled bits	 */
 	enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
@@ -539,7 +474,6 @@ static int msix_capability_init(struct pci_dev *dev,
 				struct msix_entry *entries, int nvec)
 {
 	struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
-	int status;
 	int irq, pos, i, j, nr_entries, temp = 0;
 	unsigned long phys_addr;
 	u32 table_offset;
@@ -562,13 +496,11 @@ static int msix_capability_init(struct pci_dev *dev,
 
 	/* MSI-X Table Initialization */
 	for (i = 0; i < nvec; i++) {
-		irq = create_msi_irq();
-		if (irq < 0)
+		entry = alloc_msi_entry();
+		if (!entry)
 			break;
 
-		entry = get_irq_data(irq);
  		j = entries[i].entry;
- 		entries[i].vector = irq;
 		entry->msi_attrib.type = PCI_CAP_ID_MSIX;
 		entry->msi_attrib.is_64 = 1;
 		entry->msi_attrib.entry_nr = j;
@@ -577,6 +509,14 @@ static int msix_capability_init(struct pci_dev *dev,
 		entry->msi_attrib.pos = pos;
 		entry->dev = dev;
 		entry->mask_base = base;
+
+		/* Configure MSI-X capability structure */
+		irq = arch_setup_msi_irq(dev, entry);
+		if (irq < 0) {
+			kmem_cache_free(msi_cachep, entry);
+			break;
+		}
+ 		entries[i].vector = irq;
 		if (!head) {
 			entry->link.head = irq;
 			entry->link.tail = irq;
@@ -589,14 +529,8 @@ static int msix_capability_init(struct pci_dev *dev,
 		}
 		temp = irq;
 		tail = entry;
-		/* Configure MSI-X capability structure */
-		status = arch_setup_msi_irq(irq, dev);
-		if (status < 0) {
-			destroy_msi_irq(irq);
-			break;
-		}
 
-		attach_msi_entry(entry, irq);
+		set_irq_msi(irq, entry);
 	}
 	if (i != nvec) {
 		int avail = i - 1;
@@ -613,6 +547,7 @@ static int msix_capability_init(struct pci_dev *dev,
 			avail = -EBUSY;
 		return avail;
 	}
+	dev->first_msi_irq = entries[0].vector;
 	/* Set MSI-X enabled bits */
 	enable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
 
@@ -660,13 +595,11 @@ int pci_msi_supported(struct pci_dev * dev)
  **/
 int pci_enable_msi(struct pci_dev* dev)
 {
-	int pos, temp, status;
+	int pos, status;
 
 	if (pci_msi_supported(dev) < 0)
 		return -EINVAL;
 
-	temp = dev->irq;
-
 	status = msi_init();
 	if (status < 0)
 		return status;
@@ -675,15 +608,14 @@ int pci_enable_msi(struct pci_dev* dev)
 	if (!pos)
 		return -EINVAL;
 
-	WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI));
+	WARN_ON(!!dev->msi_enabled);
 
 	/* Check whether driver already requested for MSI-X irqs */
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
+	if (pos > 0 && dev->msix_enabled) {
 			printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
-			       "Device already has MSI-X irq assigned\n",
+			       "Device already has MSI-X enabled\n",
 			       pci_name(dev));
-			dev->irq = temp;
 			return -EINVAL;
 	}
 	status = msi_capability_init(dev);
@@ -695,13 +627,15 @@ void pci_disable_msi(struct pci_dev* dev)
 	struct msi_desc *entry;
 	int pos, default_irq;
 	u16 control;
-	unsigned long flags;
 
 	if (!pci_msi_enable)
 		return;
 	if (!dev)
 		return;
 
+	if (!dev->msi_enabled)
+		return;
+
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
 	if (!pos)
 		return;
@@ -710,28 +644,26 @@ void pci_disable_msi(struct pci_dev* dev)
 	if (!(control & PCI_MSI_FLAGS_ENABLE))
 		return;
 
+
 	disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
-	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[dev->irq];
+	entry = get_irq_msi(dev->first_msi_irq);
 	if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
-		spin_unlock_irqrestore(&msi_lock, flags);
 		return;
 	}
-	if (irq_has_action(dev->irq)) {
-		spin_unlock_irqrestore(&msi_lock, flags);
+	if (irq_has_action(dev->first_msi_irq)) {
 		printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
 		       "free_irq() on MSI irq %d\n",
-		       pci_name(dev), dev->irq);
-		BUG_ON(irq_has_action(dev->irq));
+		       pci_name(dev), dev->first_msi_irq);
+		BUG_ON(irq_has_action(dev->first_msi_irq));
 	} else {
 		default_irq = entry->msi_attrib.default_irq;
-		spin_unlock_irqrestore(&msi_lock, flags);
-		msi_free_irq(dev, dev->irq);
+		msi_free_irq(dev, dev->first_msi_irq);
 
 		/* Restore dev->irq to its default pin-assertion irq */
 		dev->irq = default_irq;
 	}
+	dev->first_msi_irq = 0;
 }
 
 static int msi_free_irq(struct pci_dev* dev, int irq)
@@ -739,27 +671,20 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
 	struct msi_desc *entry;
 	int head, entry_nr, type;
 	void __iomem *base;
-	unsigned long flags;
 
-	arch_teardown_msi_irq(irq);
-
-	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[irq];
+	entry = get_irq_msi(irq);
 	if (!entry || entry->dev != dev) {
-		spin_unlock_irqrestore(&msi_lock, flags);
 		return -EINVAL;
 	}
 	type = entry->msi_attrib.type;
 	entry_nr = entry->msi_attrib.entry_nr;
 	head = entry->link.head;
 	base = entry->mask_base;
-	msi_desc[entry->link.head]->link.tail = entry->link.tail;
-	msi_desc[entry->link.tail]->link.head = entry->link.head;
-	entry->dev = NULL;
-	msi_desc[irq] = NULL;
-	spin_unlock_irqrestore(&msi_lock, flags);
+	get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
+	get_irq_msi(entry->link.tail)->link.head = entry->link.head;
 
-	destroy_msi_irq(irq);
+	arch_teardown_msi_irq(irq);
+	kmem_cache_free(msi_cachep, entry);
 
 	if (type == PCI_CAP_ID_MSIX) {
 		writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -790,7 +715,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 {
 	int status, pos, nr_entries;
-	int i, j, temp;
+	int i, j;
 	u16 control;
 
 	if (!entries || pci_msi_supported(dev) < 0)
@@ -818,16 +743,14 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 				return -EINVAL;	/* duplicate entry */
 		}
 	}
-	temp = dev->irq;
-	WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSIX));
+	WARN_ON(!!dev->msix_enabled);
 
 	/* Check whether driver already requested for MSI irq */
    	if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
-		!msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
+		dev->msi_enabled) {
 		printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
 		       "Device already has an MSI irq assigned\n",
 		       pci_name(dev));
-		dev->irq = temp;
 		return -EINVAL;
 	}
 	status = msix_capability_init(dev, entries, nvec);
@@ -836,7 +759,8 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 
 void pci_disable_msix(struct pci_dev* dev)
 {
-	int pos, temp;
+	int irq, head, tail = 0, warning = 0;
+	int pos;
 	u16 control;
 
 	if (!pci_msi_enable)
@@ -844,6 +768,9 @@ void pci_disable_msix(struct pci_dev* dev)
 	if (!dev)
 		return;
 
+	if (!dev->msix_enabled)
+		return;
+
 	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
 	if (!pos)
 		return;
@@ -854,31 +781,23 @@ void pci_disable_msix(struct pci_dev* dev)
 
 	disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX);
 
-	temp = dev->irq;
-	if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
-		int irq, head, tail = 0, warning = 0;
-		unsigned long flags;
-
-		irq = head = dev->irq;
-		dev->irq = temp;			/* Restore pin IRQ */
-		while (head != tail) {
-			spin_lock_irqsave(&msi_lock, flags);
-			tail = msi_desc[irq]->link.tail;
-			spin_unlock_irqrestore(&msi_lock, flags);
-			if (irq_has_action(irq))
-				warning = 1;
-			else if (irq != head)	/* Release MSI-X irq */
-				msi_free_irq(dev, irq);
-			irq = tail;
-		}
-		msi_free_irq(dev, irq);
-		if (warning) {
-			printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
-			       "free_irq() on all MSI-X irqs\n",
-			       pci_name(dev));
-			BUG_ON(warning > 0);
-		}
+	irq = head = dev->first_msi_irq;
+	while (head != tail) {
+		tail = get_irq_msi(irq)->link.tail;
+		if (irq_has_action(irq))
+			warning = 1;
+		else if (irq != head)	/* Release MSI-X irq */
+			msi_free_irq(dev, irq);
+		irq = tail;
+	}
+	msi_free_irq(dev, irq);
+	if (warning) {
+		printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
+			"free_irq() on all MSI-X irqs\n",
+			pci_name(dev));
+		BUG_ON(warning > 0);
 	}
+	dev->first_msi_irq = 0;
 }
 
 /**
@@ -892,35 +811,26 @@ void pci_disable_msix(struct pci_dev* dev)
  **/
 void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 {
-	int pos, temp;
-	unsigned long flags;
-
 	if (!pci_msi_enable || !dev)
  		return;
 
-	temp = dev->irq;		/* Save IOAPIC IRQ */
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-	if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) {
-		if (irq_has_action(dev->irq)) {
+	if (dev->msi_enabled) {
+		if (irq_has_action(dev->first_msi_irq)) {
 			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
 			       "called without free_irq() on MSI irq %d\n",
-			       pci_name(dev), dev->irq);
-			BUG_ON(irq_has_action(dev->irq));
+			       pci_name(dev), dev->first_msi_irq);
+			BUG_ON(irq_has_action(dev->first_msi_irq));
 		} else /* Release MSI irq assigned to this device */
-			msi_free_irq(dev, dev->irq);
-		dev->irq = temp;		/* Restore IOAPIC IRQ */
+			msi_free_irq(dev, dev->first_msi_irq);
 	}
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) {
+	if (dev->msix_enabled) {
 		int irq, head, tail = 0, warning = 0;
 		void __iomem *base = NULL;
 
-		irq = head = dev->irq;
+		irq = head = dev->first_msi_irq;
 		while (head != tail) {
-			spin_lock_irqsave(&msi_lock, flags);
-			tail = msi_desc[irq]->link.tail;
-			base = msi_desc[irq]->mask_base;
-			spin_unlock_irqrestore(&msi_lock, flags);
+			tail = get_irq_msi(irq)->link.tail;
+			base = get_irq_msi(irq)->mask_base;
 			if (irq_has_action(irq))
 				warning = 1;
 			else if (irq != head) /* Release MSI-X irq */
@@ -935,7 +845,6 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 			       pci_name(dev));
 			BUG_ON(warning > 0);
 		}
-		dev->irq = temp;		/* Restore IOAPIC IRQ */
 	}
 }
 
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 358766885260..4438ae1ede4f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -324,8 +324,7 @@ static int pci_default_resume(struct pci_dev *pci_dev)
 	/* restore the PCI config space */
 	pci_restore_state(pci_dev);
 	/* if the device was enabled before suspend, reenable */
-	if (atomic_read(&pci_dev->enable_cnt))
-		retval = __pci_enable_device(pci_dev);
+	retval = __pci_reenable_device(pci_dev);
 	/* if the device was busmaster before the suspend, make it busmaster again */
 	if (pci_dev->is_busmaster)
 		pci_set_master(pci_dev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 206c834d263a..84c757ba0664 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -392,6 +392,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 	if (state > PCI_D3hot)
 		state = PCI_D3hot;
 
+	/*
+	 * If the device or the parent bridge can't support PCI PM, ignore
+	 * the request if we're doing anything besides putting it into D0
+	 * (which would only happen on boot).
+	 */
+	if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
+		return 0;
+
 	/* Validate current state:
 	 * Can enter D0 from any state, but if we can only go deeper 
 	 * to sleep if we're already in a low power state
@@ -403,13 +411,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 	} else if (dev->current_state == state)
 		return 0;        /* we're already there */
 
-	/*
-	 * If the device or the parent bridge can't support PCI PM, ignore
-	 * the request if we're doing anything besides putting it into D0
-	 * (which would only happen on boot).
-	 */
-	if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
-		return 0;
 
 	/* find PCI PM capability in list */
 	pm = pci_find_capability(dev, PCI_CAP_ID_PM);
@@ -633,8 +634,6 @@ pci_save_state(struct pci_dev *dev)
 		pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
 	if ((i = pci_save_msi_state(dev)) != 0)
 		return i;
-	if ((i = pci_save_msix_state(dev)) != 0)
-		return i;
 	if ((i = pci_save_pcie_state(dev)) != 0)
 		return i;
 	if ((i = pci_save_pcix_state(dev)) != 0)
@@ -672,22 +671,11 @@ pci_restore_state(struct pci_dev *dev)
 	}
 	pci_restore_pcix_state(dev);
 	pci_restore_msi_state(dev);
-	pci_restore_msix_state(dev);
+
 	return 0;
 }
 
-/**
- * pci_enable_device_bars - Initialize some of a device for use
- * @dev: PCI device to be initialized
- * @bars: bitmask of BAR's that must be configured
- *
- *  Initialize device before it's used by a driver. Ask low-level code
- *  to enable selected I/O and memory resources. Wake up the device if it 
- *  was suspended. Beware, this function can fail.
- */
- 
-int
-pci_enable_device_bars(struct pci_dev *dev, int bars)
+static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
 	int err;
 
@@ -697,30 +685,47 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
 	err = pcibios_enable_device(dev, bars);
 	if (err < 0)
 		return err;
+	pci_fixup_device(pci_fixup_enable, dev);
+
 	return 0;
 }
 
 /**
- * __pci_enable_device - Initialize device before it's used by a driver.
+ * __pci_reenable_device - Resume abandoned device
+ * @dev: PCI device to be resumed
+ *
+ *  Note this function is a backend of pci_default_resume and is not supposed
+ *  to be called by normal code, write proper resume handler and use it instead.
+ */
+int
+__pci_reenable_device(struct pci_dev *dev)
+{
+	if (atomic_read(&dev->enable_cnt))
+		return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
+	return 0;
+}
+
+/**
+ * pci_enable_device_bars - Initialize some of a device for use
  * @dev: PCI device to be initialized
+ * @bars: bitmask of BAR's that must be configured
  *
  *  Initialize device before it's used by a driver. Ask low-level code
- *  to enable I/O and memory. Wake up the device if it was suspended.
- *  Beware, this function can fail.
- *
- * Note this function is a backend and is not supposed to be called by
- * normal code, use pci_enable_device() instead.
+ *  to enable selected I/O and memory resources. Wake up the device if it
+ *  was suspended. Beware, this function can fail.
  */
 int
-__pci_enable_device(struct pci_dev *dev)
+pci_enable_device_bars(struct pci_dev *dev, int bars)
 {
 	int err;
 
-	err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
-	if (err)
-		return err;
-	pci_fixup_device(pci_fixup_enable, dev);
-	return 0;
+	if (atomic_add_return(1, &dev->enable_cnt) > 1)
+		return 0;		/* already enabled */
+
+	err = do_pci_enable_device(dev, bars);
+	if (err < 0)
+		atomic_dec(&dev->enable_cnt);
+	return err;
 }
 
 /**
@@ -736,13 +741,7 @@ __pci_enable_device(struct pci_dev *dev)
  */
 int pci_enable_device(struct pci_dev *dev)
 {
-	int result;
-	if (atomic_add_return(1, &dev->enable_cnt) > 1)
-		return 0;		/* already enabled */
-	result = __pci_enable_device(dev);
-	if (result < 0)
-		atomic_dec(&dev->enable_cnt);
-	return result;
+	return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
 }
 
 /**
@@ -921,6 +920,47 @@ err_out:
 	return -EBUSY;
 }
 
+/**
+ * pci_release_selected_regions - Release selected PCI I/O and memory resources
+ * @pdev: PCI device whose resources were previously reserved
+ * @bars: Bitmask of BARs to be released
+ *
+ * Release selected PCI I/O and memory resources previously reserved.
+ * Call this function only after all use of the PCI regions has ceased.
+ */
+void pci_release_selected_regions(struct pci_dev *pdev, int bars)
+{
+	int i;
+
+	for (i = 0; i < 6; i++)
+		if (bars & (1 << i))
+			pci_release_region(pdev, i);
+}
+
+/**
+ * pci_request_selected_regions - Reserve selected PCI I/O and memory resources
+ * @pdev: PCI device whose resources are to be reserved
+ * @bars: Bitmask of BARs to be requested
+ * @res_name: Name to be associated with resource
+ */
+int pci_request_selected_regions(struct pci_dev *pdev, int bars,
+				 const char *res_name)
+{
+	int i;
+
+	for (i = 0; i < 6; i++)
+		if (bars & (1 << i))
+			if(pci_request_region(pdev, i, res_name))
+				goto err_out;
+	return 0;
+
+err_out:
+	while(--i >= 0)
+		if (bars & (1 << i))
+			pci_release_region(pdev, i);
+
+	return -EBUSY;
+}
 
 /**
  *	pci_release_regions - Release reserved PCI I/O and memory resources
@@ -933,10 +973,7 @@ err_out:
 
 void pci_release_regions(struct pci_dev *pdev)
 {
-	int i;
-	
-	for (i = 0; i < 6; i++)
-		pci_release_region(pdev, i);
+	pci_release_selected_regions(pdev, (1 << 6) - 1);
 }
 
 /**
@@ -954,18 +991,7 @@ void pci_release_regions(struct pci_dev *pdev)
  */
 int pci_request_regions(struct pci_dev *pdev, const char *res_name)
 {
-	int i;
-	
-	for (i = 0; i < 6; i++)
-		if(pci_request_region(pdev, i, res_name))
-			goto err_out;
-	return 0;
-
-err_out:
-	while(--i >= 0)
-		pci_release_region(pdev, i);
-		
-	return -EBUSY;
+	return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name);
 }
 
 /**
@@ -1148,7 +1174,23 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
 	return 0;
 }
 #endif
-     
+
+/**
+ * pci_select_bars - Make BAR mask from the type of resource
+ * @pdev: the PCI device for which BAR mask is made
+ * @flags: resource type mask to be selected
+ *
+ * This helper routine makes bar mask from the type of resource.
+ */
+int pci_select_bars(struct pci_dev *dev, unsigned long flags)
+{
+	int i, bars = 0;
+	for (i = 0; i < PCI_NUM_RESOURCES; i++)
+		if (pci_resource_flags(dev, i) & flags)
+			bars |= (1 << i);
+	return bars;
+}
+
 static int __devinit pci_init(void)
 {
 	struct pci_dev *dev = NULL;
@@ -1181,12 +1223,6 @@ early_param("pci", pci_setup);
 
 device_initcall(pci_init);
 
-#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
-/* FIXME: Some boxes have multiple ISA bridges! */
-struct pci_dev *isa_bridge;
-EXPORT_SYMBOL(isa_bridge);
-#endif
-
 EXPORT_SYMBOL_GPL(pci_restore_bars);
 EXPORT_SYMBOL(pci_enable_device_bars);
 EXPORT_SYMBOL(pci_enable_device);
@@ -1197,6 +1233,8 @@ EXPORT_SYMBOL(pci_release_regions);
 EXPORT_SYMBOL(pci_request_regions);
 EXPORT_SYMBOL(pci_release_region);
 EXPORT_SYMBOL(pci_request_region);
+EXPORT_SYMBOL(pci_release_selected_regions);
+EXPORT_SYMBOL(pci_request_selected_regions);
 EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
@@ -1205,13 +1243,10 @@ EXPORT_SYMBOL(pci_set_dma_mask);
 EXPORT_SYMBOL(pci_set_consistent_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
 EXPORT_SYMBOL(pci_find_parent_resource);
+EXPORT_SYMBOL(pci_select_bars);
 
 EXPORT_SYMBOL(pci_set_power_state);
 EXPORT_SYMBOL(pci_save_state);
 EXPORT_SYMBOL(pci_restore_state);
 EXPORT_SYMBOL(pci_enable_wake);
 
-/* Quirk info */
-
-EXPORT_SYMBOL(isa_dma_bridge_buggy);
-EXPORT_SYMBOL(pci_pci_problems);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 398852f526a6..a4f2d580625e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,6 +1,6 @@
 /* Functions internal to the PCI core code */
 
-extern int __must_check __pci_enable_device(struct pci_dev *);
+extern int __must_check __pci_reenable_device(struct pci_dev *);
 extern int pci_uevent(struct device *dev, char **envp, int num_envp,
 		      char *buffer, int buffer_size);
 extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
@@ -43,12 +43,8 @@ extern void pci_remove_legacy_files(struct pci_bus *bus);
 /* Lock for read/write access to pci device and bus lists */
 extern struct rw_semaphore pci_bus_sem;
 
-#ifdef CONFIG_PCI_MSI
-extern int pci_msi_quirk;
-#else
-#define pci_msi_quirk 0
-#endif
 extern unsigned int pci_pm_d3_delay;
+
 #ifdef CONFIG_PCI_MSI
 void disable_msi_mode(struct pci_dev *dev, int pos, int type);
 void pci_no_msi(void);
@@ -56,17 +52,15 @@ void pci_no_msi(void);
 static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
 static inline void pci_no_msi(void) { }
 #endif
+
 #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
 int pci_save_msi_state(struct pci_dev *dev);
-int pci_save_msix_state(struct pci_dev *dev);
 void pci_restore_msi_state(struct pci_dev *dev);
-void pci_restore_msix_state(struct pci_dev *dev);
 #else
 static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; }
-static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; }
 static inline void pci_restore_msi_state(struct pci_dev *dev) {}
-static inline void pci_restore_msix_state(struct pci_dev *dev) {}
 #endif
+
 static inline int pci_no_d1d2(struct pci_dev *dev)
 {
 	unsigned int parent_dstates = 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 0e0401dd02cb..2fe1d690eb13 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -144,6 +144,32 @@ static u32 pci_size(u32 base, u32 maxbase, u32 mask)
 	return size;
 }
 
+static u64 pci_size64(u64 base, u64 maxbase, u64 mask)
+{
+	u64 size = mask & maxbase;	/* Find the significant bits */
+	if (!size)
+		return 0;
+
+	/* Get the lowest of them to find the decode size, and
+	   from that the extent.  */
+	size = (size & ~(size-1)) - 1;
+
+	/* base == maxbase can be valid only if the BAR has
+	   already been programmed with all 1s.  */
+	if (base == maxbase && ((base | size) & mask) != mask)
+		return 0;
+
+	return size;
+}
+
+static inline int is_64bit_memory(u32 mask)
+{
+	if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
+	    (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
+		return 1;
+	return 0;
+}
+
 static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 {
 	unsigned int pos, reg, next;
@@ -151,6 +177,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 	struct resource *res;
 
 	for(pos=0; pos<howmany; pos = next) {
+		u64 l64;
+		u64 sz64;
+		u32 raw_sz;
+
 		next = pos+1;
 		res = &dev->resource[pos];
 		res->name = pci_name(dev);
@@ -163,9 +193,16 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 			continue;
 		if (l == 0xffffffff)
 			l = 0;
-		if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
+		raw_sz = sz;
+		if ((l & PCI_BASE_ADDRESS_SPACE) ==
+				PCI_BASE_ADDRESS_SPACE_MEMORY) {
 			sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
-			if (!sz)
+			/*
+			 * For 64bit prefetchable memory sz could be 0, if the
+			 * real size is bigger than 4G, so we need to check
+			 * szhi for that.
+			 */
+			if (!is_64bit_memory(l) && !sz)
 				continue;
 			res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
 			res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
@@ -178,30 +215,36 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 		}
 		res->end = res->start + (unsigned long) sz;
 		res->flags |= pci_calc_resource_flags(l);
-		if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
-		    == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+		if (is_64bit_memory(l)) {
 			u32 szhi, lhi;
+
 			pci_read_config_dword(dev, reg+4, &lhi);
 			pci_write_config_dword(dev, reg+4, ~0);
 			pci_read_config_dword(dev, reg+4, &szhi);
 			pci_write_config_dword(dev, reg+4, lhi);
-			szhi = pci_size(lhi, szhi, 0xffffffff);
+			sz64 = ((u64)szhi << 32) | raw_sz;
+			l64 = ((u64)lhi << 32) | l;
+			sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
 			next++;
 #if BITS_PER_LONG == 64
-			res->start |= ((unsigned long) lhi) << 32;
-			res->end = res->start + sz;
-			if (szhi) {
-				/* This BAR needs > 4GB?  Wow. */
-				res->end |= (unsigned long)szhi<<32;
+			if (!sz64) {
+				res->start = 0;
+				res->end = 0;
+				res->flags = 0;
+				continue;
 			}
+			res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
+			res->end = res->start + sz64;
 #else
-			if (szhi) {
-				printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev));
+			if (sz64 > 0x100000000ULL) {
+				printk(KERN_ERR "PCI: Unable to handle 64-bit "
+					"BAR for device %s\n", pci_name(dev));
 				res->start = 0;
 				res->flags = 0;
 			} else if (lhi) {
 				/* 64-bit wide address, treat as disabled */
-				pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
+				pci_write_config_dword(dev, reg,
+					l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
 				pci_write_config_dword(dev, reg+4, 0);
 				res->start = 0;
 				res->end = sz;
@@ -902,7 +945,6 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
 		return NULL;
 
 	pci_device_add(dev, bus);
-	pci_scan_msi_device(dev);
 
 	return dev;
 }
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c913ea4e545c..0d0ba2fad5fc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -61,7 +61,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82441,	quirk_p
     
     This appears to be BIOS not version dependent. So presumably there is a 
     chipset level fix */
-int isa_dma_bridge_buggy;		/* Exported */
+int isa_dma_bridge_buggy;
+EXPORT_SYMBOL(isa_dma_bridge_buggy);
     
 static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
 {
@@ -83,6 +84,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,	PCI_DEVICE_ID_NEC_CBUS_2,	quirk_isa_d
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,	PCI_DEVICE_ID_NEC_CBUS_3,	quirk_isa_dma_hangs );
 
 int pci_pci_problems;
+EXPORT_SYMBOL(pci_pci_problems);
 
 /*
  *	Chipsets where PCI->PCI transfers vanish or hang
@@ -94,6 +96,8 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev)
 		pci_pci_problems |= PCIPCI_FAIL;
 	}
 }
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5597,		quirk_nopcipci );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_496,		quirk_nopcipci );
 
 static void __devinit quirk_nopciamd(struct pci_dev *dev)
 {
@@ -105,9 +109,6 @@ static void __devinit quirk_nopciamd(struct pci_dev *dev)
 		pci_pci_problems |= PCIAGP_FAIL;
 	}
 }
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_5597,		quirk_nopcipci );
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_496,		quirk_nopcipci );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8151_0,	quirk_nopciamd );
 
 /*
@@ -976,52 +977,51 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 			case 0x1626: /* L3C notebook */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB)
 			switch(dev->subsystem_device) {
 			case 0x80b1: /* P4GE-V */
 			case 0x80b2: /* P4PE */
 			case 0x8093: /* P4B533-V */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB)
 			switch(dev->subsystem_device) {
 			case 0x8030: /* P4T533 */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_7205_0)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_7205_0)
 			switch (dev->subsystem_device) {
 			case 0x8070: /* P4G8X Deluxe */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH)
 			switch (dev->subsystem_device) {
 			case 0x80c9: /* PU-DLS */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
 			switch (dev->subsystem_device) {
 			case 0x1751: /* M2N notebook */
 			case 0x1821: /* M5N notebook */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
 			switch (dev->subsystem_device) {
 			case 0x184b: /* W1N notebook */
 			case 0x186a: /* M6Ne notebook */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
 			switch (dev->subsystem_device) {
 			case 0x80f2: /* P4P800-X */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
 			switch (dev->subsystem_device) {
 			case 0x1882: /* M6V notebook */
 			case 0x1977: /* A6VA notebook */
 				asus_hides_smbus = 1;
 			}
-		}
 	} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
 		if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
 			switch(dev->subsystem_device) {
@@ -1029,25 +1029,24 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 			case 0x0890: /* HP Compaq nc6000 */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
 			switch (dev->subsystem_device) {
 			case 0x12bc: /* HP D330L */
 			case 0x12bd: /* HP D530 */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
 			switch (dev->subsystem_device) {
 			case 0x099c: /* HP Compaq nx6110 */
 				asus_hides_smbus = 1;
 			}
-		}
 	} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
 		if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
 			switch(dev->subsystem_device) {
 			case 0x0001: /* Toshiba Satellite A40 */
 				asus_hides_smbus = 1;
 			}
-		if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
+		else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
 			switch(dev->subsystem_device) {
 			case 0x0001: /* Toshiba Tecra M2 */
 				asus_hides_smbus = 1;
@@ -1136,6 +1135,14 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
 		pci_write_config_byte(dev, 0x77, val & ~0x10);
 	}
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_961,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_962,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_963,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_LPC,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_961,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_962,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_963,		quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_LPC,		quirk_sis_96x_smbus );
 
 /*
  * ... This is further complicated by the fact that some SiS96x south
@@ -1145,8 +1152,6 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
  *
  * We can also enable the sis96x bit in the discovery register..
  */
-static int __devinitdata sis_96x_compatible = 0;
-
 #define SIS_DETECT_REGISTER 0x40
 
 static void quirk_sis_503(struct pci_dev *dev)
@@ -1162,9 +1167,6 @@ static void quirk_sis_503(struct pci_dev *dev)
 		return;
 	}
 
-	/* Make people aware that we changed the config.. */
-	printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible);
-
 	/*
 	 * Ok, it now shows up as a 96x.. run the 96x quirk by
 	 * hand in case it has already been processed.
@@ -1173,20 +1175,10 @@ static void quirk_sis_503(struct pci_dev *dev)
 	dev->device = devid;
 	quirk_sis_96x_smbus(dev);
 }
-
-static void __init quirk_sis_96x_compatible(struct pci_dev *dev)
-{
-	sis_96x_compatible = 1;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_645,		quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_646,		quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_648,		quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_650,		quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_651,		quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_735,		quirk_sis_96x_compatible );
-
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_503,		quirk_sis_503 );
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_503,		quirk_sis_503 );
+
+
 /*
  * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
  * and MC97 modem controller are disabled when a second PCI soundcard is
@@ -1217,21 +1209,8 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
-
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_961,		quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_962,		quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_963,		quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_LPC,		quirk_sis_96x_smbus );
-
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
 
-
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_961,		quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_962,		quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_963,		quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,	PCI_DEVICE_ID_SI_LPC,		quirk_sis_96x_smbus );
-
 #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
 
 /*
@@ -1276,7 +1255,6 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev)
 			break;
 	}
 }
-
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
 
@@ -1420,6 +1398,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    PCI_ANY_ID,	  quirk_intel_ide_co
 
 
 int pcie_mch_quirk;
+EXPORT_SYMBOL(pcie_mch_quirk);
 
 static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
 {
@@ -1646,6 +1625,7 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
 	}
 	pci_do_fixups(dev, start, end);
 }
+EXPORT_SYMBOL(pci_fixup_device);
 
 /* Enable 1k I/O space granularity on the Intel P64H2 */
 static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
@@ -1673,6 +1653,31 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	0x1460,		quirk_p64h2_1k_io);
 
+/* Fix the IOBL_ADR for 1k I/O space granularity on the Intel P64H2
+ * The IOBL_ADR gets re-written to 4k boundaries in pci_setup_bridge()
+ * in drivers/pci/setup-bus.c
+ */
+static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev)
+{
+	u16 en1k, iobl_adr, iobl_adr_1k;
+	struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+
+	pci_read_config_word(dev, 0x40, &en1k);
+
+	if (en1k & 0x200) {
+		pci_read_config_word(dev, PCI_IO_BASE, &iobl_adr);
+
+		iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00);
+
+		if (iobl_adr != iobl_adr_1k) {
+			printk(KERN_INFO "PCI: Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1 KB Granularity\n",
+				iobl_adr,iobl_adr_1k);
+			pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k);
+		}
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	0x1460,		quirk_p64h2_1k_io_fix_iobl);
+
 /* Under some circumstances, AER is not linked with extended capabilities.
  * Force it to be linked by setting the corresponding control bit in the
  * config space.
@@ -1695,9 +1700,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
 			quirk_nvidia_ck804_pcie_aer_ext_cap);
 
 #ifdef CONFIG_PCI_MSI
-/* To disable MSI globally */
-int pci_msi_quirk;
-
 /* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely
  * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
  * some other busses controlled by the chipset even if Linux is not aware of it.
@@ -1706,8 +1708,8 @@ int pci_msi_quirk;
  */
 static void __init quirk_svw_msi(struct pci_dev *dev)
 {
-	pci_msi_quirk = 1;
-	printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+	pci_no_msi();
+	printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n");
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi);
 
@@ -1788,8 +1790,3 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
 			quirk_nvidia_ck804_msi_ht_cap);
 #endif /* CONFIG_PCI_MSI */
-
-EXPORT_SYMBOL(pcie_mch_quirk);
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pci_fixup_device);
-#endif
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index b2653c4afe9e..ff98eaddaa73 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -358,43 +358,6 @@ exit:
 }
 
 /**
- * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id
- * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
- * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
- * @from: Previous PCI device found in search, or %NULL for new search.
- *
- * Iterates through the list of known PCI devices in the reverse order of
- * pci_find_device().
- * 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 as the @from argument.
- * Otherwise if @from is not %NULL, searches continue from previous device
- * on the global list.
- */
-struct pci_dev *
-pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from)
-{
-	struct list_head *n;
-	struct pci_dev *dev;
-
-	WARN_ON(in_interrupt());
-	down_read(&pci_bus_sem);
-	n = from ? from->global_list.prev : pci_devices.prev;
-
-	while (n && (n != &pci_devices)) {
-		dev = pci_dev_g(n);
-		if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
-		    (device == PCI_ANY_ID || dev->device == device))
-			goto exit;
-		n = n->prev;
-	}
-	dev = NULL;
-exit:
-	up_read(&pci_bus_sem);
-	return dev;
-}
-
-/**
  * 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.
@@ -469,7 +432,6 @@ EXPORT_SYMBOL(pci_dev_present);
 EXPORT_SYMBOL(pci_find_present);
 
 EXPORT_SYMBOL(pci_find_device);
-EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
 /* For boot time work */
 EXPORT_SYMBOL(pci_find_bus);