root/drivers/pnp/pnpacpi/rsparser.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. decode_irq_flags
  2. dma_flags
  3. pnpacpi_add_irqresource
  4. vendor_resource_matches
  5. pnpacpi_parse_allocated_vendor
  6. pnpacpi_allocated_resource
  7. pnpacpi_parse_allocated_resource
  8. pnpacpi_parse_dma_option
  9. pnpacpi_parse_irq_option
  10. pnpacpi_parse_ext_irq_option
  11. pnpacpi_parse_port_option
  12. pnpacpi_parse_fixed_port_option
  13. pnpacpi_parse_mem24_option
  14. pnpacpi_parse_mem32_option
  15. pnpacpi_parse_fixed_mem32_option
  16. pnpacpi_parse_address_option
  17. pnpacpi_parse_ext_address_option
  18. pnpacpi_option_resource
  19. pnpacpi_parse_resource_option_data
  20. pnpacpi_supported_resource
  21. pnpacpi_count_resources
  22. pnpacpi_type_resources
  23. pnpacpi_build_resource_template
  24. pnpacpi_encode_irq
  25. pnpacpi_encode_ext_irq
  26. pnpacpi_encode_dma
  27. pnpacpi_encode_io
  28. pnpacpi_encode_fixed_io
  29. pnpacpi_encode_mem24
  30. pnpacpi_encode_mem32
  31. pnpacpi_encode_fixed_mem32
  32. pnpacpi_encode_resources

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

/* [<][>][^][v][top][bottom][index][help] */