static int parse_dts(struct ckb_softc *sc) { phandle_t node; pcell_t dts_value; int len; if ((node = ofw_bus_get_node(sc->dev)) == -1) return (ENXIO); if ((len = OF_getproplen(node, "keypad,num-rows")) <= 0) return (ENXIO); OF_getprop(node, "keypad,num-rows", &dts_value, len); sc->rows = fdt32_to_cpu(dts_value); if ((len = OF_getproplen(node, "keypad,num-columns")) <= 0) return (ENXIO); OF_getprop(node, "keypad,num-columns", &dts_value, len); sc->cols = fdt32_to_cpu(dts_value); if ((sc->rows == 0) || (sc->cols == 0)) return (ENXIO); return (0); }
static int ksz9021_load_values(struct mii_softc *sc, phandle_t node, uint32_t reg, char *field1, char *field2, char *field3, char *field4) { pcell_t dts_value[1]; int len; int val; val = 0; if ((len = OF_getproplen(node, field1)) > 0) { OF_getencprop(node, field1, dts_value, len); val = PS_TO_REG(dts_value[0]); } if ((len = OF_getproplen(node, field2)) > 0) { OF_getencprop(node, field2, dts_value, len); val |= PS_TO_REG(dts_value[0]) << 4; } if ((len = OF_getproplen(node, field3)) > 0) { OF_getencprop(node, field3, dts_value, len); val |= PS_TO_REG(dts_value[0]) << 8; } if ((len = OF_getproplen(node, field4)) > 0) { OF_getencprop(node, field4, dts_value, len); val |= PS_TO_REG(dts_value[0]) << 12; } micphy_write(sc, reg, val); return (0); }
static int parse_dts(struct ckb_softc *sc) { phandle_t node; pcell_t dts_value; pcell_t *keymap; int len, ret; const char *keymap_prop = NULL; if ((node = ofw_bus_get_node(sc->dev)) == -1) return (ENXIO); if ((len = OF_getproplen(node, "google,key-rows")) <= 0) return (ENXIO); OF_getencprop(node, "google,key-rows", &dts_value, len); sc->rows = dts_value; if ((len = OF_getproplen(node, "google,key-columns")) <= 0) return (ENXIO); OF_getencprop(node, "google,key-columns", &dts_value, len); sc->cols = dts_value; if ((len = OF_getproplen(node, "freebsd,intr-gpio")) <= 0) return (ENXIO); OF_getencprop(node, "freebsd,intr-gpio", &dts_value, len); sc->gpio = dts_value; if (OF_hasprop(node, "freebsd,keymap")) { keymap_prop = "freebsd,keymap"; device_printf(sc->dev, "using FreeBSD-specific keymap from FDT\n"); } else if (OF_hasprop(node, "linux,keymap")) { keymap_prop = "linux,keymap"; device_printf(sc->dev, "using Linux keymap from FDT\n"); } else { device_printf(sc->dev, "using built-in keymap\n"); } if (keymap_prop != NULL) { if ((ret = read_keymap(node, keymap_prop, &keymap, &len))) { device_printf(sc->dev, "failed to read keymap from FDT: %d\n", ret); return (ret); } ret = parse_keymap(sc, keymap, len); free(keymap, M_DEVBUF); if (ret) { return (ret); } } else { if ((ret = parse_keymap(sc, default_keymap, KEYMAP_LEN))) { return (ret); } } if ((sc->rows == 0) || (sc->cols == 0) || (sc->gpio == 0)) return (ENXIO); return (0); }
asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer) { int phandle,i,mem_len,buffer[32]; char temp[12]; temp[0]='/'; temp[1]='m'; temp[2]='e'; temp[3]='m'; temp[4]='o'; temp[5]='r'; temp[6]='y'; temp[7]='\0'; phandle=OF_finddevice(o,temp); temp[0]='r'; temp[1]='e'; temp[2]='g'; temp[3]='\0'; mem_len = OF_getproplen(o,phandle, temp); OF_getprop(o,phandle, temp, buffer, mem_len); *nomr=mem_len >> 3; for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]); temp[0]='/'; temp[1]='c'; temp[2]='h'; temp[3]='o'; temp[4]='s'; temp[5]='e'; temp[6]='n'; temp[7]='\0'; phandle=OF_finddevice(o,temp); temp[0]='b'; temp[1]='o'; temp[2]='o'; temp[3]='t'; temp[4]='a'; temp[5]='r'; temp[6]='g'; temp[7]='s'; temp[8]='\0'; mem_len = OF_getproplen(o,phandle, temp); OF_getprop(o,phandle, temp, buffer, mem_len); for (i=0; i<=mem_len/4; i++) pointer[i+32]=buffer[i]; }
int ofw_bus_is_compatible(device_t dev, const char *onecompat) { phandle_t node; const char *compat; int len, onelen, l; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (0); if ((node = ofw_bus_get_node(dev)) == -1) return (0); /* Get total 'compatible' prop len */ if ((len = OF_getproplen(node, "compatible")) <= 0) return (0); onelen = strlen(onecompat); while (len > 0) { if (strlen(compat) == onelen && strncasecmp(compat, onecompat, onelen) == 0) /* Found it. */ return (1); /* Slide to the next sub-string. */ l = strlen(compat) + 1; compat += l; len -= l; } return (0); }
static int opaldev_probe(device_t dev) { phandle_t iparent; pcell_t *irqs; int i, n_irqs; if (!ofw_bus_is_compatible(dev, "ibm,opal-v3")) return (ENXIO); if (opal_check() != 0) return (ENXIO); device_set_desc(dev, "OPAL Abstraction Firmware"); /* Manually add IRQs before attaching */ if (OF_hasprop(ofw_bus_get_node(dev), "opal-interrupts")) { iparent = OF_finddevice("/interrupt-controller@0"); iparent = OF_xref_from_node(iparent); n_irqs = OF_getproplen(ofw_bus_get_node(dev), "opal-interrupts") / sizeof(*irqs); irqs = malloc(n_irqs * sizeof(*irqs), M_DEVBUF, M_WAITOK); OF_getencprop(ofw_bus_get_node(dev), "opal-interrupts", irqs, n_irqs * sizeof(*irqs)); for (i = 0; i < n_irqs; i++) bus_set_resource(dev, SYS_RES_IRQ, i, ofw_bus_map_intr(dev, iparent, 1, &irqs[i]), 1); free(irqs, M_DEVBUF); } return (BUS_PROBE_SPECIFIC); }
int ofw_pci_nranges(phandle_t node, struct ofw_pci_cell_info *info) { ssize_t nbase_ranges; if (info == NULL) return (-1); info->host_address_cells = 1; info->size_cells = 2; info->pci_address_cell = 3; OF_getencprop(OF_parent(node), "#address-cells", &(info->host_address_cells), sizeof(info->host_address_cells)); OF_getencprop(node, "#address-cells", &(info->pci_address_cell), sizeof(info->pci_address_cell)); OF_getencprop(node, "#size-cells", &(info->size_cells), sizeof(info->size_cells)); nbase_ranges = OF_getproplen(node, "ranges"); if (nbase_ranges <= 0) return (-1); return (nbase_ranges / sizeof(cell_t) / (info->pci_address_cell + info->host_address_cells + info->size_cells)); }
static int ofw_get_console_phandle_path(phandle_t node, phandle_t *result, const char *prop) { union { char buf[64]; phandle_t ref; } field; phandle_t output; ssize_t size; size = OF_getproplen(node, prop); if (size == -1) return (ENXIO); OF_getprop(node, prop, &field, sizeof(field)); /* This property might be either a ihandle or path. Hooray. */ output = -1; if (field.buf[size - 1] == 0) output = OF_finddevice(field.buf); if (output == -1 && size == 4) output = OF_instance_to_package(field.ref); if (output != -1) { *result = output; return (0); } return (ENXIO); }
/* * This routine is an early-usage version of the ofw_bus_is_compatible() when * the ofw_bus I/F is not available (like early console routines and similar). * Note the buffer has to be on the stack since malloc() is usually not * available in such cases either. */ int fdt_is_compatible(phandle_t node, const char *compatstr) { char buf[FDT_COMPAT_LEN]; char *compat; int len, onelen, l, rv; if ((len = OF_getproplen(node, "compatible")) <= 0) return (0); compat = (char *)&buf; bzero(compat, FDT_COMPAT_LEN); if (OF_getprop(node, "compatible", compat, FDT_COMPAT_LEN) < 0) return (0); onelen = strlen(compatstr); rv = 0; while (len > 0) { if (strncasecmp(compat, compatstr, onelen) == 0) { /* Found it. */ rv = 1; break; } /* Slide to the next sub-string. */ l = strlen(compat) + 1; compat += l; len -= l; } return (rv); }
int com_ebus_match(struct device *parent, void *match, void *aux) { struct ebus_attach_args *ea = aux; int i; for (i=0; com_names[i]; i++) if (strcmp(ea->ea_name, com_names[i]) == 0) return (1); if (strcmp(ea->ea_name, "serial") == 0) { char compat[80]; /* Could be anything. */ if ((i = OF_getproplen(ea->ea_node, "compatible")) && OF_getprop(ea->ea_node, "compatible", compat, sizeof(compat)) == i) { if (strcmp(compat, "su16552") == 0 || strcmp(compat, "su16550") == 0 || strcmp(compat, "FJSV,su") == 0 || strcmp(compat, "su") == 0) { return (1); } } } return (0); }
static int get_panel_info(struct fimd_softc *sc, struct panel_info *panel) { phandle_t node; pcell_t dts_value[3]; int len; if ((node = ofw_bus_get_node(sc->dev)) == -1) return (ENXIO); /* panel size */ if ((len = OF_getproplen(node, "panel-size")) <= 0) return (ENXIO); OF_getprop(node, "panel-size", &dts_value, len); panel->width = fdt32_to_cpu(dts_value[0]); panel->height = fdt32_to_cpu(dts_value[1]); /* hsync */ if ((len = OF_getproplen(node, "panel-hsync")) <= 0) return (ENXIO); OF_getprop(node, "panel-hsync", &dts_value, len); panel->h_back_porch = fdt32_to_cpu(dts_value[0]); panel->h_pulse_width = fdt32_to_cpu(dts_value[1]); panel->h_front_porch = fdt32_to_cpu(dts_value[2]); /* vsync */ if ((len = OF_getproplen(node, "panel-vsync")) <= 0) return (ENXIO); OF_getprop(node, "panel-vsync", &dts_value, len); panel->v_back_porch = fdt32_to_cpu(dts_value[0]); panel->v_pulse_width = fdt32_to_cpu(dts_value[1]); panel->v_front_porch = fdt32_to_cpu(dts_value[2]); /* clk divider */ if ((len = OF_getproplen(node, "panel-clk-div")) <= 0) return (ENXIO); OF_getprop(node, "panel-clk-div", &dts_value, len); panel->clk_div = fdt32_to_cpu(dts_value[0]); /* backlight pin */ if ((len = OF_getproplen(node, "panel-backlight-pin")) <= 0) return (ENXIO); OF_getprop(node, "panel-backlight-pin", &dts_value, len); panel->backlight_pin = fdt32_to_cpu(dts_value[0]); return (0); }
int fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size) { pcell_t ranges[6], *rangesptr; pcell_t addr_cells, size_cells, par_addr_cells; u_long par_bus_addr, pbase, psize; int err, len, tuple_size, tuples; if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) return (ENXIO); /* * Process 'ranges' property. */ par_addr_cells = fdt_parent_addr_cells(node); if (par_addr_cells > 2) return (ERANGE); len = OF_getproplen(node, "ranges"); if (len > sizeof(ranges)) return (ENOMEM); if (len == 0) { *base = 0; *size = ULONG_MAX; return (0); } if (!(range_id < len)) return (ERANGE); if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0) return (EINVAL); tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells + size_cells); tuples = len / tuple_size; if (par_addr_cells > 2 || addr_cells > 2 || size_cells > 2) return (ERANGE); *base = 0; *size = 0; rangesptr = &ranges[range_id]; *base = fdt_data_get((void *)rangesptr, addr_cells); rangesptr += addr_cells; par_bus_addr = fdt_data_get((void *)rangesptr, par_addr_cells); rangesptr += par_addr_cells; err = fdt_get_range_by_busaddr(OF_parent(node), par_bus_addr, &pbase, &psize); if (err == 0) *base += pbase; else *base += par_bus_addr; *size = fdt_data_get((void *)rangesptr, size_cells); return (0); }
int vbus_intr_map(int node, int ino, uint64_t *sysino) { int *imap = NULL, nimap; int *reg = NULL, nreg; int *imap_mask; int parent; int address_cells, interrupt_cells; uint64_t devhandle; uint64_t devino; int len; int err; parent = OF_parent(node); address_cells = getpropint(parent, "#address-cells", 2); interrupt_cells = getpropint(parent, "#interrupt-cells", 1); KASSERT(interrupt_cells == 1); len = OF_getproplen(parent, "interrupt-map-mask"); if (len < (address_cells + interrupt_cells) * sizeof(int)) return (-1); imap_mask = malloc(len, M_DEVBUF, M_NOWAIT); if (imap_mask == NULL) return (-1); if (OF_getprop(parent, "interrupt-map-mask", imap_mask, len) != len) return (-1); getprop(parent, "interrupt-map", sizeof(int), &nimap, (void **)&imap); getprop(node, "reg", sizeof(*reg), &nreg, (void **)®); if (nreg < address_cells) return (-1); while (nimap >= address_cells + interrupt_cells + 2) { if (vbus_cmp_cells(imap, reg, imap_mask, address_cells) && vbus_cmp_cells(&imap[address_cells], &ino, &imap_mask[address_cells], interrupt_cells)) { node = imap[address_cells + interrupt_cells]; devino = imap[address_cells + interrupt_cells + 1]; free(reg, M_DEVBUF, 0); reg = NULL; getprop(node, "reg", sizeof(*reg), &nreg, (void **)®); devhandle = reg[0] & 0x0fffffff; err = hv_intr_devino_to_sysino(devhandle, devino, sysino); if (err != H_EOK) return (-1); KASSERT(*sysino == INTVEC(*sysino)); return (0); } imap += address_cells + interrupt_cells + 2; nimap -= address_cells + interrupt_cells + 2; } return (-1); }
int fdt_get_reserved_regions(struct mem_region *mr, int *mrcnt) { pcell_t reserve[FDT_REG_CELLS * FDT_MEM_REGIONS]; pcell_t *reservep; phandle_t memory, root; uint32_t memory_size; int addr_cells, size_cells; int i, max_size, res_len, rv, tuple_size, tuples; max_size = sizeof(reserve); root = OF_finddevice("/"); memory = OF_finddevice("/memory"); if (memory == -1) { rv = ENXIO; goto out; } if ((rv = fdt_addrsize_cells(OF_parent(memory), &addr_cells, &size_cells)) != 0) goto out; if (addr_cells > 2) { rv = ERANGE; goto out; } tuple_size = sizeof(pcell_t) * (addr_cells + size_cells); res_len = OF_getproplen(root, "memreserve"); if (res_len <= 0 || res_len > sizeof(reserve)) { rv = ERANGE; goto out; } if (OF_getprop(root, "memreserve", reserve, res_len) <= 0) { rv = ENXIO; goto out; } memory_size = 0; tuples = res_len / tuple_size; reservep = (pcell_t *)&reserve; for (i = 0; i < tuples; i++) { rv = fdt_data_to_res(reservep, addr_cells, size_cells, (u_long *)&mr[i].mr_start, (u_long *)&mr[i].mr_size); if (rv != 0) goto out; reservep += addr_cells + size_cells; } *mrcnt = i; rv = 0; out: return (rv); }
static int vt_efb_probe(struct vt_device *vd) { phandle_t node; node = vt_efb_get_fbnode(); if (node == -1) return (CN_DEAD); if ((OF_getproplen(node, "height") <= 0) || (OF_getproplen(node, "width") <= 0) || (OF_getproplen(node, "depth") <= 0) || (OF_getproplen(node, "linebytes") <= 0)) return (CN_DEAD); return (CN_INTERNAL); }
/** * ti_scm_padconf_init_from_hints - processes the hints for padconf * @sc: the driver soft context * * * * LOCKING: * Internally locks it's own context. * * RETURNS: * 0 on success. * EINVAL if pin requested is outside valid range or already in use. */ static int ti_scm_padconf_init_from_fdt(struct ti_scm_softc *sc) { const struct ti_scm_padconf *padconf; const struct ti_scm_padstate *padstates; int err; phandle_t node; int len; char *fdt_pad_config; int i; char *padname, *muxname, *padstate; node = ofw_bus_get_node(sc->sc_dev); len = OF_getproplen(node, "scm-pad-config"); OF_getprop_alloc(node, "scm-pad-config", 1, (void **)&fdt_pad_config); i = len; while (i > 0) { padname = fdt_pad_config; fdt_pad_config += strlen(padname) + 1; i -= strlen(padname) + 1; if (i <= 0) break; muxname = fdt_pad_config; fdt_pad_config += strlen(muxname) + 1; i -= strlen(muxname) + 1; if (i <= 0) break; padstate = fdt_pad_config; fdt_pad_config += strlen(padstate) + 1; i -= strlen(padstate) + 1; if (i < 0) break; padconf = ti_scm_dev.padconf; while (padconf->ballname != NULL) { if (strcmp(padconf->ballname, padname) == 0) { padstates = ti_scm_dev.padstate; err = 1; while (padstates->state != NULL) { if (strcmp(padstates->state, padstate) == 0) { err = ti_scm_padconf_set_internal(sc, padconf, muxname, padstates->reg); } padstates++; } if (err) device_printf(sc->sc_dev, "err: failed to configure" "pin \"%s\"\n", padconf->ballname); } padconf++; } } return (0); }
static void ksz90x1_load_values(struct mii_softc *sc, phandle_t node, uint32_t dev, uint32_t reg, char *field1, uint32_t f1mask, int f1off, char *field2, uint32_t f2mask, int f2off, char *field3, uint32_t f3mask, int f3off, char *field4, uint32_t f4mask, int f4off) { pcell_t dts_value[1]; int len; int val; if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031) val = ksz9031_read(sc, dev, reg); else val = ksz9021_read(sc, reg); if ((len = OF_getproplen(node, field1)) > 0) { OF_getencprop(node, field1, dts_value, len); val &= ~(f1mask << f1off); val |= (PS_TO_REG(dts_value[0]) & f1mask) << f1off; } if (field2 != NULL && (len = OF_getproplen(node, field2)) > 0) { OF_getencprop(node, field2, dts_value, len); val &= ~(f2mask << f2off); val |= (PS_TO_REG(dts_value[0]) & f2mask) << f2off; } if (field3 != NULL && (len = OF_getproplen(node, field3)) > 0) { OF_getencprop(node, field3, dts_value, len); val &= ~(f3mask << f3off); val |= (PS_TO_REG(dts_value[0]) & f3mask) << f3off; } if (field4 != NULL && (len = OF_getproplen(node, field4)) > 0) { OF_getencprop(node, field4, dts_value, len); val &= ~(f4mask << f4off); val |= (PS_TO_REG(dts_value[0]) & f4mask) << f4off; } if (sc->mii_mpd_model == MII_MODEL_MICREL_KSZ9031) ksz9031_write(sc, dev, reg, val); else ksz9021_write(sc, reg, val); }
/** * twl_probe - * @dev: the twl device * * Scans the FDT for a match for the device, possible compatible device * strings are; "ti,twl6030", "ti,twl6025", "ti,twl4030". * * The FDT compat string also determines the type of device (it is currently * not possible to dynamically determine the device type). * */ static int twl_probe(device_t dev) { phandle_t node; const char *compat; int len, l; struct twl_softc *sc; if ((compat = ofw_bus_get_compat(dev)) == NULL) return (ENXIO); if ((node = ofw_bus_get_node(dev)) == 0) return (ENXIO); /* Get total 'compatible' prop len */ if ((len = OF_getproplen(node, "compatible")) <= 0) return (ENXIO); sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_type = TWL_DEVICE_UNKNOWN; while (len > 0) { if (strncasecmp(compat, "ti,twl6030", 10) == 0) sc->sc_type = TWL_DEVICE_6030; else if (strncasecmp(compat, "ti,twl6025", 10) == 0) sc->sc_type = TWL_DEVICE_6025; else if (strncasecmp(compat, "ti,twl4030", 10) == 0) sc->sc_type = TWL_DEVICE_4030; if (sc->sc_type != TWL_DEVICE_UNKNOWN) break; /* Slide to the next sub-string. */ l = strlen(compat) + 1; compat += l; len -= l; } switch (sc->sc_type) { case TWL_DEVICE_4030: device_set_desc(dev, "TI TWL4030/TPS659x0 Companion IC"); break; case TWL_DEVICE_6025: device_set_desc(dev, "TI TWL6025 Companion IC"); break; case TWL_DEVICE_6030: device_set_desc(dev, "TI TWL6030 Companion IC"); break; case TWL_DEVICE_UNKNOWN: default: return (ENXIO); } return (0); }
static int psci_v0_1_init(device_t dev) { struct psci_softc *sc = device_get_softc(dev); int psci_fn; uint32_t psci_fnid; phandle_t node; int len; /* Zero out the function ID table - Is this needed ? */ for (psci_fn = PSCI_FN_VERSION, psci_fnid = PSCI_FNID_VERSION; psci_fn < PSCI_FN_MAX; psci_fn++, psci_fnid++) sc->psci_fnids[psci_fn] = 0; /* PSCI v0.1 doesn't specify function IDs. Get them from DT */ node = ofw_bus_get_node(dev); if ((len = OF_getproplen(node, "cpu_suspend")) > 0) { OF_getencprop(node, "cpu_suspend", &psci_fnid, len); sc->psci_fnids[PSCI_FN_CPU_SUSPEND] = psci_fnid; } if ((len = OF_getproplen(node, "cpu_on")) > 0) { OF_getencprop(node, "cpu_on", &psci_fnid, len); sc->psci_fnids[PSCI_FN_CPU_ON] = psci_fnid; } if ((len = OF_getproplen(node, "cpu_off")) > 0) { OF_getencprop(node, "cpu_off", &psci_fnid, len); sc->psci_fnids[PSCI_FN_CPU_OFF] = psci_fnid; } if ((len = OF_getproplen(node, "migrate")) > 0) { OF_getencprop(node, "migrate", &psci_fnid, len); sc->psci_fnids[PSCI_FN_MIGRATE] = psci_fnid; } if (bootverbose) device_printf(dev, "PSCI version 0.1 available\n"); return(0); }
static int rk30_gpio_init(void) { phandle_t child, parent, root, ctrl; pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS]; struct gpio_ctrl_entry *e; int len, rv; root = OF_finddevice("/"); len = 0; parent = root; /* Traverse through entire tree to find nodes with 'gpios' prop */ for (child = OF_child(parent); child != 0; child = OF_peer(child)) { /* Find a 'leaf'. Start the search from this node. */ while (OF_child(child)) { parent = child; child = OF_child(child); } if ((len = OF_getproplen(child, "gpios")) > 0) { if (len > sizeof(gpios)) return (ENXIO); /* Get 'gpios' property. */ OF_getprop(child, "gpios", &gpios, len); e = (struct gpio_ctrl_entry *)&gpio_controllers; /* Find and call a handler. */ for (; e->compat; e++) { /* * First cell of 'gpios' property should * contain a ref. to a node defining GPIO * controller. */ ctrl = OF_node_from_xref(fdt32_to_cpu(gpios[0])); if (fdt_is_compatible(ctrl, e->compat)) /* Call a handler. */ if ((rv = e->handler(ctrl, (pcell_t *)&gpios, len))) return (rv); } } if (OF_peer(child) == 0) { /* No more siblings. */ child = parent; parent = OF_parent(child); } } return (0); }
static int edma_attach(device_t dev) { struct edma_softc *sc; phandle_t node; int dts_value; int len; sc = device_get_softc(dev); sc->dev = dev; if ((node = ofw_bus_get_node(sc->dev)) == -1) return (ENXIO); if ((len = OF_getproplen(node, "device-id")) <= 0) return (ENXIO); OF_getprop(node, "device-id", &dts_value, len); sc->device_id = fdt32_to_cpu(dts_value); sc->dma_stop = dma_stop; sc->dma_setup = dma_setup; sc->dma_request = dma_request; sc->channel_configure = channel_configure; sc->channel_free = channel_free; if (bus_alloc_resources(dev, edma_spec, sc->res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } /* Memory interface */ sc->bst = rman_get_bustag(sc->res[0]); sc->bsh = rman_get_bushandle(sc->res[0]); sc->bst_tcd = rman_get_bustag(sc->res[1]); sc->bsh_tcd = rman_get_bushandle(sc->res[1]); /* Setup interrupt handlers */ if (bus_setup_intr(dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE, NULL, edma_transfer_complete_intr, sc, &sc->tc_ih)) { device_printf(dev, "Unable to alloc DMA intr resource.\n"); return (ENXIO); } if (bus_setup_intr(dev, sc->res[3], INTR_TYPE_BIO | INTR_MPSAFE, NULL, edma_err_intr, sc, &sc->err_ih)) { device_printf(dev, "Unable to alloc DMA Err intr resource.\n"); return (ENXIO); } return (0); }
static int pinmux_set(struct iomuxc_softc *sc) { phandle_t child, parent, root; pcell_t iomux_config[MAX_MUX_LEN]; int len; int values; int pin; int pin_cfg; int i; root = OF_finddevice("/"); len = 0; parent = root; /* Find 'iomux_config' prop in the nodes */ for (child = OF_child(parent); child != 0; child = OF_peer(child)) { /* Find a 'leaf'. Start the search from this node. */ while (OF_child(child)) { parent = child; child = OF_child(child); } if (!fdt_is_enabled(child)) continue; if ((len = OF_getproplen(child, "iomux_config")) > 0) { OF_getprop(child, "iomux_config", &iomux_config, len); values = len / (sizeof(uint32_t)); for (i = 0; i < values; i += 2) { pin = fdt32_to_cpu(iomux_config[i]); pin_cfg = fdt32_to_cpu(iomux_config[i+1]); #if 0 device_printf(sc->dev, "Set pin %d to 0x%08x\n", pin, pin_cfg); #endif WRITE4(sc, IOMUXC(pin), pin_cfg); } } if (OF_peer(child) == 0) { /* No more siblings. */ child = parent; parent = OF_parent(child); } } return (0); }
/* * This function replaces sys/dev/cninit.c * Determine which device is the console using * the PROM "input source" and "output sink". */ void consinit() { register int chosen; char buffer[128]; extern int stdinnode, fbnode; char *consname = "unknown"; DBPRINT(("consinit()\r\n")); if (cn_tab != &consdev_prom) return; DBPRINT(("setting up stdin\r\n")); chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)); DBPRINT(("stdin instance = %x\r\n", stdin)); if ((stdinnode = OF_instance_to_package(stdin)) == 0) { printf("WARNING: no PROM stdin\n"); } #if NUKBD > 0 else { if (OF_getprop(stdinnode, "compatible", buffer, sizeof(buffer)) != -1 && strncmp("usb", buffer, 3) == 0) ukbd_cnattach(); } #endif DBPRINT(("setting up stdout\r\n")); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); DBPRINT(("stdout instance = %x\r\n", stdout)); if ((fbnode = OF_instance_to_package(stdout)) == 0) printf("WARNING: no PROM stdout\n"); DBPRINT(("stdout package = %x\r\n", fbnode)); if (stdinnode && (OF_getproplen(stdinnode,"keyboard") >= 0)) { consname = "keyboard/display"; } else if (fbnode && (OF_instance_to_path(stdin, buffer, sizeof(buffer)) >= 0)) { consname = buffer; } printf("console is %s\n", consname); /* Initialize PROM console */ (*cn_tab->cn_probe)(cn_tab); (*cn_tab->cn_init)(cn_tab); }
/* Allocates a new array for keymap and returns it in 'keymap'. */ static int read_keymap(phandle_t node, const char *prop, pcell_t **keymap, size_t *len) { if ((*len = OF_getproplen(node, prop)) <= 0) { return (ENXIO); } if ((*keymap = malloc(*len, M_DEVBUF, M_NOWAIT)) == NULL) { return (ENOMEM); } if (OF_getencprop(node, prop, *keymap, *len) != *len) { return (ENXIO); } return (0); }
static int simplebus_fill_ranges(phandle_t node, struct simplebus_softc *sc) { int host_address_cells; cell_t *base_ranges; ssize_t nbase_ranges; int err; int i, j, k; err = OF_searchencprop(OF_parent(node), "#address-cells", &host_address_cells, sizeof(host_address_cells)); if (err <= 0) return (-1); nbase_ranges = OF_getproplen(node, "ranges"); if (nbase_ranges < 0) return (-1); sc->nranges = nbase_ranges / sizeof(cell_t) / (sc->acells + host_address_cells + sc->scells); if (sc->nranges == 0) return (0); sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]), M_DEVBUF, M_WAITOK); base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); OF_getencprop(node, "ranges", base_ranges, nbase_ranges); for (i = 0, j = 0; i < sc->nranges; i++) { sc->ranges[i].bus = 0; for (k = 0; k < sc->acells; k++) { sc->ranges[i].bus <<= 32; sc->ranges[i].bus |= base_ranges[j++]; } sc->ranges[i].host = 0; for (k = 0; k < host_address_cells; k++) { sc->ranges[i].host <<= 32; sc->ranges[i].host |= base_ranges[j++]; } sc->ranges[i].size = 0; for (k = 0; k < sc->scells; k++) { sc->ranges[i].size <<= 32; sc->ranges[i].size |= base_ranges[j++]; } } free(base_ranges, M_DEVBUF); return (sc->nranges); }
int ofw_bus_node_status_okay(phandle_t node) { char status[OFW_STATUS_LEN]; int len; len = OF_getproplen(node, "status"); if (len <= 0) return (1); OF_getprop(node, "status", status, OFW_STATUS_LEN); if ((len == 5 && (bcmp(status, "okay", len) == 0)) || (len == 3 && (bcmp(status, "ok", len)))) return (1); return (0); }
static int ofw_pci_fill_ranges(phandle_t node, struct ofw_pci_range *ranges) { int host_address_cells = 1, pci_address_cells = 3, size_cells = 2; cell_t *base_ranges; ssize_t nbase_ranges; int nranges; int i, j, k; OF_getprop(OF_parent(node), "#address-cells", &host_address_cells, sizeof(host_address_cells)); OF_getprop(node, "#address-cells", &pci_address_cells, sizeof(pci_address_cells)); OF_getprop(node, "#size-cells", &size_cells, sizeof(size_cells)); nbase_ranges = OF_getproplen(node, "ranges"); if (nbase_ranges <= 0) return (-1); nranges = nbase_ranges / sizeof(cell_t) / (pci_address_cells + host_address_cells + size_cells); base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); OF_getprop(node, "ranges", base_ranges, nbase_ranges); for (i = 0, j = 0; i < nranges; i++) { ranges[i].pci_hi = base_ranges[j++]; ranges[i].pci = 0; for (k = 0; k < pci_address_cells - 1; k++) { ranges[i].pci <<= 32; ranges[i].pci |= base_ranges[j++]; } ranges[i].host = 0; for (k = 0; k < host_address_cells; k++) { ranges[i].host <<= 32; ranges[i].host |= base_ranges[j++]; } ranges[i].size = 0; for (k = 0; k < size_cells; k++) { ranges[i].size <<= 32; ranges[i].size |= base_ranges[j++]; } } free(base_ranges, M_DEVBUF); return (nranges); }
int fdt_is_compatible_strict(phandle_t node, const char *compatible) { char compat[FDT_COMPAT_LEN]; if (OF_getproplen(node, "compatible") <= 0) return (0); if (OF_getprop(node, "compatible", compat, FDT_COMPAT_LEN) < 0) return (0); if (strncasecmp(compat, compatible, FDT_COMPAT_LEN) == 0) /* This fits. */ return (1); return (0); }
int fdt_is_type(phandle_t node, const char *typestr) { char type[FDT_TYPE_LEN]; if (OF_getproplen(node, "device_type") <= 0) return (0); if (OF_getprop(node, "device_type", type, FDT_TYPE_LEN) < 0) return (0); if (strncasecmp(type, typestr, FDT_TYPE_LEN) == 0) /* This fits. */ return (1); return (0); }
static int rtaspci_probe(device_t dev) { const char *type; if (!rtas_exists()) return (ENXIO); type = ofw_bus_get_type(dev); if (OF_getproplen(ofw_bus_get_node(dev), "used-by-rtas") < 0) return (ENXIO); if (type == NULL || strcmp(type, "pci") != 0) return (ENXIO); device_set_desc(dev, "RTAS Host-PCI bridge"); return (BUS_PROBE_GENERIC); }