Hi Loic:
Thank you very much,I found the interrupt handler function mt_eint_demux() in irq-mt-eic.c , and from the count this function called, the cpu lost some interrupts。 I think when this function is processing, next interrupt comes, so it is not processed in time. so, is there some suggestions?
static irqreturn_t mt_eint_demux(unsigned irq, struct irq_desc *desc)
{
unsigned int index, rst;
unsigned long base;
unsigned int status = 0;
unsigned int status_check;
unsigned int reg_base, offset;
unsigned long long t1 = 0;
unsigned long long t2 = 0;
int mask_status = 0;
struct irq_chip *chip = irq_get_chip(irq);
struct eint_chip *eint_chip = irq_get_handler_data(irq);
chained_irq_enter(chip, desc);
/*
* NoteXXX: Need to get the wake up for 0.5 seconds when an EINT intr tirggers.
* This is used to prevent system from suspend such that other drivers
* or applications can have enough time to obtain their own wake lock.
* (This information is gotten from the power management owner.)
*/
tasklet_schedule(&eint_tasklet);
dbgmsg("EINT Module - %s ISR Start\n", __func__);
for (reg_base = 0; reg_base < EINT_MAX_CHANNEL; reg_base += 32) {
/* read status register every 32 interrupts */
status = mt_eint_get_status(reg_base);
if (status)
dbgmsg("EINT Module - index:%d,EINT_STA = 0x%x\n", reg_base, status);
else
continue;
for (offset = 0; offset < 32; offset++) {
index = reg_base + offset;
if (index >= EINT_MAX_CHANNEL)
break;
status_check = status & (1 << (index % 32));
if (!status_check)
continue;
/* we got an eint */
EINT_FUNC.count[index]++;
/* deal with EINT from request_irq() */
dbgmsg("Got EINT %d: go with new mt_eint\n", index);
//printk(KERN_ALERT"Got EINT %d: go with new mt_eint\n", index);
if ((EINT_FUNC.is_deb_en[index] == 1)
&& (index >= MAX_HW_DEBOUNCE_CNT)) {
/* if its debounce is enable and it is a sw debounce */
mt_eint_mask(index);
dbgmsg("got sw index %d\n", index);
mt_eint_set_timer_event(index);
} else {
dbgmsg("got hw index %d\n", index);
t1 = sched_clock();
generic_handle_irq(index + EINT_IRQ_BASE);
t2 = sched_clock();
if ((EINT_FUNC.is_deb_en[index] == 1)
&& (index < MAX_HW_DEBOUNCE_CNT)) {
mask_status = (mt_eint_get_mask(index) == 1) ? 1 : 0;
mt_eint_mask(index);
/* Don't need to use reset ? */
/* reset debounce counter */
base = (index / 4) * 4 + EINT_DBNC_SET_BASE;
rst = (EINT_DBNC_RST_BIT <<
EINT_DBNC_SET_RST_BITS) << ((index % 4) * 8);
mt_reg_sync_writel(rst, base);
if (mask_status == 0)
mt_eint_unmask(index);
}
#if (EINT_DEBUG == 1)
dbgmsg(“EINT Module - EINT_STA after ack = 0x%x\n”,
mt_eint_get_status(index));
#endif
if ((t2 - t1) > EINT_DELAY_WARNING)
pr_warn("[EINT]Warn!EINT:%d run too long,s:%llu,e:%llu,total:%llu\n",
index, t1, t2, (t2 - t1));
}
if (eint_chip->dual_edges[index])
mt_eint_flip_edge(eint_chip, index);
}
#ifdef CONFIG_MTK_EIC_HISTORY_DUMP
insert_trigger_entity(index, 1, t1);
#endif
}
dbgmsg("EINT Module - %s ISR END\n", __func__);
chained_irq_exit(chip, desc);
return IRQ_HANDLED;
}