#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/reboot.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>
#include <machine/cpufunc.h>
#include <hppa/dev/viper.h>
#include <hppa/gsc/gscbusvar.h>
int gscmatch(struct device *, void *, void *);
void gscattach(struct device *, struct device *, void *);
const struct cfattach gsc_ca = {
sizeof(struct gsc_softc), gscmatch, gscattach
};
struct cfdriver gsc_cd = {
NULL, "gsc", DV_DULL
};
int
gscmatch(struct device *parent, void *cfdata, void *aux)
{
struct confargs *ca = aux;
return !strcmp(ca->ca_name, "gsc");
}
void
gscattach(struct device *parent, struct device *self, void *aux)
{
struct gsc_softc *sc = (struct gsc_softc *)self;
struct gsc_attach_args *ga = aux;
int s, irqbit;
sc->sc_iot = ga->ga_iot;
sc->sc_ic = ga->ga_ic;
irqbit = cpu_intr_findirq();
if (irqbit >= 0)
printf(" irq %d", irqbit);
#ifdef USELEDS
if (machine_ledaddr)
printf(": %sleds", machine_ledword? "word" : "");
#endif
printf ("\n");
if (irqbit < 0)
sc->sc_ih = NULL;
else
sc->sc_ih = cpu_intr_establish(IPL_NESTED, irqbit,
gsc_intr, (void *)sc->sc_ic, sc->sc_dev.dv_xname);
if (sc->sc_ih == NULL) {
printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
return;
}
s = splhigh();
if (ga->ga_parent == gsc_asp)
viper_setintrwnd(1 << irqbit);
else
sc->sc_ic->iar = cpu_gethpa(0) | (31 - irqbit);
splx(s);
pdc_scanbus(self, &ga->ga_ca, MAXMODBUS, 0, 0);
}
int
gscprint(void *aux, const char *pnp)
{
struct gsc_attach_args *ga = aux;
if (pnp)
printf("%s at %s", ga->ga_name, pnp);
return (UNCONF);
}
void *
gsc_intr_establish(struct gsc_softc *sc, int irq, int pri,
int (*handler)(void *v), void *arg, const char *name)
{
void *iv;
if ((iv = cpu_intr_map(sc->sc_ih, pri, irq, handler, arg, name)))
sc->sc_ic->imr |= (1 << irq);
else {
#ifdef GSCDEBUG
printf("%s: attaching irq %d, already occupied\n",
sc->sc_dev.dv_xname, irq);
#endif
}
return (iv);
}
void
gsc_intr_disestablish(struct gsc_softc *sc, void *v)
{
#if notyet
sc->sc_ic->imr &= ~(1 << irq);
cpu_intr_unmap(sc->sc_ih, v);
#endif
}