aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorRajesh Shah <rajesh.shah@intel.com>2005-11-23 18:44:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-24 02:04:27 -0500
commit5a49f2036ad14092c11d09f186da86fd5ae49a05 (patch)
tree75817c2524974df325db97786469e806c4ee546a /drivers/pci
parentdcb890749bbe63af96163c499e9c86b441fb6c83 (diff)
[PATCH] PCI Express Hotplug: clear sticky power-fault bit
Per the PCI Express spec, the power-fault-detected bit in the slot status register can be set anytime hardware detects a power fault, regardless of whether the slot has a device populated in it or not. This bit is sticky and must be explicitly cleared. This patch is needed to allow hot-add after such a power fault has been detected. Signed-off-by: Rajesh Shah <rajesh.shah@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/pciehp.h1
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c15
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c10
3 files changed, 11 insertions, 15 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index c42b68d3aa24..6a61b9f286e1 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -59,7 +59,6 @@ struct slot {
59 struct slot *next; 59 struct slot *next;
60 u8 bus; 60 u8 bus;
61 u8 device; 61 u8 device;
62 u16 status;
63 u32 number; 62 u32 number;
64 u8 state; 63 u8 state;
65 struct timer_list task_event; 64 struct timer_list task_event;
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 5e582eca21d8..83c4b865718a 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -207,7 +207,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
207 * power fault Cleared 207 * power fault Cleared
208 */ 208 */
209 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); 209 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
210 p_slot->status = 0x00;
211 taskInfo->event_type = INT_POWER_FAULT_CLEAR; 210 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
212 } else { 211 } else {
213 /* 212 /*
@@ -215,8 +214,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
215 */ 214 */
216 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); 215 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
217 taskInfo->event_type = INT_POWER_FAULT; 216 taskInfo->event_type = INT_POWER_FAULT;
218 /* set power fault status for this board */
219 p_slot->status = 0xFF;
220 info("power fault bit %x set\n", hp_slot); 217 info("power fault bit %x set\n", hp_slot);
221 } 218 }
222 if (rc) 219 if (rc)
@@ -317,13 +314,10 @@ static int board_added(struct slot *p_slot)
317 return rc; 314 return rc;
318 } 315 }
319 316
320 dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
321
322 /* Check for a power fault */ 317 /* Check for a power fault */
323 if (p_slot->status == 0xFF) { 318 if (p_slot->hpc_ops->query_power_fault(p_slot)) {
324 /* power fault occurred, but it was benign */ 319 dbg("%s: power fault detected\n", __FUNCTION__);
325 rc = POWER_FAILURE; 320 rc = POWER_FAILURE;
326 p_slot->status = 0;
327 goto err_exit; 321 goto err_exit;
328 } 322 }
329 323
@@ -334,8 +328,6 @@ static int board_added(struct slot *p_slot)
334 goto err_exit; 328 goto err_exit;
335 } 329 }
336 330
337 p_slot->status = 0;
338
339 /* 331 /*
340 * Some PCI Express root ports require fixup after hot-plug operation. 332 * Some PCI Express root ports require fixup after hot-plug operation.
341 */ 333 */
@@ -382,9 +374,6 @@ static int remove_board(struct slot *p_slot)
382 374
383 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); 375 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
384 376
385 /* Change status to shutdown */
386 p_slot->status = 0x01;
387
388 /* Wait for exclusive access to hardware */ 377 /* Wait for exclusive access to hardware */
389 down(&ctrl->crit_sect); 378 down(&ctrl->crit_sect);
390 379
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 2387e75da0fe..0b8b26beb163 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -750,7 +750,7 @@ static int hpc_power_on_slot(struct slot * slot)
750{ 750{
751 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 751 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
752 u16 slot_cmd; 752 u16 slot_cmd;
753 u16 slot_ctrl; 753 u16 slot_ctrl, slot_status;
754 754
755 int retval = 0; 755 int retval = 0;
756 756
@@ -767,6 +767,14 @@ static int hpc_power_on_slot(struct slot * slot)
767 return -1; 767 return -1;
768 } 768 }
769 769
770 /* Clear sticky power-fault bit from previous power failures */
771 hp_register_read_word(php_ctlr->pci_dev,
772 SLOT_STATUS(slot->ctrl->cap_base), slot_status);
773 slot_status &= PWR_FAULT_DETECTED;
774 if (slot_status)
775 hp_register_write_word(php_ctlr->pci_dev,
776 SLOT_STATUS(slot->ctrl->cap_base), slot_status);
777
770 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); 778 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
771 779
772 if (retval) { 780 if (retval) {