Date: Wed, 23 Oct 2013 20:00:15 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r257016 - in head/sys: conf dev/ofw powerpc/powerpc Message-ID: <201310232000.r9NK0Faw024533@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Wed Oct 23 20:00:14 2013 New Revision: 257016 URL: http://svnweb.freebsd.org/changeset/base/257016 Log: Factor out MI portions of the PowerPC nexus device into /sys/dev/ofw. The sparc64 driver will be modified to use this shortly. Added: head/sys/dev/ofw/ofw_nexus.c - copied, changed from r257007, head/sys/powerpc/powerpc/nexus.c head/sys/dev/ofw/ofw_nexus.h - copied, changed from r257007, head/sys/sparc64/include/nexusvar.h Modified: head/sys/conf/files.powerpc head/sys/powerpc/powerpc/nexus.c Modified: head/sys/conf/files.powerpc ============================================================================== --- head/sys/conf/files.powerpc Wed Oct 23 19:56:13 2013 (r257015) +++ head/sys/conf/files.powerpc Wed Oct 23 20:00:14 2013 (r257016) @@ -46,6 +46,7 @@ dev/ofw/ofw_bus_subr.c optional aim dev/ofw/ofw_console.c optional aim dev/ofw/ofw_disk.c optional ofwd aim dev/ofw/ofw_iicbus.c optional iicbus aim +dev/ofw/ofw_nexus.c optional aim | fdt dev/ofw/ofw_standard.c optional aim powerpc dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx Copied and modified: head/sys/dev/ofw/ofw_nexus.c (from r257007, head/sys/powerpc/powerpc/nexus.c) ============================================================================== --- head/sys/powerpc/powerpc/nexus.c Wed Oct 23 18:58:38 2013 (r257007, copy source) +++ head/sys/dev/ofw/ofw_nexus.c Wed Oct 23 20:00:14 2013 (r257016) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> +#include <dev/ofw/ofw_nexus.h> #include <dev/ofw/openfirm.h> #include <machine/bus.h> @@ -64,8 +65,6 @@ __FBSDID("$FreeBSD$"); * Additionally, interrupt setup/teardown and some resource management are * done at this level. * - * Maybe this code should get into dev/ofw to some extent, as some of it should - * work for all Open Firmware based machines... */ struct nexus_devinfo { @@ -73,31 +72,15 @@ struct nexus_devinfo { struct resource_list ndi_rl; }; -struct nexus_softc { - uint32_t acells, scells; - struct rman sc_intr_rman; - struct rman sc_mem_rman; -}; - static device_probe_t nexus_probe; static device_attach_t nexus_attach; static bus_print_child_t nexus_print_child; static bus_add_child_t nexus_add_child; static bus_probe_nomatch_t nexus_probe_nomatch; -static bus_setup_intr_t nexus_setup_intr; -static bus_teardown_intr_t nexus_teardown_intr; static bus_alloc_resource_t nexus_alloc_resource; -static bus_activate_resource_t nexus_activate_resource; -static bus_deactivate_resource_t nexus_deactivate_resource; static bus_adjust_resource_t nexus_adjust_resource; static bus_release_resource_t nexus_release_resource; static bus_get_resource_list_t nexus_get_resource_list; -#ifdef SMP -static bus_bind_intr_t nexus_bind_intr; -#endif -static bus_config_intr_t nexus_config_intr; -static ofw_bus_map_intr_t nexus_ofw_map_intr; -static ofw_bus_config_intr_t nexus_ofw_config_intr; static ofw_bus_get_devinfo_t nexus_get_devinfo; static int nexus_inlist(const char *, const char *const *); @@ -122,19 +105,11 @@ static device_method_t nexus_methods[] = DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), - DEVMETHOD(bus_activate_resource, nexus_activate_resource), - DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_adjust_resource, nexus_adjust_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), - DEVMETHOD(bus_setup_intr, nexus_setup_intr), - DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), DEVMETHOD(bus_get_resource_list, nexus_get_resource_list), -#ifdef SMP - DEVMETHOD(bus_bind_intr, nexus_bind_intr), -#endif - DEVMETHOD(bus_config_intr, nexus_config_intr), /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_devinfo, nexus_get_devinfo), @@ -143,18 +118,13 @@ static device_method_t nexus_methods[] = DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), - DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), - DEVMETHOD(ofw_bus_config_intr, nexus_ofw_config_intr), DEVMETHOD_END }; -static devclass_t nexus_devclass; - -DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc)); -EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, - BUS_PASS_BUS); -MODULE_VERSION(nexus, 1); +DEFINE_CLASS_0(ofw_nexus, ofw_nexus_driver, nexus_methods, + sizeof(struct ofw_nexus_softc)); +MODULE_VERSION(ofw_nexus, 1); static const char *const nexus_excl_name[] = { "FJSV,system", @@ -182,9 +152,6 @@ static const char *const nexus_excl_type NULL }; -extern struct bus_space_tag nexus_bustag; -extern struct bus_dma_tag nexus_dmatag; - static int nexus_inlist(const char *name, const char *const *list) { @@ -215,7 +182,7 @@ static int nexus_attach(device_t dev) { struct nexus_devinfo *ndi; - struct nexus_softc *sc; + struct ofw_nexus_softc *sc; device_t cdev; phandle_t node; @@ -321,79 +288,11 @@ nexus_probe_nomatch(device_t bus, device type != NULL ? type : "unknown"); } -static int -nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r, - int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, - void **cookiep) -{ - int error; - - if (r == NULL) - panic("%s: NULL interrupt resource!", __func__); - - if ((rman_get_flags(r) & RF_SHAREABLE) == 0) - flags |= INTR_EXCL; - - /* We depend here on rman_activate_resource() being idempotent. */ - error = rman_activate_resource(r); - if (error) - return (error); - - error = powerpc_setup_intr(device_get_nameunit(child), - rman_get_start(r), filt, intr, arg, flags, cookiep); - - return (error); -} - -static int -nexus_teardown_intr(device_t bus __unused, device_t child __unused, - struct resource *r, void *ih) -{ - - if (r == NULL) - return (EINVAL); - - return (powerpc_teardown_intr(ih)); -} - -#ifdef SMP -static int -nexus_bind_intr(device_t bus __unused, device_t child __unused, - struct resource *r, int cpu) -{ - - return (powerpc_bind_intr(rman_get_start(r), cpu)); -} -#endif - -static int -nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, - enum intr_polarity pol) -{ - - return (powerpc_config_intr(irq, trig, pol)); -} - -static int -nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int irq) -{ - return (MAP_IRQ(iparent, irq)); -} - -static int -nexus_ofw_config_intr(device_t dev, device_t child, int irq, int sense) -{ - - return (bus_generic_config_intr(child, irq, (sense & 1) ? - INTR_TRIGGER_LEVEL : INTR_TRIGGER_EDGE, - INTR_POLARITY_LOW)); -} - static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct nexus_softc *sc; + struct ofw_nexus_softc *sc; struct rman *rm; struct resource *rv; struct resource_list_entry *rle; @@ -454,52 +353,10 @@ nexus_alloc_resource(device_t bus, devic } static int -nexus_activate_resource(device_t bus __unused, device_t child __unused, - int type, int rid __unused, struct resource *r) -{ - - if (type == SYS_RES_MEMORY) { - vm_offset_t start; - void *p; - - start = (vm_offset_t) rman_get_start(r); - if (bootverbose) - printf("nexus mapdev: start %zx, len %ld\n", start, - rman_get_size(r)); - - p = pmap_mapdev(start, (vm_size_t) rman_get_size(r)); - if (p == NULL) - return (ENOMEM); - rman_set_virtual(r, p); - rman_set_bustag(r, &bs_be_tag); - rman_set_bushandle(r, (u_long)p); - } - return (rman_activate_resource(r)); -} - -static int -nexus_deactivate_resource(device_t bus __unused, device_t child __unused, - int type __unused, int rid __unused, struct resource *r) -{ - - /* - * If this is a memory resource, unmap it. - */ - if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) { - bus_size_t psize; - - psize = rman_get_size(r); - pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize); - } - - return (rman_deactivate_resource(r)); -} - -static int nexus_adjust_resource(device_t bus, device_t child __unused, int type, struct resource *r, u_long start, u_long end) { - struct nexus_softc *sc; + struct ofw_nexus_softc *sc; struct rman *rm; device_t nexus; @@ -559,7 +416,7 @@ nexus_get_devinfo(device_t bus __unused, static struct nexus_devinfo * nexus_setup_dinfo(device_t dev, phandle_t node) { - struct nexus_softc *sc; + struct ofw_nexus_softc *sc; struct nexus_devinfo *ndi; uint32_t *reg, *intr, icells; uint64_t phys, size; Copied and modified: head/sys/dev/ofw/ofw_nexus.h (from r257007, head/sys/sparc64/include/nexusvar.h) ============================================================================== --- head/sys/sparc64/include/nexusvar.h Wed Oct 23 18:58:38 2013 (r257007, copy source) +++ head/sys/dev/ofw/ofw_nexus.h Wed Oct 23 20:00:14 2013 (r257016) @@ -26,9 +26,15 @@ * $FreeBSD$ */ -#ifndef _MACHINE_NEXUSVAR_H_ -#define _MACHINE_NEXUSVAR_H_ +#ifndef _OFW_NEXUS_H_ +#define _OFW_NEXUS_H_ -DECLARE_CLASS(nexus_driver); +struct ofw_nexus_softc { + uint32_t acells, scells; + struct rman sc_intr_rman; + struct rman sc_mem_rman; +}; -#endif /* _MACHINE_NEXUSVAR_H_ */ +DECLARE_CLASS(ofw_nexus_driver); + +#endif /* _OFW_NEXUS_H_ */ Modified: head/sys/powerpc/powerpc/nexus.c ============================================================================== --- head/sys/powerpc/powerpc/nexus.c Wed Oct 23 19:56:13 2013 (r257015) +++ head/sys/powerpc/powerpc/nexus.c Wed Oct 23 20:00:14 2013 (r257016) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> +#include <dev/ofw/ofw_nexus.h> #include <dev/ofw/openfirm.h> #include <machine/bus.h> @@ -63,86 +64,31 @@ __FBSDID("$FreeBSD$"); * * Additionally, interrupt setup/teardown and some resource management are * done at this level. - * - * Maybe this code should get into dev/ofw to some extent, as some of it should - * work for all Open Firmware based machines... */ -struct nexus_devinfo { - struct ofw_bus_devinfo ndi_obdinfo; - struct resource_list ndi_rl; -}; - -struct nexus_softc { - uint32_t acells, scells; - struct rman sc_intr_rman; - struct rman sc_mem_rman; -}; - -static device_probe_t nexus_probe; -static device_attach_t nexus_attach; -static bus_print_child_t nexus_print_child; -static bus_add_child_t nexus_add_child; -static bus_probe_nomatch_t nexus_probe_nomatch; static bus_setup_intr_t nexus_setup_intr; static bus_teardown_intr_t nexus_teardown_intr; -static bus_alloc_resource_t nexus_alloc_resource; static bus_activate_resource_t nexus_activate_resource; static bus_deactivate_resource_t nexus_deactivate_resource; -static bus_adjust_resource_t nexus_adjust_resource; -static bus_release_resource_t nexus_release_resource; -static bus_get_resource_list_t nexus_get_resource_list; #ifdef SMP static bus_bind_intr_t nexus_bind_intr; #endif static bus_config_intr_t nexus_config_intr; static ofw_bus_map_intr_t nexus_ofw_map_intr; static ofw_bus_config_intr_t nexus_ofw_config_intr; -static ofw_bus_get_devinfo_t nexus_get_devinfo; - -static int nexus_inlist(const char *, const char *const *); -static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t); -static void nexus_destroy_dinfo(struct nexus_devinfo *); -static int nexus_print_res(struct nexus_devinfo *); static device_method_t nexus_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, nexus_probe), - DEVMETHOD(device_attach, nexus_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - /* Bus interface */ - DEVMETHOD(bus_print_child, nexus_print_child), - DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch), - DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), - DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), - DEVMETHOD(bus_add_child, nexus_add_child), - DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str), - DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), - DEVMETHOD(bus_adjust_resource, nexus_adjust_resource), - DEVMETHOD(bus_release_resource, nexus_release_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), - DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - DEVMETHOD(bus_get_resource_list, nexus_get_resource_list), #ifdef SMP DEVMETHOD(bus_bind_intr, nexus_bind_intr), #endif DEVMETHOD(bus_config_intr, nexus_config_intr), /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_devinfo, nexus_get_devinfo), - DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat), - DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model), - DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), - DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), - DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr), DEVMETHOD(ofw_bus_config_intr, nexus_ofw_config_intr), @@ -151,176 +97,12 @@ static device_method_t nexus_methods[] = static devclass_t nexus_devclass; -DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc)); +DEFINE_CLASS_1(nexus, nexus_driver, nexus_methods, + sizeof(struct ofw_nexus_softc), ofw_nexus_driver); EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0, BUS_PASS_BUS); MODULE_VERSION(nexus, 1); -static const char *const nexus_excl_name[] = { - "FJSV,system", - "aliases", - "associations", - "chosen", - "cmp", - "counter-timer", /* No separate device; handled by psycho/sbus */ - "failsafe", - "memory", - "openprom", - "options", - "packages", - "physical-memory", - "rsc", - "sgcn", - "todsg", - "virtual-memory", - NULL -}; - -static const char *const nexus_excl_type[] = { - "core", - "cpu", - NULL -}; - -extern struct bus_space_tag nexus_bustag; -extern struct bus_dma_tag nexus_dmatag; - -static int -nexus_inlist(const char *name, const char *const *list) -{ - int i; - - if (name == NULL) - return (0); - for (i = 0; list[i] != NULL; i++) - if (strcmp(name, list[i]) == 0) - return (1); - return (0); -} - -#define NEXUS_EXCLUDED(name, type) \ - (nexus_inlist((name), nexus_excl_name) || \ - ((type) != NULL && nexus_inlist((type), nexus_excl_type))) - -static int -nexus_probe(device_t dev) -{ - - /* Nexus does always match. */ - device_set_desc(dev, "Open Firmware Nexus device"); - return (0); -} - -static int -nexus_attach(device_t dev) -{ - struct nexus_devinfo *ndi; - struct nexus_softc *sc; - device_t cdev; - phandle_t node; - - sc = device_get_softc(dev); - - if (strcmp(device_get_name(device_get_parent(dev)), "root") == 0) { - node = OF_peer(0); - - sc->sc_intr_rman.rm_type = RMAN_ARRAY; - sc->sc_intr_rman.rm_descr = "Interrupts"; - sc->sc_mem_rman.rm_type = RMAN_ARRAY; - sc->sc_mem_rman.rm_descr = "Device Memory"; - if (rman_init(&sc->sc_intr_rman) != 0 || - rman_init(&sc->sc_mem_rman) != 0 || - rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0 || - rman_manage_region(&sc->sc_mem_rman, 0, BUS_SPACE_MAXADDR) - != 0) - panic("%s: failed to set up rmans.", __func__); - } else - node = ofw_bus_get_node(dev); - - /* - * Allow devices to identify. - */ - bus_generic_probe(dev); - - /* - * If no Open Firmware, bail early - */ - if (node == -1) - return (bus_generic_attach(dev)); - - /* - * Some important numbers - */ - sc->acells = 2; - OF_getencprop(node, "#address-cells", &sc->acells, sizeof(sc->acells)); - sc->scells = 1; - OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells)); - - /* - * Now walk the OFW tree and attach top-level devices. - */ - for (node = OF_child(node); node > 0; node = OF_peer(node)) { - if ((ndi = nexus_setup_dinfo(dev, node)) == NULL) - continue; - cdev = device_add_child(dev, NULL, -1); - if (cdev == NULL) { - device_printf(dev, "<%s>: device_add_child failed\n", - ndi->ndi_obdinfo.obd_name); - nexus_destroy_dinfo(ndi); - continue; - } - device_set_ivars(cdev, ndi); - } - return (bus_generic_attach(dev)); -} - -static device_t -nexus_add_child(device_t dev, u_int order, const char *name, int unit) -{ - device_t cdev; - struct nexus_devinfo *ndi; - - cdev = device_add_child_ordered(dev, order, name, unit); - if (cdev == NULL) - return (NULL); - - ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); - ndi->ndi_obdinfo.obd_node = -1; - resource_list_init(&ndi->ndi_rl); - device_set_ivars(cdev, ndi); - - return (cdev); -} - -static int -nexus_print_child(device_t bus, device_t child) -{ - int rv; - - rv = bus_print_child_header(bus, child); - rv += nexus_print_res(device_get_ivars(child)); - rv += bus_print_child_footer(bus, child); - return (rv); -} - -static void -nexus_probe_nomatch(device_t bus, device_t child) -{ - const char *name, *type; - - if (!bootverbose) - return; - - name = ofw_bus_get_name(child); - type = ofw_bus_get_type(child); - - device_printf(bus, "<%s>", - name != NULL ? name : "unknown"); - nexus_print_res(device_get_ivars(child)); - printf(" type %s (no driver attached)\n", - type != NULL ? type : "unknown"); -} - static int nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, @@ -389,70 +171,6 @@ nexus_ofw_config_intr(device_t dev, devi INTR_POLARITY_LOW)); } -static struct resource * -nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) -{ - struct nexus_softc *sc; - struct rman *rm; - struct resource *rv; - struct resource_list_entry *rle; - device_t nexus; - int isdefault, passthrough; - - isdefault = (start == 0UL && end == ~0UL); - passthrough = (device_get_parent(child) != bus); - nexus = bus; - while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0) - nexus = device_get_parent(nexus); - sc = device_get_softc(nexus); - rle = NULL; - - if (!passthrough && isdefault) { - rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), - type, *rid); - if (rle == NULL) - return (NULL); - if (rle->res != NULL) - panic("%s: resource entry is busy", __func__); - start = rle->start; - count = ulmax(count, rle->count); - end = ulmax(rle->end, start + count - 1); - } - - switch (type) { - case SYS_RES_IRQ: - rm = &sc->sc_intr_rman; - break; - case SYS_RES_MEMORY: - rm = &sc->sc_mem_rman; - break; - default: - return (NULL); - } - - rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, - child); - if (rv == NULL) - return (NULL); - rman_set_rid(rv, *rid); - - if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, - *rid, rv) != 0) { - rman_release_resource(rv); - return (NULL); - } - - if (!passthrough && rle != NULL) { - rle->res = rv; - rle->start = rman_get_start(rv); - rle->end = rman_get_end(rv); - rle->count = rle->end - rle->start + 1; - } - - return (rv); -} - static int nexus_activate_resource(device_t bus __unused, device_t child __unused, int type, int rid __unused, struct resource *r) @@ -495,161 +213,3 @@ nexus_deactivate_resource(device_t bus _ return (rman_deactivate_resource(r)); } -static int -nexus_adjust_resource(device_t bus, device_t child __unused, int type, - struct resource *r, u_long start, u_long end) -{ - struct nexus_softc *sc; - struct rman *rm; - device_t nexus; - - nexus = bus; - while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0) - nexus = device_get_parent(nexus); - sc = device_get_softc(nexus); - switch (type) { - case SYS_RES_IRQ: - rm = &sc->sc_intr_rman; - break; - case SYS_RES_MEMORY: - rm = &sc->sc_mem_rman; - break; - default: - return (EINVAL); - } - if (rm == NULL) - return (ENXIO); - if (rman_is_region_manager(r, rm) == 0) - return (EINVAL); - return (rman_adjust_resource(r, start, end)); -} - -static int -nexus_release_resource(device_t bus __unused, device_t child, int type, - int rid, struct resource *r) -{ - int error; - - if ((rman_get_flags(r) & RF_ACTIVE) != 0) { - error = bus_deactivate_resource(child, type, rid, r); - if (error) - return (error); - } - return (rman_release_resource(r)); -} - -static struct resource_list * -nexus_get_resource_list(device_t bus __unused, device_t child) -{ - struct nexus_devinfo *ndi; - - ndi = device_get_ivars(child); - return (&ndi->ndi_rl); -} - -static const struct ofw_bus_devinfo * -nexus_get_devinfo(device_t bus __unused, device_t child) -{ - struct nexus_devinfo *ndi; - - ndi = device_get_ivars(child); - return (&ndi->ndi_obdinfo); -} - -static struct nexus_devinfo * -nexus_setup_dinfo(device_t dev, phandle_t node) -{ - struct nexus_softc *sc; - struct nexus_devinfo *ndi; - uint32_t *reg, *intr, icells; - uint64_t phys, size; - phandle_t iparent; - int i, j; - int nintr; - int nreg; - - sc = device_get_softc(dev); - - ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO); - if (ofw_bus_gen_setup_devinfo(&ndi->ndi_obdinfo, node) != 0) { - free(ndi, M_DEVBUF); - return (NULL); - } - if (NEXUS_EXCLUDED(ndi->ndi_obdinfo.obd_name, - ndi->ndi_obdinfo.obd_type)) { - ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo); - free(ndi, M_DEVBUF); - return (NULL); - } - - resource_list_init(&ndi->ndi_rl); - nreg = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)®); - if (nreg == -1) - nreg = 0; - if (nreg % (sc->acells + sc->scells) != 0) { - if (bootverbose) - device_printf(dev, "Malformed reg property on <%s>\n", - ndi->ndi_obdinfo.obd_name); - nreg = 0; - } - - for (i = 0; i < nreg; i += sc->acells + sc->scells) { - phys = size = 0; - for (j = 0; j < sc->acells; j++) { - phys <<= 32; - phys |= reg[i + j]; - } - for (j = 0; j < sc->scells; j++) { - size <<= 32; - size |= reg[i + sc->acells + j]; - } - /* Skip the dummy reg property of glue devices like ssm(4). */ - if (size != 0) - resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i, - phys, phys + size - 1, size); - } - free(reg, M_OFWPROP); - - nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr), - (void **)&intr); - if (nintr > 0) { - iparent = 0; - OF_searchprop(node, "interrupt-parent", &iparent, - sizeof(iparent)); - OF_searchprop(iparent, "#interrupt-cells", &icells, - sizeof(icells)); - for (i = 0; i < nintr; i+= icells) { - intr[i] = ofw_bus_map_intr(dev, iparent, intr[i]); - resource_list_add(&ndi->ndi_rl, SYS_RES_IRQ, i, intr[i], - intr[i], 1); - if (icells > 1) - ofw_bus_config_intr(dev, intr[i], intr[i+1]); - } - free(intr, M_OFWPROP); - } - - return (ndi); -} - -static void -nexus_destroy_dinfo(struct nexus_devinfo *ndi) -{ - - resource_list_free(&ndi->ndi_rl); - ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo); - free(ndi, M_DEVBUF); -} - -static int -nexus_print_res(struct nexus_devinfo *ndi) -{ - int rv; - - rv = 0; - rv += resource_list_print_type(&ndi->ndi_rl, "mem", SYS_RES_MEMORY, - "%#lx"); - rv += resource_list_print_type(&ndi->ndi_rl, "irq", SYS_RES_IRQ, - "%ld"); - return (rv); -} -
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310232000.r9NK0Faw024533>