mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 14:34:28 +08:00
[PATCH] shpchp: Cleanup interrupt handler
This patch cleans up the interrupt handler of shpchp driver. This patch has no functional changes. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Cc: Kristen Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
d4fbf60066
commit
c4cecc1937
@ -90,6 +90,12 @@
|
|||||||
#define MRLSENSOR 0x40000000
|
#define MRLSENSOR 0x40000000
|
||||||
#define ATTN_BUTTON 0x80000000
|
#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
|
* Controller SERR-INT Register
|
||||||
*/
|
*/
|
||||||
@ -218,7 +224,7 @@ static spinlock_t list_lock;
|
|||||||
|
|
||||||
static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
|
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 void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
|
||||||
static int hpc_check_cmd_status(struct controller *ctrl);
|
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 */
|
/* 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);
|
init_timer(&php_ctlr->int_poll_timer);
|
||||||
if (!shpchp_poll_time)
|
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;
|
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 controller *ctrl = (struct controller *)dev_id;
|
||||||
struct php_ctlr_state_s *php_ctlr;
|
struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
|
||||||
u8 schedule_flag = 0;
|
u32 serr_int, slot_reg, intr_loc, intr_loc2;
|
||||||
u32 temp_dword, intr_loc, intr_loc2;
|
|
||||||
int hp_slot;
|
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 */
|
/* Check to see if it was our interrupt */
|
||||||
intr_loc = shpc_readl(ctrl, INTR_LOC);
|
intr_loc = shpc_readl(ctrl, INTR_LOC);
|
||||||
|
|
||||||
if (!intr_loc)
|
if (!intr_loc)
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
|
||||||
dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
|
dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
|
||||||
|
|
||||||
if(!shpchp_poll_mode) {
|
if(!shpchp_poll_mode) {
|
||||||
/* Mask Global Interrupt Mask - see implementation note on p. 139 */
|
/*
|
||||||
/* of SHPC spec rev 1.0*/
|
* Mask Global Interrupt Mask - see implementation
|
||||||
temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
|
* note on p. 139 of SHPC spec rev 1.0
|
||||||
temp_dword |= GLOBAL_INTR_MASK;
|
*/
|
||||||
temp_dword &= ~SERR_INTR_RSVDZ_MASK;
|
serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
|
||||||
shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
|
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);
|
intr_loc2 = shpc_readl(ctrl, INTR_LOC);
|
||||||
dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
|
dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intr_loc & 0x0001) {
|
if (intr_loc & CMD_INTR_PENDING) {
|
||||||
/*
|
/*
|
||||||
* Command Complete Interrupt Pending
|
* Command Complete Interrupt Pending
|
||||||
* RO only - clear by writing 1 to the Command Completion
|
* RO only - clear by writing 1 to the Command Completion
|
||||||
* Detect bit in Controller SERR-INT register
|
* Detect bit in Controller SERR-INT register
|
||||||
*/
|
*/
|
||||||
temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
|
serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
|
||||||
temp_dword &= ~SERR_INTR_RSVDZ_MASK;
|
serr_int &= ~SERR_INTR_RSVDZ_MASK;
|
||||||
shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
|
shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
|
||||||
|
|
||||||
ctrl->cmd_busy = 0;
|
ctrl->cmd_busy = 0;
|
||||||
wake_up_interruptible(&ctrl->queue);
|
wake_up_interruptible(&ctrl->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((intr_loc = (intr_loc >> 1)) == 0)
|
if (!(intr_loc & ~CMD_INTR_PENDING))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
|
for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
|
||||||
/* To find out which slot has interrupt pending */
|
/* To find out which slot has interrupt pending */
|
||||||
if ((intr_loc >> hp_slot) & 0x01) {
|
if (!(intr_loc & SLOT_INTR_PENDING(hp_slot)))
|
||||||
temp_dword = shpc_readl(ctrl, SLOT_REG(hp_slot));
|
continue;
|
||||||
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(
|
|
||||||
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(
|
|
||||||
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(
|
|
||||||
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(
|
|
||||||
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);
|
slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
|
||||||
dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
|
dbg("%s: Slot %x with intr, slot register = %x\n",
|
||||||
}
|
__FUNCTION__, hp_slot, slot_reg);
|
||||||
|
|
||||||
|
if (slot_reg & MRL_CHANGE_DETECTED)
|
||||||
|
php_ctlr->switch_change_callback(
|
||||||
|
hp_slot, php_ctlr->callback_instance_id);
|
||||||
|
|
||||||
|
if (slot_reg & BUTTON_PRESS_DETECTED)
|
||||||
|
php_ctlr->attention_button_callback(
|
||||||
|
hp_slot, php_ctlr->callback_instance_id);
|
||||||
|
|
||||||
|
if (slot_reg & PRSNT_CHANGE_DETECTED)
|
||||||
|
php_ctlr->presence_change_callback(
|
||||||
|
hp_slot , php_ctlr->callback_instance_id);
|
||||||
|
|
||||||
|
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 */
|
||||||
|
slot_reg &= ~SLOT_REG_RSVDZ_MASK;
|
||||||
|
shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (!shpchp_poll_mode) {
|
if (!shpchp_poll_mode) {
|
||||||
/* Unmask Global Interrupt Mask */
|
/* Unmask Global Interrupt Mask */
|
||||||
temp_dword = shpc_readl(ctrl, SERR_INTR_ENABLE);
|
serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
|
||||||
temp_dword &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
|
serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
|
||||||
shpc_writel(ctrl, SERR_INTR_ENABLE, temp_dword);
|
shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
Loading…
Reference in New Issue
Block a user