Messages in this thread Patch in this message |  | | | Subject | Re: [PATCH] x86: Get irq for hpet timer | | From | Kevin Hao <> | | Date | Tue, 20 May 2008 17:03:39 +0800 |
On Mon, 2008-05-19 at 18:10 +0200, Clemens Ladisch wrote: > Kevin Hao wrote: > > + for (irq = find_first_bit(&cap, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; > > + irq = find_next_bit(&cap, HPET_MAX_IRQ, 1 + irq)) { > > + if (request_irq(irq, hpet_interrupt, irq_flags, > > + devp->hd_name, (void *)devp)) > > This spams my log with interrupt sharing violations. As long as we do > not know that the interrupt slot is empty, we need IRQF_PROBE_SHARED > here.
Ok, added.
> > Another problem: the interrupt controller doesn't get correctly > initialized for some interrupt line that didn't already have some > routing: > | $ cat /proc/interrupts > | CPU0 > | 0: 63 IO-APIC-edge timer > | 1: 96 IO-APIC-edge i8042 > | 2: 0 XT-PIC-XT hpet2 > | 6: 3 IO-APIC-edge floppy > | 7: 0 IO-APIC-edge parport0 > | 8: 3 IO-APIC-edge rtc > | 9: 0 IO-APIC-fasteoi acpi > | ... > > Additionally, I vaguely remember that on X86, there is some funny stuff > going on with interrupt lines 0, 2 and 8 which means that the interrupt > number passed to request_irq() is not necessarily identical to the > hardware interrupt line. > > I don't know which of these problems is responsible, or if I'm totally > wrong, but on my machine, interrupts from hpet2 do not arrive. >
We can simply skip these special IRQ. :-) Does anyone has a better solution?
---- diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 0fdc627..b04a15d 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -390,6 +390,11 @@ static int hpet_timer_get_irq(struct hpet_dev *devp) struct hpets *hpetp; unsigned long cap, irq_flags; int irq; + /* + * skip IRQ0, IRQ2, IRQ8 because which is always used by some + * legacy device + */ + unsigned long skip_irq = (1 << 0) | (1 << 2) | (1 << 8); timer = devp->hd_timer; hpet = devp->hd_hpet; @@ -411,6 +416,9 @@ static int hpet_timer_get_irq(struct hpet_dev *devp) cap = (readq(&timer->hpet_config) & Tn_INT_ROUTE_CAP_MASK) >> Tn_INT_ROUTE_CAP_SHIFT; + cap &= ~skip_irq; + + irq_flags |= IRQF_PROBE_SHARED; for (irq = find_first_bit(&cap, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; irq = find_next_bit(&cap, HPET_MAX_IRQ, 1 + irq)) { --- Best Regards, Kevin > > Regards, > Clemens
|  |