fhc.c (182070) | fhc.c (190098) |
---|---|
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 182070 2008-08-23 16:07:20Z marius $"); | 29__FBSDID("$FreeBSD: head/sys/sparc64/fhc/fhc.c 190098 2009-03-19 20:29:23Z 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> --- 47 unchanged lines hidden (view full) --- 85 DEVMETHOD(device_attach, fhc_attach), 86 DEVMETHOD(device_shutdown, bus_generic_shutdown), 87 DEVMETHOD(device_suspend, bus_generic_suspend), 88 DEVMETHOD(device_resume, bus_generic_resume), 89 90 /* Bus interface */ 91 DEVMETHOD(bus_print_child, fhc_print_child), 92 DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), | 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> --- 47 unchanged lines hidden (view full) --- 85 DEVMETHOD(device_attach, fhc_attach), 86 DEVMETHOD(device_shutdown, bus_generic_shutdown), 87 DEVMETHOD(device_suspend, bus_generic_suspend), 88 DEVMETHOD(device_resume, bus_generic_resume), 89 90 /* Bus interface */ 91 DEVMETHOD(bus_print_child, fhc_print_child), 92 DEVMETHOD(bus_probe_nomatch, fhc_probe_nomatch), |
93 DEVMETHOD(bus_setup_intr, fhc_setup_intr), 94 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), | |
95 DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), | 93 DEVMETHOD(bus_alloc_resource, fhc_alloc_resource), |
96 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), | |
97 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 98 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), | 94 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 95 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), |
99 DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), | 96 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 97 DEVMETHOD(bus_setup_intr, fhc_setup_intr), 98 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), |
100 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), | 99 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), |
100 DEVMETHOD(bus_get_resource_list, fhc_get_resource_list), |
|
101 102 /* ofw_bus interface */ 103 DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), 104 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 105 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 106 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 107 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 108 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 109 | 101 102 /* ofw_bus interface */ 103 DEVMETHOD(ofw_bus_get_devinfo, fhc_get_devinfo), 104 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), 105 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), 106 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), 107 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), 108 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), 109 |
110 { NULL, NULL } | 110 KOBJMETHOD_END |
111}; 112 113static driver_t fhc_driver = { 114 "fhc", 115 fhc_methods, 116 sizeof(struct fhc_softc), 117}; 118 --- 41 unchanged lines hidden (view full) --- 160 uint32_t board; 161 uint32_t ctrl; 162 uint32_t *intr; 163 uint32_t iv; 164 char *name; 165 int central; 166 int error; 167 int i; | 111}; 112 113static driver_t fhc_driver = { 114 "fhc", 115 fhc_methods, 116 sizeof(struct fhc_softc), 117}; 118 --- 41 unchanged lines hidden (view full) --- 160 uint32_t board; 161 uint32_t ctrl; 162 uint32_t *intr; 163 uint32_t iv; 164 char *name; 165 int central; 166 int error; 167 int i; |
168 int nintr; 169 int nreg; 170 int rid; | 168 int j; |
171 172 sc = device_get_softc(dev); 173 node = ofw_bus_get_node(dev); 174 175 central = 0; 176 if (strcmp(device_get_name(device_get_parent(dev)), "central") == 0) 177 central = 1; 178 179 for (i = 0; i < FHC_NREG; i++) { | 169 170 sc = device_get_softc(dev); 171 node = ofw_bus_get_node(dev); 172 173 central = 0; 174 if (strcmp(device_get_name(device_get_parent(dev)), "central") == 0) 175 central = 1; 176 177 for (i = 0; i < FHC_NREG; i++) { |
180 rid = i; | 178 j = i; |
181 sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | 179 sc->sc_memres[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, |
182 &rid, RF_ACTIVE); | 180 &j, RF_ACTIVE); |
183 if (sc->sc_memres[i] == NULL) { 184 device_printf(dev, "cannot allocate resource %d\n", i); 185 error = ENXIO; 186 goto fail_memres; 187 } 188 } 189 190 if (central != 0) { --- 43 unchanged lines hidden (view full) --- 234 * of central(4) is indented to be used, otherwise we would have 235 * conflicts registering the interrupt controllers for all FHC 236 * boards as the board number and thus the IGN isn't unique. 237 */ 238 if (central == 1) { 239 /* 240 * Hunt through all the interrupt mapping regs and register 241 * our interrupt controller for the corresponding interrupt | 181 if (sc->sc_memres[i] == NULL) { 182 device_printf(dev, "cannot allocate resource %d\n", i); 183 error = ENXIO; 184 goto fail_memres; 185 } 186 } 187 188 if (central != 0) { --- 43 unchanged lines hidden (view full) --- 232 * of central(4) is indented to be used, otherwise we would have 233 * conflicts registering the interrupt controllers for all FHC 234 * boards as the board number and thus the IGN isn't unique. 235 */ 236 if (central == 1) { 237 /* 238 * Hunt through all the interrupt mapping regs and register 239 * our interrupt controller for the corresponding interrupt |
242 * vectors. | 240 * vectors. We do this early in order to be able to catch 241 * stray interrupts. |
243 */ 244 for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { 245 fica = malloc(sizeof(*fica), M_DEVBUF, M_NOWAIT); 246 if (fica == NULL) 247 panic("%s: could not allocate interrupt " 248 "controller argument", __func__); 249 fica->fica_sc = sc; 250 fica->fica_memres = sc->sc_memres[i]; 251#ifdef FHC_DEBUG 252 device_printf(dev, "intr map %d: %#lx, clr: %#lx\n", i, 253 (u_long)bus_read_4(fica->fica_memres, FHC_IMAP), 254 (u_long)bus_read_4(fica->fica_memres, FHC_ICLR)); 255#endif 256 /* 257 * XXX we only pick the INO rather than the INR 258 * from the IMR since the firmware may not provide 259 * the IGN and the IGN is constant for all devices 260 * on that FireHose controller. 261 */ | 242 */ 243 for (i = FHC_FANFAIL; i <= FHC_TOD; i++) { 244 fica = malloc(sizeof(*fica), M_DEVBUF, M_NOWAIT); 245 if (fica == NULL) 246 panic("%s: could not allocate interrupt " 247 "controller argument", __func__); 248 fica->fica_sc = sc; 249 fica->fica_memres = sc->sc_memres[i]; 250#ifdef FHC_DEBUG 251 device_printf(dev, "intr map %d: %#lx, clr: %#lx\n", i, 252 (u_long)bus_read_4(fica->fica_memres, FHC_IMAP), 253 (u_long)bus_read_4(fica->fica_memres, FHC_ICLR)); 254#endif 255 /* 256 * XXX we only pick the INO rather than the INR 257 * from the IMR since the firmware may not provide 258 * the IGN and the IGN is constant for all devices 259 * on that FireHose controller. 260 */ |
262 if (intr_controller_register(INTMAP_VEC(sc->sc_ign, | 261 j = intr_controller_register(INTMAP_VEC(sc->sc_ign, |
263 INTINO(bus_read_4(fica->fica_memres, FHC_IMAP))), | 262 INTINO(bus_read_4(fica->fica_memres, FHC_IMAP))), |
264 &fhc_ic, fica) != 0) 265 panic("%s: could not register interrupt " 266 "controller for map %d", __func__, i); | 263 &fhc_ic, fica); 264 if (j != 0) 265 device_printf(dev, "could not register " 266 "interrupt controller for map %d (%d)\n", 267 i, j); |
267 } 268 } else { 269 snprintf(ledname, sizeof(ledname), "board%d", board); 270 sc->sc_led_dev = led_create(fhc_led_func, sc, ledname); 271 } 272 273 for (child = OF_child(node); child != 0; child = OF_peer(child)) { 274 fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO); 275 if (ofw_bus_gen_setup_devinfo(&fdi->fdi_obdinfo, child) != 0) { 276 free(fdi, M_DEVBUF); 277 continue; 278 } | 268 } 269 } else { 270 snprintf(ledname, sizeof(ledname), "board%d", board); 271 sc->sc_led_dev = led_create(fhc_led_func, sc, ledname); 272 } 273 274 for (child = OF_child(node); child != 0; child = OF_peer(child)) { 275 fdi = malloc(sizeof(*fdi), M_DEVBUF, M_WAITOK | M_ZERO); 276 if (ofw_bus_gen_setup_devinfo(&fdi->fdi_obdinfo, child) != 0) { 277 free(fdi, M_DEVBUF); 278 continue; 279 } |
279 nreg = OF_getprop_alloc(child, "reg", sizeof(*reg), | 280 i = OF_getprop_alloc(child, "reg", sizeof(*reg), |
280 (void **)®); | 281 (void **)®); |
281 if (nreg == -1) { | 282 if (i == -1) { |
282 device_printf(dev, "<%s>: incomplete\n", 283 fdi->fdi_obdinfo.obd_name); 284 ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo); 285 free(fdi, M_DEVBUF); 286 continue; 287 } 288 resource_list_init(&fdi->fdi_rl); | 283 device_printf(dev, "<%s>: incomplete\n", 284 fdi->fdi_obdinfo.obd_name); 285 ofw_bus_gen_destroy_devinfo(&fdi->fdi_obdinfo); 286 free(fdi, M_DEVBUF); 287 continue; 288 } 289 resource_list_init(&fdi->fdi_rl); |
289 for (i = 0; i < nreg; i++) 290 resource_list_add(&fdi->fdi_rl, SYS_RES_MEMORY, i, 291 reg[i].sbr_offset, reg[i].sbr_offset + 292 reg[i].sbr_size, reg[i].sbr_size); | 290 for (j = 0; j < i; j++) 291 resource_list_add(&fdi->fdi_rl, SYS_RES_MEMORY, j, 292 reg[j].sbr_offset, reg[j].sbr_offset + 293 reg[j].sbr_size, reg[j].sbr_size); |
293 free(reg, M_OFWPROP); 294 if (central == 1) { | 294 free(reg, M_OFWPROP); 295 if (central == 1) { |
295 nintr = OF_getprop_alloc(child, "interrupts", | 296 i = OF_getprop_alloc(child, "interrupts", |
296 sizeof(*intr), (void **)&intr); | 297 sizeof(*intr), (void **)&intr); |
297 if (nintr != -1) { 298 for (i = 0; i < nintr; i++) { 299 iv = INTMAP_VEC(sc->sc_ign, intr[i]); | 298 if (i != -1) { 299 for (j = 0; j < i; j++) { 300 iv = INTMAP_VEC(sc->sc_ign, intr[j]); |
300 resource_list_add(&fdi->fdi_rl, | 301 resource_list_add(&fdi->fdi_rl, |
301 SYS_RES_IRQ, i, iv, iv, 1); | 302 SYS_RES_IRQ, j, iv, iv, 1); |
302 } 303 free(intr, M_OFWPROP); 304 } 305 } 306 cdev = device_add_child(dev, NULL, -1); 307 if (cdev == NULL) { 308 device_printf(dev, "<%s>: device_add_child failed\n", 309 fdi->fdi_obdinfo.obd_name); --- 210 unchanged lines hidden --- | 303 } 304 free(intr, M_OFWPROP); 305 } 306 } 307 cdev = device_add_child(dev, NULL, -1); 308 if (cdev == NULL) { 309 device_printf(dev, "<%s>: device_add_child failed\n", 310 fdi->fdi_obdinfo.obd_name); --- 210 unchanged lines hidden --- |