int phy_get_by_ofw_idx(device_t consumer_dev, phandle_t cnode, int idx, phy_t *phy) { phandle_t xnode; pcell_t *cells; device_t phydev; int ncells, rv; intptr_t id; if (cnode <= 0) cnode = ofw_bus_get_node(consumer_dev); if (cnode <= 0) { device_printf(consumer_dev, "%s called on not ofw based device\n", __func__); return (ENXIO); } rv = ofw_bus_parse_xref_list_alloc(cnode, "phys", "#phy-cells", idx, &xnode, &ncells, &cells); if (rv != 0) return (rv); /* Tranlate provider to device. */ phydev = OF_device_from_xref(xnode); if (phydev == NULL) { OF_prop_free(cells); return (ENODEV); } /* Map phy to number. */ rv = PHY_MAP(phydev, xnode, ncells, cells, &id); OF_prop_free(cells); if (rv != 0) return (rv); return (phy_get_by_id(consumer_dev, phydev, id, phy)); }
int hwreset_get_by_ofw_idx(device_t consumer_dev, int idx, hwreset_t *rst) { phandle_t cnode, xnode; pcell_t *cells; device_t rstdev; int ncells, rv; intptr_t id; cnode = ofw_bus_get_node(consumer_dev); if (cnode <= 0) { device_printf(consumer_dev, "%s called on not ofw based device\n", __func__); return (ENXIO); } rv = ofw_bus_parse_xref_list_alloc(cnode, "resets", "#reset-cells", idx, &xnode, &ncells, &cells); if (rv != 0) return (rv); /* Tranlate provider to device */ rstdev = OF_device_from_xref(xnode); if (rstdev == NULL) { free(cells, M_OFWPROP); return (ENODEV); } /* Map reset to number */ rv = HWRESET_MAP(rstdev, xnode, ncells, cells, &id); free(cells, M_OFWPROP); if (rv != 0) return (rv); return (hwreset_get_by_id(consumer_dev, rstdev, id, rst)); }
/* * Utility functions for easier handling of OFW GPIO pins. * * !!! BEWARE !!! * GPIOBUS uses children's IVARs, so we cannot use this interface for cross * tree consumers. * */ static int gpio_pin_get_by_ofw_impl(device_t consumer, phandle_t cnode, char *prop_name, int idx, gpio_pin_t *out_pin) { phandle_t xref; pcell_t *cells; device_t busdev; struct gpiobus_pin pin; int ncells, rv; KASSERT(consumer != NULL && cnode > 0, ("both consumer and cnode required")); rv = ofw_bus_parse_xref_list_alloc(cnode, prop_name, "#gpio-cells", idx, &xref, &ncells, &cells); if (rv != 0) return (rv); /* Translate provider to device. */ pin.dev = OF_device_from_xref(xref); if (pin.dev == NULL) { OF_prop_free(cells); return (ENODEV); } /* Test if GPIO bus already exist. */ busdev = GPIO_GET_BUS(pin.dev); if (busdev == NULL) { OF_prop_free(cells); return (ENODEV); } /* Map GPIO pin. */ rv = gpio_map_gpios(pin.dev, cnode, OF_node_from_xref(xref), ncells, cells, &pin.pin, &pin.flags); OF_prop_free(cells); if (rv != 0) return (ENXIO); /* Reserve GPIO pin. */ rv = gpiobus_acquire_pin(busdev, pin.pin); if (rv != 0) return (EBUSY); *out_pin = malloc(sizeof(struct gpiobus_pin), M_DEVBUF, M_WAITOK | M_ZERO); **out_pin = pin; return (0); }
static int tegra124_coretemp_ofw_parse(struct tegra124_coretemp_softc *sc) { int rv, ncells; phandle_t node, xnode; pcell_t *cells; node = OF_peer(0); node = ofw_bus_find_child(node, "thermal-zones"); if (node <= 0) { device_printf(sc->dev, "Cannot find 'thermal-zones'.\n"); return (ENXIO); } node = ofw_bus_find_child(node, "cpu"); if (node <= 0) { device_printf(sc->dev, "Cannot find 'cpu'\n"); return (ENXIO); } rv = ofw_bus_parse_xref_list_alloc(node, "thermal-sensors", "#thermal-sensor-cells", 0, &xnode, &ncells, &cells); if (rv != 0) { device_printf(sc->dev, "Cannot parse 'thermal-sensors' property.\n"); return (ENXIO); } if (ncells != 1) { device_printf(sc->dev, "Invalid format of 'thermal-sensors' property(%d).\n", ncells); return (ENXIO); } sc->tsens_id = 0x100 + sc->cpu_id; //cells[0]; OF_prop_free(cells); sc->tsens_dev = OF_device_from_xref(xnode); if (sc->tsens_dev == NULL) { device_printf(sc->dev, "Cannot find thermal sensors device."); return (ENXIO); } return (0); }