fhc.c (170387) | fhc.c (172066) |
---|---|
1/*- 2 * Copyright (c) 2003 Jake Burkholder. 3 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 Jake Burkholder. 3 * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/sparc64/fhc/fhc.c 170387 2007-06-06 22:19:23Z piso $"); | 29__FBSDID("$FreeBSD: head/sys/sparc64/fhc/fhc.c 172066 2007-09-06 19:16:30Z marius $"); |
30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/kernel.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37#include <sys/pcpu.h> --- 7 unchanged lines hidden (view full) --- 45#include <machine/bus_common.h> 46#include <machine/resource.h> 47 48#include <sys/rman.h> 49 50#include <sparc64/fhc/fhcreg.h> 51#include <sparc64/sbus/ofw_sbus.h> 52 | 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bus.h> 34#include <sys/kernel.h> 35#include <sys/malloc.h> 36#include <sys/module.h> 37#include <sys/pcpu.h> --- 7 unchanged lines hidden (view full) --- 45#include <machine/bus_common.h> 46#include <machine/resource.h> 47 48#include <sys/rman.h> 49 50#include <sparc64/fhc/fhcreg.h> 51#include <sparc64/sbus/ofw_sbus.h> 52 |
53struct fhc_clr { 54 driver_filter_t *fc_filter; 55 driver_intr_t *fc_func; 56 void *fc_arg; 57 void *fc_cookie; 58 bus_space_tag_t fc_bt; 59 bus_space_handle_t fc_bh; 60}; 61 | |
62struct fhc_devinfo { 63 struct ofw_bus_devinfo fdi_obdinfo; 64 struct resource_list fdi_rl; 65}; 66 67struct fhc_softc { | 53struct fhc_devinfo { 54 struct ofw_bus_devinfo fdi_obdinfo; 55 struct resource_list fdi_rl; 56}; 57 58struct fhc_softc { |
68 struct resource * sc_memres[FHC_NREG]; 69 bus_space_handle_t sc_bh[FHC_NREG]; 70 bus_space_tag_t sc_bt[FHC_NREG]; | 59 struct resource *sc_memres[FHC_NREG]; |
71 int sc_nrange; 72 struct sbus_ranges *sc_ranges; | 60 int sc_nrange; 61 struct sbus_ranges *sc_ranges; |
73 uint32_t sc_board; | |
74 int sc_ign; 75 struct cdev *sc_led_dev; | 62 int sc_ign; 63 struct cdev *sc_led_dev; |
76 int sc_flags; 77#define FHC_CENTRAL (1 << 0) | |
78}; 79 80static device_probe_t fhc_probe; 81static device_attach_t fhc_attach; 82static bus_print_child_t fhc_print_child; 83static bus_probe_nomatch_t fhc_probe_nomatch; 84static bus_setup_intr_t fhc_setup_intr; | 64}; 65 66static device_probe_t fhc_probe; 67static device_attach_t fhc_attach; 68static bus_print_child_t fhc_print_child; 69static bus_probe_nomatch_t fhc_probe_nomatch; 70static bus_setup_intr_t fhc_setup_intr; |
85static bus_teardown_intr_t fhc_teardown_intr; | |
86static bus_alloc_resource_t fhc_alloc_resource; 87static bus_get_resource_list_t fhc_get_resource_list; 88static ofw_bus_get_devinfo_t fhc_get_devinfo; 89 | 71static bus_alloc_resource_t fhc_alloc_resource; 72static bus_get_resource_list_t fhc_get_resource_list; 73static ofw_bus_get_devinfo_t fhc_get_devinfo; 74 |
90static driver_filter_t fhc_filter_stub; 91static driver_intr_t fhc_intr_stub; | 75static void fhc_intr_enable(void *); 76static void fhc_intr_disable(void *); 77static void fhc_intr_eoi(void *); |
92static void fhc_led_func(void *, int); 93static int fhc_print_res(struct fhc_devinfo *); 94 95static device_method_t fhc_methods[] = { 96 /* Device interface */ 97 DEVMETHOD(device_probe, fhc_probe), 98 DEVMETHOD(device_attach, fhc_attach), 99 DEVMETHOD(device_shutdown, bus_generic_shutdown), 100 DEVMETHOD(device_suspend, bus_generic_suspend), 101 DEVMETHOD(device_resume, bus_generic_resume), 102 103 /* Bus interface */ 104 DEVMETHOD(bus_print_child, fhc_print_child), 105 DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), 106 DEVMETHOD(bus_setup_intr, fhc_setup_intr), | 78static void fhc_led_func(void *, int); 79static int fhc_print_res(struct fhc_devinfo *); 80 81static device_method_t fhc_methods[] = { 82 /* Device interface */ 83 DEVMETHOD(device_probe, fhc_probe), 84 DEVMETHOD(device_attach, fhc_attach), 85 DEVMETHOD(device_shutdown, bus_generic_shutdown), 86 DEVMETHOD(device_suspend, bus_generic_suspend), 87 DEVMETHOD(device_resume, bus_generic_resume), 88 89 /* Bus interface */ 90 DEVMETHOD(bus_print_child, fhc_print_child), 91 DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), 92 DEVMETHOD(bus_setup_intr, fhc_setup_intr), |
107 DEVMETHOD(bus_teardown_intr, fhc_teardown_intr), | 93 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), |
108 DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), 109 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 110 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 111 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 112 DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), 113 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 114 115 /* ofw_bus interface */ --- 13 unchanged lines hidden (view full) --- 129 sizeof(struct fhc_softc), 130}; 131 132static devclass_t fhc_devclass; 133 134DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0); 135DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0); 136 | 94 DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), 95 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 96 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 97 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 98 DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), 99 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 100 101 /* ofw_bus interface */ --- 13 unchanged lines hidden (view full) --- 115 sizeof(struct fhc_softc), 116}; 117 118static devclass_t fhc_devclass; 119 120DRIVER_MODULE(fhc, central, fhc_driver, fhc_devclass, 0, 0); 121DRIVER_MODULE(fhc, nexus, fhc_driver, fhc_devclass, 0, 0); 122 |
123static const struct intr_controller fhc_ic = { 124 fhc_intr_enable, 125 fhc_intr_disable, 126 fhc_intr_eoi 127}; 128 129struct fhc_icarg { 130 struct fhc_softc *fica_sc; 131 struct resource *fica_memres; 132}; 133 |
|
137static int 138fhc_probe(device_t dev) 139{ 140 141 if (strcmp(ofw_bus_get_name(dev), "fhc") == 0) { 142 device_set_desc(dev, "fhc"); 143 return (0); 144 } 145 return (ENXIO); 146} 147 148static int 149fhc_attach(device_t dev) 150{ 151 char ledname[sizeof("boardXX")]; 152 struct fhc_devinfo *fdi; | 134static int 135fhc_probe(device_t dev) 136{ 137 138 if (strcmp(ofw_bus_get_name(dev), "fhc") == 0) { 139 device_set_desc(dev, "fhc"); 140 return (0); 141 } 142 return (ENXIO); 143} 144 145static int 146fhc_attach(device_t dev) 147{ 148 char ledname[sizeof("boardXX")]; 149 struct fhc_devinfo *fdi; |
153 struct sbus_regs *reg; | 150 struct fhc_icarg *fica; |
154 struct fhc_softc *sc; | 151 struct fhc_softc *sc; |
152 struct sbus_regs *reg; |
|
155 phandle_t child; 156 phandle_t node; 157 device_t cdev; 158 uint32_t board; 159 uint32_t ctrl; 160 uint32_t *intr; 161 uint32_t iv; 162 char *name; | 153 phandle_t child; 154 phandle_t node; 155 device_t cdev; 156 uint32_t board; 157 uint32_t ctrl; 158 uint32_t *intr; 159 uint32_t iv; 160 char *name; |
161 int central; |
|
163 int error; 164 int i; 165 int nintr; 166 int nreg; 167 int rid; 168 169 sc = device_get_softc(dev); 170 node = ofw_bus_get_node(dev); 171 | 162 int error; 163 int i; 164 int nintr; 165 int nreg; 166 int rid; 167 168 sc = device_get_softc(dev); 169 node = ofw_bus_get_node(dev); 170 |
171 central = 0; |
|
172 if (strcmp(device_get_name(device_get_parent(dev)), "central") == 0) | 172 if (strcmp(device_get_name(device_get_parent(dev)), "central") == 0) |
173 sc->sc_flags |= FHC_CENTRAL; | 173 central = 1; |
174 175 for (i = 0; i < FHC_NREG; i++) { 176 rid = i; 177 sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 178 &rid, RF_ACTIVE); 179 if (sc->sc_memres[i] == NULL) { 180 device_printf(dev, "cannot allocate resource %d\n", i); 181 error = ENXIO; 182 goto fail_memres; 183 } | 174 175 for (i = 0; i < FHC_NREG; i++) { 176 rid = i; 177 sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 178 &rid, RF_ACTIVE); 179 if (sc->sc_memres[i] == NULL) { 180 device_printf(dev, "cannot allocate resource %d\n", i); 181 error = ENXIO; 182 goto fail_memres; 183 } |
184 sc->sc_bt[i] = rman_get_bustag(sc->sc_memres[i]); 185 sc->sc_bh[i] = rman_get_bushandle(sc->sc_memres[i]); | |
186 } 187 | 184 } 185 |
188 if ((sc->sc_flags & FHC_CENTRAL) != 0) { 189 board = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], 190 sc->sc_bh[FHC_INTERNAL], FHC_BSR); 191 sc->sc_board = ((board >> 16) & 0x1) | ((board >> 12) & 0xe); | 186 if (central != 0) { 187 board = bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_BSR); 188 board = ((board >> 16) & 0x1) | ((board >> 12) & 0xe); |
192 } else { | 189 } else { |
193 if (OF_getprop(node, "board#", &sc->sc_board, 194 sizeof(sc->sc_board)) == -1) { | 190 if (OF_getprop(node, "board#", &board, sizeof(board)) == -1) { |
195 device_printf(dev, "cannot get board number\n"); 196 error = ENXIO; 197 goto fail_memres; 198 } 199 } 200 | 191 device_printf(dev, "cannot get board number\n"); 192 error = ENXIO; 193 goto fail_memres; 194 } 195 } 196 |
201 device_printf(dev, "board %d, ", sc->sc_board); | 197 device_printf(dev, "board %d, ", board); |
202 if (OF_getprop_alloc(node, "board-model", 1, (void **)&name) != -1) { 203 printf("model %s\n", name); 204 free(name, M_OFWPROP); 205 } else 206 printf("model unknown\n"); 207 208 for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { | 198 if (OF_getprop_alloc(node, "board-model", 1, (void **)&name) != -1) { 199 printf("model %s\n", name); 200 free(name, M_OFWPROP); 201 } else 202 printf("model unknown\n"); 203 204 for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { |
209 bus_space_write_4(sc->sc_bt[i], sc->sc_bh[i], FHC_ICLR, 0x0); 210 bus_space_read_4(sc->sc_bt[i], sc->sc_bh[i], FHC_ICLR); | 205 bus_write_4(sc->sc_memres[i], FHC_ICLR, 0x0); 206 (void)bus_read_4(sc->sc_memres[i], FHC_ICLR); |
211 } 212 | 207 } 208 |
213 sc->sc_ign = sc->sc_board << 1; 214 bus_space_write_4(sc->sc_bt[FHC_IGN], sc->sc_bh[FHC_IGN], 0x0, 215 sc->sc_ign); 216 sc->sc_ign = bus_space_read_4(sc->sc_bt[FHC_IGN], 217 sc->sc_bh[FHC_IGN], 0x0); | 209 sc->sc_ign = board << 1; 210 bus_write_4(sc->sc_memres[FHC_IGN], 0x0, sc->sc_ign); 211 sc->sc_ign = bus_read_4(sc->sc_memres[FHC_IGN], 0x0); |
218 | 212 |
219 ctrl = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], 220 sc->sc_bh[FHC_INTERNAL], FHC_CTRL); 221 if ((sc->sc_flags & FHC_CENTRAL) == 0) | 213 ctrl = bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL); 214 if (central == 0) |
222 ctrl |= FHC_CTRL_IXIST; 223 ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE); | 215 ctrl |= FHC_CTRL_IXIST; 216 ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE); |
224 bus_space_write_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], 225 FHC_CTRL, ctrl); 226 bus_space_read_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], 227 FHC_CTRL); | 217 bus_write_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL, ctrl); 218 (void)bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL); |
228 229 sc->sc_nrange = OF_getprop_alloc(node, "ranges", 230 sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges); 231 if (sc->sc_nrange == -1) { 232 device_printf(dev, "cannot get ranges\n"); 233 error = ENXIO; 234 goto fail_memres; 235 } 236 | 219 220 sc->sc_nrange = OF_getprop_alloc(node, "ranges", 221 sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges); 222 if (sc->sc_nrange == -1) { 223 device_printf(dev, "cannot get ranges\n"); 224 error = ENXIO; 225 goto fail_memres; 226 } 227 |
237 if ((sc->sc_flags & FHC_CENTRAL) == 0) { 238 snprintf(ledname, sizeof(ledname), "board%d", sc->sc_board); | 228 /* 229 * Apparently only the interrupt controller of boards hanging off 230 * of central(4) is indented to be used, otherwise we would have 231 * conflicts registering the interrupt controllers for all FHC 232 * boards as the board number and thus the IGN isn't unique. 233 */ 234 if (central == 1) { 235 /* 236 * Hunt through all the interrupt mapping regs and register 237 * our interrupt controller for the corresponding interrupt 238 * vectors. 239 */ 240 for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { 241 fica = malloc(sizeof(*fica), M_DEVBUF, M_NOWAIT); 242 if (fica == NULL) 243 panic("%s: could not allocate interrupt " 244 "controller argument", __func__); 245 fica->fica_sc = sc; 246 fica->fica_memres = sc->sc_memres[i]; 247#ifdef FHC_DEBUG 248 device_printf(dev, "intr map %d: %#lx, clr: %#lx\n", i, 249 (u_long)bus_read_4(fica->fica_memres, FHC_IMAP), 250 (u_long)bus_read_4(fica->fica_memres, FHC_ICLR)); 251#endif 252 /* 253 * XXX we only pick the INO rather than the INR 254 * from the IMR since the firmware may not provide 255 * the IGN and the IGN is constant for all devices 256 * on that FireHose controller. 257 */ 258 if (intr_controller_register(INTMAP_VEC(sc->sc_ign, 259 INTINO(bus_read_4(fica->fica_memres, FHC_IMAP))), 260 &fhc_ic, fica) != 0) 261 panic("%s: could not register interrupt " 262 "controller for map %d", __func__, i); 263 } 264 } else { 265 snprintf(ledname, sizeof(ledname), "board%d", board); |
239 sc->sc_led_dev = led_create(fhc_led_func, sc, ledname); 240 } 241 242 for (child = OF_child(node); child != 0; child = OF_peer(child)) { 243 fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO); 244 if (ofw_bus_gen_setup_devinfo(&fdi->fdi_obdinfo, child) != 0) { 245 free(fdi, M_DEVBUF); 246 continue; --- 8 unchanged lines hidden (view full) --- 255 continue; 256 } 257 resource_list_init(&fdi->fdi_rl); 258 for (i = 0; i < nreg; i++) 259 resource_list_add(&fdi->fdi_rl, SYS_RES_MEMORY, i, 260 reg[i].sbr_offset, reg[i].sbr_offset + 261 reg[i].sbr_size, reg[i].sbr_size); 262 free(reg, M_OFWPROP); | 266 sc->sc_led_dev = led_create(fhc_led_func, sc, ledname); 267 } 268 269 for (child = OF_child(node); child != 0; child = OF_peer(child)) { 270 fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO); 271 if (ofw_bus_gen_setup_devinfo(&fdi->fdi_obdinfo, child) != 0) { 272 free(fdi, M_DEVBUF); 273 continue; --- 8 unchanged lines hidden (view full) --- 282 continue; 283 } 284 resource_list_init(&fdi->fdi_rl); 285 for (i = 0; i < nreg; i++) 286 resource_list_add(&fdi->fdi_rl, SYS_RES_MEMORY, i, 287 reg[i].sbr_offset, reg[i].sbr_offset + 288 reg[i].sbr_size, reg[i].sbr_size); 289 free(reg, M_OFWPROP); |
263 nintr = OF_getprop_alloc(child, "interrupts", sizeof(*intr), 264 (void **)&intr); 265 if (nintr != -1) { 266 for (i = 0; i < nintr; i++) { 267 iv = INTINO(intr[i]) | 268 (sc->sc_ign << INTMAP_IGN_SHIFT); 269 resource_list_add(&fdi->fdi_rl, SYS_RES_IRQ, i, 270 iv, iv, 1); | 290 if (central == 1) { 291 nintr = OF_getprop_alloc(child, "interrupts", 292 sizeof(*intr), (void **)&intr); 293 if (nintr != -1) { 294 for (i = 0; i < nintr; i++) { 295 iv = INTMAP_VEC(sc->sc_ign, intr[i]); 296 resource_list_add(&fdi->fdi_rl, 297 SYS_RES_IRQ, i, iv, iv, 1); 298 } 299 free(intr, M_OFWPROP); |
271 } | 300 } |
272 free(intr, M_OFWPROP); | |
273 } 274 cdev = device_add_child(dev, NULL, -1); 275 if (cdev == NULL) { 276 device_printf(dev, "<%s>: device_add_child failed\n", 277 fdi->fdi_obdinfo.obd_name); 278 resource_list_free(&fdi->fdi_rl); 279 ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo); 280 free(fdi, M_DEVBUF); --- 30 unchanged lines hidden (view full) --- 311 312 device_printf(dev, "<%s>", ofw_bus_get_name(child)); 313 fhc_print_res(device_get_ivars(child)); 314 type = ofw_bus_get_type(child); 315 printf(" type %s (no driver attached)\n", 316 type != NULL ? type : "unknown"); 317} 318 | 301 } 302 cdev = device_add_child(dev, NULL, -1); 303 if (cdev == NULL) { 304 device_printf(dev, "<%s>: device_add_child failed\n", 305 fdi->fdi_obdinfo.obd_name); 306 resource_list_free(&fdi->fdi_rl); 307 ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo); 308 free(fdi, M_DEVBUF); --- 30 unchanged lines hidden (view full) --- 339 340 device_printf(dev, "<%s>", ofw_bus_get_name(child)); 341 fhc_print_res(device_get_ivars(child)); 342 type = ofw_bus_get_type(child); 343 printf(" type %s (no driver attached)\n", 344 type != NULL ? type : "unknown"); 345} 346 |
319static int 320fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags, 321 driver_filter_t *filt, driver_intr_t *func, void *arg, void **cookiep) | 347static void 348fhc_intr_enable(void *arg) |
322{ | 349{ |
323 struct fhc_softc *sc; 324 struct fhc_clr *fc; 325 bus_space_tag_t bt; 326 bus_space_handle_t bh; 327 int error; 328 int i; 329 long vec; 330 uint32_t inr; | 350 struct intr_vector *iv = arg; 351 struct fhc_icarg *fica = iv->iv_icarg; |
331 | 352 |
332 if (filt != NULL && func != NULL) 333 return (EINVAL); 334 335 sc = device_get_softc(bus); 336 vec = rman_get_start(r); 337 338 bt = NULL; 339 bh = 0; 340 inr = 0; 341 for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { 342 if (INTINO(bus_space_read_4(sc->sc_bt[i], sc->sc_bh[i], 343 FHC_IMAP)) == INTINO(vec)){ 344 bt = sc->sc_bt[i]; 345 bh = sc->sc_bh[i]; 346 inr = INTINO(vec) | (sc->sc_ign << INTMAP_IGN_SHIFT); 347 break; 348 } 349 } 350 if (inr == 0) 351 return (0); 352 353 fc = malloc(sizeof(*fc), M_DEVBUF, M_WAITOK | M_ZERO); 354 if (fc == NULL) 355 return (0); 356 fc->fc_filter = filt; 357 fc->fc_func = func; 358 fc->fc_arg = arg; 359 fc->fc_bt = bt; 360 fc->fc_bh = bh; 361 362 bus_space_write_4(bt, bh, FHC_IMAP, inr); 363 bus_space_read_4(bt, bh, FHC_IMAP); 364 365 error = bus_generic_setup_intr(bus, child, r, flags, fhc_filter_stub, 366 fhc_intr_stub, fc, cookiep); 367 if (error != 0) { 368 free(fc, M_DEVBUF); 369 return (error); 370 } 371 fc->fc_cookie = *cookiep; 372 *cookiep = fc; 373 374 bus_space_write_4(bt, bh, FHC_ICLR, 0x0); 375 bus_space_write_4(bt, bh, FHC_IMAP, INTMAP_ENABLE(inr, PCPU_GET(mid))); 376 bus_space_read_4(bt, bh, FHC_IMAP); 377 378 return (error); | 353 bus_write_4(fica->fica_memres, FHC_IMAP, 354 INTMAP_ENABLE(iv->iv_vec, iv->iv_mid)); 355 (void)bus_read_4(fica->fica_memres, FHC_IMAP); |
379} 380 | 356} 357 |
381static int 382fhc_teardown_intr(device_t bus, device_t child, struct resource *r, 383 void *cookie) | 358static void 359fhc_intr_disable(void *arg) |
384{ | 360{ |
385 struct fhc_clr *fc; 386 int error; | 361 struct intr_vector *iv = arg; 362 struct fhc_icarg *fica = iv->iv_icarg; |
387 | 363 |
388 fc = cookie; 389 error = bus_generic_teardown_intr(bus, child, r, fc->fc_cookie); 390 if (error != 0) 391 free(fc, M_DEVBUF); 392 return (error); | 364 bus_write_4(fica->fica_memres, FHC_IMAP, iv->iv_vec); 365 (void)bus_read_4(fica->fica_memres, FHC_IMAP); |
393} 394 | 366} 367 |
395static int 396fhc_filter_stub(void *arg) | 368static void 369fhc_intr_eoi(void *arg) |
397{ | 370{ |
398 struct fhc_clr *fc = arg; 399 int res; | 371 struct intr_vector *iv = arg; 372 struct fhc_icarg *fica = iv->iv_icarg; |
400 | 373 |
401 if (fc->fc_filter != NULL) { 402 res = fc->fc_filter(fc->fc_arg); 403 bus_space_write_4(fc->fc_bt, fc->fc_bh, FHC_ICLR, 0x0); 404 bus_space_read_4(fc->fc_bt, fc->fc_bh, FHC_ICLR); 405 } else 406 res = FILTER_SCHEDULE_THREAD; 407 408 return (res); | 374 bus_write_4(fica->fica_memres, FHC_ICLR, 0x0); 375 (void)bus_read_4(fica->fica_memres, FHC_ICLR); |
409} 410 | 376} 377 |
411static void 412fhc_intr_stub(void *arg) | 378static int 379fhc_setup_intr(device_t bus, device_t child, struct resource *r, int flags, 380 driver_filter_t *filt, driver_intr_t *func, void *arg, void **cookiep) |
413{ | 381{ |
414 struct fhc_clr *fc = arg; | 382 struct fhc_softc *sc; 383 u_long vec; |
415 | 384 |
416 fc->fc_func(fc->fc_arg); 417 if (fc->fc_filter == NULL) { 418 bus_space_write_4(fc->fc_bt, fc->fc_bh, FHC_ICLR, 0x0); 419 bus_space_read_4(fc->fc_bt, fc->fc_bh, FHC_ICLR); 420 } | 385 sc = device_get_softc(bus); 386 /* 387 * Make sure the vector is fully specified and we registered 388 * our interrupt controller for it. 389 */ 390 vec = rman_get_start(r); 391 if (INTIGN(vec) != sc->sc_ign || intr_vectors[vec].iv_ic != &fhc_ic) { 392 device_printf(bus, "invalid interrupt vector 0x%lx\n", vec); 393 return (EINVAL); 394 } 395 return (bus_generic_setup_intr(bus, child, r, flags, filt, func, 396 arg, cookiep)); |
421} 422 423static struct resource * 424fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, 425 u_long start, u_long end, u_long count, u_int flags) 426{ 427 struct resource_list *rl; 428 struct resource_list_entry *rle; --- 7 unchanged lines hidden (view full) --- 436 int i; 437 438 isdefault = (start == 0UL && end == ~0UL); 439 passthrough = (device_get_parent(child) != bus); 440 res = NULL; 441 rle = NULL; 442 rl = BUS_GET_RESOURCE_LIST(bus, child); 443 sc = device_get_softc(bus); | 397} 398 399static struct resource * 400fhc_alloc_resource(device_t bus, device_t child, int type, int *rid, 401 u_long start, u_long end, u_long count, u_int flags) 402{ 403 struct resource_list *rl; 404 struct resource_list_entry *rle; --- 7 unchanged lines hidden (view full) --- 412 int i; 413 414 isdefault = (start == 0UL && end == ~0UL); 415 passthrough = (device_get_parent(child) != bus); 416 res = NULL; 417 rle = NULL; 418 rl = BUS_GET_RESOURCE_LIST(bus, child); 419 sc = device_get_softc(bus); |
444 rle = resource_list_find(rl, type, *rid); | |
445 switch (type) { 446 case SYS_RES_IRQ: 447 return (resource_list_alloc(rl, bus, child, type, rid, start, 448 end, count, flags)); 449 case SYS_RES_MEMORY: 450 if (!passthrough) { | 420 switch (type) { 421 case SYS_RES_IRQ: 422 return (resource_list_alloc(rl, bus, child, type, rid, start, 423 end, count, flags)); 424 case SYS_RES_MEMORY: 425 if (!passthrough) { |
426 rle = resource_list_find(rl, type, *rid); |
|
451 if (rle == NULL) 452 return (NULL); 453 if (rle->res != NULL) 454 panic("%s: resource entry is busy", __func__); 455 if (isdefault) { 456 start = rle->start; 457 count = ulmax(count, rle->count); 458 end = ulmax(rle->end, start + count - 1); --- 41 unchanged lines hidden (view full) --- 500static void 501fhc_led_func(void *arg, int onoff) 502{ 503 struct fhc_softc *sc; 504 uint32_t ctrl; 505 506 sc = (struct fhc_softc *)arg; 507 | 427 if (rle == NULL) 428 return (NULL); 429 if (rle->res != NULL) 430 panic("%s: resource entry is busy", __func__); 431 if (isdefault) { 432 start = rle->start; 433 count = ulmax(count, rle->count); 434 end = ulmax(rle->end, start + count - 1); --- 41 unchanged lines hidden (view full) --- 476static void 477fhc_led_func(void *arg, int onoff) 478{ 479 struct fhc_softc *sc; 480 uint32_t ctrl; 481 482 sc = (struct fhc_softc *)arg; 483 |
508 ctrl = bus_space_read_4(sc->sc_bt[FHC_INTERNAL], 509 sc->sc_bh[FHC_INTERNAL], FHC_CTRL); | 484 ctrl = bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL); |
510 if (onoff) 511 ctrl |= FHC_CTRL_RLED; 512 else 513 ctrl &= ~FHC_CTRL_RLED; 514 ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE); | 485 if (onoff) 486 ctrl |= FHC_CTRL_RLED; 487 else 488 ctrl &= ~FHC_CTRL_RLED; 489 ctrl &= ~(FHC_CTRL_AOFF | FHC_CTRL_BOFF | FHC_CTRL_SLINE); |
515 bus_space_write_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], 516 FHC_CTRL, ctrl); 517 bus_space_read_4(sc->sc_bt[FHC_INTERNAL], sc->sc_bh[FHC_INTERNAL], 518 FHC_CTRL); | 490 bus_write_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL, ctrl); 491 (void)bus_read_4(sc->sc_memres[FHC_INTERNAL], FHC_CTRL); |
519} 520 521static int 522fhc_print_res(struct fhc_devinfo *fdi) 523{ 524 int rv; 525 526 rv = 0; 527 rv += resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY, 528 "%#lx"); 529 rv += resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld"); 530 return (rv); 531} | 492} 493 494static int 495fhc_print_res(struct fhc_devinfo *fdi) 496{ 497 int rv; 498 499 rv = 0; 500 rv += resource_list_print_type(&fdi->fdi_rl, "mem", SYS_RES_MEMORY, 501 "%#lx"); 502 rv += resource_list_print_type(&fdi->fdi_rl, "irq", SYS_RES_IRQ, "%ld"); 503 return (rv); 504} |