Re: ISR for shared IRQ is called again and again

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 17:44 Wed 25 Feb     , Denis Borisevich wrote:
> Hi!
> I've done some tests and here is what I figured out: the interrupts
> assigned to the device controlled by the ahci driver keep going even
> without my driver loaded and even with all my boards removed from
> system physically. So it seems that everything ok.
> But I have another question concerning interrupts:
> Let's take the situation I described in my first and second posts - I
> have a system with the PCI board which I develop driver for. This
> board shares interrupt with the device controlled by ahci driver. The
> question is why every interrupt I got on this line is interpreted by
> my driver as the interrupt which belongs to it?

If an interrupt is shared, the kernel does not know which device a raised
interrupt belongs to. For this reason, it is delivered to every driver which
has an interrupt handler for this interrupt.

> Here is the code I use:
> 
> === CODE BELOW ===
> 
> to register ISR:
> struct my_dev *board;
> request_irq(board->irq, my_interrupt_handler, IRQF_SHARED, "my_module", board);
> 
> ISR:
> static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
> {
>     struct my_dev *board;
>     int i, retval = IRQ_NONE;
> 
>     // find out which board got an interrupt
>     for (i = 0; i < MAX_BOARDS; i++)
>         if (dev_id == &my_boards[i]) {
>         board = dev_id;
>         break;
>     }
> 
>     // Check if interrupt was issued by another device (in case of shared
>     // interrupt line).
>     if (i == MAX_BOARDS)
>         goto handled;
>     if (board == NULL)
>         goto handled;
> 
>     // if we are here then it's our interrupt
>     retval = IRQ_HANDLED;
> 
>     /* here goes some checks on the device registers
>        to know if there is interrupts pending in it.
>        these checks are sure to be right. If there's no
>        interrupt, then debug message "no interrupt" is
>        printed.
>     */
>      .......
>     /* here goes the interrupt handling, if the previous check
>        was successful
>     */
>     .......
> 
>     handled:
>        return retval;
> }
> 
> === CODE ABOVE ===
> 
> So, what do I have now. When no program touches my device (it is
> idling) and the ahci driver is loaded I have this "no interrupt"
> message in dmesg output 20-30 times per second. When some application
> uses my device I have the proper printouts (the kind of interrupt and
> so on) and bunch of these "no interrupt". When I install my board into
> another PCI slot (and get another interrupt line) I never see these
> "no interrupt" messages, but only the ones concerning to the actual
> interrupt handling in my driver. Which indicates that driver works as
> intended. The questions is why the dev_id parameter of
> my_interrupt_handler() holds the data which belongs to one of the
> boards controlled by my driver (which is the reason why the check in
> the very beginning of ISR routine is passed)?

The dev_id is the what you passed it request_irq. You do not need the loop,
because you will not be called if dev_id is not your device. The 2
if...goto handled should never happen. What you need to do in the interrupt
handler is to ask the device if it has raised the interrupt and do the
interrupt handling if necessary. Something like this:

static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
{
	struct my_dev *board = dev_id;

	int interrupts_pending = do_some_check;

	if (interrupts_pending == 0) {
		/* probably another device which is sharing the interrupt has
		 * raised thi irq
		 */
		return IRQ_NONE;
	}

	/* here goes the interrupt handling */

	return IRQ_HANDLED;
}

	-Michi

-- 
programing a layer 3+4 network protocol for mesh networks
see http://michaelblizek.twilightparadox.com


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux