196495d90SSimon Glass /* 296495d90SSimon Glass * Copyright (c) 2013 Google, Inc 396495d90SSimon Glass * 496495d90SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 596495d90SSimon Glass */ 696495d90SSimon Glass 796495d90SSimon Glass #include <common.h> 896495d90SSimon Glass #include <dm.h> 996495d90SSimon Glass #include <errno.h> 10b892d127SSimon Glass #include <malloc.h> 1196495d90SSimon Glass #include <asm/gpio.h> 12fe1ef503SSimon Glass #include <linux/ctype.h> 1396495d90SSimon Glass 1496495d90SSimon Glass /** 1596495d90SSimon Glass * gpio_to_device() - Convert global GPIO number to device, number 1696495d90SSimon Glass * gpio: The numeric representation of the GPIO 1796495d90SSimon Glass * 1896495d90SSimon Glass * Convert the GPIO number to an entry in the list of GPIOs 1996495d90SSimon Glass * or GPIO blocks registered with the GPIO controller. Returns 2096495d90SSimon Glass * entry on success, NULL on error. 2196495d90SSimon Glass */ 2254c5d08aSHeiko Schocher static int gpio_to_device(unsigned int gpio, struct udevice **devp, 2396495d90SSimon Glass unsigned int *offset) 2496495d90SSimon Glass { 2596495d90SSimon Glass struct gpio_dev_priv *uc_priv; 2654c5d08aSHeiko Schocher struct udevice *dev; 2796495d90SSimon Glass int ret; 2896495d90SSimon Glass 2996495d90SSimon Glass for (ret = uclass_first_device(UCLASS_GPIO, &dev); 3096495d90SSimon Glass dev; 3196495d90SSimon Glass ret = uclass_next_device(&dev)) { 3296495d90SSimon Glass uc_priv = dev->uclass_priv; 3396495d90SSimon Glass if (gpio >= uc_priv->gpio_base && 3496495d90SSimon Glass gpio < uc_priv->gpio_base + uc_priv->gpio_count) { 3596495d90SSimon Glass *devp = dev; 3696495d90SSimon Glass *offset = gpio - uc_priv->gpio_base; 3796495d90SSimon Glass return 0; 3896495d90SSimon Glass } 3996495d90SSimon Glass } 4096495d90SSimon Glass 4196495d90SSimon Glass /* No such GPIO */ 4296495d90SSimon Glass return ret ? ret : -EINVAL; 4396495d90SSimon Glass } 4496495d90SSimon Glass 4554c5d08aSHeiko Schocher int gpio_lookup_name(const char *name, struct udevice **devp, 4696495d90SSimon Glass unsigned int *offsetp, unsigned int *gpiop) 4796495d90SSimon Glass { 48fe1ef503SSimon Glass struct gpio_dev_priv *uc_priv = NULL; 4954c5d08aSHeiko Schocher struct udevice *dev; 50fe1ef503SSimon Glass ulong offset; 51fe1ef503SSimon Glass int numeric; 5296495d90SSimon Glass int ret; 5396495d90SSimon Glass 5496495d90SSimon Glass if (devp) 5596495d90SSimon Glass *devp = NULL; 56fe1ef503SSimon Glass numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1; 5796495d90SSimon Glass for (ret = uclass_first_device(UCLASS_GPIO, &dev); 5896495d90SSimon Glass dev; 5996495d90SSimon Glass ret = uclass_next_device(&dev)) { 6096495d90SSimon Glass int len; 6196495d90SSimon Glass 6296495d90SSimon Glass uc_priv = dev->uclass_priv; 63fe1ef503SSimon Glass if (numeric != -1) { 64fe1ef503SSimon Glass offset = numeric - uc_priv->gpio_base; 65fe1ef503SSimon Glass /* Allow GPIOs to be numbered from 0 */ 66fe1ef503SSimon Glass if (offset >= 0 && offset < uc_priv->gpio_count) 67fe1ef503SSimon Glass break; 68fe1ef503SSimon Glass } 69fe1ef503SSimon Glass 7096495d90SSimon Glass len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0; 7196495d90SSimon Glass 72939cda5bSSimon Glass if (!strncasecmp(name, uc_priv->bank_name, len)) { 73fe1ef503SSimon Glass if (!strict_strtoul(name + len, 10, &offset)) 74fe1ef503SSimon Glass break; 75fe1ef503SSimon Glass } 76fe1ef503SSimon Glass } 77fe1ef503SSimon Glass 78fe1ef503SSimon Glass if (!dev) 79fe1ef503SSimon Glass return ret ? ret : -EINVAL; 80fe1ef503SSimon Glass 8196495d90SSimon Glass if (devp) 8296495d90SSimon Glass *devp = dev; 8396495d90SSimon Glass if (offsetp) 8496495d90SSimon Glass *offsetp = offset; 8596495d90SSimon Glass if (gpiop) 8696495d90SSimon Glass *gpiop = uc_priv->gpio_base + offset; 8796495d90SSimon Glass 88fe1ef503SSimon Glass return 0; 8996495d90SSimon Glass } 9096495d90SSimon Glass 9196495d90SSimon Glass /** 9296495d90SSimon Glass * gpio_request() - [COMPAT] Request GPIO 9396495d90SSimon Glass * gpio: GPIO number 9496495d90SSimon Glass * label: Name for the requested GPIO 9596495d90SSimon Glass * 96b892d127SSimon Glass * The label is copied and allocated so the caller does not need to keep 97b892d127SSimon Glass * the pointer around. 98b892d127SSimon Glass * 9996495d90SSimon Glass * This function implements the API that's compatible with current 10096495d90SSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 10196495d90SSimon Glass * GPIO driver. Returns 0 on success, negative value on error. 10296495d90SSimon Glass */ 10396495d90SSimon Glass int gpio_request(unsigned gpio, const char *label) 10496495d90SSimon Glass { 105b892d127SSimon Glass struct gpio_dev_priv *uc_priv; 10696495d90SSimon Glass unsigned int offset; 10754c5d08aSHeiko Schocher struct udevice *dev; 108b892d127SSimon Glass char *str; 10996495d90SSimon Glass int ret; 11096495d90SSimon Glass 11196495d90SSimon Glass ret = gpio_to_device(gpio, &dev, &offset); 11296495d90SSimon Glass if (ret) 11396495d90SSimon Glass return ret; 11496495d90SSimon Glass 115b892d127SSimon Glass uc_priv = dev->uclass_priv; 116b892d127SSimon Glass if (uc_priv->name[offset]) 117b892d127SSimon Glass return -EBUSY; 118b892d127SSimon Glass str = strdup(label); 119b892d127SSimon Glass if (!str) 120b892d127SSimon Glass return -ENOMEM; 121b892d127SSimon Glass if (gpio_get_ops(dev)->request) { 122b892d127SSimon Glass ret = gpio_get_ops(dev)->request(dev, offset, label); 123b892d127SSimon Glass if (ret) { 124b892d127SSimon Glass free(str); 125b892d127SSimon Glass return ret; 126b892d127SSimon Glass } 127b892d127SSimon Glass } 128b892d127SSimon Glass uc_priv->name[offset] = str; 12996495d90SSimon Glass 130b892d127SSimon Glass return 0; 13196495d90SSimon Glass } 13296495d90SSimon Glass 13396495d90SSimon Glass /** 134*d44f597bSSimon Glass * gpio_requestf() - [COMPAT] Request GPIO 135*d44f597bSSimon Glass * @gpio: GPIO number 136*d44f597bSSimon Glass * @fmt: Format string for the requested GPIO 137*d44f597bSSimon Glass * @...: Arguments for the printf() format string 138*d44f597bSSimon Glass * 139*d44f597bSSimon Glass * This function implements the API that's compatible with current 140*d44f597bSSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 141*d44f597bSSimon Glass * GPIO driver. Returns 0 on success, negative value on error. 142*d44f597bSSimon Glass */ 143*d44f597bSSimon Glass int gpio_requestf(unsigned gpio, const char *fmt, ...) 144*d44f597bSSimon Glass { 145*d44f597bSSimon Glass va_list args; 146*d44f597bSSimon Glass char buf[40]; 147*d44f597bSSimon Glass 148*d44f597bSSimon Glass va_start(args, fmt); 149*d44f597bSSimon Glass vscnprintf(buf, sizeof(buf), fmt, args); 150*d44f597bSSimon Glass va_end(args); 151*d44f597bSSimon Glass return gpio_request(gpio, buf); 152*d44f597bSSimon Glass } 153*d44f597bSSimon Glass 154*d44f597bSSimon Glass /** 15596495d90SSimon Glass * gpio_free() - [COMPAT] Relinquish GPIO 15696495d90SSimon Glass * gpio: GPIO number 15796495d90SSimon Glass * 15896495d90SSimon Glass * This function implements the API that's compatible with current 15996495d90SSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 16096495d90SSimon Glass * GPIO driver. Returns 0 on success, negative value on error. 16196495d90SSimon Glass */ 16296495d90SSimon Glass int gpio_free(unsigned gpio) 16396495d90SSimon Glass { 164b892d127SSimon Glass struct gpio_dev_priv *uc_priv; 16596495d90SSimon Glass unsigned int offset; 16654c5d08aSHeiko Schocher struct udevice *dev; 16796495d90SSimon Glass int ret; 16896495d90SSimon Glass 16996495d90SSimon Glass ret = gpio_to_device(gpio, &dev, &offset); 17096495d90SSimon Glass if (ret) 17196495d90SSimon Glass return ret; 17296495d90SSimon Glass 173b892d127SSimon Glass uc_priv = dev->uclass_priv; 174b892d127SSimon Glass if (!uc_priv->name[offset]) 175b892d127SSimon Glass return -ENXIO; 176b892d127SSimon Glass if (gpio_get_ops(dev)->free) { 177b892d127SSimon Glass ret = gpio_get_ops(dev)->free(dev, offset); 178b892d127SSimon Glass if (ret) 179b892d127SSimon Glass return ret; 180b892d127SSimon Glass } 181b892d127SSimon Glass 182b892d127SSimon Glass free(uc_priv->name[offset]); 183b892d127SSimon Glass uc_priv->name[offset] = NULL; 184b892d127SSimon Glass 18596495d90SSimon Glass return 0; 186b892d127SSimon Glass } 187b892d127SSimon Glass 188b892d127SSimon Glass static int check_reserved(struct udevice *dev, unsigned offset, 189b892d127SSimon Glass const char *func) 190b892d127SSimon Glass { 191b892d127SSimon Glass struct gpio_dev_priv *uc_priv = dev->uclass_priv; 192b892d127SSimon Glass 193b892d127SSimon Glass if (!uc_priv->name[offset]) { 194b892d127SSimon Glass printf("%s: %s: error: gpio %s%d not reserved\n", 195b892d127SSimon Glass dev->name, func, 196b892d127SSimon Glass uc_priv->bank_name ? uc_priv->bank_name : "", offset); 197b892d127SSimon Glass return -EBUSY; 198b892d127SSimon Glass } 199b892d127SSimon Glass 200b892d127SSimon Glass return 0; 20196495d90SSimon Glass } 20296495d90SSimon Glass 20396495d90SSimon Glass /** 20496495d90SSimon Glass * gpio_direction_input() - [COMPAT] Set GPIO direction to input 20596495d90SSimon Glass * gpio: GPIO number 20696495d90SSimon Glass * 20796495d90SSimon Glass * This function implements the API that's compatible with current 20896495d90SSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 20996495d90SSimon Glass * GPIO driver. Returns 0 on success, negative value on error. 21096495d90SSimon Glass */ 21196495d90SSimon Glass int gpio_direction_input(unsigned gpio) 21296495d90SSimon Glass { 21396495d90SSimon Glass unsigned int offset; 21454c5d08aSHeiko Schocher struct udevice *dev; 21596495d90SSimon Glass int ret; 21696495d90SSimon Glass 21796495d90SSimon Glass ret = gpio_to_device(gpio, &dev, &offset); 21896495d90SSimon Glass if (ret) 21996495d90SSimon Glass return ret; 220b892d127SSimon Glass ret = check_reserved(dev, offset, "dir_input"); 22196495d90SSimon Glass 222b892d127SSimon Glass return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset); 22396495d90SSimon Glass } 22496495d90SSimon Glass 22596495d90SSimon Glass /** 22696495d90SSimon Glass * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value 22796495d90SSimon Glass * gpio: GPIO number 22896495d90SSimon Glass * value: Logical value to be set on the GPIO pin 22996495d90SSimon Glass * 23096495d90SSimon Glass * This function implements the API that's compatible with current 23196495d90SSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 23296495d90SSimon Glass * GPIO driver. Returns 0 on success, negative value on error. 23396495d90SSimon Glass */ 23496495d90SSimon Glass int gpio_direction_output(unsigned gpio, int value) 23596495d90SSimon Glass { 23696495d90SSimon Glass unsigned int offset; 23754c5d08aSHeiko Schocher struct udevice *dev; 23896495d90SSimon Glass int ret; 23996495d90SSimon Glass 24096495d90SSimon Glass ret = gpio_to_device(gpio, &dev, &offset); 24196495d90SSimon Glass if (ret) 24296495d90SSimon Glass return ret; 243b892d127SSimon Glass ret = check_reserved(dev, offset, "dir_output"); 24496495d90SSimon Glass 245b892d127SSimon Glass return ret ? ret : 246b892d127SSimon Glass gpio_get_ops(dev)->direction_output(dev, offset, value); 24796495d90SSimon Glass } 24896495d90SSimon Glass 24996495d90SSimon Glass /** 25096495d90SSimon Glass * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value 25196495d90SSimon Glass * gpio: GPIO number 25296495d90SSimon Glass * 25396495d90SSimon Glass * This function implements the API that's compatible with current 25496495d90SSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 25596495d90SSimon Glass * GPIO driver. Returns the value of the GPIO pin, or negative value 25696495d90SSimon Glass * on error. 25796495d90SSimon Glass */ 25896495d90SSimon Glass int gpio_get_value(unsigned gpio) 25996495d90SSimon Glass { 26096495d90SSimon Glass unsigned int offset; 26154c5d08aSHeiko Schocher struct udevice *dev; 26296495d90SSimon Glass int ret; 26396495d90SSimon Glass 26496495d90SSimon Glass ret = gpio_to_device(gpio, &dev, &offset); 26596495d90SSimon Glass if (ret) 26696495d90SSimon Glass return ret; 267b892d127SSimon Glass ret = check_reserved(dev, offset, "get_value"); 26896495d90SSimon Glass 269b892d127SSimon Glass return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset); 27096495d90SSimon Glass } 27196495d90SSimon Glass 27296495d90SSimon Glass /** 27396495d90SSimon Glass * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin 27496495d90SSimon Glass * gpio: GPIO number 27596495d90SSimon Glass * value: Logical value to be set on the GPIO pin. 27696495d90SSimon Glass * 27796495d90SSimon Glass * This function implements the API that's compatible with current 27896495d90SSimon Glass * GPIO API used in U-Boot. The request is forwarded to particular 27996495d90SSimon Glass * GPIO driver. Returns 0 on success, negative value on error. 28096495d90SSimon Glass */ 28196495d90SSimon Glass int gpio_set_value(unsigned gpio, int value) 28296495d90SSimon Glass { 28396495d90SSimon Glass unsigned int offset; 28454c5d08aSHeiko Schocher struct udevice *dev; 28596495d90SSimon Glass int ret; 28696495d90SSimon Glass 28796495d90SSimon Glass ret = gpio_to_device(gpio, &dev, &offset); 28896495d90SSimon Glass if (ret) 28996495d90SSimon Glass return ret; 290b892d127SSimon Glass ret = check_reserved(dev, offset, "set_value"); 29196495d90SSimon Glass 292b892d127SSimon Glass return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value); 29396495d90SSimon Glass } 29496495d90SSimon Glass 29554c5d08aSHeiko Schocher const char *gpio_get_bank_info(struct udevice *dev, int *bit_count) 29696495d90SSimon Glass { 29796495d90SSimon Glass struct gpio_dev_priv *priv; 29896495d90SSimon Glass 29996495d90SSimon Glass /* Must be called on an active device */ 30096495d90SSimon Glass priv = dev->uclass_priv; 30196495d90SSimon Glass assert(priv); 30296495d90SSimon Glass 30396495d90SSimon Glass *bit_count = priv->gpio_count; 30496495d90SSimon Glass return priv->bank_name; 30596495d90SSimon Glass } 30696495d90SSimon Glass 3076449a506SSimon Glass static const char * const gpio_function[GPIOF_COUNT] = { 3086449a506SSimon Glass "input", 3096449a506SSimon Glass "output", 3106449a506SSimon Glass "unused", 3116449a506SSimon Glass "unknown", 3126449a506SSimon Glass "func", 3136449a506SSimon Glass }; 3146449a506SSimon Glass 3156449a506SSimon Glass int get_function(struct udevice *dev, int offset, bool skip_unused, 3166449a506SSimon Glass const char **namep) 3176449a506SSimon Glass { 3186449a506SSimon Glass struct gpio_dev_priv *uc_priv = dev->uclass_priv; 3196449a506SSimon Glass struct dm_gpio_ops *ops = gpio_get_ops(dev); 3206449a506SSimon Glass 3216449a506SSimon Glass BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); 3226449a506SSimon Glass if (!device_active(dev)) 3236449a506SSimon Glass return -ENODEV; 3246449a506SSimon Glass if (offset < 0 || offset >= uc_priv->gpio_count) 3256449a506SSimon Glass return -EINVAL; 3266449a506SSimon Glass if (namep) 3276449a506SSimon Glass *namep = uc_priv->name[offset]; 3286449a506SSimon Glass if (skip_unused && !uc_priv->name[offset]) 3296449a506SSimon Glass return GPIOF_UNUSED; 3306449a506SSimon Glass if (ops->get_function) { 3316449a506SSimon Glass int ret; 3326449a506SSimon Glass 3336449a506SSimon Glass ret = ops->get_function(dev, offset); 3346449a506SSimon Glass if (ret < 0) 3356449a506SSimon Glass return ret; 3366449a506SSimon Glass if (ret >= ARRAY_SIZE(gpio_function)) 3376449a506SSimon Glass return -ENODATA; 3386449a506SSimon Glass return ret; 3396449a506SSimon Glass } 3406449a506SSimon Glass 3416449a506SSimon Glass return GPIOF_UNKNOWN; 3426449a506SSimon Glass } 3436449a506SSimon Glass 3446449a506SSimon Glass int gpio_get_function(struct udevice *dev, int offset, const char **namep) 3456449a506SSimon Glass { 3466449a506SSimon Glass return get_function(dev, offset, true, namep); 3476449a506SSimon Glass } 3486449a506SSimon Glass 3496449a506SSimon Glass int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep) 3506449a506SSimon Glass { 3516449a506SSimon Glass return get_function(dev, offset, false, namep); 3526449a506SSimon Glass } 3536449a506SSimon Glass 3540757535aSSimon Glass int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) 3550757535aSSimon Glass { 3560757535aSSimon Glass struct dm_gpio_ops *ops = gpio_get_ops(dev); 3570757535aSSimon Glass struct gpio_dev_priv *priv; 3580757535aSSimon Glass char *str = buf; 3590757535aSSimon Glass int func; 3600757535aSSimon Glass int ret; 3610757535aSSimon Glass int len; 3620757535aSSimon Glass 3630757535aSSimon Glass BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); 3640757535aSSimon Glass 3650757535aSSimon Glass *buf = 0; 3660757535aSSimon Glass priv = dev->uclass_priv; 3670757535aSSimon Glass ret = gpio_get_raw_function(dev, offset, NULL); 3680757535aSSimon Glass if (ret < 0) 3690757535aSSimon Glass return ret; 3700757535aSSimon Glass func = ret; 3710757535aSSimon Glass len = snprintf(str, buffsize, "%s%d: %s", 3720757535aSSimon Glass priv->bank_name ? priv->bank_name : "", 3730757535aSSimon Glass offset, gpio_function[func]); 3740757535aSSimon Glass if (func == GPIOF_INPUT || func == GPIOF_OUTPUT || 3750757535aSSimon Glass func == GPIOF_UNUSED) { 3760757535aSSimon Glass const char *label; 3770757535aSSimon Glass bool used; 3780757535aSSimon Glass 3790757535aSSimon Glass ret = ops->get_value(dev, offset); 3800757535aSSimon Glass if (ret < 0) 3810757535aSSimon Glass return ret; 3820757535aSSimon Glass used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED; 3830757535aSSimon Glass snprintf(str + len, buffsize - len, ": %d [%c]%s%s", 3840757535aSSimon Glass ret, 3850757535aSSimon Glass used ? 'x' : ' ', 3860757535aSSimon Glass used ? " " : "", 3870757535aSSimon Glass label ? label : ""); 3880757535aSSimon Glass } 3890757535aSSimon Glass 3900757535aSSimon Glass return 0; 3910757535aSSimon Glass } 3920757535aSSimon Glass 39396495d90SSimon Glass /* We need to renumber the GPIOs when any driver is probed/removed */ 394b892d127SSimon Glass static int gpio_renumber(struct udevice *removed_dev) 39596495d90SSimon Glass { 39696495d90SSimon Glass struct gpio_dev_priv *uc_priv; 39754c5d08aSHeiko Schocher struct udevice *dev; 39896495d90SSimon Glass struct uclass *uc; 39996495d90SSimon Glass unsigned base; 40096495d90SSimon Glass int ret; 40196495d90SSimon Glass 40296495d90SSimon Glass ret = uclass_get(UCLASS_GPIO, &uc); 40396495d90SSimon Glass if (ret) 40496495d90SSimon Glass return ret; 40596495d90SSimon Glass 40696495d90SSimon Glass /* Ensure that we have a base for each bank */ 40796495d90SSimon Glass base = 0; 40896495d90SSimon Glass uclass_foreach_dev(dev, uc) { 409b892d127SSimon Glass if (device_active(dev) && dev != removed_dev) { 41096495d90SSimon Glass uc_priv = dev->uclass_priv; 41196495d90SSimon Glass uc_priv->gpio_base = base; 41296495d90SSimon Glass base += uc_priv->gpio_count; 41396495d90SSimon Glass } 41496495d90SSimon Glass } 41596495d90SSimon Glass 41696495d90SSimon Glass return 0; 41796495d90SSimon Glass } 41896495d90SSimon Glass 41954c5d08aSHeiko Schocher static int gpio_post_probe(struct udevice *dev) 42096495d90SSimon Glass { 421b892d127SSimon Glass struct gpio_dev_priv *uc_priv = dev->uclass_priv; 422b892d127SSimon Glass 423b892d127SSimon Glass uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *)); 424b892d127SSimon Glass if (!uc_priv->name) 425b892d127SSimon Glass return -ENOMEM; 426b892d127SSimon Glass 427b892d127SSimon Glass return gpio_renumber(NULL); 42896495d90SSimon Glass } 42996495d90SSimon Glass 43054c5d08aSHeiko Schocher static int gpio_pre_remove(struct udevice *dev) 43196495d90SSimon Glass { 432b892d127SSimon Glass struct gpio_dev_priv *uc_priv = dev->uclass_priv; 433b892d127SSimon Glass int i; 434b892d127SSimon Glass 435b892d127SSimon Glass for (i = 0; i < uc_priv->gpio_count; i++) { 436b892d127SSimon Glass if (uc_priv->name[i]) 437b892d127SSimon Glass free(uc_priv->name[i]); 438b892d127SSimon Glass } 439b892d127SSimon Glass free(uc_priv->name); 440b892d127SSimon Glass 441b892d127SSimon Glass return gpio_renumber(dev); 44296495d90SSimon Glass } 44396495d90SSimon Glass 44496495d90SSimon Glass UCLASS_DRIVER(gpio) = { 44596495d90SSimon Glass .id = UCLASS_GPIO, 44696495d90SSimon Glass .name = "gpio", 44796495d90SSimon Glass .post_probe = gpio_post_probe, 44896495d90SSimon Glass .pre_remove = gpio_pre_remove, 44996495d90SSimon Glass .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv), 45096495d90SSimon Glass }; 451