Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/gpio/ofw_gpiobus.c
Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | gpio_pin_get_by_ofw_impl(device_t consumer, phandle_t cnode, | ||||
rv = ofw_bus_parse_xref_list_alloc(cnode, prop_name, "#gpio-cells", | rv = ofw_bus_parse_xref_list_alloc(cnode, prop_name, "#gpio-cells", | ||||
idx, &xref, &ncells, &cells); | idx, &xref, &ncells, &cells); | ||||
if (rv != 0) | if (rv != 0) | ||||
return (rv); | return (rv); | ||||
/* Translate provider to device. */ | /* Translate provider to device. */ | ||||
pin.dev = OF_device_from_xref(xref); | pin.dev = OF_device_from_xref(xref); | ||||
if (pin.dev == NULL) { | if (pin.dev == NULL) { | ||||
free(cells, M_OFWPROP); | OF_prop_free(cells); | ||||
return (ENODEV); | return (ENODEV); | ||||
} | } | ||||
/* Test if GPIO bus already exist. */ | /* Test if GPIO bus already exist. */ | ||||
busdev = GPIO_GET_BUS(pin.dev); | busdev = GPIO_GET_BUS(pin.dev); | ||||
if (busdev == NULL) { | if (busdev == NULL) { | ||||
free(cells, M_OFWPROP); | OF_prop_free(cells); | ||||
return (ENODEV); | return (ENODEV); | ||||
} | } | ||||
/* Map GPIO pin. */ | /* Map GPIO pin. */ | ||||
rv = gpio_map_gpios(pin.dev, cnode, OF_node_from_xref(xref), ncells, | rv = gpio_map_gpios(pin.dev, cnode, OF_node_from_xref(xref), ncells, | ||||
cells, &pin.pin, &pin.flags); | cells, &pin.pin, &pin.flags); | ||||
free(cells, M_OFWPROP); | OF_prop_free(cells); | ||||
if (rv != 0) | if (rv != 0) | ||||
return (ENXIO); | return (ENXIO); | ||||
/* Reserve GPIO pin. */ | /* Reserve GPIO pin. */ | ||||
rv = gpiobus_map_pin(busdev, pin.pin); | rv = gpiobus_map_pin(busdev, pin.pin); | ||||
if (rv != 0) | if (rv != 0) | ||||
return (EBUSY); | return (EBUSY); | ||||
▲ Show 20 Lines • Show All 272 Lines • ▼ Show 20 Lines | while (i < ncells) { | ||||
* Check for gpio-controller property and read the #gpio-cells | * Check for gpio-controller property and read the #gpio-cells | ||||
* for this GPIO controller. | * for this GPIO controller. | ||||
*/ | */ | ||||
if (!OF_hasprop(gpio, "gpio-controller") || | if (!OF_hasprop(gpio, "gpio-controller") || | ||||
OF_getencprop(gpio, "#gpio-cells", &gpiocells, | OF_getencprop(gpio, "#gpio-cells", &gpiocells, | ||||
sizeof(gpiocells)) < 0) { | sizeof(gpiocells)) < 0) { | ||||
device_printf(consumer, | device_printf(consumer, | ||||
"gpio reference is not a gpio-controller.\n"); | "gpio reference is not a gpio-controller.\n"); | ||||
free(gpios, M_OFWPROP); | OF_prop_free(gpios); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (ncells - i < gpiocells + 1) { | if (ncells - i < gpiocells + 1) { | ||||
device_printf(consumer, | device_printf(consumer, | ||||
"%s cells doesn't match #gpio-cells.\n", pname); | "%s cells doesn't match #gpio-cells.\n", pname); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
npins++; | npins++; | ||||
i += gpiocells + 1; | i += gpiocells + 1; | ||||
} | } | ||||
if (npins == 0 || pins == NULL) { | if (npins == 0 || pins == NULL) { | ||||
if (npins == 0) | if (npins == 0) | ||||
device_printf(consumer, "no pin specified in %s.\n", | device_printf(consumer, "no pin specified in %s.\n", | ||||
pname); | pname); | ||||
free(gpios, M_OFWPROP); | OF_prop_free(gpios); | ||||
return (npins); | return (npins); | ||||
} | } | ||||
*pins = malloc(sizeof(struct gpiobus_pin) * npins, M_DEVBUF, | *pins = malloc(sizeof(struct gpiobus_pin) * npins, M_DEVBUF, | ||||
M_NOWAIT | M_ZERO); | M_NOWAIT | M_ZERO); | ||||
if (*pins == NULL) { | if (*pins == NULL) { | ||||
free(gpios, M_OFWPROP); | OF_prop_free(gpios); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
/* Decode the gpio specifier on the second pass. */ | /* Decode the gpio specifier on the second pass. */ | ||||
i = 0; | i = 0; | ||||
j = 0; | j = 0; | ||||
while (i < ncells) { | while (i < ncells) { | ||||
/* Allow NULL specifiers. */ | /* Allow NULL specifiers. */ | ||||
if (gpios[i] == 0) { | if (gpios[i] == 0) { | ||||
Show All 38 Lines | if (gpio_map_gpios((*pins)[j].dev, cnode, gpio, gpiocells, | ||||
goto fail; | goto fail; | ||||
} | } | ||||
/* Reserve the GPIO pin. */ | /* Reserve the GPIO pin. */ | ||||
if (gpiobus_map_pin(bussc->sc_busdev, (*pins)[j].pin) != 0) | if (gpiobus_map_pin(bussc->sc_busdev, (*pins)[j].pin) != 0) | ||||
goto fail; | goto fail; | ||||
j++; | j++; | ||||
i += gpiocells + 1; | i += gpiocells + 1; | ||||
} | } | ||||
free(gpios, M_OFWPROP); | OF_prop_free(gpios); | ||||
return (npins); | return (npins); | ||||
fail: | fail: | ||||
free(gpios, M_OFWPROP); | OF_prop_free(gpios); | ||||
free(*pins, M_DEVBUF); | free(*pins, M_DEVBUF); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
static int | static int | ||||
ofw_gpiobus_probe(device_t dev) | ofw_gpiobus_probe(device_t dev) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 101 Lines • Show Last 20 Lines |