1 /* $OpenBSD: gscbus.c,v 1.31 2018/05/14 13:54:39 kettenis Exp $ */
2
3 /*
4 * Copyright (c) 1998 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* #define GSCDEBUG */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/device.h>
34 #include <sys/malloc.h>
35 #include <sys/mbuf.h>
36 #include <sys/reboot.h>
37
38 #include <machine/iomod.h>
39 #include <machine/autoconf.h>
40 #include <machine/cpufunc.h>
41 #include <hppa/dev/viper.h>
42
43 #include <hppa/gsc/gscbusvar.h>
44
45 int gscmatch(struct device *, void *, void *);
46 void gscattach(struct device *, struct device *, void *);
47
48 const struct cfattach gsc_ca = {
49 sizeof(struct gsc_softc), gscmatch, gscattach
50 };
51
52 struct cfdriver gsc_cd = {
53 NULL, "gsc", DV_DULL
54 };
55
56 int
gscmatch(parent,cfdata,aux)57 gscmatch(parent, cfdata, aux)
58 struct device *parent;
59 void *cfdata;
60 void *aux;
61 {
62 struct confargs *ca = aux;
63
64 return !strcmp(ca->ca_name, "gsc");
65 }
66
67 void
gscattach(parent,self,aux)68 gscattach(parent, self, aux)
69 struct device *parent;
70 struct device *self;
71 void *aux;
72 {
73 struct gsc_softc *sc = (struct gsc_softc *)self;
74 struct gsc_attach_args *ga = aux;
75 int s, irqbit;
76
77 sc->sc_iot = ga->ga_iot;
78 sc->sc_ic = ga->ga_ic;
79
80 irqbit = cpu_intr_findirq();
81 if (irqbit >= 0)
82 printf(" irq %d", irqbit);
83
84 #ifdef USELEDS
85 if (machine_ledaddr)
86 printf(": %sleds", machine_ledword? "word" : "");
87 #endif
88 printf ("\n");
89
90 if (irqbit < 0)
91 sc->sc_ih = NULL;
92 else
93 sc->sc_ih = cpu_intr_establish(IPL_NESTED, irqbit,
94 gsc_intr, (void *)sc->sc_ic, sc->sc_dev.dv_xname);
95 if (sc->sc_ih == NULL) {
96 printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname);
97 return;
98 }
99
100 /*
101 * On ASP, the IAR register is not writable; we need to go through
102 * the memory controller to achieve proper routing.
103 */
104 s = splhigh();
105 if (ga->ga_parent == gsc_asp)
106 viper_setintrwnd(1 << irqbit);
107 else
108 sc->sc_ic->iar = cpu_gethpa(0) | (31 - irqbit);
109 splx(s);
110
111 pdc_scanbus(self, &ga->ga_ca, MAXMODBUS, 0, 0);
112 }
113
114 int
gscprint(aux,pnp)115 gscprint(aux, pnp)
116 void *aux;
117 const char *pnp;
118 {
119 struct gsc_attach_args *ga = aux;
120
121 if (pnp)
122 printf("%s at %s", ga->ga_name, pnp);
123 return (UNCONF);
124 }
125
126 void *
gsc_intr_establish(sc,irq,pri,handler,arg,name)127 gsc_intr_establish(sc, irq, pri, handler, arg, name)
128 struct gsc_softc *sc;
129 int pri;
130 int irq;
131 int (*handler)(void *v);
132 void *arg;
133 const char *name;
134 {
135 void *iv;
136
137 if ((iv = cpu_intr_map(sc->sc_ih, pri, irq, handler, arg, name)))
138 sc->sc_ic->imr |= (1 << irq);
139 else {
140 #ifdef GSCDEBUG
141 printf("%s: attaching irq %d, already occupied\n",
142 sc->sc_dev.dv_xname, irq);
143 #endif
144 }
145
146 return (iv);
147 }
148
149 void
gsc_intr_disestablish(sc,v)150 gsc_intr_disestablish(sc, v)
151 struct gsc_softc *sc;
152 void *v;
153 {
154 #if notyet
155 sc->sc_ic->imr &= ~(1 << irq);
156
157 cpu_intr_unmap(sc->sc_ih, v);
158 #endif
159 }
160