Commit 5a49f203 authored by Rajesh Shah's avatar Rajesh Shah Committed by Linus Torvalds

[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: default avatarRajesh Shah <rajesh.shah@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent dcb89074
...@@ -59,7 +59,6 @@ struct slot { ...@@ -59,7 +59,6 @@ struct slot {
struct slot *next; struct slot *next;
u8 bus; u8 bus;
u8 device; u8 device;
u16 status;
u32 number; u32 number;
u8 state; u8 state;
struct timer_list task_event; struct timer_list task_event;
......
...@@ -207,7 +207,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) ...@@ -207,7 +207,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
* power fault Cleared * power fault Cleared
*/ */
info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
p_slot->status = 0x00;
taskInfo->event_type = INT_POWER_FAULT_CLEAR; taskInfo->event_type = INT_POWER_FAULT_CLEAR;
} else { } else {
/* /*
...@@ -215,8 +214,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) ...@@ -215,8 +214,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
*/ */
info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
taskInfo->event_type = INT_POWER_FAULT; taskInfo->event_type = INT_POWER_FAULT;
/* set power fault status for this board */
p_slot->status = 0xFF;
info("power fault bit %x set\n", hp_slot); info("power fault bit %x set\n", hp_slot);
} }
if (rc) if (rc)
...@@ -317,13 +314,10 @@ static int board_added(struct slot *p_slot) ...@@ -317,13 +314,10 @@ static int board_added(struct slot *p_slot)
return rc; return rc;
} }
dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
/* Check for a power fault */ /* Check for a power fault */
if (p_slot->status == 0xFF) { if (p_slot->hpc_ops->query_power_fault(p_slot)) {
/* power fault occurred, but it was benign */ dbg("%s: power fault detected\n", __FUNCTION__);
rc = POWER_FAILURE; rc = POWER_FAILURE;
p_slot->status = 0;
goto err_exit; goto err_exit;
} }
...@@ -334,8 +328,6 @@ static int board_added(struct slot *p_slot) ...@@ -334,8 +328,6 @@ static int board_added(struct slot *p_slot)
goto err_exit; goto err_exit;
} }
p_slot->status = 0;
/* /*
* Some PCI Express root ports require fixup after hot-plug operation. * Some PCI Express root ports require fixup after hot-plug operation.
*/ */
...@@ -382,9 +374,6 @@ static int remove_board(struct slot *p_slot) ...@@ -382,9 +374,6 @@ static int remove_board(struct slot *p_slot)
dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
/* Change status to shutdown */
p_slot->status = 0x01;
/* Wait for exclusive access to hardware */ /* Wait for exclusive access to hardware */
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
......
...@@ -750,7 +750,7 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -750,7 +750,7 @@ static int hpc_power_on_slot(struct slot * slot)
{ {
struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd; u16 slot_cmd;
u16 slot_ctrl; u16 slot_ctrl, slot_status;
int retval = 0; int retval = 0;
...@@ -767,6 +767,14 @@ static int hpc_power_on_slot(struct slot * slot) ...@@ -767,6 +767,14 @@ static int hpc_power_on_slot(struct slot * slot)
return -1; 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);
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); retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
if (retval) { if (retval) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment