diff options
author | jhb <jhb@FreeBSD.org> | 2010-12-07 18:49:11 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2010-12-07 18:49:11 +0000 |
commit | 37fc67e5bad45bc2ccc28a4e5323143fdf61384a (patch) | |
tree | 7eca214fa1e02e214567fee31c3b167442ddae0b /sys/dev/acpica | |
parent | 7aa4e35a24d07cbf7ef35c26ef7ac092a2f54e5e (diff) | |
download | FreeBSD-src-37fc67e5bad45bc2ccc28a4e5323143fdf61384a.zip FreeBSD-src-37fc67e5bad45bc2ccc28a4e5323143fdf61384a.tar.gz |
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)
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r-- | sys/dev/acpica/acpi_hpet.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/sys/dev/acpica/acpi_hpet.c b/sys/dev/acpica/acpi_hpet.c index efe5747..97fe991 100644 --- a/sys/dev/acpica/acpi_hpet.c +++ b/sys/dev/acpica/acpi_hpet.c @@ -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"); |