diff options
author | benno <benno@FreeBSD.org> | 2003-01-09 06:21:42 +0000 |
---|---|---|
committer | benno <benno@FreeBSD.org> | 2003-01-09 06:21:42 +0000 |
commit | ee721e5aaae05206a861d75da3a0be6ec442f014 (patch) | |
tree | 81382a6ce59ba85ab0612e38099bb0183baeac62 /sys/powerpc | |
parent | e9de2598cfe47f91ad97a4e43a073d67c88f6068 (diff) | |
download | FreeBSD-src-ee721e5aaae05206a861d75da3a0be6ec442f014.zip FreeBSD-src-ee721e5aaae05206a861d75da3a0be6ec442f014.tar.gz |
- Remove the ignore list and replace it with a quirk list of sorts.
- Add a quirk type for devices whose interrupt properties are actually
attached to their children.
- Flag the "escc" (zs-alike serial controller) device as having this quirk.
- Rework the interrupt discovery code to deal with devices that have more than
one interrupt.
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/powermac/macio.c | 78 | ||||
-rw-r--r-- | sys/powerpc/powermac/maciovar.h | 3 |
2 files changed, 58 insertions, 23 deletions
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c index bf8c577..53db86a 100644 --- a/sys/powerpc/powermac/macio.c +++ b/sys/powerpc/powermac/macio.c @@ -127,22 +127,31 @@ static struct macio_pci_dev { * Devices to exclude from the probe * XXX some of these may be required in the future... */ -static char *macio_excl_name[] = { - "interrupt-controller", - "escc-legacy", - "gpio", - "timer", - NULL +#define MACIO_QUIRK_IGNORE 0x00000001 +#define MACIO_QUIRK_CHILD_HAS_INTR 0x00000002 + +struct macio_quirk_entry { + const char *mq_name; + int mq_quirks; +}; + +static struct macio_quirk_entry macio_quirks[] = { + { "interrupt-controller", MACIO_QUIRK_IGNORE }, + { "escc-legacy", MACIO_QUIRK_IGNORE }, + { "gpio", MACIO_QUIRK_IGNORE }, + { "timer", MACIO_QUIRK_IGNORE }, + { "escc", MACIO_QUIRK_CHILD_HAS_INTR }, + { NULL, 0 } }; static int -macio_inlist(char *name) +macio_get_quirks(const char *name) { - int i; + struct macio_quirk_entry *mqe; - for (i = 0; macio_excl_name[i] != NULL; i++) - if (strcmp(name, macio_excl_name[i]) == 0) - return (1); + for (mqe = macio_quirks; mqe->mq_name != NULL; mqe++) + if (strcmp(name, mqe->mq_name) == 0) + return (mqe->mq_quirks); return (0); } @@ -153,15 +162,27 @@ macio_inlist(char *name) static void macio_add_intr(phandle_t devnode, struct macio_devinfo *dinfo) { - u_int intr = -1; - - if ((OF_getprop(devnode, "interrupts", &intr, sizeof(intr)) != -1) || - (OF_getprop(devnode, "AAPL,interrupts", - &intr, sizeof(intr) != -1))) { - resource_list_add(&dinfo->mdi_resources, - SYS_RES_IRQ, 0, intr, intr, 1); - } - dinfo->mdi_interrupt = intr; + int intr; + + if (dinfo->mdi_ninterrupts >= 5) { + printf("macio: device has more than 5 interrupts\n"); + return; + } + + if (OF_getprop(devnode, "interrupts", &intr, sizeof(intr)) == -1) { + if (OF_getprop(devnode, "AAPL,interrupts", &intr, + sizeof(intr)) == -1) + return; + } + + if (intr == -1) + return; + + resource_list_add(&dinfo->mdi_resources, SYS_RES_IRQ, + dinfo->mdi_ninterrupts, intr, intr, 1); + + dinfo->mdi_interrupts[dinfo->mdi_ninterrupts] = intr; + dinfo->mdi_ninterrupts++; } @@ -183,7 +204,7 @@ macio_add_reg(phandle_t devnode, struct macio_devinfo *dinfo) dinfo->mdi_nregs = 1; start = dinfo->mdi_reg[0]; end = start + dinfo->mdi_reg[1] - 1; - resource_list_add(&dinfo->mdi_resources, SYS_RES_MEMORY, 0, + resource_list_add_next(&dinfo->mdi_resources, SYS_RES_MEMORY, start, end, end - start + 1); } else { dinfo->mdi_nregs = -1; @@ -221,9 +242,11 @@ macio_attach(device_t dev) struct macio_devinfo *dinfo; phandle_t root; phandle_t child; + phandle_t subchild; device_t cdev; u_int reg[3]; char *name, *type; + int quirks; sc = device_get_softc(dev); root = sc->sc_node = OF_finddevice("mac-io"); @@ -255,7 +278,8 @@ macio_attach(device_t dev) OF_getprop_alloc(child, "name", 1, (void **)&name); OF_getprop_alloc(child, "device_type", 1, (void **)&type); - if (macio_inlist(name)) { + quirks = macio_get_quirks(name); + if ((quirks & MACIO_QUIRK_IGNORE) != 0) { free(name, M_OFWPROP); free(type, M_OFWPROP); continue; @@ -269,8 +293,18 @@ macio_attach(device_t dev) dinfo->mdi_node = child; dinfo->mdi_name = name; dinfo->mdi_device_type = type; + dinfo->mdi_ninterrupts = 0; macio_add_intr(child, dinfo); macio_add_reg(child, dinfo); + + + if ((quirks & MACIO_QUIRK_CHILD_HAS_INTR) != 0) { + for (subchild = OF_child(child); subchild != 0; + subchild = OF_peer(subchild)) { + macio_add_intr(subchild, dinfo); + } + } + device_set_ivars(cdev, dinfo); } else { free(name, M_OFWPROP); diff --git a/sys/powerpc/powermac/maciovar.h b/sys/powerpc/powermac/maciovar.h index 9570f5b..7882bca 100644 --- a/sys/powerpc/powermac/maciovar.h +++ b/sys/powerpc/powermac/maciovar.h @@ -82,7 +82,8 @@ struct macio_devinfo { phandle_t mdi_node; char *mdi_name; char *mdi_device_type; - int mdi_interrupt; + int mdi_interrupts[5]; + int mdi_ninterrupts; int mdi_base; int mdi_nregs; u_int mdi_reg[MACIO_MAXREG]; |