summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2005-03-04 22:23:21 +0000
committermarius <marius@FreeBSD.org>2005-03-04 22:23:21 +0000
commitd730e7dc0a683c07a1bcb12a666d1971b6f739de (patch)
treef0137a61cb51a1bada1585d68d76b4c9a8eebbae
parentee7224dfdd43a3858556ec007e57d600e6150a93 (diff)
downloadFreeBSD-src-d730e7dc0a683c07a1bcb12a666d1971b6f739de.zip
FreeBSD-src-d730e7dc0a683c07a1bcb12a666d1971b6f739de.tar.gz
- sparc64/fhc/fhc.c:
Change fhc(4) to use IRQ numbers instead of RIDs for allocating the IRQs of children. This works similar to e.g. sbus(4), i.e. add the IRQ resources as fully specified to the resource lists of the children, allocate them like normal. When establishing the interrupt search the interrupt maps of the children for a matching INO to determine which map we need to write the fully specified interrupt number to and to enable the mapping (before the RID was used to indicate which interrupt map to use). - dev/puc/puc.c: Revert rev. 1.38, with the above change fhc(4) no longer needs special treatment for allocating IRQs. Thanks to: joerg for providing access to an E3500
-rw-r--r--sys/dev/puc/puc.c9
-rw-r--r--sys/sparc64/fhc/fhc.c96
2 files changed, 57 insertions, 48 deletions
diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c
index 11506e5..86e2a0c 100644
--- a/sys/dev/puc/puc.c
+++ b/sys/dev/puc/puc.c
@@ -97,10 +97,6 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#ifdef __sparc64__
-#include <sparc64/fhc/fhcreg.h>
-#endif
-
#define PUC_ENTRAILS 1
#include <dev/puc/pucvar.h>
@@ -193,12 +189,7 @@ puc_attach(device_t dev, const struct puc_device_description *desc)
printf("puc: name: %s\n", sc->sc_desc.name);
#endif
-
rid = 0;
-#ifdef __sparc64__
- if (strcmp(device_get_name(device_get_parent(dev)), "fhc") == 0)
- rid = FHC_UART;
-#endif
res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | RF_SHAREABLE);
if (!res)
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index e6cc2cd..196f3fe 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -85,7 +85,10 @@ fhc_attach(device_t dev)
bus_addr_t off;
device_t cdev;
uint32_t ctrl;
+ uint32_t *intr;
+ uint32_t iv;
char *name;
+ int nintr;
int nreg;
int i;
@@ -154,6 +157,17 @@ fhc_attach(device_t dev)
}
free(reg, M_OFWPROP);
}
+ nintr = OF_getprop_alloc(child, "interrupts",
+ sizeof(*intr), (void **)&intr);
+ if (nintr != -1) {
+ for (i = 0; i < nintr; i++) {
+ iv = INTINO(intr[i]) |
+ (sc->sc_ign << INTMAP_IGN_SHIFT);
+ resource_list_add(&fdi->fdi_rl,
+ SYS_RES_IRQ, i, iv, iv, 1);
+ }
+ free(intr, M_OFWPROP);
+ }
device_set_ivars(cdev, fdi);
} else
free(name, M_OFWPROP);
@@ -172,6 +186,7 @@ fhc_print_child(device_t dev, device_t child)
rv = bus_print_child_header(dev, child);
rv += resource_list_print_type(&fdi->fdi_rl, "mem",
SYS_RES_MEMORY, "%#lx");
+ rv += resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld");
rv += bus_print_child_footer(dev, child);
return (rv);
}
@@ -184,6 +199,7 @@ fhc_probe_nomatch(device_t dev, device_t child)
fdi = device_get_ivars(child);
device_printf(dev, "<%s>", fdi->fdi_name);
resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY, "%#lx");
+ resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld");
printf(" type %s (no driver attached)\n",
fdi->fdi_type != NULL ? fdi->fdi_type : "unknown");
}
@@ -194,23 +210,41 @@ fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
{
struct fhc_softc *sc;
struct fhc_clr *fc;
+ bus_space_tag_t bt;
+ bus_space_handle_t bh;
int error;
- int rid;
+ int i;
+ long vec;
+ uint32_t inr;
sc = device_get_softc(bus);
- rid = rman_get_rid(r);
+ vec = rman_get_start(r);
+
+ bt = NULL;
+ bh = 0;
+ inr = 0;
+ for (i = FHC_FANFAIL; i <= FHC_TOD; i++) {
+ if (INTINO(bus_space_read_4(sc->sc_bt[i], sc->sc_bh[i],
+ FHC_IMAP)) == INTINO(vec)){
+ bt = sc->sc_bt[i];
+ bh = sc->sc_bh[i];
+ inr = INTINO(vec) | (sc->sc_ign << INTMAP_IGN_SHIFT);
+ break;
+ }
+ }
+ if (inr == 0)
+ return (0);
fc = malloc(sizeof(*fc), M_DEVBUF, M_WAITOK | M_ZERO);
if (fc == NULL)
return (0);
fc->fc_func = func;
fc->fc_arg = arg;
- fc->fc_bt = sc->sc_bt[rid];
- fc->fc_bh = sc->sc_bh[rid];
+ fc->fc_bt = bt;
+ fc->fc_bh = bh;
- bus_space_write_4(sc->sc_bt[rid], sc->sc_bh[rid], FHC_IMAP,
- rman_get_start(r));
- bus_space_read_4(sc->sc_bt[rid], sc->sc_bh[rid], FHC_IMAP);
+ bus_space_write_4(bt, bh, FHC_IMAP, inr);
+ bus_space_read_4(bt, bh, FHC_IMAP);
error = bus_generic_setup_intr(bus, child, r, flags, fhc_intr_stub,
fc, cookiep);
@@ -221,10 +255,9 @@ fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
fc->fc_cookie = *cookiep;
*cookiep = fc;
- bus_space_write_4(sc->sc_bt[rid], sc->sc_bh[rid], FHC_ICLR, 0x0);
- bus_space_write_4(sc->sc_bt[rid], sc->sc_bh[rid], FHC_IMAP,
- INTMAP_ENABLE(rman_get_start(r), PCPU_GET(mid)));
- bus_space_read_4(sc->sc_bt[rid], sc->sc_bh[rid], FHC_IMAP);
+ bus_space_write_4(bt, bh, FHC_ICLR, 0x0);
+ bus_space_write_4(bt, bh, FHC_IMAP, INTMAP_ENABLE(inr, PCPU_GET(mid)));
+ bus_space_read_4(bt, bh, FHC_IMAP);
return (error);
}
@@ -266,43 +299,28 @@ fhc_alloc_resource(device_t bus, device_t child, int type, int *rid,
bus_addr_t cend;
bus_addr_t phys;
int isdefault;
- uint32_t map;
- uint32_t vec;
int i;
isdefault = (start == 0UL && end == ~0UL);
res = NULL;
sc = device_get_softc(bus);
+ fdi = device_get_ivars(child);
+ rle = resource_list_find(&fdi->fdi_rl, type, *rid);
+ if (rle == NULL)
+ return (NULL);
+ if (rle->res != NULL)
+ panic("%s: resource entry is busy", __func__);
+ if (isdefault) {
+ start = rle->start;
+ count = ulmax(count, rle->count);
+ end = ulmax(rle->end, start + count - 1);
+ }
switch (type) {
case SYS_RES_IRQ:
- if (!isdefault || count != 1 || *rid < FHC_FANFAIL ||
- *rid > FHC_TOD)
- break;
-
- map = bus_space_read_4(sc->sc_bt[*rid], sc->sc_bh[*rid],
- FHC_IMAP);
- vec = INTINO(map) | (sc->sc_ign << INTMAP_IGN_SHIFT);
- bus_space_write_4(sc->sc_bt[*rid], sc->sc_bh[*rid],
- FHC_IMAP, vec);
- bus_space_read_4(sc->sc_bt[*rid], sc->sc_bh[*rid], FHC_IMAP);
-
res = bus_generic_alloc_resource(bus, child, type, rid,
- vec, vec, 1, flags);
- if (res != NULL)
- rman_set_rid(res, *rid);
+ start, end, count, flags);
break;
case SYS_RES_MEMORY:
- fdi = device_get_ivars(child);
- rle = resource_list_find(&fdi->fdi_rl, type, *rid);
- if (rle == NULL)
- return (NULL);
- if (rle->res != NULL)
- panic("%s: resource entry is busy", __func__);
- if (isdefault) {
- start = rle->start;
- count = ulmax(count, rle->count);
- end = ulmax(rle->end, start + count - 1);
- }
for (i = 0; i < sc->sc_nrange; i++) {
coffset = sc->sc_ranges[i].coffset;
cend = coffset + sc->sc_ranges[i].size - 1;
@@ -334,7 +352,7 @@ fhc_release_resource(device_t bus, device_t child, int type, int rid,
int error;
error = bus_generic_release_resource(bus, child, type, rid, r);
- if (type != SYS_RES_MEMORY || error != 0)
+ if (error != 0)
return (error);
fdi = device_get_ivars(child);
rle = resource_list_find(&fdi->fdi_rl, type, rid);
OpenPOWER on IntegriCloud