[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>
This commit is contained in:
parent
dcb890749b
commit
5a49f2036a
|
@ -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)
|
||||||
* 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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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) {
|
||||||
|
|
Reference in New Issue