Use proper resource ID's for HPET IRQ resources. This mostly consists of
looking to see if there is an existing IRQ resource for a given IRQ provided by the BIOS and using that RID if so. Otherwise, allocate a new RID for the new IRQ. Reviewed by: mav (a while ago)
This commit is contained in:
parent
bb7c5fa31c
commit
4a588c1ba7
@ -303,6 +303,23 @@ hpet_find(ACPI_HANDLE handle, UINT32 level, void *context,
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an existing IRQ resource that matches the requested IRQ range
|
||||
* and return its RID. If one is not found, use a new RID.
|
||||
*/
|
||||
static int
|
||||
hpet_find_irq_rid(device_t dev, u_long start, u_long end)
|
||||
{
|
||||
u_long irq;
|
||||
int error, rid;
|
||||
|
||||
for (rid = 0;; rid++) {
|
||||
error = bus_get_resource(dev, SYS_RES_IRQ, rid, &irq, NULL);
|
||||
if (error != 0 || (start <= irq && irq <= end))
|
||||
return (rid);
|
||||
}
|
||||
}
|
||||
|
||||
/* Discover the HPET via the ACPI table of the same name. */
|
||||
static void
|
||||
hpet_identify(driver_t *driver, device_t parent)
|
||||
@ -540,6 +557,7 @@ hpet_attach(device_t dev)
|
||||
dvectors &= ~(1 << t->irq);
|
||||
}
|
||||
if (t->irq >= 0) {
|
||||
t->intr_rid = hpet_find_irq_rid(dev, t->irq, t->irq);
|
||||
if (!(t->intr_res =
|
||||
bus_alloc_resource(dev, SYS_RES_IRQ, &t->intr_rid,
|
||||
t->irq, t->irq, 1, RF_ACTIVE))) {
|
||||
@ -590,12 +608,12 @@ hpet_attach(device_t dev)
|
||||
}
|
||||
bus_write_4(sc->mem_res, HPET_ISR, 0xffffffff);
|
||||
sc->irq = -1;
|
||||
sc->intr_rid = -1;
|
||||
/* If at least one timer needs legacy IRQ - set it up. */
|
||||
if (sc->useirq) {
|
||||
j = i = fls(cvectors) - 1;
|
||||
while (j > 0 && (cvectors & (1 << (j - 1))) != 0)
|
||||
j--;
|
||||
sc->intr_rid = hpet_find_irq_rid(dev, j, i);
|
||||
if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
|
||||
&sc->intr_rid, j, i, 1, RF_SHAREABLE | RF_ACTIVE)))
|
||||
device_printf(dev,"Can't map interrupt.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user