uboot/drivers/gpio/gpio-uclass.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013 Google, Inc
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <errno.h>
  10#include <fdtdec.h>
  11#include <malloc.h>
  12#include <asm/gpio.h>
  13#include <linux/ctype.h>
  14
  15DECLARE_GLOBAL_DATA_PTR;
  16
  17/**
  18 * gpio_to_device() - Convert global GPIO number to device, number
  19 *
  20 * Convert the GPIO number to an entry in the list of GPIOs
  21 * or GPIO blocks registered with the GPIO controller. Returns
  22 * entry on success, NULL on error.
  23 *
  24 * @gpio:       The numeric representation of the GPIO
  25 * @desc:       Returns description (desc->flags will always be 0)
  26 * @return 0 if found, -ENOENT if not found
  27 */
  28static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
  29{
  30        struct gpio_dev_priv *uc_priv;
  31        struct udevice *dev;
  32        int ret;
  33
  34        for (ret = uclass_first_device(UCLASS_GPIO, &dev);
  35             dev;
  36             ret = uclass_next_device(&dev)) {
  37                uc_priv = dev_get_uclass_priv(dev);
  38                if (gpio >= uc_priv->gpio_base &&
  39                    gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
  40                        desc->dev = dev;
  41                        desc->offset = gpio - uc_priv->gpio_base;
  42                        desc->flags = 0;
  43                        return 0;
  44                }
  45        }
  46
  47        /* No such GPIO */
  48        return ret ? ret : -ENOENT;
  49}
  50
  51int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
  52{
  53        struct gpio_dev_priv *uc_priv = NULL;
  54        struct udevice *dev;
  55        ulong offset;
  56        int numeric;
  57        int ret;
  58
  59        numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
  60        for (ret = uclass_first_device(UCLASS_GPIO, &dev);
  61             dev;
  62             ret = uclass_next_device(&dev)) {
  63                int len;
  64
  65                uc_priv = dev_get_uclass_priv(dev);
  66                if (numeric != -1) {
  67                        offset = numeric - uc_priv->gpio_base;
  68                        /* Allow GPIOs to be numbered from 0 */
  69                        if (offset >= 0 && offset < uc_priv->gpio_count)
  70                                break;
  71                }
  72
  73                len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
  74
  75                if (!strncasecmp(name, uc_priv->bank_name, len)) {
  76                        if (!strict_strtoul(name + len, 10, &offset))
  77                                break;
  78                }
  79        }
  80
  81        if (!dev)
  82                return ret ? ret : -EINVAL;
  83
  84        desc->dev = dev;
  85        desc->offset = offset;
  86
  87        return 0;
  88}
  89
  90int gpio_lookup_name(const char *name, struct udevice **devp,
  91                     unsigned int *offsetp, unsigned int *gpiop)
  92{
  93        struct gpio_desc desc;
  94        int ret;
  95
  96        if (devp)
  97                *devp = NULL;
  98        ret = dm_gpio_lookup_name(name, &desc);
  99        if (ret)
 100                return ret;
 101
 102        if (devp)
 103                *devp = desc.dev;
 104        if (offsetp)
 105                *offsetp = desc.offset;
 106        if (gpiop) {
 107                struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
 108
 109                *gpiop = uc_priv->gpio_base + desc.offset;
 110        }
 111
 112        return 0;
 113}
 114
 115static int gpio_find_and_xlate(struct gpio_desc *desc,
 116                               struct fdtdec_phandle_args *args)
 117{
 118        struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
 119
 120        /* Use the first argument as the offset by default */
 121        if (args->args_count > 0)
 122                desc->offset = args->args[0];
 123        else
 124                desc->offset = -1;
 125        desc->flags = 0;
 126
 127        return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
 128}
 129
 130int dm_gpio_request(struct gpio_desc *desc, const char *label)
 131{
 132        struct udevice *dev = desc->dev;
 133        struct gpio_dev_priv *uc_priv;
 134        char *str;
 135        int ret;
 136
 137        uc_priv = dev_get_uclass_priv(dev);
 138        if (uc_priv->name[desc->offset])
 139                return -EBUSY;
 140        str = strdup(label);
 141        if (!str)
 142                return -ENOMEM;
 143        if (gpio_get_ops(dev)->request) {
 144                ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
 145                if (ret) {
 146                        free(str);
 147                        return ret;
 148                }
 149        }
 150        uc_priv->name[desc->offset] = str;
 151
 152        return 0;
 153}
 154
 155static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
 156{
 157        va_list args;
 158        char buf[40];
 159
 160        va_start(args, fmt);
 161        vscnprintf(buf, sizeof(buf), fmt, args);
 162        va_end(args);
 163        return dm_gpio_request(desc, buf);
 164}
 165
 166/**
 167 * gpio_request() - [COMPAT] Request GPIO
 168 * gpio:        GPIO number
 169 * label:       Name for the requested GPIO
 170 *
 171 * The label is copied and allocated so the caller does not need to keep
 172 * the pointer around.
 173 *
 174 * This function implements the API that's compatible with current
 175 * GPIO API used in U-Boot. The request is forwarded to particular
 176 * GPIO driver. Returns 0 on success, negative value on error.
 177 */
 178int gpio_request(unsigned gpio, const char *label)
 179{
 180        struct gpio_desc desc;
 181        int ret;
 182
 183        ret = gpio_to_device(gpio, &desc);
 184        if (ret)
 185                return ret;
 186
 187        return dm_gpio_request(&desc, label);
 188}
 189
 190/**
 191 * gpio_requestf() - [COMPAT] Request GPIO
 192 * @gpio:       GPIO number
 193 * @fmt:        Format string for the requested GPIO
 194 * @...:        Arguments for the printf() format string
 195 *
 196 * This function implements the API that's compatible with current
 197 * GPIO API used in U-Boot. The request is forwarded to particular
 198 * GPIO driver. Returns 0 on success, negative value on error.
 199 */
 200int gpio_requestf(unsigned gpio, const char *fmt, ...)
 201{
 202        va_list args;
 203        char buf[40];
 204
 205        va_start(args, fmt);
 206        vscnprintf(buf, sizeof(buf), fmt, args);
 207        va_end(args);
 208        return gpio_request(gpio, buf);
 209}
 210
 211int _dm_gpio_free(struct udevice *dev, uint offset)
 212{
 213        struct gpio_dev_priv *uc_priv;
 214        int ret;
 215
 216        uc_priv = dev_get_uclass_priv(dev);
 217        if (!uc_priv->name[offset])
 218                return -ENXIO;
 219        if (gpio_get_ops(dev)->free) {
 220                ret = gpio_get_ops(dev)->free(dev, offset);
 221                if (ret)
 222                        return ret;
 223        }
 224
 225        free(uc_priv->name[offset]);
 226        uc_priv->name[offset] = NULL;
 227
 228        return 0;
 229}
 230
 231/**
 232 * gpio_free() - [COMPAT] Relinquish GPIO
 233 * gpio:        GPIO number
 234 *
 235 * This function implements the API that's compatible with current
 236 * GPIO API used in U-Boot. The request is forwarded to particular
 237 * GPIO driver. Returns 0 on success, negative value on error.
 238 */
 239int gpio_free(unsigned gpio)
 240{
 241        struct gpio_desc desc;
 242        int ret;
 243
 244        ret = gpio_to_device(gpio, &desc);
 245        if (ret)
 246                return ret;
 247
 248        return _dm_gpio_free(desc.dev, desc.offset);
 249}
 250
 251static int check_reserved(struct gpio_desc *desc, const char *func)
 252{
 253        struct gpio_dev_priv *uc_priv;
 254
 255        if (!dm_gpio_is_valid(desc))
 256                return -ENOENT;
 257
 258        uc_priv = dev_get_uclass_priv(desc->dev);
 259        if (!uc_priv->name[desc->offset]) {
 260                printf("%s: %s: error: gpio %s%d not reserved\n",
 261                       desc->dev->name, func,
 262                       uc_priv->bank_name ? uc_priv->bank_name : "",
 263                       desc->offset);
 264                return -EBUSY;
 265        }
 266
 267        return 0;
 268}
 269
 270/**
 271 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
 272 * gpio:        GPIO number
 273 *
 274 * This function implements the API that's compatible with current
 275 * GPIO API used in U-Boot. The request is forwarded to particular
 276 * GPIO driver. Returns 0 on success, negative value on error.
 277 */
 278int gpio_direction_input(unsigned gpio)
 279{
 280        struct gpio_desc desc;
 281        int ret;
 282
 283        ret = gpio_to_device(gpio, &desc);
 284        if (ret)
 285                return ret;
 286        ret = check_reserved(&desc, "dir_input");
 287        if (ret)
 288                return ret;
 289
 290        return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
 291}
 292
 293/**
 294 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
 295 * gpio:        GPIO number
 296 * value:       Logical value to be set on the GPIO pin
 297 *
 298 * This function implements the API that's compatible with current
 299 * GPIO API used in U-Boot. The request is forwarded to particular
 300 * GPIO driver. Returns 0 on success, negative value on error.
 301 */
 302int gpio_direction_output(unsigned gpio, int value)
 303{
 304        struct gpio_desc desc;
 305        int ret;
 306
 307        ret = gpio_to_device(gpio, &desc);
 308        if (ret)
 309                return ret;
 310        ret = check_reserved(&desc, "dir_output");
 311        if (ret)
 312                return ret;
 313
 314        return gpio_get_ops(desc.dev)->direction_output(desc.dev,
 315                                                        desc.offset, value);
 316}
 317
 318int dm_gpio_get_value(struct gpio_desc *desc)
 319{
 320        int value;
 321        int ret;
 322
 323        ret = check_reserved(desc, "get_value");
 324        if (ret)
 325                return ret;
 326
 327        value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
 328
 329        return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
 330}
 331
 332int dm_gpio_set_value(struct gpio_desc *desc, int value)
 333{
 334        int ret;
 335
 336        ret = check_reserved(desc, "set_value");
 337        if (ret)
 338                return ret;
 339
 340        if (desc->flags & GPIOD_ACTIVE_LOW)
 341                value = !value;
 342        gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
 343        return 0;
 344}
 345
 346int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
 347{
 348        struct udevice *dev = desc->dev;
 349        struct dm_gpio_ops *ops = gpio_get_ops(dev);
 350        int ret;
 351
 352        ret = check_reserved(desc, "set_dir");
 353        if (ret)
 354                return ret;
 355
 356        if (flags & GPIOD_IS_OUT) {
 357                int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
 358
 359                if (flags & GPIOD_ACTIVE_LOW)
 360                        value = !value;
 361                ret = ops->direction_output(dev, desc->offset, value);
 362        } else  if (flags & GPIOD_IS_IN) {
 363                ret = ops->direction_input(dev, desc->offset);
 364        }
 365        if (ret)
 366                return ret;
 367        /*
 368         * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
 369         * futures
 370         */
 371        desc->flags = flags;
 372
 373        return 0;
 374}
 375
 376int dm_gpio_set_dir(struct gpio_desc *desc)
 377{
 378        return dm_gpio_set_dir_flags(desc, desc->flags);
 379}
 380
 381/**
 382 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
 383 * gpio:        GPIO number
 384 *
 385 * This function implements the API that's compatible with current
 386 * GPIO API used in U-Boot. The request is forwarded to particular
 387 * GPIO driver. Returns the value of the GPIO pin, or negative value
 388 * on error.
 389 */
 390int gpio_get_value(unsigned gpio)
 391{
 392        int ret;
 393
 394        struct gpio_desc desc;
 395
 396        ret = gpio_to_device(gpio, &desc);
 397        if (ret)
 398                return ret;
 399        return dm_gpio_get_value(&desc);
 400}
 401
 402/**
 403 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
 404 * gpio:        GPIO number
 405 * value:       Logical value to be set on the GPIO pin.
 406 *
 407 * This function implements the API that's compatible with current
 408 * GPIO API used in U-Boot. The request is forwarded to particular
 409 * GPIO driver. Returns 0 on success, negative value on error.
 410 */
 411int gpio_set_value(unsigned gpio, int value)
 412{
 413        struct gpio_desc desc;
 414        int ret;
 415
 416        ret = gpio_to_device(gpio, &desc);
 417        if (ret)
 418                return ret;
 419        return dm_gpio_set_value(&desc, value);
 420}
 421
 422const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
 423{
 424        struct gpio_dev_priv *priv;
 425
 426        /* Must be called on an active device */
 427        priv = dev_get_uclass_priv(dev);
 428        assert(priv);
 429
 430        *bit_count = priv->gpio_count;
 431        return priv->bank_name;
 432}
 433
 434static const char * const gpio_function[GPIOF_COUNT] = {
 435        "input",
 436        "output",
 437        "unused",
 438        "unknown",
 439        "func",
 440};
 441
 442int get_function(struct udevice *dev, int offset, bool skip_unused,
 443                 const char **namep)
 444{
 445        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 446        struct dm_gpio_ops *ops = gpio_get_ops(dev);
 447
 448        BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
 449        if (!device_active(dev))
 450                return -ENODEV;
 451        if (offset < 0 || offset >= uc_priv->gpio_count)
 452                return -EINVAL;
 453        if (namep)
 454                *namep = uc_priv->name[offset];
 455        if (skip_unused && !uc_priv->name[offset])
 456                return GPIOF_UNUSED;
 457        if (ops->get_function) {
 458                int ret;
 459
 460                ret = ops->get_function(dev, offset);
 461                if (ret < 0)
 462                        return ret;
 463                if (ret >= ARRAY_SIZE(gpio_function))
 464                        return -ENODATA;
 465                return ret;
 466        }
 467
 468        return GPIOF_UNKNOWN;
 469}
 470
 471int gpio_get_function(struct udevice *dev, int offset, const char **namep)
 472{
 473        return get_function(dev, offset, true, namep);
 474}
 475
 476int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
 477{
 478        return get_function(dev, offset, false, namep);
 479}
 480
 481int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
 482{
 483        struct dm_gpio_ops *ops = gpio_get_ops(dev);
 484        struct gpio_dev_priv *priv;
 485        char *str = buf;
 486        int func;
 487        int ret;
 488        int len;
 489
 490        BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
 491
 492        *buf = 0;
 493        priv = dev_get_uclass_priv(dev);
 494        ret = gpio_get_raw_function(dev, offset, NULL);
 495        if (ret < 0)
 496                return ret;
 497        func = ret;
 498        len = snprintf(str, buffsize, "%s%d: %s",
 499                       priv->bank_name ? priv->bank_name : "",
 500                       offset, gpio_function[func]);
 501        if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
 502            func == GPIOF_UNUSED) {
 503                const char *label;
 504                bool used;
 505
 506                ret = ops->get_value(dev, offset);
 507                if (ret < 0)
 508                        return ret;
 509                used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
 510                snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
 511                         ret,
 512                         used ? 'x' : ' ',
 513                         used ? " " : "",
 514                         label ? label : "");
 515        }
 516
 517        return 0;
 518}
 519
 520int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
 521{
 522        int i, ret;
 523        int gpio;
 524
 525        for (i = 0; i < 32; i++) {
 526                gpio = gpio_num_array[i];
 527                if (gpio == -1)
 528                        break;
 529                ret = gpio_requestf(gpio, fmt, i);
 530                if (ret)
 531                        goto err;
 532                ret = gpio_direction_input(gpio);
 533                if (ret) {
 534                        gpio_free(gpio);
 535                        goto err;
 536                }
 537        }
 538
 539        return 0;
 540err:
 541        for (i--; i >= 0; i--)
 542                gpio_free(gpio_num_array[i]);
 543
 544        return ret;
 545}
 546
 547/*
 548 * get a number comprised of multiple GPIO values. gpio_num_array points to
 549 * the array of gpio pin numbers to scan, terminated by -1.
 550 */
 551int gpio_get_values_as_int(const int *gpio_list)
 552{
 553        int gpio;
 554        unsigned bitmask = 1;
 555        unsigned vector = 0;
 556        int ret;
 557
 558        while (bitmask &&
 559               ((gpio = *gpio_list++) != -1)) {
 560                ret = gpio_get_value(gpio);
 561                if (ret < 0)
 562                        return ret;
 563                else if (ret)
 564                        vector |= bitmask;
 565                bitmask <<= 1;
 566        }
 567
 568        return vector;
 569}
 570
 571static int _gpio_request_by_name_nodev(const void *blob, int node,
 572                                       const char *list_name, int index,
 573                                       struct gpio_desc *desc, int flags,
 574                                       bool add_index)
 575{
 576        struct fdtdec_phandle_args args;
 577        int ret;
 578
 579        desc->dev = NULL;
 580        desc->offset = 0;
 581        ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
 582                                             "#gpio-cells", 0, index, &args);
 583        if (ret) {
 584                debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
 585                goto err;
 586        }
 587
 588        ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
 589                                             &desc->dev);
 590        if (ret) {
 591                debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
 592                goto err;
 593        }
 594        ret = gpio_find_and_xlate(desc, &args);
 595        if (ret) {
 596                debug("%s: gpio_find_and_xlate failed\n", __func__);
 597                goto err;
 598        }
 599        ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
 600                               fdt_get_name(blob, node, NULL),
 601                               list_name, index);
 602        if (ret) {
 603                debug("%s: dm_gpio_requestf failed\n", __func__);
 604                goto err;
 605        }
 606        ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
 607        if (ret) {
 608                debug("%s: dm_gpio_set_dir failed\n", __func__);
 609                goto err;
 610        }
 611
 612        return 0;
 613err:
 614        debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
 615              __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
 616        return ret;
 617}
 618
 619int gpio_request_by_name_nodev(const void *blob, int node,
 620                               const char *list_name, int index,
 621                               struct gpio_desc *desc, int flags)
 622{
 623        return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
 624                                           flags, index > 0);
 625}
 626
 627int gpio_request_by_name(struct udevice *dev,  const char *list_name, int index,
 628                         struct gpio_desc *desc, int flags)
 629{
 630        /*
 631         * This isn't ideal since we don't use dev->name in the debug()
 632         * calls in gpio_request_by_name(), but we can do this until
 633         * gpio_request_by_name_nodev() can be dropped.
 634         */
 635        return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
 636                                          list_name, index, desc, flags);
 637}
 638
 639int gpio_request_list_by_name_nodev(const void *blob, int node,
 640                                    const char *list_name,
 641                                    struct gpio_desc *desc, int max_count,
 642                                    int flags)
 643{
 644        int count;
 645        int ret;
 646
 647        for (count = 0; count < max_count; count++) {
 648                ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
 649                                                  &desc[count], flags, true);
 650                if (ret == -ENOENT)
 651                        break;
 652                else if (ret)
 653                        goto err;
 654        }
 655
 656        /* We ran out of GPIOs in the list */
 657        return count;
 658
 659err:
 660        gpio_free_list_nodev(desc, count - 1);
 661
 662        return ret;
 663}
 664
 665int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
 666                              struct gpio_desc *desc, int max_count,
 667                              int flags)
 668{
 669        /*
 670         * This isn't ideal since we don't use dev->name in the debug()
 671         * calls in gpio_request_by_name(), but we can do this until
 672         * gpio_request_list_by_name_nodev() can be dropped.
 673         */
 674        return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
 675                                               list_name, desc, max_count,
 676                                               flags);
 677}
 678
 679int gpio_get_list_count(struct udevice *dev, const char *list_name)
 680{
 681        int ret;
 682
 683        ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
 684                                             list_name, "#gpio-cells", 0, -1,
 685                                             NULL);
 686        if (ret) {
 687                debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
 688                      __func__, dev->name, list_name, ret);
 689        }
 690
 691        return ret;
 692}
 693
 694int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
 695{
 696        /* For now, we don't do any checking of dev */
 697        return _dm_gpio_free(desc->dev, desc->offset);
 698}
 699
 700int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
 701{
 702        int i;
 703
 704        /* For now, we don't do any checking of dev */
 705        for (i = 0; i < count; i++)
 706                dm_gpio_free(dev, &desc[i]);
 707
 708        return 0;
 709}
 710
 711int gpio_free_list_nodev(struct gpio_desc *desc, int count)
 712{
 713        return gpio_free_list(NULL, desc, count);
 714}
 715
 716/* We need to renumber the GPIOs when any driver is probed/removed */
 717static int gpio_renumber(struct udevice *removed_dev)
 718{
 719        struct gpio_dev_priv *uc_priv;
 720        struct udevice *dev;
 721        struct uclass *uc;
 722        unsigned base;
 723        int ret;
 724
 725        ret = uclass_get(UCLASS_GPIO, &uc);
 726        if (ret)
 727                return ret;
 728
 729        /* Ensure that we have a base for each bank */
 730        base = 0;
 731        uclass_foreach_dev(dev, uc) {
 732                if (device_active(dev) && dev != removed_dev) {
 733                        uc_priv = dev_get_uclass_priv(dev);
 734                        uc_priv->gpio_base = base;
 735                        base += uc_priv->gpio_count;
 736                }
 737        }
 738
 739        return 0;
 740}
 741
 742int gpio_get_number(struct gpio_desc *desc)
 743{
 744        struct udevice *dev = desc->dev;
 745        struct gpio_dev_priv *uc_priv;
 746
 747        if (!dev)
 748                return -1;
 749        uc_priv = dev->uclass_priv;
 750
 751        return uc_priv->gpio_base + desc->offset;
 752}
 753
 754static int gpio_post_probe(struct udevice *dev)
 755{
 756        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 757
 758        uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
 759        if (!uc_priv->name)
 760                return -ENOMEM;
 761
 762        return gpio_renumber(NULL);
 763}
 764
 765static int gpio_pre_remove(struct udevice *dev)
 766{
 767        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 768        int i;
 769
 770        for (i = 0; i < uc_priv->gpio_count; i++) {
 771                if (uc_priv->name[i])
 772                        free(uc_priv->name[i]);
 773        }
 774        free(uc_priv->name);
 775
 776        return gpio_renumber(dev);
 777}
 778
 779UCLASS_DRIVER(gpio) = {
 780        .id             = UCLASS_GPIO,
 781        .name           = "gpio",
 782        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 783        .post_probe     = gpio_post_probe,
 784        .pre_remove     = gpio_pre_remove,
 785        .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
 786};
 787