Deleted Added
full compact
36c36
< __FBSDID("$FreeBSD: stable/10/sys/dev/ofw/ofwbus.c 283477 2015-05-24 17:51:57Z ian $");
---
> __FBSDID("$FreeBSD: stable/10/sys/dev/ofw/ofwbus.c 266160 2014-05-15 17:30:16Z ian $");
53d52
< #include <dev/fdt/simplebus.h>
65a65,69
> struct ofwbus_devinfo {
> struct ofw_bus_devinfo ndi_obdinfo;
> struct resource_list ndi_rl;
> };
>
67c71
< struct simplebus_softc simplebus_sc;
---
> uint32_t acells, scells;
74a79,81
> static bus_print_child_t ofwbus_print_child;
> static bus_add_child_t ofwbus_add_child;
> static bus_probe_nomatch_t ofwbus_probe_nomatch;
77a85,86
> static bus_get_resource_list_t ofwbus_get_resource_list;
> static ofw_bus_get_devinfo_t ofwbus_get_devinfo;
78a88,92
> static int ofwbus_inlist(const char *, const char *const *);
> static struct ofwbus_devinfo * ofwbus_setup_dinfo(device_t, phandle_t);
> static void ofwbus_destroy_dinfo(struct ofwbus_devinfo *);
> static int ofwbus_print_res(struct ofwbus_devinfo *);
>
83a98,101
> DEVMETHOD(device_detach, bus_generic_detach),
> DEVMETHOD(device_shutdown, bus_generic_shutdown),
> DEVMETHOD(device_suspend, bus_generic_suspend),
> DEVMETHOD(device_resume, bus_generic_resume),
85a104,109
> DEVMETHOD(bus_print_child, ofwbus_print_child),
> DEVMETHOD(bus_probe_nomatch, ofwbus_probe_nomatch),
> DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
> DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
> DEVMETHOD(bus_add_child, ofwbus_add_child),
> DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
88a113,120
> DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
> DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
> DEVMETHOD(bus_get_resource_list, ofwbus_get_resource_list),
> DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
> DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
> DEVMETHOD(bus_config_intr, bus_generic_config_intr),
> DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
> DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
89a122,129
> /* ofw_bus interface */
> DEVMETHOD(ofw_bus_get_devinfo, ofwbus_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),
>
93,94c133,137
< DEFINE_CLASS_1(ofwbus, ofwbus_driver, ofwbus_methods,
< sizeof(struct ofwbus_softc), simplebus_driver);
---
> static driver_t ofwbus_driver = {
> "ofwbus",
> ofwbus_methods,
> sizeof(struct ofwbus_softc)
> };
96,97c139
< EARLY_DRIVER_MODULE(ofwbus, nexus, ofwbus_driver, ofwbus_devclass, 0, 0,
< BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
---
> DRIVER_MODULE(ofwbus, nexus, ofwbus_driver, ofwbus_devclass, 0, 0);
99a142,184
> static const char *const ofwbus_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 ofwbus_excl_type[] = {
> "core",
> "cpu",
> NULL
> };
>
> static int
> ofwbus_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 OFWBUS_EXCLUDED(name, type) \
> (ofwbus_inlist((name), ofwbus_excl_name) || \
> ((type) != NULL && ofwbus_inlist((type), ofwbus_excl_type)))
>
107c192
<
---
>
122a208
> struct ofwbus_devinfo *ndi;
123a210
> device_t cdev;
125d211
< struct ofw_bus_devinfo obd;
137,141d222
< /*
< * ofwbus bus starts on unamed node in FDT, so we cannot make
< * ofw_bus_devinfo from it. Pass node to simplebus_init directly.
< */
< simplebus_init(dev, node);
157a239,246
> * 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));
>
> /*
161c250
< if (ofw_bus_gen_setup_devinfo(&obd, node) != 0)
---
> if ((ndi = ofwbus_setup_dinfo(dev, node)) == NULL)
163c252,259
< simplebus_add_device(dev, node, 0, NULL, -1, NULL);
---
> cdev = device_add_child(dev, NULL, -1);
> if (cdev == NULL) {
> device_printf(dev, "<%s>: device_add_child failed\n",
> ndi->ndi_obdinfo.obd_name);
> ofwbus_destroy_dinfo(ndi);
> continue;
> }
> device_set_ivars(cdev, ndi);
167a264,310
> static device_t
> ofwbus_add_child(device_t dev, u_int order, const char *name, int unit)
> {
> device_t cdev;
> struct ofwbus_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
> ofwbus_print_child(device_t bus, device_t child)
> {
> int rv;
>
> rv = bus_print_child_header(bus, child);
> rv += ofwbus_print_res(device_get_ivars(child));
> rv += bus_print_child_footer(bus, child);
> return (rv);
> }
>
> static void
> ofwbus_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");
> ofwbus_print_res(device_get_ivars(child));
> printf(" type %s (no driver attached)\n",
> type != NULL ? type : "unknown");
> }
>
181a325
>
185,188c329
< if (rle == NULL) {
< if (bootverbose)
< device_printf(bus, "no default resources for "
< "rid = %d, type = %d\n", *rid, type);
---
> if (rle == NULL)
190c331,332
< }
---
> if (rle->res != NULL)
> panic("%s: resource entry is busy", __func__);
259c401
< ofwbus_release_resource(device_t bus, device_t child, int type,
---
> ofwbus_release_resource(device_t bus __unused, device_t child, int type,
262d403
< struct resource_list_entry *rle;
265,269d405
< /* Clean resource list entry */
< rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), type, rid);
< if (rle != NULL)
< rle->res = NULL;
<
276a413,527
>
> static struct resource_list *
> ofwbus_get_resource_list(device_t bus __unused, device_t child)
> {
> struct ofwbus_devinfo *ndi;
>
> ndi = device_get_ivars(child);
> return (&ndi->ndi_rl);
> }
>
> static const struct ofw_bus_devinfo *
> ofwbus_get_devinfo(device_t bus __unused, device_t child)
> {
> struct ofwbus_devinfo *ndi;
>
> ndi = device_get_ivars(child);
> return (&ndi->ndi_obdinfo);
> }
>
> static struct ofwbus_devinfo *
> ofwbus_setup_dinfo(device_t dev, phandle_t node)
> {
> struct ofwbus_softc *sc;
> struct ofwbus_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 (OFWBUS_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 **)&reg);
> 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_searchencprop(node, "interrupt-parent", &iparent,
> sizeof(iparent));
> OF_searchencprop(OF_xref_phandle(iparent), "#interrupt-cells",
> &icells, sizeof(icells));
> for (i = 0; i < nintr; i+= icells) {
> intr[i] = ofw_bus_map_intr(dev, iparent, icells,
> &intr[i]);
> resource_list_add(&ndi->ndi_rl, SYS_RES_IRQ, i, intr[i],
> intr[i], 1);
> }
> free(intr, M_OFWPROP);
> }
>
> return (ndi);
> }
>
> static void
> ofwbus_destroy_dinfo(struct ofwbus_devinfo *ndi)
> {
>
> resource_list_free(&ndi->ndi_rl);
> ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
> free(ndi, M_DEVBUF);
> }
>
> static int
> ofwbus_print_res(struct ofwbus_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);
> }
>