static int nvmem_get_cell_node(phandle_t node, int idx, phandle_t *cell) { phandle_t *p_cell; phandle_t cell_node; int ncell; if (!OF_hasprop(node, "nvmem-cells") || !OF_hasprop(node, "nvmem-cell-names")) return (ENOENT); ncell = OF_getencprop_alloc_multi(node, "nvmem-cells", sizeof(*p_cell), (void **)&p_cell); if (ncell <= 0) return (ENOENT); cell_node = OF_node_from_xref(p_cell[idx]); if (cell_node == p_cell[idx]) { if (bootverbose) printf("nvmem_get_node: Cannot resolve phandle %x\n", p_cell[idx]); OF_prop_free(p_cell); return (ENOENT); } OF_prop_free(p_cell); *cell = cell_node; return (0); }
int opal_check(void) { phandle_t opal; cell_t val[2]; if (opal_initialized) return (0); opal = OF_finddevice("/ibm,opal"); if (opal == -1) return (ENOENT); if (!OF_hasprop(opal, "opal-base-address") || !OF_hasprop(opal, "opal-entry-address")) return (ENOENT); OF_getencprop(opal, "opal-base-address", val, sizeof(val)); opal_data = ((uint64_t)val[0] << 32) | val[1]; OF_getencprop(opal, "opal-entry-address", val, sizeof(val)); opal_entrypoint = ((uint64_t)val[0] << 32) | val[1]; opal_msr = mfmsr() & ~(PSL_EE | PSL_IR | PSL_DR | PSL_SE); opal_initialized = 1; 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); }
mii_fdt_phy_config_t * mii_fdt_get_config(device_t phydev) { mii_fdt_phy_config_t *cfg; device_t miibus, macdev; pcell_t val; miibus = device_get_parent(phydev); macdev = device_get_parent(miibus); cfg = malloc(sizeof(*cfg), M_OFWPROP, M_ZERO | M_WAITOK); /* * If we can't find our parent MAC's node, there's nothing more we can * fill in; cfg is already full of zero/default values, return it. */ if ((cfg->macnode = ofw_bus_get_node(macdev)) == -1) return (cfg); cfg->con_type = mii_fdt_get_contype(cfg->macnode); /* * If we can't find our own PHY node, there's nothing more we can fill * in, just return what we've got. */ if ((cfg->phynode = mii_fdt_get_phynode(cfg->macnode)) == -1) return (cfg); if (OF_getencprop(cfg->phynode, "max-speed", &val, sizeof(val)) > 0) cfg->max_speed = val; if (ofw_bus_node_is_compatible(cfg->phynode, "ethernet-phy-ieee802.3-c45")) cfg->flags |= MIIF_FDT_COMPAT_CLAUSE45; if (OF_hasprop(cfg->phynode, "broken-turn-around")) cfg->flags |= MIIF_FDT_BROKEN_TURNAROUND; if (OF_hasprop(cfg->phynode, "enet-phy-lane-swap")) cfg->flags |= MIIF_FDT_LANE_SWAP; if (OF_hasprop(cfg->phynode, "enet-phy-lane-no-swap")) cfg->flags |= MIIF_FDT_NO_LANE_SWAP; if (OF_hasprop(cfg->phynode, "eee-broken-100tx")) cfg->flags |= MIIF_FDT_EEE_BROKEN_100TX; if (OF_hasprop(cfg->phynode, "eee-broken-1000t")) cfg->flags |= MIIF_FDT_EEE_BROKEN_1000T; if (OF_hasprop(cfg->phynode, "eee-broken-10gt")) cfg->flags |= MIIF_FDT_EEE_BROKEN_10GT; if (OF_hasprop(cfg->phynode, "eee-broken-1000kx")) cfg->flags |= MIIF_FDT_EEE_BROKEN_1000KX; if (OF_hasprop(cfg->phynode, "eee-broken-10gkx4")) cfg->flags |= MIIF_FDT_EEE_BROKEN_10GKX4; if (OF_hasprop(cfg->phynode, "eee-broken-10gkr")) cfg->flags |= MIIF_FDT_EEE_BROKEN_10GKR; return (cfg); }
static int reset_hsic_hub(struct exynos_ehci_softc *esc, phandle_t hub) { device_t gpio_dev; pcell_t pin; /* TODO: check that hub is compatible with "smsc,usb3503" */ if (!OF_hasprop(hub, "freebsd,reset-gpio")) { return (1); } if (OF_getencprop(hub, "freebsd,reset-gpio", &pin, sizeof(pin)) < 0) { device_printf(esc->dev, "failed to decode reset GPIO pin number for HSIC hub\n"); return (1); } /* Get the GPIO device, we need this to give power to USB */ gpio_dev = devclass_get_device(devclass_find("gpio"), 0); if (gpio_dev == NULL) { device_printf(esc->dev, "Cant find gpio device\n"); return (1); } GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_LOW); DELAY(100); GPIO_PIN_SET(gpio_dev, pin, GPIO_PIN_HIGH); 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); }
static int jz4780_pinctrl_attach(device_t dev) { struct jz4780_pinctrl_softc *sc; struct resource_list *rs; struct resource_list_entry *re; phandle_t dt_parent, dt_child; int i, ret; sc = device_get_softc(dev); sc->dev = dev; /* * Fetch our own resource list to dole memory between children */ rs = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); if (rs == NULL) return (ENXIO); re = resource_list_find(rs, SYS_RES_MEMORY, 0); if (re == NULL) return (ENXIO); simplebus_init(dev, 0); /* Iterate over this node children, looking for pin controllers */ dt_parent = ofw_bus_get_node(dev); i = 0; for (dt_child = OF_child(dt_parent); dt_child != 0; dt_child = OF_peer(dt_child)) { struct simplebus_devinfo *ndi; device_t child; bus_addr_t phys; bus_size_t size; /* Add gpio controller child */ if (!OF_hasprop(dt_child, "gpio-controller")) continue; child = simplebus_add_device(dev, dt_child, 0, NULL, -1, NULL); if (child == NULL) break; /* Setup child resources */ phys = CHIP_REG_OFFSET(re->start, i); size = CHIP_REG_STRIDE; if (phys + size - 1 <= re->end) { ndi = device_get_ivars(child); resource_list_add(&ndi->rl, SYS_RES_MEMORY, 0, phys, phys + size - 1, size); } i++; } ret = bus_generic_attach(dev); if (ret == 0) { fdt_pinctrl_register(dev, "ingenic,pins"); fdt_pinctrl_configure_tree(dev); } return (ret); }
int ofw_bus_has_prop(device_t dev, const char *propname) { phandle_t node; if ((node = ofw_bus_get_node(dev)) == -1) return (0); return (OF_hasprop(node, propname)); }
static int opalflash_attach(device_t dev) { struct opalflash_softc *sc; phandle_t node; cell_t flash_blocksize, opal_id; uint32_t regs[2]; sc = device_get_softc(dev); sc->sc_dev = dev; node = ofw_bus_get_node(dev); OF_getencprop(node, "ibm,opal-id", &opal_id, sizeof(opal_id)); sc->sc_opal_id = opal_id; if (OF_getencprop(node, "ibm,flash-block-size", &flash_blocksize, sizeof(flash_blocksize)) < 0) { device_printf(dev, "Cannot determine flash block size.\n"); return (ENXIO); } if (!OF_hasprop(node, "no-erase")) sc->sc_erase = true; OPALFLASH_LOCK_INIT(sc); if (OF_getencprop(node, "reg", regs, sizeof(regs)) < 0) { device_printf(dev, "Unable to get flash size.\n"); return (ENXIO); } sc->sc_disk = disk_alloc(); sc->sc_disk->d_name = "opalflash"; sc->sc_disk->d_open = opalflash_open; sc->sc_disk->d_close = opalflash_close; sc->sc_disk->d_strategy = opalflash_strategy; sc->sc_disk->d_ioctl = opalflash_ioctl; sc->sc_disk->d_getattr = opalflash_getattr; sc->sc_disk->d_drv1 = sc; sc->sc_disk->d_maxsize = DFLTPHYS; sc->sc_disk->d_mediasize = regs[1]; sc->sc_disk->d_unit = device_get_unit(sc->sc_dev); sc->sc_disk->d_sectorsize = FLASH_BLOCKSIZE; sc->sc_disk->d_stripesize = flash_blocksize; sc->sc_disk->d_dump = NULL; disk_create(sc->sc_disk, DISK_VERSION); bioq_init(&sc->sc_bio_queue); kproc_create(&opalflash_task, sc, &sc->sc_p, 0, 0, "task: OPAL Flash"); return (0); }
static int gpioled_attach(device_t dev) { struct gpioleds_softc *sc; phandle_t child, leds; int total_leds; if ((leds = ofw_bus_get_node(dev)) == -1) return (ENXIO); sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_busdev = device_get_parent(dev); /* Traverse the 'gpio-leds' node and count leds */ total_leds = 0; for (child = OF_child(leds); child != 0; child = OF_peer(child)) { if (!OF_hasprop(child, "gpios")) continue; total_leds++; } if (total_leds) { sc->sc_leds = malloc(sizeof(struct gpioled) * total_leds, M_DEVBUF, M_WAITOK | M_ZERO); sc->sc_total_leds = 0; /* Traverse the 'gpio-leds' node and count leds */ for (child = OF_child(leds); child != 0; child = OF_peer(child)) { if (!OF_hasprop(child, "gpios")) continue; gpioleds_attach_led(sc, child, &sc->sc_leds[sc->sc_total_leds]); sc->sc_total_leds++; } } return (0); }
static int mtk_usb_phy_detach(device_t dev) { struct mtk_usb_phy_softc *sc = device_get_softc(dev); phandle_t node; /* Get our FDT node */ node = ofw_bus_get_node(dev); /* If we have resets defined - assert them */ if (OF_hasprop(node, "resets")) fdt_reset_assert_all(dev); /* If we have clocks defined - disable them */ if (OF_hasprop(node, "clocks")) fdt_clock_disable_all(dev); /* Finally, release resources, if any were allocated */ if (sc->res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res); return (0); }
static int axgbe_get_optional_prop(device_t dev, phandle_t node, const char *name, int *data, size_t len) { if (!OF_hasprop(node, name)) return (-1); if (OF_getencprop(node, name, data, len) <= 0) { device_printf(dev,"%s property is invalid\n", name); return (ENXIO); } return (0); }
/* * Write protect setup. */ static void wp_setup(struct sdhci_fdt_gpio *gpio, phandle_t node) { device_t dev; dev = gpio->dev; if (OF_hasprop(node, "wp-disable")) { gpio->wp_disabled = true; if (bootverbose) device_printf(dev, "Write protect disabled\n"); return; } if (gpio_pin_get_by_ofw_property(dev, node, "wp-gpios", &gpio->wp_pin)) return; if (OF_hasprop(node, "wp-inverted")) gpio->wp_inverted = true; if (bootverbose) device_printf(dev, "Write protect switch on %s pin %u\n", device_get_nameunit(gpio->wp_pin->dev), gpio->wp_pin->pin); }
static int jz4780_pinctrl_parse_pincfg(phandle_t pincfgxref, uint32_t *bias_value) { phandle_t pincfg_node; int i; pincfg_node = OF_node_from_xref(pincfgxref); for (i = 0; i < nitems(jx4780_bias_table); i++) { if (OF_hasprop(pincfg_node, jx4780_bias_table[i].name)) { *bias_value = jx4780_bias_table[i].bias; return 0; } } return -1; }
/* * Get interrupt parent for given node. * Returns 0 if interrupt parent doesn't exist. */ phandle_t ofw_bus_find_iparent(phandle_t node) { phandle_t iparent; if (OF_searchencprop(node, "interrupt-parent", &iparent, sizeof(iparent)) == -1) { for (iparent = node; iparent != 0; iparent = OF_parent(iparent)) { if (OF_hasprop(iparent, "interrupt-controller")) break; } iparent = OF_xref_from_node(iparent); } return (iparent); }
static int ahci_fdt_probe(device_t dev) { struct ahci_controller *ctlr = device_get_softc(dev); phandle_t node; if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) return (ENXIO); device_set_desc_copy(dev, "AHCI SATA controller"); node = ofw_bus_get_node(dev); ctlr->dma_coherent = OF_hasprop(node, "dma-coherent"); return (BUS_PROBE_DEFAULT); }
static int mtk_gpio_probe(device_t dev) { phandle_t node; if (!ofw_bus_status_okay(dev)) return (ENXIO); if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); node = ofw_bus_get_node(dev); if (!OF_hasprop(node, "gpio-controller")) return (ENXIO); device_set_desc(dev, "MTK GPIO Controller (v1)"); return (BUS_PROBE_DEFAULT); }
int nvmem_write_cell_by_idx(phandle_t node, int idx, void *cell, size_t buflen) { phandle_t cell_node, prov_node; device_t provider; uint32_t reg[2]; int rv; rv = nvmem_get_cell_node(node, idx, &cell_node); if (rv != 0) return (rv); prov_node = OF_parent(cell_node); if (OF_hasprop(prov_node, "read-only")) return (ENXIO); /* Validate the reg property */ if (OF_getencprop(cell_node, "reg", reg, sizeof(reg)) != sizeof(reg)) { if (bootverbose) printf("nvmem_get_cell_by_idx: Cannot parse reg property of cell %d\n", idx); return (ENXIO); } if (buflen != reg[1]) return (EINVAL); provider = OF_device_from_xref(OF_xref_from_node(prov_node)); if (provider == NULL) { if (bootverbose) printf("nvmem_get_cell_by_idx: Cannot find the nvmem device\n"); return (ENXIO); } rv = NVMEM_WRITE(provider, reg[0], reg[1], cell); if (rv != 0) { return (rv); } return (0); }
static int gpiobacklight_attach(device_t dev) { struct gpiobacklight_softc *sc; struct sysctl_ctx_list *ctx; struct sysctl_oid *tree; phandle_t node; sc = device_get_softc(dev); if ((node = ofw_bus_get_node(dev)) == -1) return (ENXIO); if (OF_hasprop(node, "default-on")) sc->sc_brightness = true; else sc->sc_brightness = false; gpio_pin_get_by_ofw_idx(dev, node, 0, &sc->sc_pin); if (sc->sc_pin == NULL) { device_printf(dev, "failed to map GPIO pin\n"); return (ENXIO); } gpio_pin_setflags(sc->sc_pin, GPIO_PIN_OUTPUT); gpiobacklight_update_brightness(sc); /* Init backlight interface */ ctx = device_get_sysctl_ctx(dev); tree = device_get_sysctl_tree(dev); sc->sc_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "brightness", CTLTYPE_INT | CTLFLAG_RW, sc, 0, gpiobacklight_sysctl, "I", "backlight brightness"); return (0); }
static int ofw_gpiobus_attach(device_t dev) { int err; phandle_t child; err = gpiobus_init_softc(dev); if (err != 0) return (err); bus_generic_probe(dev); bus_enumerate_hinted_children(dev); /* * Attach the children represented in the device tree. */ for (child = OF_child(ofw_bus_get_node(dev)); child != 0; child = OF_peer(child)) { if (!OF_hasprop(child, "gpios")) continue; if (ofw_gpiobus_add_fdt_child(dev, NULL, child) == NULL) continue; } return (bus_generic_attach(dev)); }
static int usbphy_attach(device_t dev) { struct usbphy_softc * sc; int rid, rv; phandle_t node; sc = device_get_softc(dev); sc->dev = dev; rid = 0; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_SHAREABLE); if (sc->mem_res == NULL) { device_printf(dev, "Cannot allocate memory resources\n"); return (ENXIO); } rid = 1; sc->pads_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_SHAREABLE); if (sc->mem_res == NULL) { device_printf(dev, "Cannot allocate memory resources\n"); return (ENXIO); } node = ofw_bus_get_node(dev); rv = hwreset_get_by_ofw_name(sc->dev, 0, "usb", &sc->reset_usb); if (rv != 0) { device_printf(dev, "Cannot get 'usb' reset\n"); return (ENXIO); } rv = hwreset_get_by_ofw_name(sc->dev, 0, "utmi-pads", &sc->reset_pads); if (rv != 0) { device_printf(dev, "Cannot get 'utmi-pads' reset\n"); return (ENXIO); } rv = clk_get_by_ofw_name(sc->dev, 0, "reg", &sc->clk_reg); if (rv != 0) { device_printf(sc->dev, "Cannot get 'reg' clock\n"); return (ENXIO); } rv = clk_get_by_ofw_name(sc->dev, 0, "pll_u", &sc->clk_pllu); if (rv != 0) { device_printf(sc->dev, "Cannot get 'pll_u' clock\n"); return (ENXIO); } rv = clk_get_by_ofw_name(sc->dev, 0, "utmi-pads", &sc->clk_pads); if (rv != 0) { device_printf(sc->dev, "Cannot get 'utmi-pads' clock\n"); return (ENXIO); } rv = hwreset_deassert(sc->reset_usb); if (rv != 0) { device_printf(dev, "Cannot unreset 'usb' reset\n"); return (ENXIO); } rv = clk_enable(sc->clk_pllu); if (rv != 0) { device_printf(sc->dev, "Cannot enable 'pllu' clock\n"); return (ENXIO); } rv = clk_enable(sc->clk_reg); if (rv != 0) { device_printf(sc->dev, "Cannot enable 'reg' clock\n"); return (ENXIO); } if (OF_hasprop(node, "nvidia,has-utmi-pad-registers")) sc->have_utmi_regs = true; sc->dr_mode = usb_get_dr_mode(dev, node, "dr_mode"); if (sc->dr_mode == USB_DR_MODE_UNKNOWN) sc->dr_mode = USB_DR_MODE_HOST; sc->ifc_type = usb_get_ifc_mode(dev, node, "phy_type"); /* We supports only utmi phy mode for now .... */ if (sc->ifc_type != USB_IFC_TYPE_UTMI) { device_printf(dev, "Unsupported phy type\n"); return (ENXIO); } rv = usbphy_utmi_read_params(sc, node); if (rv < 0) return rv; if (OF_hasprop(node, "vbus-supply")) { rv = regulator_get_by_ofw_property(sc->dev, 0, "vbus-supply", &sc->supply_vbus); if (rv != 0) { device_printf(sc->dev, "Cannot get \"vbus\" regulator\n"); return (ENXIO); } rv = regulator_enable(sc->supply_vbus); if (rv != 0) { device_printf(sc->dev, "Cannot enable \"vbus\" regulator\n"); return (rv); } } phy_register_provider(dev); return (0); }
static int a10_gpio_attach(device_t dev) { int rid; phandle_t gpio; struct a10_gpio_softc *sc; sc = device_get_softc(dev); sc->sc_dev = dev; mtx_init(&sc->sc_mtx, "a10 gpio", "gpio", MTX_SPIN); rid = 0; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_mem_res) { device_printf(dev, "cannot allocate memory window\n"); goto fail; } sc->sc_bst = rman_get_bustag(sc->sc_mem_res); sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); rid = 0; sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->sc_irq_res) { device_printf(dev, "cannot allocate interrupt\n"); goto fail; } /* Find our node. */ gpio = ofw_bus_get_node(sc->sc_dev); if (!OF_hasprop(gpio, "gpio-controller")) /* Node is not a GPIO controller. */ goto fail; /* Use the right pin data for the current SoC */ switch (allwinner_soc_type()) { #ifdef SOC_ALLWINNER_A10 case ALLWINNERSOC_A10: sc->padconf = &a10_padconf; break; #endif #ifdef SOC_ALLWINNER_A20 case ALLWINNERSOC_A20: sc->padconf = &a20_padconf; break; #endif #ifdef SOC_ALLWINNER_A31 case ALLWINNERSOC_A31: sc->padconf = &a31_padconf; break; #endif #ifdef SOC_ALLWINNER_A31S case ALLWINNERSOC_A31S: sc->padconf = &a31s_padconf; break; #endif default: return (ENOENT); } sc->sc_busdev = gpiobus_attach_bus(dev); if (sc->sc_busdev == NULL) goto fail; /* * Register as a pinctrl device */ fdt_pinctrl_register(dev, "allwinner,pins"); fdt_pinctrl_configure_tree(dev); return (0); fail: if (sc->sc_irq_res) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); mtx_destroy(&sc->sc_mtx); return (ENXIO); }
static int mtk_gpio_attach(device_t dev) { struct mtk_gpio_softc *sc; phandle_t node; uint32_t i, num_pins; sc = device_get_softc(dev); sc->dev = dev; if (bus_alloc_resources(dev, mtk_gpio_spec, sc->res)) { device_printf(dev, "could not allocate resources for device\n"); return (ENXIO); } MTK_GPIO_LOCK_INIT(sc); node = ofw_bus_get_node(dev); if (OF_hasprop(node, "clocks")) mtk_soc_start_clock(dev); if (OF_hasprop(node, "resets")) mtk_soc_reset_device(dev); if (OF_getprop(node, "ralink,register-map", sc->regs, GPIO_PIOMAX) <= 0) { device_printf(dev, "Failed to read register map\n"); return (ENXIO); } if (OF_hasprop(node, "ralink,num-gpios") && (OF_getencprop(node, "ralink,num-gpios", &num_pins, sizeof(num_pins)) >= 0)) sc->num_pins = num_pins; else sc->num_pins = MTK_GPIO_PINS; for (i = 0; i < sc->num_pins; i++) { sc->pins[i].pin_caps |= GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | GPIO_PIN_INVOUT; sc->pins[i].intr_polarity = INTR_POLARITY_HIGH; sc->pins[i].intr_trigger = INTR_TRIGGER_EDGE; snprintf(sc->pins[i].pin_name, GPIOMAXNAME - 1, "gpio%c%d", device_get_unit(dev) + 'a', i); sc->pins[i].pin_name[GPIOMAXNAME - 1] = '\0'; mtk_gpio_pin_probe(sc, i); } if (mtk_pic_register_isrcs(sc) != 0) { device_printf(dev, "could not register PIC ISRCs\n"); goto fail; } if (intr_pic_register(dev, OF_xref_from_node(node)) != 0) { device_printf(dev, "could not register PIC\n"); goto fail; } if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, mtk_gpio_intr, NULL, sc, &sc->intrhand) != 0) goto fail_pic; sc->busdev = gpiobus_attach_bus(dev); if (sc->busdev == NULL) goto fail_pic; return (0); fail_pic: intr_pic_deregister(dev, OF_xref_from_node(node)); fail: if(sc->intrhand != NULL) bus_teardown_intr(dev, sc->res[1], sc->intrhand); bus_release_resources(dev, mtk_gpio_spec, sc->res); MTK_GPIO_LOCK_DESTROY(sc); return (ENXIO); }
static int rk30_gpio_attach(device_t dev) { struct rk30_gpio_softc *sc = device_get_softc(dev); uint32_t func; int i, rid; phandle_t gpio; sc->sc_dev = dev; mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF); rid = 0; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_mem_res) { device_printf(dev, "cannot allocate memory window\n"); return (ENXIO); } sc->sc_bst = rman_get_bustag(sc->sc_mem_res); sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); rid = 0; sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->sc_irq_res) { bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); device_printf(dev, "cannot allocate interrupt\n"); return (ENXIO); } /* Find our node. */ gpio = ofw_bus_get_node(sc->sc_dev); if (!OF_hasprop(gpio, "gpio-controller")) /* Node is not a GPIO controller. */ goto fail; /* Initialize the software controlled pins. */ for (i = 0; i < RK30_GPIO_PINS; i++) { snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, "pin %d", i); func = rk30_gpio_get_function(sc, i); sc->sc_gpio_pins[i].gp_pin = i; sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS; sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func); } sc->sc_gpio_npins = i; device_add_child(dev, "gpioc", device_get_unit(dev)); device_add_child(dev, "gpiobus", device_get_unit(dev)); return (bus_generic_attach(dev)); fail: if (sc->sc_irq_res) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); return (ENXIO); }
int ofw_cpu_early_foreach(ofw_cpu_foreach_cb callback, boolean_t only_runnable) { phandle_t node, child; pcell_t addr_cells, reg[2]; char status[16]; char device_type[16]; u_int id, next_id; int count, rv; count = 0; id = 0; next_id = 0; node = OF_finddevice("/cpus"); if (node == -1) return (-1); /* Find the number of cells in the cpu register */ if (OF_getencprop(node, "#address-cells", &addr_cells, sizeof(addr_cells)) < 0) return (-1); for (child = OF_child(node); child != 0; child = OF_peer(child), id = next_id) { /* Check if child is a CPU */ memset(device_type, 0, sizeof(device_type)); rv = OF_getprop(child, "device_type", device_type, sizeof(device_type) - 1); if (rv < 0) continue; if (strcmp(device_type, "cpu") != 0) continue; /* We're processing CPU, update next_id used in the next iteration */ next_id++; /* * If we are filtering by runnable then limit to only * those that have been enabled, or do provide a method * to enable them. */ if (only_runnable) { status[0] = '\0'; OF_getprop(child, "status", status, sizeof(status)); if (status[0] != '\0' && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0 && !OF_hasprop(child, "enable-method")) continue; } /* * Check we have a register to identify the cpu */ rv = OF_getencprop(child, "reg", reg, addr_cells * sizeof(cell_t)); if (rv != addr_cells * sizeof(cell_t)) continue; if (callback == NULL || callback(id, child, addr_cells, reg)) count++; } return (only_runnable ? count : id); }
static int ofw_gpiobus_parse_gpios_impl(device_t consumer, phandle_t cnode, char *pname, struct gpiobus_softc *bussc, struct gpiobus_pin **pins) { int gpiocells, i, j, ncells, npins; pcell_t *gpios; phandle_t gpio; ncells = OF_getencprop_alloc(cnode, pname, sizeof(*gpios), (void **)&gpios); if (ncells == -1) { device_printf(consumer, "Warning: No %s specified in fdt data; " "device may not function.\n", pname); return (-1); } /* * The gpio-specifier is controller independent, the first pcell has * the reference to the GPIO controller phandler. * Count the number of encoded gpio-specifiers on the first pass. */ i = 0; npins = 0; while (i < ncells) { /* Allow NULL specifiers. */ if (gpios[i] == 0) { npins++; i++; continue; } gpio = OF_node_from_xref(gpios[i]); /* If we have bussc, ignore devices from other gpios. */ if (bussc != NULL) if (ofw_bus_get_node(bussc->sc_dev) != gpio) return (0); /* * Check for gpio-controller property and read the #gpio-cells * for this GPIO controller. */ if (!OF_hasprop(gpio, "gpio-controller") || OF_getencprop(gpio, "#gpio-cells", &gpiocells, sizeof(gpiocells)) < 0) { device_printf(consumer, "gpio reference is not a gpio-controller.\n"); OF_prop_free(gpios); return (-1); } if (ncells - i < gpiocells + 1) { device_printf(consumer, "%s cells doesn't match #gpio-cells.\n", pname); return (-1); } npins++; i += gpiocells + 1; } if (npins == 0 || pins == NULL) { if (npins == 0) device_printf(consumer, "no pin specified in %s.\n", pname); OF_prop_free(gpios); return (npins); } *pins = malloc(sizeof(struct gpiobus_pin) * npins, M_DEVBUF, M_NOWAIT | M_ZERO); if (*pins == NULL) { OF_prop_free(gpios); return (-1); } /* Decode the gpio specifier on the second pass. */ i = 0; j = 0; while (i < ncells) { /* Allow NULL specifiers. */ if (gpios[i] == 0) { j++; i++; continue; } gpio = OF_node_from_xref(gpios[i]); /* Read gpio-cells property for this GPIO controller. */ if (OF_getencprop(gpio, "#gpio-cells", &gpiocells, sizeof(gpiocells)) < 0) { device_printf(consumer, "gpio does not have the #gpio-cells property.\n"); goto fail; } /* Return the device reference for the GPIO controller. */ (*pins)[j].dev = OF_device_from_xref(gpios[i]); if ((*pins)[j].dev == NULL) { device_printf(consumer, "no device registered for the gpio controller.\n"); goto fail; } /* * If the gpiobus softc is NULL we use the GPIO_GET_BUS() to * retrieve it. The GPIO_GET_BUS() method is only valid after * the child is probed and attached. */ if (bussc == NULL) { if (GPIO_GET_BUS((*pins)[j].dev) == NULL) { device_printf(consumer, "no gpiobus reference for %s.\n", device_get_nameunit((*pins)[j].dev)); goto fail; } bussc = device_get_softc(GPIO_GET_BUS((*pins)[j].dev)); } /* Get the GPIO pin number and flags. */ if (gpio_map_gpios((*pins)[j].dev, cnode, gpio, gpiocells, &gpios[i + 1], &(*pins)[j].pin, &(*pins)[j].flags) != 0) { device_printf(consumer, "cannot map the gpios specifier.\n"); goto fail; } /* Reserve the GPIO pin. */ if (gpiobus_acquire_pin(bussc->sc_busdev, (*pins)[j].pin) != 0) goto fail; j++; i += gpiocells + 1; } OF_prop_free(gpios); return (npins); fail: OF_prop_free(gpios); free(*pins, M_DEVBUF); return (-1); }
static int tegra124_pmc_parse_fdt(struct tegra124_pmc_softc *sc, phandle_t node) { int rv; uint32_t tmp; uint32_t tmparr[2]; rv = OF_getencprop(node, "nvidia,suspend-mode", &tmp, sizeof(tmp)); if (rv > 0) { switch (tmp) { case 0: sc->suspend_mode = TEGRA_SUSPEND_LP0; break; case 1: sc->suspend_mode = TEGRA_SUSPEND_LP1; break; case 2: sc->suspend_mode = TEGRA_SUSPEND_LP2; break; default: sc->suspend_mode = TEGRA_SUSPEND_NONE; break; } } rv = OF_getencprop(node, "nvidia,cpu-pwr-good-time", &tmp, sizeof(tmp)); if (rv > 0) { sc->cpu_good_time = tmp; sc->suspend_mode = TEGRA_SUSPEND_NONE; } rv = OF_getencprop(node, "nvidia,cpu-pwr-off-time", &tmp, sizeof(tmp)); if (rv > 0) { sc->cpu_off_time = tmp; sc->suspend_mode = TEGRA_SUSPEND_NONE; } rv = OF_getencprop(node, "nvidia,core-pwr-good-time", tmparr, sizeof(tmparr)); if (rv == sizeof(tmparr)) { sc->core_osc_time = tmparr[0]; sc->core_pmu_time = tmparr[1]; sc->suspend_mode = TEGRA_SUSPEND_NONE; } rv = OF_getencprop(node, "nvidia,core-pwr-off-time", &tmp, sizeof(tmp)); if (rv > 0) { sc->core_off_time = tmp; sc->suspend_mode = TEGRA_SUSPEND_NONE; } sc->corereq_high = OF_hasprop(node, "nvidia,core-power-req-active-high"); sc->sysclkreq_high = OF_hasprop(node, "nvidia,sys-clock-req-active-high"); sc->combined_req = OF_hasprop(node, "nvidia,combined-power-req"); sc->cpu_pwr_good_en = OF_hasprop(node, "nvidia,cpu-pwr-good-en"); rv = OF_getencprop(node, "nvidia,lp0-vec", tmparr, sizeof(tmparr)); if (rv == sizeof(tmparr)) { sc->lp0_vec_phys = tmparr[0]; sc->core_pmu_time = tmparr[1]; sc->lp0_vec_size = TEGRA_SUSPEND_NONE; if (sc->suspend_mode == TEGRA_SUSPEND_LP0) sc->suspend_mode = TEGRA_SUSPEND_LP1; } return 0; }
static int rk30_gpio_attach(device_t dev) { struct rk30_gpio_softc *sc = device_get_softc(dev); int i, rid; phandle_t gpio; unsigned long start; if (rk30_gpio_sc) return (ENXIO); sc->sc_dev = dev; mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF); rid = 0; sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->sc_mem_res) { device_printf(dev, "cannot allocate memory window\n"); goto fail; } sc->sc_bst = rman_get_bustag(sc->sc_mem_res); sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); /* Check the unit we are attaching by our base address. */ sc->sc_bank = -1; start = rman_get_start(sc->sc_mem_res); for (i = 0; i < nitems(rk30_gpio_base_addr); i++) { if (rk30_gpio_base_addr[i] == start) { sc->sc_bank = i; break; } } if (sc->sc_bank == -1) { device_printf(dev, "unsupported device unit (only GPIO0..3 are supported)\n"); goto fail; } rid = 0; sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (!sc->sc_irq_res) { device_printf(dev, "cannot allocate interrupt\n"); goto fail; } /* Find our node. */ gpio = ofw_bus_get_node(sc->sc_dev); if (!OF_hasprop(gpio, "gpio-controller")) /* Node is not a GPIO controller. */ goto fail; /* Initialize the software controlled pins. */ for (i = 0; i < RK30_GPIO_PINS; i++) { snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, "pin %d", i); sc->sc_gpio_pins[i].gp_pin = i; sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS; sc->sc_gpio_pins[i].gp_flags = rk30_gpio_get_function(sc, i); } sc->sc_gpio_npins = i; rk30_gpio_sc = sc; rk30_gpio_init(); sc->sc_busdev = gpiobus_attach_bus(dev); if (sc->sc_busdev == NULL) goto fail; return (0); fail: if (sc->sc_irq_res) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); mtx_destroy(&sc->sc_mtx); return (ENXIO); }
static int axgbe_attach(device_t dev) { struct axgbe_softc *sc; struct ifnet *ifp; pcell_t phy_handle; device_t phydev; phandle_t node, phy_node; struct resource *mac_res[11]; struct resource *phy_res[4]; ssize_t len; int error, i, j; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); if (OF_getencprop(node, "phy-handle", &phy_handle, sizeof(phy_handle)) <= 0) { phy_node = node; if (bus_alloc_resources(dev, mac_spec, mac_res)) { device_printf(dev, "could not allocate phy resources\n"); return (ENXIO); } sc->prv.xgmac_res = mac_res[0]; sc->prv.xpcs_res = mac_res[1]; sc->prv.rxtx_res = mac_res[2]; sc->prv.sir0_res = mac_res[3]; sc->prv.sir1_res = mac_res[4]; sc->prv.dev_irq_res = mac_res[5]; sc->prv.per_channel_irq = OF_hasprop(node, XGBE_DMA_IRQS_PROPERTY); for (i = 0, j = 6; j < nitems(mac_res) - 1 && mac_res[j + 1] != NULL; i++, j++) { if (sc->prv.per_channel_irq) { sc->prv.chan_irq_res[i] = mac_res[j]; } } /* The last entry is the auto-negotiation interrupt */ sc->prv.an_irq_res = mac_res[j]; } else { phydev = OF_device_from_xref(phy_handle); phy_node = ofw_bus_get_node(phydev); if (bus_alloc_resources(phydev, old_phy_spec, phy_res)) { device_printf(dev, "could not allocate phy resources\n"); return (ENXIO); } if (bus_alloc_resources(dev, old_mac_spec, mac_res)) { device_printf(dev, "could not allocate mac resources\n"); return (ENXIO); } sc->prv.rxtx_res = phy_res[0]; sc->prv.sir0_res = phy_res[1]; sc->prv.sir1_res = phy_res[2]; sc->prv.an_irq_res = phy_res[3]; sc->prv.xgmac_res = mac_res[0]; sc->prv.xpcs_res = mac_res[1]; sc->prv.dev_irq_res = mac_res[2]; sc->prv.per_channel_irq = OF_hasprop(node, XGBE_DMA_IRQS_PROPERTY); if (sc->prv.per_channel_irq) { for (i = 0, j = 3; i < nitems(sc->prv.chan_irq_res) && mac_res[j] != NULL; i++, j++) { sc->prv.chan_irq_res[i] = mac_res[j]; } } } if ((len = OF_getproplen(node, "mac-address")) < 0) { device_printf(dev, "No mac-address property\n"); return (EINVAL); } if (len != ETHER_ADDR_LEN) return (EINVAL); OF_getprop(node, "mac-address", sc->mac_addr, ETHER_ADDR_LEN); sc->prv.netdev = ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "Cannot alloc ifnet\n"); return (ENXIO); } sc->prv.dev = dev; sc->prv.dmat = bus_get_dma_tag(dev); sc->prv.phy.advertising = ADVERTISED_10000baseKR_Full | ADVERTISED_1000baseKX_Full; /* * Read the needed properties from the phy node. */ /* This is documented as optional, but Linux requires it */ if (OF_getencprop(phy_node, XGBE_SPEEDSET_PROPERTY, &sc->prv.speed_set, sizeof(sc->prv.speed_set)) <= 0) { device_printf(dev, "%s property is missing\n", XGBE_SPEEDSET_PROPERTY); return (EINVAL); } error = axgbe_get_optional_prop(dev, phy_node, XGBE_BLWC_PROPERTY, sc->prv.serdes_blwc, sizeof(sc->prv.serdes_blwc)); if (error > 0) { return (error); } else if (error < 0) { sc->prv.serdes_blwc[0] = XGBE_SPEED_1000_BLWC; sc->prv.serdes_blwc[1] = XGBE_SPEED_2500_BLWC; sc->prv.serdes_blwc[2] = XGBE_SPEED_10000_BLWC; } error = axgbe_get_optional_prop(dev, phy_node, XGBE_CDR_RATE_PROPERTY, sc->prv.serdes_cdr_rate, sizeof(sc->prv.serdes_cdr_rate)); if (error > 0) { return (error); } else if (error < 0) { sc->prv.serdes_cdr_rate[0] = XGBE_SPEED_1000_CDR; sc->prv.serdes_cdr_rate[1] = XGBE_SPEED_2500_CDR; sc->prv.serdes_cdr_rate[2] = XGBE_SPEED_10000_CDR; } error = axgbe_get_optional_prop(dev, phy_node, XGBE_PQ_SKEW_PROPERTY, sc->prv.serdes_pq_skew, sizeof(sc->prv.serdes_pq_skew)); if (error > 0) { return (error); } else if (error < 0) { sc->prv.serdes_pq_skew[0] = XGBE_SPEED_1000_PQ; sc->prv.serdes_pq_skew[1] = XGBE_SPEED_2500_PQ; sc->prv.serdes_pq_skew[2] = XGBE_SPEED_10000_PQ; } error = axgbe_get_optional_prop(dev, phy_node, XGBE_TX_AMP_PROPERTY, sc->prv.serdes_tx_amp, sizeof(sc->prv.serdes_tx_amp)); if (error > 0) { return (error); } else if (error < 0) { sc->prv.serdes_tx_amp[0] = XGBE_SPEED_1000_TXAMP; sc->prv.serdes_tx_amp[1] = XGBE_SPEED_2500_TXAMP; sc->prv.serdes_tx_amp[2] = XGBE_SPEED_10000_TXAMP; } error = axgbe_get_optional_prop(dev, phy_node, XGBE_DFE_CFG_PROPERTY, sc->prv.serdes_dfe_tap_cfg, sizeof(sc->prv.serdes_dfe_tap_cfg)); if (error > 0) { return (error); } else if (error < 0) { sc->prv.serdes_dfe_tap_cfg[0] = XGBE_SPEED_1000_DFE_TAP_CONFIG; sc->prv.serdes_dfe_tap_cfg[1] = XGBE_SPEED_2500_DFE_TAP_CONFIG; sc->prv.serdes_dfe_tap_cfg[2] = XGBE_SPEED_10000_DFE_TAP_CONFIG; } error = axgbe_get_optional_prop(dev, phy_node, XGBE_DFE_ENA_PROPERTY, sc->prv.serdes_dfe_tap_ena, sizeof(sc->prv.serdes_dfe_tap_ena)); if (error > 0) { return (error); } else if (error < 0) { sc->prv.serdes_dfe_tap_ena[0] = XGBE_SPEED_1000_DFE_TAP_ENABLE; sc->prv.serdes_dfe_tap_ena[1] = XGBE_SPEED_2500_DFE_TAP_ENABLE; sc->prv.serdes_dfe_tap_ena[2] = XGBE_SPEED_10000_DFE_TAP_ENABLE; } /* Check if the NIC is DMA coherent */ sc->prv.coherent = OF_hasprop(node, "dma-coherent"); if (sc->prv.coherent) { sc->prv.axdomain = XGBE_DMA_OS_AXDOMAIN; sc->prv.arcache = XGBE_DMA_OS_ARCACHE; sc->prv.awcache = XGBE_DMA_OS_AWCACHE; } else { sc->prv.axdomain = XGBE_DMA_SYS_AXDOMAIN; sc->prv.arcache = XGBE_DMA_SYS_ARCACHE; sc->prv.awcache = XGBE_DMA_SYS_AWCACHE; } /* Create the lock & workqueues */ spin_lock_init(&sc->prv.xpcs_lock); sc->prv.dev_workqueue = taskqueue_create("axgbe", M_WAITOK, taskqueue_thread_enqueue, &sc->prv.dev_workqueue); taskqueue_start_threads(&sc->prv.dev_workqueue, 1, PI_NET, "axgbe taskq"); /* Set the needed pointers */ xgbe_init_function_ptrs_phy(&sc->prv.phy_if); xgbe_init_function_ptrs_dev(&sc->prv.hw_if); xgbe_init_function_ptrs_desc(&sc->prv.desc_if); /* Reset the hardware */ sc->prv.hw_if.exit(&sc->prv); /* Read the hardware features */ xgbe_get_all_hw_features(&sc->prv); /* Set default values */ sc->prv.pblx8 = DMA_PBL_X8_ENABLE; sc->prv.tx_desc_count = XGBE_TX_DESC_CNT; sc->prv.tx_sf_mode = MTL_TSF_ENABLE; sc->prv.tx_threshold = MTL_TX_THRESHOLD_64; sc->prv.tx_pbl = DMA_PBL_16; sc->prv.tx_osp_mode = DMA_OSP_ENABLE; sc->prv.rx_desc_count = XGBE_RX_DESC_CNT; sc->prv.rx_sf_mode = MTL_RSF_DISABLE; sc->prv.rx_threshold = MTL_RX_THRESHOLD_64; sc->prv.rx_pbl = DMA_PBL_16; sc->prv.pause_autoneg = 1; sc->prv.tx_pause = 1; sc->prv.rx_pause = 1; sc->prv.phy_speed = SPEED_UNKNOWN; sc->prv.power_down = 0; /* TODO: Limit to min(ncpus, hw rings) */ sc->prv.tx_ring_count = 1; sc->prv.tx_q_count = 1; sc->prv.rx_ring_count = 1; sc->prv.rx_q_count = sc->prv.hw_feat.rx_q_cnt; /* Init the PHY */ sc->prv.phy_if.phy_init(&sc->prv); /* Set the coalescing */ xgbe_init_rx_coalesce(&sc->prv); xgbe_init_tx_coalesce(&sc->prv); if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_init = axgbe_init; ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = axgbe_ioctl; ifp->if_transmit = xgbe_xmit; ifp->if_qflush = axgbe_qflush; ifp->if_get_counter = axgbe_get_counter; /* TODO: Support HW offload */ ifp->if_capabilities = 0; ifp->if_capenable = 0; ifp->if_hwassist = 0; ether_ifattach(ifp, sc->mac_addr); ifmedia_init(&sc->media, IFM_IMASK, axgbe_media_change, axgbe_media_status); #ifdef notyet ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_KR, 0, NULL); #endif ifmedia_add(&sc->media, IFM_ETHER | IFM_1000_KX, 0, NULL); ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO); set_bit(XGBE_DOWN, &sc->prv.dev_state); if (xgbe_open(ifp) < 0) { device_printf(dev, "ndo_open failed\n"); return (ENXIO); } return (0); }
static int mtk_usb_phy_attach(device_t dev) { struct mtk_usb_phy_softc * sc = device_get_softc(dev); phandle_t node; uint32_t val; int rid; sc->dev = dev; /* Get our FDT node and SoC id */ node = ofw_bus_get_node(dev); /* Now let's see about setting USB to host or device mode */ /* XXX: is it the same for all SoCs? */ val = mtk_sysctl_get(SYSCTL_SYSCFG1); if (OF_hasprop(node, "mtk,usb-device")) val &= ~SYSCFG1_USB_HOST_MODE; else val |= SYSCFG1_USB_HOST_MODE; mtk_sysctl_set(SYSCTL_SYSCFG1, val); /* If we have clocks defined - enable them */ if (OF_hasprop(node, "clocks")) fdt_clock_enable_all(dev); /* If we have resets defined - perform a reset sequence */ if (OF_hasprop(node, "resets")) { fdt_reset_assert_all(dev); DELAY(RESET_ASSERT_DELAY); fdt_reset_deassert_all(dev); DELAY(RESET_DEASSERT_DELAY); } /* Careful, some devices actually require resources */ if (OF_hasprop(node, "reg")) { rid = 0; sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->res == NULL) { device_printf(dev, "could not map memory\n"); return (ENXIO); } } else { sc->res = NULL; } /* Some SoCs require specific USB PHY init... handle these */ switch (sc->socid) { case MTK_SOC_MT7628: /* Fallthrough */ case MTK_SOC_MT7688: if (sc->res == NULL) return (ENXIO); sc->fm_base = MT7628_FM_FEG_BASE; sc->u2_base = MT7628_U2_BASE; sc->sr_coef = MT7628_SR_COEF; mtk_usb_phy_mt7628_init(dev); break; case MTK_SOC_MT7621: if (sc->res == NULL) return (ENXIO); sc->fm_base = MT7621_FM_FEG_BASE; sc->u2_base = MT7621_U2_BASE; sc->sr_coef = MT7621_SR_COEF; mtk_usb_phy_mt7621_init(dev); break; } /* We no longer need the resources, release them */ if (sc->res != NULL) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res); return (0); }