linux/drivers/gpio/gpiolib-acpi.c
<<
>>
Prefs
   1/*
   2 * ACPI helpers for GPIO API
   3 *
   4 * Copyright (C) 2012, Intel Corporation
   5 * Authors: Mathias Nyman <mathias.nyman@linux.intel.com>
   6 *          Mika Westerberg <mika.westerberg@linux.intel.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/errno.h>
  14#include <linux/gpio.h>
  15#include <linux/gpio/consumer.h>
  16#include <linux/gpio/driver.h>
  17#include <linux/export.h>
  18#include <linux/acpi.h>
  19#include <linux/interrupt.h>
  20#include <linux/mutex.h>
  21#include <linux/pinctrl/pinctrl.h>
  22
  23#include "gpiolib.h"
  24
  25struct acpi_gpio_event {
  26        struct list_head node;
  27        acpi_handle handle;
  28        unsigned int pin;
  29        unsigned int irq;
  30        struct gpio_desc *desc;
  31};
  32
  33struct acpi_gpio_connection {
  34        struct list_head node;
  35        unsigned int pin;
  36        struct gpio_desc *desc;
  37};
  38
  39struct acpi_gpio_chip {
  40        /*
  41         * ACPICA requires that the first field of the context parameter
  42         * passed to acpi_install_address_space_handler() is large enough
  43         * to hold struct acpi_connection_info.
  44         */
  45        struct acpi_connection_info conn_info;
  46        struct list_head conns;
  47        struct mutex conn_lock;
  48        struct gpio_chip *chip;
  49        struct list_head events;
  50};
  51
  52static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
  53{
  54        if (!gc->dev)
  55                return false;
  56
  57        return ACPI_HANDLE(gc->dev) == data;
  58}
  59
  60#ifdef CONFIG_PINCTRL
  61/**
  62 * acpi_gpiochip_pin_to_gpio_offset() - translates ACPI GPIO to Linux GPIO
  63 * @chip: GPIO chip
  64 * @pin: ACPI GPIO pin number from GpioIo/GpioInt resource
  65 *
  66 * Function takes ACPI GpioIo/GpioInt pin number as a parameter and
  67 * translates it to a corresponding offset suitable to be passed to a
  68 * GPIO controller driver.
  69 *
  70 * Typically the returned offset is same as @pin, but if the GPIO
  71 * controller uses pin controller and the mapping is not contigous the
  72 * offset might be different.
  73 */
  74static int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip, int pin)
  75{
  76        struct gpio_pin_range *pin_range;
  77
  78        /* If there are no ranges in this chip, use 1:1 mapping */
  79        if (list_empty(&chip->pin_ranges))
  80                return pin;
  81
  82        list_for_each_entry(pin_range, &chip->pin_ranges, node) {
  83                const struct pinctrl_gpio_range *range = &pin_range->range;
  84                int i;
  85
  86                if (range->pins) {
  87                        for (i = 0; i < range->npins; i++) {
  88                                if (range->pins[i] == pin)
  89                                        return range->base + i - chip->base;
  90                        }
  91                } else {
  92                        if (pin >= range->pin_base &&
  93                            pin < range->pin_base + range->npins) {
  94                                unsigned gpio_base;
  95
  96                                gpio_base = range->base - chip->base;
  97                                return gpio_base + pin - range->pin_base;
  98                        }
  99                }
 100        }
 101
 102        return -EINVAL;
 103}
 104#else
 105static inline int acpi_gpiochip_pin_to_gpio_offset(struct gpio_chip *chip,
 106                                                   int pin)
 107{
 108        return pin;
 109}
 110#endif
 111
 112/**
 113 * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API
 114 * @path:       ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
 115 * @pin:        ACPI GPIO pin number (0-based, controller-relative)
 116 *
 117 * Returns GPIO descriptor to use with Linux generic GPIO API, or ERR_PTR
 118 * error value
 119 */
 120
 121static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
 122{
 123        struct gpio_chip *chip;
 124        acpi_handle handle;
 125        acpi_status status;
 126        int offset;
 127
 128        status = acpi_get_handle(NULL, path, &handle);
 129        if (ACPI_FAILURE(status))
 130                return ERR_PTR(-ENODEV);
 131
 132        chip = gpiochip_find(handle, acpi_gpiochip_find);
 133        if (!chip)
 134                return ERR_PTR(-ENODEV);
 135
 136        offset = acpi_gpiochip_pin_to_gpio_offset(chip, pin);
 137        if (offset < 0)
 138                return ERR_PTR(offset);
 139
 140        return gpiochip_get_desc(chip, offset);
 141}
 142
 143static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
 144{
 145        struct acpi_gpio_event *event = data;
 146
 147        acpi_evaluate_object(event->handle, NULL, NULL, NULL);
 148
 149        return IRQ_HANDLED;
 150}
 151
 152static irqreturn_t acpi_gpio_irq_handler_evt(int irq, void *data)
 153{
 154        struct acpi_gpio_event *event = data;
 155
 156        acpi_execute_simple_method(event->handle, NULL, event->pin);
 157
 158        return IRQ_HANDLED;
 159}
 160
 161static void acpi_gpio_chip_dh(acpi_handle handle, void *data)
 162{
 163        /* The address of this function is used as a key. */
 164}
 165
 166static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
 167                                                   void *context)
 168{
 169        struct acpi_gpio_chip *acpi_gpio = context;
 170        struct gpio_chip *chip = acpi_gpio->chip;
 171        struct acpi_resource_gpio *agpio;
 172        acpi_handle handle, evt_handle;
 173        struct acpi_gpio_event *event;
 174        irq_handler_t handler = NULL;
 175        struct gpio_desc *desc;
 176        unsigned long irqflags;
 177        int ret, pin, irq;
 178
 179        if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
 180                return AE_OK;
 181
 182        agpio = &ares->data.gpio;
 183        if (agpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_INT)
 184                return AE_OK;
 185
 186        handle = ACPI_HANDLE(chip->dev);
 187        pin = agpio->pin_table[0];
 188
 189        if (pin <= 255) {
 190                char ev_name[5];
 191                sprintf(ev_name, "_%c%02X",
 192                        agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L',
 193                        pin);
 194                if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle)))
 195                        handler = acpi_gpio_irq_handler;
 196        }
 197        if (!handler) {
 198                if (ACPI_SUCCESS(acpi_get_handle(handle, "_EVT", &evt_handle)))
 199                        handler = acpi_gpio_irq_handler_evt;
 200        }
 201        if (!handler)
 202                return AE_BAD_PARAMETER;
 203
 204        desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event");
 205        if (IS_ERR(desc)) {
 206                dev_err(chip->dev, "Failed to request GPIO\n");
 207                return AE_ERROR;
 208        }
 209
 210        gpiod_direction_input(desc);
 211
 212        ret = gpiochip_lock_as_irq(chip, pin);
 213        if (ret) {
 214                dev_err(chip->dev, "Failed to lock GPIO as interrupt\n");
 215                goto fail_free_desc;
 216        }
 217
 218        irq = gpiod_to_irq(desc);
 219        if (irq < 0) {
 220                dev_err(chip->dev, "Failed to translate GPIO to IRQ\n");
 221                goto fail_unlock_irq;
 222        }
 223
 224        irqflags = IRQF_ONESHOT;
 225        if (agpio->triggering == ACPI_LEVEL_SENSITIVE) {
 226                if (agpio->polarity == ACPI_ACTIVE_HIGH)
 227                        irqflags |= IRQF_TRIGGER_HIGH;
 228                else
 229                        irqflags |= IRQF_TRIGGER_LOW;
 230        } else {
 231                switch (agpio->polarity) {
 232                case ACPI_ACTIVE_HIGH:
 233                        irqflags |= IRQF_TRIGGER_RISING;
 234                        break;
 235                case ACPI_ACTIVE_LOW:
 236                        irqflags |= IRQF_TRIGGER_FALLING;
 237                        break;
 238                default:
 239                        irqflags |= IRQF_TRIGGER_RISING |
 240                                    IRQF_TRIGGER_FALLING;
 241                        break;
 242                }
 243        }
 244
 245        event = kzalloc(sizeof(*event), GFP_KERNEL);
 246        if (!event)
 247                goto fail_unlock_irq;
 248
 249        event->handle = evt_handle;
 250        event->irq = irq;
 251        event->pin = pin;
 252        event->desc = desc;
 253
 254        ret = request_threaded_irq(event->irq, NULL, handler, irqflags,
 255                                   "ACPI:Event", event);
 256        if (ret) {
 257                dev_err(chip->dev, "Failed to setup interrupt handler for %d\n",
 258                        event->irq);
 259                goto fail_free_event;
 260        }
 261
 262        list_add_tail(&event->node, &acpi_gpio->events);
 263        return AE_OK;
 264
 265fail_free_event:
 266        kfree(event);
 267fail_unlock_irq:
 268        gpiochip_unlock_as_irq(chip, pin);
 269fail_free_desc:
 270        gpiochip_free_own_desc(desc);
 271
 272        return AE_ERROR;
 273}
 274
 275/**
 276 * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
 277 * @chip:      GPIO chip
 278 *
 279 * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
 280 * handled by ACPI event methods which need to be called from the GPIO
 281 * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which
 282 * gpio pins have acpi event methods and assigns interrupt handlers that calls
 283 * the acpi event methods for those pins.
 284 */
 285void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
 286{
 287        struct acpi_gpio_chip *acpi_gpio;
 288        acpi_handle handle;
 289        acpi_status status;
 290
 291        if (!chip->dev || !chip->to_irq)
 292                return;
 293
 294        handle = ACPI_HANDLE(chip->dev);
 295        if (!handle)
 296                return;
 297
 298        status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
 299        if (ACPI_FAILURE(status))
 300                return;
 301
 302        INIT_LIST_HEAD(&acpi_gpio->events);
 303        acpi_walk_resources(ACPI_HANDLE(chip->dev), "_AEI",
 304                            acpi_gpiochip_request_interrupt, acpi_gpio);
 305}
 306
 307/**
 308 * acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts.
 309 * @chip:      GPIO chip
 310 *
 311 * Free interrupts associated with GPIO ACPI event method for the given
 312 * GPIO chip.
 313 */
 314void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
 315{
 316        struct acpi_gpio_chip *acpi_gpio;
 317        struct acpi_gpio_event *event, *ep;
 318        acpi_handle handle;
 319        acpi_status status;
 320
 321        if (!chip->dev || !chip->to_irq)
 322                return;
 323
 324        handle = ACPI_HANDLE(chip->dev);
 325        if (!handle)
 326                return;
 327
 328        status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
 329        if (ACPI_FAILURE(status))
 330                return;
 331
 332        list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
 333                struct gpio_desc *desc;
 334
 335                free_irq(event->irq, event);
 336                desc = event->desc;
 337                if (WARN_ON(IS_ERR(desc)))
 338                        continue;
 339                gpiochip_unlock_as_irq(chip, event->pin);
 340                gpiochip_free_own_desc(desc);
 341                list_del(&event->node);
 342                kfree(event);
 343        }
 344}
 345
 346int acpi_dev_add_driver_gpios(struct acpi_device *adev,
 347                              const struct acpi_gpio_mapping *gpios)
 348{
 349        if (adev && gpios) {
 350                adev->driver_gpios = gpios;
 351                return 0;
 352        }
 353        return -EINVAL;
 354}
 355EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
 356
 357static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
 358                                      const char *name, int index,
 359                                      struct acpi_reference_args *args)
 360{
 361        const struct acpi_gpio_mapping *gm;
 362
 363        if (!adev->driver_gpios)
 364                return false;
 365
 366        for (gm = adev->driver_gpios; gm->name; gm++)
 367                if (!strcmp(name, gm->name) && gm->data && index < gm->size) {
 368                        const struct acpi_gpio_params *par = gm->data + index;
 369
 370                        args->adev = adev;
 371                        args->args[0] = par->crs_entry_index;
 372                        args->args[1] = par->line_index;
 373                        args->args[2] = par->active_low;
 374                        args->nargs = 3;
 375                        return true;
 376                }
 377
 378        return false;
 379}
 380
 381struct acpi_gpio_lookup {
 382        struct acpi_gpio_info info;
 383        int index;
 384        int pin_index;
 385        struct gpio_desc *desc;
 386        int n;
 387};
 388
 389static int acpi_find_gpio(struct acpi_resource *ares, void *data)
 390{
 391        struct acpi_gpio_lookup *lookup = data;
 392
 393        if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
 394                return 1;
 395
 396        if (lookup->n++ == lookup->index && !lookup->desc) {
 397                const struct acpi_resource_gpio *agpio = &ares->data.gpio;
 398                int pin_index = lookup->pin_index;
 399
 400                if (pin_index >= agpio->pin_table_length)
 401                        return 1;
 402
 403                lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr,
 404                                              agpio->pin_table[pin_index]);
 405                lookup->info.gpioint =
 406                        agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT;
 407
 408                /*
 409                 * ActiveLow is only specified for GpioInt resource. If
 410                 * GpioIo is used then the only way to set the flag is
 411                 * to use _DSD "gpios" property.
 412                 */
 413                if (lookup->info.gpioint)
 414                        lookup->info.active_low =
 415                                agpio->polarity == ACPI_ACTIVE_LOW;
 416        }
 417
 418        return 1;
 419}
 420
 421/**
 422 * acpi_get_gpiod_by_index() - get a GPIO descriptor from device resources
 423 * @adev: pointer to a ACPI device to get GPIO from
 424 * @propname: Property name of the GPIO (optional)
 425 * @index: index of GpioIo/GpioInt resource (starting from %0)
 426 * @info: info pointer to fill in (optional)
 427 *
 428 * Function goes through ACPI resources for @adev and based on @index looks
 429 * up a GpioIo/GpioInt resource, translates it to the Linux GPIO descriptor,
 430 * and returns it. @index matches GpioIo/GpioInt resources only so if there
 431 * are total %3 GPIO resources, the index goes from %0 to %2.
 432 *
 433 * If @propname is specified the GPIO is looked using device property. In
 434 * that case @index is used to select the GPIO entry in the property value
 435 * (in case of multiple).
 436 *
 437 * If the GPIO cannot be translated or there is an error an ERR_PTR is
 438 * returned.
 439 *
 440 * Note: if the GPIO resource has multiple entries in the pin list, this
 441 * function only returns the first.
 442 */
 443struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
 444                                          const char *propname, int index,
 445                                          struct acpi_gpio_info *info)
 446{
 447        struct acpi_gpio_lookup lookup;
 448        struct list_head resource_list;
 449        bool active_low = false;
 450        int ret;
 451
 452        if (!adev)
 453                return ERR_PTR(-ENODEV);
 454
 455        memset(&lookup, 0, sizeof(lookup));
 456        lookup.index = index;
 457
 458        if (propname) {
 459                struct acpi_reference_args args;
 460
 461                dev_dbg(&adev->dev, "GPIO: looking up %s\n", propname);
 462
 463                memset(&args, 0, sizeof(args));
 464                ret = acpi_dev_get_property_reference(adev, propname,
 465                                                      index, &args);
 466                if (ret) {
 467                        bool found = acpi_get_driver_gpio_data(adev, propname,
 468                                                               index, &args);
 469                        if (!found)
 470                                return ERR_PTR(ret);
 471                }
 472
 473                /*
 474                 * The property was found and resolved so need to
 475                 * lookup the GPIO based on returned args instead.
 476                 */
 477                adev = args.adev;
 478                if (args.nargs >= 2) {
 479                        lookup.index = args.args[0];
 480                        lookup.pin_index = args.args[1];
 481                        /*
 482                         * 3rd argument, if present is used to
 483                         * specify active_low.
 484                         */
 485                        if (args.nargs >= 3)
 486                                active_low = !!args.args[2];
 487                }
 488
 489                dev_dbg(&adev->dev, "GPIO: _DSD returned %s %zd %llu %llu %llu\n",
 490                        dev_name(&adev->dev), args.nargs,
 491                        args.args[0], args.args[1], args.args[2]);
 492        } else {
 493                dev_dbg(&adev->dev, "GPIO: looking up %d in _CRS\n", index);
 494        }
 495
 496        INIT_LIST_HEAD(&resource_list);
 497        ret = acpi_dev_get_resources(adev, &resource_list, acpi_find_gpio,
 498                                     &lookup);
 499        if (ret < 0)
 500                return ERR_PTR(ret);
 501
 502        acpi_dev_free_resource_list(&resource_list);
 503
 504        if (lookup.desc && info) {
 505                *info = lookup.info;
 506                if (active_low)
 507                        info->active_low = active_low;
 508        }
 509
 510        return lookup.desc ? lookup.desc : ERR_PTR(-ENOENT);
 511}
 512
 513static acpi_status
 514acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
 515                            u32 bits, u64 *value, void *handler_context,
 516                            void *region_context)
 517{
 518        struct acpi_gpio_chip *achip = region_context;
 519        struct gpio_chip *chip = achip->chip;
 520        struct acpi_resource_gpio *agpio;
 521        struct acpi_resource *ares;
 522        int pin_index = (int)address;
 523        acpi_status status;
 524        bool pull_up;
 525        int length;
 526        int i;
 527
 528        status = acpi_buffer_to_resource(achip->conn_info.connection,
 529                                         achip->conn_info.length, &ares);
 530        if (ACPI_FAILURE(status))
 531                return status;
 532
 533        if (WARN_ON(ares->type != ACPI_RESOURCE_TYPE_GPIO)) {
 534                ACPI_FREE(ares);
 535                return AE_BAD_PARAMETER;
 536        }
 537
 538        agpio = &ares->data.gpio;
 539        pull_up = agpio->pin_config == ACPI_PIN_CONFIG_PULLUP;
 540
 541        if (WARN_ON(agpio->io_restriction == ACPI_IO_RESTRICT_INPUT &&
 542            function == ACPI_WRITE)) {
 543                ACPI_FREE(ares);
 544                return AE_BAD_PARAMETER;
 545        }
 546
 547        length = min(agpio->pin_table_length, (u16)(pin_index + bits));
 548        for (i = pin_index; i < length; ++i) {
 549                unsigned pin = agpio->pin_table[i];
 550                struct acpi_gpio_connection *conn;
 551                struct gpio_desc *desc;
 552                bool found;
 553
 554                mutex_lock(&achip->conn_lock);
 555
 556                found = false;
 557                list_for_each_entry(conn, &achip->conns, node) {
 558                        if (conn->pin == pin) {
 559                                found = true;
 560                                desc = conn->desc;
 561                                break;
 562                        }
 563                }
 564                if (!found) {
 565                        desc = gpiochip_request_own_desc(chip, pin,
 566                                                         "ACPI:OpRegion");
 567                        if (IS_ERR(desc)) {
 568                                status = AE_ERROR;
 569                                mutex_unlock(&achip->conn_lock);
 570                                goto out;
 571                        }
 572
 573                        switch (agpio->io_restriction) {
 574                        case ACPI_IO_RESTRICT_INPUT:
 575                                gpiod_direction_input(desc);
 576                                break;
 577                        case ACPI_IO_RESTRICT_OUTPUT:
 578                                /*
 579                                 * ACPI GPIO resources don't contain an
 580                                 * initial value for the GPIO. Therefore we
 581                                 * deduce that value from the pull field
 582                                 * instead. If the pin is pulled up we
 583                                 * assume default to be high, otherwise
 584                                 * low.
 585                                 */
 586                                gpiod_direction_output(desc, pull_up);
 587                                break;
 588                        default:
 589                                /*
 590                                 * Assume that the BIOS has configured the
 591                                 * direction and pull accordingly.
 592                                 */
 593                                break;
 594                        }
 595
 596                        conn = kzalloc(sizeof(*conn), GFP_KERNEL);
 597                        if (!conn) {
 598                                status = AE_NO_MEMORY;
 599                                gpiochip_free_own_desc(desc);
 600                                mutex_unlock(&achip->conn_lock);
 601                                goto out;
 602                        }
 603
 604                        conn->pin = pin;
 605                        conn->desc = desc;
 606                        list_add_tail(&conn->node, &achip->conns);
 607                }
 608
 609                mutex_unlock(&achip->conn_lock);
 610
 611                if (function == ACPI_WRITE)
 612                        gpiod_set_raw_value_cansleep(desc,
 613                                                     !!((1 << i) & *value));
 614                else
 615                        *value |= (u64)gpiod_get_raw_value_cansleep(desc) << i;
 616        }
 617
 618out:
 619        ACPI_FREE(ares);
 620        return status;
 621}
 622
 623static void acpi_gpiochip_request_regions(struct acpi_gpio_chip *achip)
 624{
 625        struct gpio_chip *chip = achip->chip;
 626        acpi_handle handle = ACPI_HANDLE(chip->dev);
 627        acpi_status status;
 628
 629        INIT_LIST_HEAD(&achip->conns);
 630        mutex_init(&achip->conn_lock);
 631        status = acpi_install_address_space_handler(handle, ACPI_ADR_SPACE_GPIO,
 632                                                    acpi_gpio_adr_space_handler,
 633                                                    NULL, achip);
 634        if (ACPI_FAILURE(status))
 635                dev_err(chip->dev, "Failed to install GPIO OpRegion handler\n");
 636}
 637
 638static void acpi_gpiochip_free_regions(struct acpi_gpio_chip *achip)
 639{
 640        struct gpio_chip *chip = achip->chip;
 641        acpi_handle handle = ACPI_HANDLE(chip->dev);
 642        struct acpi_gpio_connection *conn, *tmp;
 643        acpi_status status;
 644
 645        status = acpi_remove_address_space_handler(handle, ACPI_ADR_SPACE_GPIO,
 646                                                   acpi_gpio_adr_space_handler);
 647        if (ACPI_FAILURE(status)) {
 648                dev_err(chip->dev, "Failed to remove GPIO OpRegion handler\n");
 649                return;
 650        }
 651
 652        list_for_each_entry_safe_reverse(conn, tmp, &achip->conns, node) {
 653                gpiochip_free_own_desc(conn->desc);
 654                list_del(&conn->node);
 655                kfree(conn);
 656        }
 657}
 658
 659void acpi_gpiochip_add(struct gpio_chip *chip)
 660{
 661        struct acpi_gpio_chip *acpi_gpio;
 662        acpi_handle handle;
 663        acpi_status status;
 664
 665        if (!chip || !chip->dev)
 666                return;
 667
 668        handle = ACPI_HANDLE(chip->dev);
 669        if (!handle)
 670                return;
 671
 672        acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
 673        if (!acpi_gpio) {
 674                dev_err(chip->dev,
 675                        "Failed to allocate memory for ACPI GPIO chip\n");
 676                return;
 677        }
 678
 679        acpi_gpio->chip = chip;
 680
 681        status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
 682        if (ACPI_FAILURE(status)) {
 683                dev_err(chip->dev, "Failed to attach ACPI GPIO chip\n");
 684                kfree(acpi_gpio);
 685                return;
 686        }
 687
 688        acpi_gpiochip_request_regions(acpi_gpio);
 689}
 690
 691void acpi_gpiochip_remove(struct gpio_chip *chip)
 692{
 693        struct acpi_gpio_chip *acpi_gpio;
 694        acpi_handle handle;
 695        acpi_status status;
 696
 697        if (!chip || !chip->dev)
 698                return;
 699
 700        handle = ACPI_HANDLE(chip->dev);
 701        if (!handle)
 702                return;
 703
 704        status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
 705        if (ACPI_FAILURE(status)) {
 706                dev_warn(chip->dev, "Failed to retrieve ACPI GPIO chip\n");
 707                return;
 708        }
 709
 710        acpi_gpiochip_free_regions(acpi_gpio);
 711
 712        acpi_detach_data(handle, acpi_gpio_chip_dh);
 713        kfree(acpi_gpio);
 714}
 715