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

Commit c4cecc19 authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by Greg Kroah-Hartman
Browse files

[PATCH] shpchp: Cleanup interrupt handler



This patch cleans up the interrupt handler of shpchp driver. This
patch has no functional changes.

Signed-off-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: Kristen Accardi <kristen.c.accardi@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d4fbf600
Loading
Loading
Loading
Loading
+57 −68
Original line number Diff line number Diff line
@@ -90,6 +90,12 @@
#define	MRLSENSOR		0x40000000
#define ATTN_BUTTON		0x80000000

/*
 * Interrupt Locator Register definitions
 */
#define CMD_INTR_PENDING	(1 << 0)
#define SLOT_INTR_PENDING(i)	(1 << (i + 1))

/*
 * Controller SERR-INT Register
 */
@@ -218,7 +224,7 @@ static spinlock_t list_lock;

static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);

static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs);

static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
static int hpc_check_cmd_status(struct controller *ctrl);
@@ -279,7 +285,7 @@ static void int_poll_timeout(unsigned long lphp_ctlr)
    }

    /* Poll for interrupt events.  regs == NULL => polling */
    shpc_isr( 0, (void *)php_ctlr, NULL );
    shpc_isr(0, php_ctlr->callback_instance_id, NULL );

    init_timer(&php_ctlr->int_poll_timer);
	if (!shpchp_poll_time)
@@ -875,103 +881,86 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
	return retval;
}

static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs)
{
	struct controller *ctrl = NULL;
	struct php_ctlr_state_s *php_ctlr;
	u8 schedule_flag = 0;
	u32 temp_dword, intr_loc, intr_loc2;
	struct controller *ctrl = (struct controller *)dev_id;
	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
	u32 serr_int, slot_reg, intr_loc, intr_loc2;
	int hp_slot;

	if (!dev_id)
		return IRQ_NONE;

	if (!shpchp_poll_mode) { 
		ctrl = (struct controller *)dev_id;
		php_ctlr = ctrl->hpc_ctlr_handle;
	} else { 
		php_ctlr = (struct php_ctlr_state_s *) dev_id;
		ctrl = (struct controller *)php_ctlr->callback_instance_id;
	}

	if (!ctrl)
		return IRQ_NONE;
	
	if (!php_ctlr || !php_ctlr->creg)
		return IRQ_NONE;

	/* Check to see if it was our interrupt */
	intr_loc = shpc_readl(ctrl, INTR_LOC);

	if (!intr_loc)
		return IRQ_NONE;

	dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); 

	if(!shpchp_poll_mode) {
		/* Mask Global Interrupt Mask - see implementation note on p. 139 */
		/* of SHPC spec rev 1.0*/
		temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
		temp_dword |= GLOBAL_INTR_MASK;
		temp_dword &= ~SERR_INTR_RSVDZ_MASK;
		shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
		/*
		 * Mask Global Interrupt Mask - see implementation
		 * note on p. 139 of SHPC spec rev 1.0
		 */
		serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
		serr_int |= GLOBAL_INTR_MASK;
		serr_int &= ~SERR_INTR_RSVDZ_MASK;
		shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);

		intr_loc2 = shpc_readl(ctrl, INTR_LOC);
		dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 
	}

	if (intr_loc & 0x0001) {
	if (intr_loc & CMD_INTR_PENDING) {
		/* 
		 * Command Complete Interrupt Pending 
		 * RO only - clear by writing 1 to the Command Completion
		 * Detect bit in Controller SERR-INT register
		 */
		temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
		temp_dword &= ~SERR_INTR_RSVDZ_MASK;
		shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
		serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
		serr_int &= ~SERR_INTR_RSVDZ_MASK;
		shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);

		ctrl->cmd_busy = 0;
		wake_up_interruptible(&ctrl->queue);
	}

	if ((intr_loc = (intr_loc >> 1)) == 0)
	if (!(intr_loc & ~CMD_INTR_PENDING))
		goto out;

	for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { 
		/* To find out which slot has interrupt pending */
		if ((intr_loc >> hp_slot) & 0x01) {
			temp_dword = shpc_readl(ctrl, SLOT_REG(hp_slot));
		if (!(intr_loc & SLOT_INTR_PENDING(hp_slot)))
			continue;

		slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
		dbg("%s: Slot %x with intr, slot register = %x\n",
				__FUNCTION__, hp_slot, temp_dword);
			if ((php_ctlr->switch_change_callback) &&
			    (temp_dword & MRL_CHANGE_DETECTED))
				schedule_flag += php_ctlr->switch_change_callback(
		    __FUNCTION__, hp_slot, slot_reg);

		if (slot_reg & MRL_CHANGE_DETECTED)
			php_ctlr->switch_change_callback(
				hp_slot, php_ctlr->callback_instance_id);
			if ((php_ctlr->attention_button_callback) &&
			    (temp_dword & BUTTON_PRESS_DETECTED))
				schedule_flag += php_ctlr->attention_button_callback(

		if (slot_reg & BUTTON_PRESS_DETECTED)
			php_ctlr->attention_button_callback(
				hp_slot, php_ctlr->callback_instance_id);
			if ((php_ctlr->presence_change_callback) &&
			    (temp_dword & PRSNT_CHANGE_DETECTED))
				schedule_flag += php_ctlr->presence_change_callback(

		if (slot_reg & PRSNT_CHANGE_DETECTED)
			php_ctlr->presence_change_callback(
				hp_slot , php_ctlr->callback_instance_id);
			if ((php_ctlr->power_fault_callback) &&
			    (temp_dword & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)))
				schedule_flag += php_ctlr->power_fault_callback(

		if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED))
			php_ctlr->power_fault_callback(
				hp_slot, php_ctlr->callback_instance_id);

		/* Clear all slot events */
			temp_dword &= ~SLOT_REG_RSVDZ_MASK;
			shpc_writel(ctrl, SLOT_REG(hp_slot), temp_dword);

			intr_loc2 = shpc_readl(ctrl, INTR_LOC);
			dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 
		}
		slot_reg &= ~SLOT_REG_RSVDZ_MASK;
		shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
	}
 out:
	if (!shpchp_poll_mode) {
		/* Unmask Global Interrupt Mask */
		temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
		temp_dword &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
		shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
		serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
		serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
		shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
	}
	
	return IRQ_HANDLED;