Re: better leve triggered IRQ management needed

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

 




On Sun, 30 Apr 2006, Neil Brown wrote:
> 
> The thing is: This is exactly what I am currently doing to solve the
> problem.

I'm not entirely surprised. As mentioned, the ELCR register _originally_ 
selected between EISA (level) and ISA (edge) interrupts.

But EISA (and later PCI) interrupts were not just level, they were level 
active _low_. While old ISA interrupts are edge-triggered, active _high_.

Which explains why it not only changes the trigger, but also the polarity.

Now, fast-forward a decade or two, and imagine that the world is 99% PCI, 
and nobody really has any devices that are _electrically_ ISA any more, 
but there are some legacy stuff that _looks_ like ISA. What would you do 
to simplify your life from a hw perspective?

I suspect that the thing to do is to internally just say that all 
interrupts are active low. There's no reason to _really_ have active high, 
because there are no real devices left that drive the irq line that way. 

Now, the _sane_ thing to do would be to also make all interrupts be 
level-triggered, and make the whole ELCR register be a total dummy 
register. But you can't really do that without being worried about 
breaking compatibility (for example, the timer interrupt is a 50% 
duty-cycle on/off thing, so it really _does_ end up being edge-triggered). 

So you leave the ELCR register mattering for a edge/level thing, but the 
polarity issue is just gone.

But then on _other_ southbridges, you'll have the old behaviour, and there 
simply is no way for the OS to know. Yeah, we could look at the 
nortbridge and southbridge combination, and perhaps know that some of them 
always have a "active low" polarity regardless of ELCR. But nobody even 
_documents_ these things, exactly because it's not supposed to matter.

So we're kind of screwed. We have to _act_ as if we still lived in the 
middle ages, and people still used edge-triggered active-high interrupts. 
Even when it's not necessarily the case any more..

Gaah.

That said, I'm surprised that the kernel doesn't set ELCR for you. If it 
sees a PCI device, it really should know that it's a PCI interrupt. I 
wonder if we should do the following.. (Does this automatically make it do 
the right thing on your machine?)

			Linus

---
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 7323544..6e3eaef 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -881,6 +881,7 @@ static int pcibios_lookup_irq(struct pci
 	((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
 		DBG(" -> got IRQ %d\n", irq);
 		msg = "Found";
+		eisa_set_level_irq(newirq);
 	} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
 		DBG(" -> assigning IRQ %d", newirq);
 		if (r->set(pirq_router_dev, dev, pirq, newirq)) {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux