linux/drivers/pnp/pnpacpi/rsparser.c
<<
>>
Prefs
   1/*
   2 * pnpacpi -- PnP ACPI driver
   3 *
   4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
   5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
   6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
   7 *      Bjorn Helgaas <bjorn.helgaas@hp.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of the GNU General Public License as published by the
  11 * Free Software Foundation; either version 2, or (at your option) any
  12 * later version.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 */
  19#include <linux/kernel.h>
  20#include <linux/acpi.h>
  21#include <linux/pci.h>
  22#include <linux/pnp.h>
  23#include <linux/slab.h>
  24#include "../base.h"
  25#include "pnpacpi.h"
  26
  27static void decode_irq_flags(struct pnp_dev *dev, int flags, u8 *triggering,
  28                             u8 *polarity, u8 *shareable)
  29{
  30        switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL |
  31                         IORESOURCE_IRQ_LOWEDGE  | IORESOURCE_IRQ_HIGHEDGE)) {
  32        case IORESOURCE_IRQ_LOWLEVEL:
  33                *triggering = ACPI_LEVEL_SENSITIVE;
  34                *polarity = ACPI_ACTIVE_LOW;
  35                break;
  36        case IORESOURCE_IRQ_HIGHLEVEL:
  37                *triggering = ACPI_LEVEL_SENSITIVE;
  38                *polarity = ACPI_ACTIVE_HIGH;
  39                break;
  40        case IORESOURCE_IRQ_LOWEDGE:
  41                *triggering = ACPI_EDGE_SENSITIVE;
  42                *polarity = ACPI_ACTIVE_LOW;
  43                break;
  44        case IORESOURCE_IRQ_HIGHEDGE:
  45                *triggering = ACPI_EDGE_SENSITIVE;
  46                *polarity = ACPI_ACTIVE_HIGH;
  47                break;
  48        default:
  49                dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n",
  50                        flags);
  51                *triggering = ACPI_EDGE_SENSITIVE;
  52                *polarity = ACPI_ACTIVE_HIGH;
  53                break;
  54        }
  55
  56        if (flags & IORESOURCE_IRQ_SHAREABLE)
  57                *shareable = ACPI_SHARED;
  58        else
  59                *shareable = ACPI_EXCLUSIVE;
  60}
  61
  62static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
  63                     int transfer)
  64{
  65        int flags = 0;
  66
  67        if (bus_master)
  68                flags |= IORESOURCE_DMA_MASTER;
  69        switch (type) {
  70        case ACPI_COMPATIBILITY:
  71                flags |= IORESOURCE_DMA_COMPATIBLE;
  72                break;
  73        case ACPI_TYPE_A:
  74                flags |= IORESOURCE_DMA_TYPEA;
  75                break;
  76        case ACPI_TYPE_B:
  77                flags |= IORESOURCE_DMA_TYPEB;
  78                break;
  79        case ACPI_TYPE_F:
  80                flags |= IORESOURCE_DMA_TYPEF;
  81                break;
  82        default:
  83                /* Set a default value ? */
  84                flags |= IORESOURCE_DMA_COMPATIBLE;
  85                dev_err(&dev->dev, "invalid DMA type %d\n", type);
  86        }
  87        switch (transfer) {
  88        case ACPI_TRANSFER_8:
  89                flags |= IORESOURCE_DMA_8BIT;
  90                break;
  91        case ACPI_TRANSFER_8_16:
  92                flags |= IORESOURCE_DMA_8AND16BIT;
  93                break;
  94        case ACPI_TRANSFER_16:
  95                flags |= IORESOURCE_DMA_16BIT;
  96                break;
  97        default:
  98                /* Set a default value ? */
  99                flags |= IORESOURCE_DMA_8AND16BIT;
 100                dev_err(&dev->dev, "invalid DMA transfer type %d\n", transfer);
 101        }
 102
 103        return flags;
 104}
 105
 106/*
 107 * Allocated Resources
 108 */
 109
 110static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r)
 111{
 112        if (!(r->flags & IORESOURCE_DISABLED))
 113                pcibios_penalize_isa_irq(r->start, 1);
 114
 115        pnp_add_resource(dev, r);
 116}
 117
 118/*
 119 * Device CSRs that do not appear in PCI config space should be described
 120 * via ACPI.  This would normally be done with Address Space Descriptors
 121 * marked as "consumer-only," but old versions of Windows and Linux ignore
 122 * the producer/consumer flag, so HP invented a vendor-defined resource to
 123 * describe the location and size of CSR space.
 124 */
 125static struct acpi_vendor_uuid hp_ccsr_uuid = {
 126        .subtype = 2,
 127        .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
 128            0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
 129};
 130
 131static int vendor_resource_matches(struct pnp_dev *dev,
 132                                   struct acpi_resource_vendor_typed *vendor,
 133                                   struct acpi_vendor_uuid *match,
 134                                   int expected_len)
 135{
 136        int uuid_len = sizeof(vendor->uuid);
 137        u8 uuid_subtype = vendor->uuid_subtype;
 138        u8 *uuid = vendor->uuid;
 139        int actual_len;
 140
 141        /* byte_length includes uuid_subtype and uuid */
 142        actual_len = vendor->byte_length - uuid_len - 1;
 143
 144        if (uuid_subtype == match->subtype &&
 145            uuid_len == sizeof(match->data) &&
 146            memcmp(uuid, match->data, uuid_len) == 0) {
 147                if (expected_len && expected_len != actual_len) {
 148                        dev_err(&dev->dev,
 149                                "wrong vendor descriptor size; expected %d, found %d bytes\n",
 150                                expected_len, actual_len);
 151                        return 0;
 152                }
 153
 154                return 1;
 155        }
 156
 157        return 0;
 158}
 159
 160static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
 161                                    struct acpi_resource_vendor_typed *vendor)
 162{
 163        if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) {
 164                u64 start, length;
 165
 166                memcpy(&start, vendor->byte_data, sizeof(start));
 167                memcpy(&length, vendor->byte_data + 8, sizeof(length));
 168
 169                pnp_add_mem_resource(dev, start, start + length - 1, 0);
 170        }
 171}
 172
 173static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
 174                                              void *data)
 175{
 176        struct pnp_dev *dev = data;
 177        struct acpi_resource_dma *dma;
 178        struct acpi_resource_vendor_typed *vendor_typed;
 179        struct acpi_resource_gpio *gpio;
 180        struct resource_win win = {{0}, 0};
 181        struct resource *r = &win.res;
 182        int i, flags;
 183
 184        if (acpi_dev_resource_address_space(res, &win)
 185            || acpi_dev_resource_ext_address_space(res, &win)) {
 186                pnp_add_resource(dev, &win.res);
 187                return AE_OK;
 188        }
 189
 190        r->flags = 0;
 191        if (acpi_dev_resource_interrupt(res, 0, r)) {
 192                pnpacpi_add_irqresource(dev, r);
 193                for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
 194                        pnpacpi_add_irqresource(dev, r);
 195
 196                if (i > 1) {
 197                        /*
 198                         * The IRQ encoder puts a single interrupt in each
 199                         * descriptor, so if a _CRS descriptor has more than
 200                         * one interrupt, we won't be able to re-encode it.
 201                         */
 202                        if (pnp_can_write(dev)) {
 203                                dev_warn(&dev->dev,
 204                                         "multiple interrupts in _CRS descriptor; configuration can't be changed\n");
 205                                dev->capabilities &= ~PNP_WRITE;
 206                        }
 207                }
 208                return AE_OK;
 209        } else if (acpi_gpio_get_irq_resource(res, &gpio)) {
 210                /*
 211                 * If the resource is GpioInt() type then extract the IRQ
 212                 * from GPIO resource and fill it into IRQ resource type.
 213                 */
 214                i = acpi_dev_gpio_irq_get(dev->data, 0);
 215                if (i >= 0) {
 216                        flags = acpi_dev_irq_flags(gpio->triggering,
 217                                                   gpio->polarity,
 218                                                   gpio->sharable);
 219                } else {
 220                        flags = IORESOURCE_DISABLED;
 221                }
 222                pnp_add_irq_resource(dev, i, flags);
 223                return AE_OK;
 224        } else if (r->flags & IORESOURCE_DISABLED) {
 225                pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
 226                return AE_OK;
 227        }
 228
 229        switch (res->type) {
 230        case ACPI_RESOURCE_TYPE_MEMORY24:
 231        case ACPI_RESOURCE_TYPE_MEMORY32:
 232        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 233                if (acpi_dev_resource_memory(res, r))
 234                        pnp_add_resource(dev, r);
 235                break;
 236        case ACPI_RESOURCE_TYPE_IO:
 237        case ACPI_RESOURCE_TYPE_FIXED_IO:
 238                if (acpi_dev_resource_io(res, r))
 239                        pnp_add_resource(dev, r);
 240                break;
 241        case ACPI_RESOURCE_TYPE_DMA:
 242                dma = &res->data.dma;
 243                if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
 244                        flags = dma_flags(dev, dma->type, dma->bus_master,
 245                                          dma->transfer);
 246                else
 247                        flags = IORESOURCE_DISABLED;
 248                pnp_add_dma_resource(dev, dma->channels[0], flags);
 249                break;
 250
 251        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 252        case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 253                break;
 254
 255        case ACPI_RESOURCE_TYPE_VENDOR:
 256                vendor_typed = &res->data.vendor_typed;
 257                pnpacpi_parse_allocated_vendor(dev, vendor_typed);
 258                break;
 259
 260        case ACPI_RESOURCE_TYPE_END_TAG:
 261                break;
 262
 263        case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 264                break;
 265
 266        case ACPI_RESOURCE_TYPE_SERIAL_BUS:
 267                /* serial bus connections (I2C/SPI/UART) are not pnp */
 268                break;
 269
 270        default:
 271                dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
 272                         res->type);
 273                return AE_ERROR;
 274        }
 275
 276        return AE_OK;
 277}
 278
 279int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
 280{
 281        struct acpi_device *acpi_dev = dev->data;
 282        acpi_handle handle = acpi_dev->handle;
 283        acpi_status status;
 284
 285        pnp_dbg(&dev->dev, "parse allocated resources\n");
 286
 287        pnp_init_resources(dev);
 288
 289        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 290                                     pnpacpi_allocated_resource, dev);
 291
 292        if (ACPI_FAILURE(status)) {
 293                if (status != AE_NOT_FOUND)
 294                        dev_err(&dev->dev, "can't evaluate _CRS: %d", status);
 295                return -EPERM;
 296        }
 297        return 0;
 298}
 299
 300static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
 301                                            unsigned int option_flags,
 302                                            struct acpi_resource_dma *p)
 303{
 304        int i;
 305        unsigned char map = 0, flags;
 306
 307        for (i = 0; i < p->channel_count; i++)
 308                map |= 1 << p->channels[i];
 309
 310        flags = dma_flags(dev, p->type, p->bus_master, p->transfer);
 311        pnp_register_dma_resource(dev, option_flags, map, flags);
 312}
 313
 314static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
 315                                            unsigned int option_flags,
 316                                            struct acpi_resource_irq *p)
 317{
 318        int i;
 319        pnp_irq_mask_t map;
 320        unsigned char flags;
 321
 322        bitmap_zero(map.bits, PNP_IRQ_NR);
 323        for (i = 0; i < p->interrupt_count; i++)
 324                if (p->interrupts[i])
 325                        __set_bit(p->interrupts[i], map.bits);
 326
 327        flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 328        pnp_register_irq_resource(dev, option_flags, &map, flags);
 329}
 330
 331static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
 332                                        unsigned int option_flags,
 333                                        struct acpi_resource_extended_irq *p)
 334{
 335        int i;
 336        pnp_irq_mask_t map;
 337        unsigned char flags;
 338
 339        bitmap_zero(map.bits, PNP_IRQ_NR);
 340        for (i = 0; i < p->interrupt_count; i++) {
 341                if (p->interrupts[i]) {
 342                        if (p->interrupts[i] < PNP_IRQ_NR)
 343                                __set_bit(p->interrupts[i], map.bits);
 344                        else
 345                                dev_err(&dev->dev,
 346                                        "ignoring IRQ %d option (too large for %d entry bitmap)\n",
 347                                        p->interrupts[i], PNP_IRQ_NR);
 348                }
 349        }
 350
 351        flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 352        pnp_register_irq_resource(dev, option_flags, &map, flags);
 353}
 354
 355static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
 356                                             unsigned int option_flags,
 357                                             struct acpi_resource_io *io)
 358{
 359        unsigned char flags = 0;
 360
 361        if (io->io_decode == ACPI_DECODE_16)
 362                flags = IORESOURCE_IO_16BIT_ADDR;
 363        pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
 364                                   io->alignment, io->address_length, flags);
 365}
 366
 367static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
 368                                        unsigned int option_flags,
 369                                        struct acpi_resource_fixed_io *io)
 370{
 371        pnp_register_port_resource(dev, option_flags, io->address, io->address,
 372                                   0, io->address_length, IORESOURCE_IO_FIXED);
 373}
 374
 375static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
 376                                              unsigned int option_flags,
 377                                              struct acpi_resource_memory24 *p)
 378{
 379        unsigned char flags = 0;
 380
 381        if (p->write_protect == ACPI_READ_WRITE_MEMORY)
 382                flags = IORESOURCE_MEM_WRITEABLE;
 383        pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
 384                                  p->alignment, p->address_length, flags);
 385}
 386
 387static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
 388                                              unsigned int option_flags,
 389                                              struct acpi_resource_memory32 *p)
 390{
 391        unsigned char flags = 0;
 392
 393        if (p->write_protect == ACPI_READ_WRITE_MEMORY)
 394                flags = IORESOURCE_MEM_WRITEABLE;
 395        pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
 396                                  p->alignment, p->address_length, flags);
 397}
 398
 399static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
 400                                        unsigned int option_flags,
 401                                        struct acpi_resource_fixed_memory32 *p)
 402{
 403        unsigned char flags = 0;
 404
 405        if (p->write_protect == ACPI_READ_WRITE_MEMORY)
 406                flags = IORESOURCE_MEM_WRITEABLE;
 407        pnp_register_mem_resource(dev, option_flags, p->address, p->address,
 408                                  0, p->address_length, flags);
 409}
 410
 411static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
 412                                                unsigned int option_flags,
 413                                                struct acpi_resource *r)
 414{
 415        struct acpi_resource_address64 addr, *p = &addr;
 416        acpi_status status;
 417        unsigned char flags = 0;
 418
 419        status = acpi_resource_to_address64(r, p);
 420        if (ACPI_FAILURE(status)) {
 421                dev_warn(&dev->dev, "can't convert resource type %d\n",
 422                         r->type);
 423                return;
 424        }
 425
 426        if (p->resource_type == ACPI_MEMORY_RANGE) {
 427                if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
 428                        flags = IORESOURCE_MEM_WRITEABLE;
 429                pnp_register_mem_resource(dev, option_flags, p->address.minimum,
 430                                          p->address.minimum, 0, p->address.address_length,
 431                                          flags);
 432        } else if (p->resource_type == ACPI_IO_RANGE)
 433                pnp_register_port_resource(dev, option_flags, p->address.minimum,
 434                                           p->address.minimum, 0, p->address.address_length,
 435                                           IORESOURCE_IO_FIXED);
 436}
 437
 438static __init void pnpacpi_parse_ext_address_option(struct pnp_dev *dev,
 439                                                    unsigned int option_flags,
 440                                                    struct acpi_resource *r)
 441{
 442        struct acpi_resource_extended_address64 *p = &r->data.ext_address64;
 443        unsigned char flags = 0;
 444
 445        if (p->resource_type == ACPI_MEMORY_RANGE) {
 446                if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
 447                        flags = IORESOURCE_MEM_WRITEABLE;
 448                pnp_register_mem_resource(dev, option_flags, p->address.minimum,
 449                                          p->address.minimum, 0, p->address.address_length,
 450                                          flags);
 451        } else if (p->resource_type == ACPI_IO_RANGE)
 452                pnp_register_port_resource(dev, option_flags, p->address.minimum,
 453                                           p->address.minimum, 0, p->address.address_length,
 454                                           IORESOURCE_IO_FIXED);
 455}
 456
 457struct acpipnp_parse_option_s {
 458        struct pnp_dev *dev;
 459        unsigned int option_flags;
 460};
 461
 462static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
 463                                                  void *data)
 464{
 465        int priority;
 466        struct acpipnp_parse_option_s *parse_data = data;
 467        struct pnp_dev *dev = parse_data->dev;
 468        unsigned int option_flags = parse_data->option_flags;
 469
 470        switch (res->type) {
 471        case ACPI_RESOURCE_TYPE_IRQ:
 472                pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
 473                break;
 474
 475        case ACPI_RESOURCE_TYPE_DMA:
 476                pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
 477                break;
 478
 479        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 480                switch (res->data.start_dpf.compatibility_priority) {
 481                case ACPI_GOOD_CONFIGURATION:
 482                        priority = PNP_RES_PRIORITY_PREFERRED;
 483                        break;
 484
 485                case ACPI_ACCEPTABLE_CONFIGURATION:
 486                        priority = PNP_RES_PRIORITY_ACCEPTABLE;
 487                        break;
 488
 489                case ACPI_SUB_OPTIMAL_CONFIGURATION:
 490                        priority = PNP_RES_PRIORITY_FUNCTIONAL;
 491                        break;
 492                default:
 493                        priority = PNP_RES_PRIORITY_INVALID;
 494                        break;
 495                }
 496                parse_data->option_flags = pnp_new_dependent_set(dev, priority);
 497                break;
 498
 499        case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 500                parse_data->option_flags = 0;
 501                break;
 502
 503        case ACPI_RESOURCE_TYPE_IO:
 504                pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
 505                break;
 506
 507        case ACPI_RESOURCE_TYPE_FIXED_IO:
 508                pnpacpi_parse_fixed_port_option(dev, option_flags,
 509                                                &res->data.fixed_io);
 510                break;
 511
 512        case ACPI_RESOURCE_TYPE_VENDOR:
 513        case ACPI_RESOURCE_TYPE_END_TAG:
 514                break;
 515
 516        case ACPI_RESOURCE_TYPE_MEMORY24:
 517                pnpacpi_parse_mem24_option(dev, option_flags,
 518                                           &res->data.memory24);
 519                break;
 520
 521        case ACPI_RESOURCE_TYPE_MEMORY32:
 522                pnpacpi_parse_mem32_option(dev, option_flags,
 523                                           &res->data.memory32);
 524                break;
 525
 526        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 527                pnpacpi_parse_fixed_mem32_option(dev, option_flags,
 528                                                 &res->data.fixed_memory32);
 529                break;
 530
 531        case ACPI_RESOURCE_TYPE_ADDRESS16:
 532        case ACPI_RESOURCE_TYPE_ADDRESS32:
 533        case ACPI_RESOURCE_TYPE_ADDRESS64:
 534                pnpacpi_parse_address_option(dev, option_flags, res);
 535                break;
 536
 537        case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
 538                pnpacpi_parse_ext_address_option(dev, option_flags, res);
 539                break;
 540
 541        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 542                pnpacpi_parse_ext_irq_option(dev, option_flags,
 543                                             &res->data.extended_irq);
 544                break;
 545
 546        case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 547                break;
 548
 549        default:
 550                dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
 551                         res->type);
 552                return AE_ERROR;
 553        }
 554
 555        return AE_OK;
 556}
 557
 558int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
 559{
 560        struct acpi_device *acpi_dev = dev->data;
 561        acpi_handle handle = acpi_dev->handle;
 562        acpi_status status;
 563        struct acpipnp_parse_option_s parse_data;
 564
 565        pnp_dbg(&dev->dev, "parse resource options\n");
 566
 567        parse_data.dev = dev;
 568        parse_data.option_flags = 0;
 569
 570        status = acpi_walk_resources(handle, METHOD_NAME__PRS,
 571                                     pnpacpi_option_resource, &parse_data);
 572
 573        if (ACPI_FAILURE(status)) {
 574                if (status != AE_NOT_FOUND)
 575                        dev_err(&dev->dev, "can't evaluate _PRS: %d", status);
 576                return -EPERM;
 577        }
 578        return 0;
 579}
 580
 581static int pnpacpi_supported_resource(struct acpi_resource *res)
 582{
 583        switch (res->type) {
 584        case ACPI_RESOURCE_TYPE_IRQ:
 585        case ACPI_RESOURCE_TYPE_DMA:
 586        case ACPI_RESOURCE_TYPE_IO:
 587        case ACPI_RESOURCE_TYPE_FIXED_IO:
 588        case ACPI_RESOURCE_TYPE_MEMORY24:
 589        case ACPI_RESOURCE_TYPE_MEMORY32:
 590        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 591        case ACPI_RESOURCE_TYPE_ADDRESS16:
 592        case ACPI_RESOURCE_TYPE_ADDRESS32:
 593        case ACPI_RESOURCE_TYPE_ADDRESS64:
 594        case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
 595        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 596                return 1;
 597        }
 598        return 0;
 599}
 600
 601/*
 602 * Set resource
 603 */
 604static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
 605                                           void *data)
 606{
 607        int *res_cnt = data;
 608
 609        if (pnpacpi_supported_resource(res))
 610                (*res_cnt)++;
 611        return AE_OK;
 612}
 613
 614static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
 615{
 616        struct acpi_resource **resource = data;
 617
 618        if (pnpacpi_supported_resource(res)) {
 619                (*resource)->type = res->type;
 620                (*resource)->length = sizeof(struct acpi_resource);
 621                if (res->type == ACPI_RESOURCE_TYPE_IRQ)
 622                        (*resource)->data.irq.descriptor_length =
 623                                        res->data.irq.descriptor_length;
 624                (*resource)++;
 625        }
 626
 627        return AE_OK;
 628}
 629
 630int pnpacpi_build_resource_template(struct pnp_dev *dev,
 631                                    struct acpi_buffer *buffer)
 632{
 633        struct acpi_device *acpi_dev = dev->data;
 634        acpi_handle handle = acpi_dev->handle;
 635        struct acpi_resource *resource;
 636        int res_cnt = 0;
 637        acpi_status status;
 638
 639        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 640                                     pnpacpi_count_resources, &res_cnt);
 641        if (ACPI_FAILURE(status)) {
 642                dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
 643                return -EINVAL;
 644        }
 645        if (!res_cnt)
 646                return -EINVAL;
 647        buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
 648        buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
 649        if (!buffer->pointer)
 650                return -ENOMEM;
 651
 652        resource = (struct acpi_resource *)buffer->pointer;
 653        status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 654                                     pnpacpi_type_resources, &resource);
 655        if (ACPI_FAILURE(status)) {
 656                kfree(buffer->pointer);
 657                dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
 658                return -EINVAL;
 659        }
 660        /* resource will pointer the end resource now */
 661        resource->type = ACPI_RESOURCE_TYPE_END_TAG;
 662        resource->length = sizeof(struct acpi_resource);
 663
 664        return 0;
 665}
 666
 667static void pnpacpi_encode_irq(struct pnp_dev *dev,
 668                               struct acpi_resource *resource,
 669                               struct resource *p)
 670{
 671        struct acpi_resource_irq *irq = &resource->data.irq;
 672        u8 triggering, polarity, shareable;
 673
 674        if (!pnp_resource_enabled(p)) {
 675                irq->interrupt_count = 0;
 676                pnp_dbg(&dev->dev, "  encode irq (%s)\n",
 677                        p ? "disabled" : "missing");
 678                return;
 679        }
 680
 681        decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
 682        irq->triggering = triggering;
 683        irq->polarity = polarity;
 684        irq->sharable = shareable;
 685        irq->interrupt_count = 1;
 686        irq->interrupts[0] = p->start;
 687
 688        pnp_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
 689                (int) p->start,
 690                triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
 691                polarity == ACPI_ACTIVE_LOW ? "low" : "high",
 692                irq->sharable == ACPI_SHARED ? "shared" : "exclusive",
 693                irq->descriptor_length);
 694}
 695
 696static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
 697                                   struct acpi_resource *resource,
 698                                   struct resource *p)
 699{
 700        struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
 701        u8 triggering, polarity, shareable;
 702
 703        if (!pnp_resource_enabled(p)) {
 704                extended_irq->interrupt_count = 0;
 705                pnp_dbg(&dev->dev, "  encode extended irq (%s)\n",
 706                        p ? "disabled" : "missing");
 707                return;
 708        }
 709
 710        decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
 711        extended_irq->producer_consumer = ACPI_CONSUMER;
 712        extended_irq->triggering = triggering;
 713        extended_irq->polarity = polarity;
 714        extended_irq->sharable = shareable;
 715        extended_irq->interrupt_count = 1;
 716        extended_irq->interrupts[0] = p->start;
 717
 718        pnp_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
 719                triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
 720                polarity == ACPI_ACTIVE_LOW ? "low" : "high",
 721                extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
 722}
 723
 724static void pnpacpi_encode_dma(struct pnp_dev *dev,
 725                               struct acpi_resource *resource,
 726                               struct resource *p)
 727{
 728        struct acpi_resource_dma *dma = &resource->data.dma;
 729
 730        if (!pnp_resource_enabled(p)) {
 731                dma->channel_count = 0;
 732                pnp_dbg(&dev->dev, "  encode dma (%s)\n",
 733                        p ? "disabled" : "missing");
 734                return;
 735        }
 736
 737        /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
 738        switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
 739        case IORESOURCE_DMA_TYPEA:
 740                dma->type = ACPI_TYPE_A;
 741                break;
 742        case IORESOURCE_DMA_TYPEB:
 743                dma->type = ACPI_TYPE_B;
 744                break;
 745        case IORESOURCE_DMA_TYPEF:
 746                dma->type = ACPI_TYPE_F;
 747                break;
 748        default:
 749                dma->type = ACPI_COMPATIBILITY;
 750        }
 751
 752        switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
 753        case IORESOURCE_DMA_8BIT:
 754                dma->transfer = ACPI_TRANSFER_8;
 755                break;
 756        case IORESOURCE_DMA_8AND16BIT:
 757                dma->transfer = ACPI_TRANSFER_8_16;
 758                break;
 759        default:
 760                dma->transfer = ACPI_TRANSFER_16;
 761        }
 762
 763        dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
 764        dma->channel_count = 1;
 765        dma->channels[0] = p->start;
 766
 767        pnp_dbg(&dev->dev, "  encode dma %d "
 768                "type %#x transfer %#x master %d\n",
 769                (int) p->start, dma->type, dma->transfer, dma->bus_master);
 770}
 771
 772static void pnpacpi_encode_io(struct pnp_dev *dev,
 773                              struct acpi_resource *resource,
 774                              struct resource *p)
 775{
 776        struct acpi_resource_io *io = &resource->data.io;
 777
 778        if (pnp_resource_enabled(p)) {
 779                /* Note: pnp_assign_port copies pnp_port->flags into p->flags */
 780                io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
 781                    ACPI_DECODE_16 : ACPI_DECODE_10;
 782                io->minimum = p->start;
 783                io->maximum = p->end;
 784                io->alignment = 0;      /* Correct? */
 785                io->address_length = resource_size(p);
 786        } else {
 787                io->minimum = 0;
 788                io->address_length = 0;
 789        }
 790
 791        pnp_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
 792                io->minimum + io->address_length - 1, io->io_decode);
 793}
 794
 795static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
 796                                    struct acpi_resource *resource,
 797                                    struct resource *p)
 798{
 799        struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
 800
 801        if (pnp_resource_enabled(p)) {
 802                fixed_io->address = p->start;
 803                fixed_io->address_length = resource_size(p);
 804        } else {
 805                fixed_io->address = 0;
 806                fixed_io->address_length = 0;
 807        }
 808
 809        pnp_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
 810                fixed_io->address + fixed_io->address_length - 1);
 811}
 812
 813static void pnpacpi_encode_mem24(struct pnp_dev *dev,
 814                                 struct acpi_resource *resource,
 815                                 struct resource *p)
 816{
 817        struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
 818
 819        if (pnp_resource_enabled(p)) {
 820                /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
 821                memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
 822                    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
 823                memory24->minimum = p->start;
 824                memory24->maximum = p->end;
 825                memory24->alignment = 0;
 826                memory24->address_length = resource_size(p);
 827        } else {
 828                memory24->minimum = 0;
 829                memory24->address_length = 0;
 830        }
 831
 832        pnp_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
 833                memory24->minimum,
 834                memory24->minimum + memory24->address_length - 1,
 835                memory24->write_protect);
 836}
 837
 838static void pnpacpi_encode_mem32(struct pnp_dev *dev,
 839                                 struct acpi_resource *resource,
 840                                 struct resource *p)
 841{
 842        struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
 843
 844        if (pnp_resource_enabled(p)) {
 845                memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
 846                    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
 847                memory32->minimum = p->start;
 848                memory32->maximum = p->end;
 849                memory32->alignment = 0;
 850                memory32->address_length = resource_size(p);
 851        } else {
 852                memory32->minimum = 0;
 853                memory32->alignment = 0;
 854        }
 855
 856        pnp_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
 857                memory32->minimum,
 858                memory32->minimum + memory32->address_length - 1,
 859                memory32->write_protect);
 860}
 861
 862static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
 863                                       struct acpi_resource *resource,
 864                                       struct resource *p)
 865{
 866        struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
 867
 868        if (pnp_resource_enabled(p)) {
 869                fixed_memory32->write_protect =
 870                    p->flags & IORESOURCE_MEM_WRITEABLE ?
 871                    ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
 872                fixed_memory32->address = p->start;
 873                fixed_memory32->address_length = resource_size(p);
 874        } else {
 875                fixed_memory32->address = 0;
 876                fixed_memory32->address_length = 0;
 877        }
 878
 879        pnp_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
 880                fixed_memory32->address,
 881                fixed_memory32->address + fixed_memory32->address_length - 1,
 882                fixed_memory32->write_protect);
 883}
 884
 885int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
 886{
 887        int i = 0;
 888        /* pnpacpi_build_resource_template allocates extra mem */
 889        int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
 890        struct acpi_resource *resource = buffer->pointer;
 891        unsigned int port = 0, irq = 0, dma = 0, mem = 0;
 892
 893        pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt);
 894        while (i < res_cnt) {
 895                switch (resource->type) {
 896                case ACPI_RESOURCE_TYPE_IRQ:
 897                        pnpacpi_encode_irq(dev, resource,
 898                               pnp_get_resource(dev, IORESOURCE_IRQ, irq));
 899                        irq++;
 900                        break;
 901
 902                case ACPI_RESOURCE_TYPE_DMA:
 903                        pnpacpi_encode_dma(dev, resource,
 904                                pnp_get_resource(dev, IORESOURCE_DMA, dma));
 905                        dma++;
 906                        break;
 907                case ACPI_RESOURCE_TYPE_IO:
 908                        pnpacpi_encode_io(dev, resource,
 909                                pnp_get_resource(dev, IORESOURCE_IO, port));
 910                        port++;
 911                        break;
 912                case ACPI_RESOURCE_TYPE_FIXED_IO:
 913                        pnpacpi_encode_fixed_io(dev, resource,
 914                                pnp_get_resource(dev, IORESOURCE_IO, port));
 915                        port++;
 916                        break;
 917                case ACPI_RESOURCE_TYPE_MEMORY24:
 918                        pnpacpi_encode_mem24(dev, resource,
 919                                pnp_get_resource(dev, IORESOURCE_MEM, mem));
 920                        mem++;
 921                        break;
 922                case ACPI_RESOURCE_TYPE_MEMORY32:
 923                        pnpacpi_encode_mem32(dev, resource,
 924                                pnp_get_resource(dev, IORESOURCE_MEM, mem));
 925                        mem++;
 926                        break;
 927                case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 928                        pnpacpi_encode_fixed_mem32(dev, resource,
 929                                pnp_get_resource(dev, IORESOURCE_MEM, mem));
 930                        mem++;
 931                        break;
 932                case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 933                        pnpacpi_encode_ext_irq(dev, resource,
 934                                pnp_get_resource(dev, IORESOURCE_IRQ, irq));
 935                        irq++;
 936                        break;
 937                case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 938                case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 939                case ACPI_RESOURCE_TYPE_VENDOR:
 940                case ACPI_RESOURCE_TYPE_END_TAG:
 941                case ACPI_RESOURCE_TYPE_ADDRESS16:
 942                case ACPI_RESOURCE_TYPE_ADDRESS32:
 943                case ACPI_RESOURCE_TYPE_ADDRESS64:
 944                case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
 945                case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 946                default:        /* other type */
 947                        dev_warn(&dev->dev,
 948                                 "can't encode unknown resource type %d\n",
 949                                 resource->type);
 950                        return -EINVAL;
 951                }
 952                resource++;
 953                i++;
 954        }
 955        return 0;
 956}
 957