Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ struct slot {
	struct slot *next;
	u8 bus;
	u8 device;
	u16 status;
	u32 number;
	u8 state;
	struct timer_list task_event;
+2 −13
Original line number Diff line number Diff line
@@ -207,7 +207,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
		 * power fault Cleared
		 */
		info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
		p_slot->status = 0x00;
		taskInfo->event_type = INT_POWER_FAULT_CLEAR;
	} 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);
		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);
	}
	if (rc)
@@ -317,13 +314,10 @@ static int board_added(struct slot *p_slot)
		return rc;
	}

	dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);

	/* Check for a power fault */
	if (p_slot->status == 0xFF) {
		/* power fault occurred, but it was benign */
	if (p_slot->hpc_ops->query_power_fault(p_slot)) {
		dbg("%s: power fault detected\n", __FUNCTION__);
		rc = POWER_FAILURE;
		p_slot->status = 0;
		goto err_exit;
	}

@@ -334,8 +328,6 @@ static int board_added(struct slot *p_slot)
		goto err_exit;
	}

	p_slot->status = 0;

	/*
	 * 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);

	/* Change status to shutdown */
	p_slot->status = 0x01;

	/* Wait for exclusive access to hardware */
	down(&ctrl->crit_sect);

+9 −1
Original line number Diff line number Diff line
@@ -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;
	u16 slot_cmd;
	u16 slot_ctrl;
	u16 slot_ctrl, slot_status;

	int retval = 0;

@@ -767,6 +767,14 @@ static int hpc_power_on_slot(struct slot * slot)
		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);

	if (retval) {