summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_hpet.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/acpica/acpi_hpet.c')
-rw-r--r--sys/dev/acpica/acpi_hpet.c20
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");
OpenPOWER on IntegriCloud