root/drivers/acpi/resource.c

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

DEFINITIONS

This source file includes following definitions.
  1. acpi_iospace_resource_valid
  2. acpi_iospace_resource_valid
  3. is_gsi
  4. is_gsi
  5. acpi_dev_resource_len_valid
  6. acpi_dev_memresource_flags
  7. acpi_dev_get_memresource
  8. acpi_dev_resource_memory
  9. acpi_dev_ioresource_flags
  10. acpi_dev_get_ioresource
  11. acpi_dev_resource_io
  12. acpi_decode_space
  13. acpi_dev_resource_address_space
  14. acpi_dev_resource_ext_address_space
  15. acpi_dev_irq_flags
  16. acpi_dev_get_irq_type
  17. acpi_dev_irqresource_disabled
  18. acpi_dev_get_irqresource
  19. acpi_dev_resource_interrupt
  20. acpi_dev_free_resource_list
  21. acpi_dev_new_resource_entry
  22. acpi_dev_process_resource
  23. __acpi_dev_get_resources
  24. acpi_dev_get_resources
  25. is_memory
  26. acpi_dev_get_dma_resources
  27. acpi_dev_filter_resource_type
  28. acpi_dev_consumes_res
  29. acpi_res_consumer_cb
  30. acpi_resource_consumer

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * drivers/acpi/resource.c - ACPI device resources interpretation.
   4  *
   5  * Copyright (C) 2012, Intel Corp.
   6  * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
   7  *
   8  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   9  *
  10  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  11  */
  12 
  13 #include <linux/acpi.h>
  14 #include <linux/device.h>
  15 #include <linux/export.h>
  16 #include <linux/ioport.h>
  17 #include <linux/slab.h>
  18 #include <linux/irq.h>
  19 
  20 #ifdef CONFIG_X86
  21 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
  22 static inline bool acpi_iospace_resource_valid(struct resource *res)
  23 {
  24         /* On X86 IO space is limited to the [0 - 64K] IO port range */
  25         return res->end < 0x10003;
  26 }
  27 #else
  28 #define valid_IRQ(i) (true)
  29 /*
  30  * ACPI IO descriptors on arches other than X86 contain MMIO CPU physical
  31  * addresses mapping IO space in CPU physical address space, IO space
  32  * resources can be placed anywhere in the 64-bit physical address space.
  33  */
  34 static inline bool
  35 acpi_iospace_resource_valid(struct resource *res) { return true; }
  36 #endif
  37 
  38 #if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
  39 static inline bool is_gsi(struct acpi_resource_extended_irq *ext_irq)
  40 {
  41         return ext_irq->resource_source.string_length == 0 &&
  42                ext_irq->producer_consumer == ACPI_CONSUMER;
  43 }
  44 #else
  45 static inline bool is_gsi(struct acpi_resource_extended_irq *ext_irq)
  46 {
  47         return true;
  48 }
  49 #endif
  50 
  51 static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
  52 {
  53         u64 reslen = end - start + 1;
  54 
  55         /*
  56          * CHECKME: len might be required to check versus a minimum
  57          * length as well. 1 for io is fine, but for memory it does
  58          * not make any sense at all.
  59          * Note: some BIOSes report incorrect length for ACPI address space
  60          * descriptor, so remove check of 'reslen == len' to avoid regression.
  61          */
  62         if (len && reslen && start <= end)
  63                 return true;
  64 
  65         pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
  66                 io ? "io" : "mem", start, end, len);
  67 
  68         return false;
  69 }
  70 
  71 static void acpi_dev_memresource_flags(struct resource *res, u64 len,
  72                                        u8 write_protect)
  73 {
  74         res->flags = IORESOURCE_MEM;
  75 
  76         if (!acpi_dev_resource_len_valid(res->start, res->end, len, false))
  77                 res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
  78 
  79         if (write_protect == ACPI_READ_WRITE_MEMORY)
  80                 res->flags |= IORESOURCE_MEM_WRITEABLE;
  81 }
  82 
  83 static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
  84                                      u8 write_protect)
  85 {
  86         res->start = start;
  87         res->end = start + len - 1;
  88         acpi_dev_memresource_flags(res, len, write_protect);
  89 }
  90 
  91 /**
  92  * acpi_dev_resource_memory - Extract ACPI memory resource information.
  93  * @ares: Input ACPI resource object.
  94  * @res: Output generic resource object.
  95  *
  96  * Check if the given ACPI resource object represents a memory resource and
  97  * if that's the case, use the information in it to populate the generic
  98  * resource object pointed to by @res.
  99  *
 100  * Return:
 101  * 1) false with res->flags setting to zero: not the expected resource type
 102  * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
 103  * 3) true: valid assigned resource
 104  */
 105 bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
 106 {
 107         struct acpi_resource_memory24 *memory24;
 108         struct acpi_resource_memory32 *memory32;
 109         struct acpi_resource_fixed_memory32 *fixed_memory32;
 110 
 111         switch (ares->type) {
 112         case ACPI_RESOURCE_TYPE_MEMORY24:
 113                 memory24 = &ares->data.memory24;
 114                 acpi_dev_get_memresource(res, memory24->minimum << 8,
 115                                          memory24->address_length << 8,
 116                                          memory24->write_protect);
 117                 break;
 118         case ACPI_RESOURCE_TYPE_MEMORY32:
 119                 memory32 = &ares->data.memory32;
 120                 acpi_dev_get_memresource(res, memory32->minimum,
 121                                          memory32->address_length,
 122                                          memory32->write_protect);
 123                 break;
 124         case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 125                 fixed_memory32 = &ares->data.fixed_memory32;
 126                 acpi_dev_get_memresource(res, fixed_memory32->address,
 127                                          fixed_memory32->address_length,
 128                                          fixed_memory32->write_protect);
 129                 break;
 130         default:
 131                 res->flags = 0;
 132                 return false;
 133         }
 134 
 135         return !(res->flags & IORESOURCE_DISABLED);
 136 }
 137 EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
 138 
 139 static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
 140                                       u8 io_decode, u8 translation_type)
 141 {
 142         res->flags = IORESOURCE_IO;
 143 
 144         if (!acpi_dev_resource_len_valid(res->start, res->end, len, true))
 145                 res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
 146 
 147         if (!acpi_iospace_resource_valid(res))
 148                 res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
 149 
 150         if (io_decode == ACPI_DECODE_16)
 151                 res->flags |= IORESOURCE_IO_16BIT_ADDR;
 152         if (translation_type == ACPI_SPARSE_TRANSLATION)
 153                 res->flags |= IORESOURCE_IO_SPARSE;
 154 }
 155 
 156 static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
 157                                     u8 io_decode)
 158 {
 159         res->start = start;
 160         res->end = start + len - 1;
 161         acpi_dev_ioresource_flags(res, len, io_decode, 0);
 162 }
 163 
 164 /**
 165  * acpi_dev_resource_io - Extract ACPI I/O resource information.
 166  * @ares: Input ACPI resource object.
 167  * @res: Output generic resource object.
 168  *
 169  * Check if the given ACPI resource object represents an I/O resource and
 170  * if that's the case, use the information in it to populate the generic
 171  * resource object pointed to by @res.
 172  *
 173  * Return:
 174  * 1) false with res->flags setting to zero: not the expected resource type
 175  * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
 176  * 3) true: valid assigned resource
 177  */
 178 bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
 179 {
 180         struct acpi_resource_io *io;
 181         struct acpi_resource_fixed_io *fixed_io;
 182 
 183         switch (ares->type) {
 184         case ACPI_RESOURCE_TYPE_IO:
 185                 io = &ares->data.io;
 186                 acpi_dev_get_ioresource(res, io->minimum,
 187                                         io->address_length,
 188                                         io->io_decode);
 189                 break;
 190         case ACPI_RESOURCE_TYPE_FIXED_IO:
 191                 fixed_io = &ares->data.fixed_io;
 192                 acpi_dev_get_ioresource(res, fixed_io->address,
 193                                         fixed_io->address_length,
 194                                         ACPI_DECODE_10);
 195                 break;
 196         default:
 197                 res->flags = 0;
 198                 return false;
 199         }
 200 
 201         return !(res->flags & IORESOURCE_DISABLED);
 202 }
 203 EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
 204 
 205 static bool acpi_decode_space(struct resource_win *win,
 206                               struct acpi_resource_address *addr,
 207                               struct acpi_address64_attribute *attr)
 208 {
 209         u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16;
 210         bool wp = addr->info.mem.write_protect;
 211         u64 len = attr->address_length;
 212         u64 start, end, offset = 0;
 213         struct resource *res = &win->res;
 214 
 215         /*
 216          * Filter out invalid descriptor according to ACPI Spec 5.0, section
 217          * 6.4.3.5 Address Space Resource Descriptors.
 218          */
 219         if ((addr->min_address_fixed != addr->max_address_fixed && len) ||
 220             (addr->min_address_fixed && addr->max_address_fixed && !len))
 221                 pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n",
 222                          addr->min_address_fixed, addr->max_address_fixed, len);
 223 
 224         /*
 225          * For bridges that translate addresses across the bridge,
 226          * translation_offset is the offset that must be added to the
 227          * address on the secondary side to obtain the address on the
 228          * primary side. Non-bridge devices must list 0 for all Address
 229          * Translation offset bits.
 230          */
 231         if (addr->producer_consumer == ACPI_PRODUCER)
 232                 offset = attr->translation_offset;
 233         else if (attr->translation_offset)
 234                 pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n",
 235                          attr->translation_offset);
 236         start = attr->minimum + offset;
 237         end = attr->maximum + offset;
 238 
 239         win->offset = offset;
 240         res->start = start;
 241         res->end = end;
 242         if (sizeof(resource_size_t) < sizeof(u64) &&
 243             (offset != win->offset || start != res->start || end != res->end)) {
 244                 pr_warn("acpi resource window ([%#llx-%#llx] ignored, not CPU addressable)\n",
 245                         attr->minimum, attr->maximum);
 246                 return false;
 247         }
 248 
 249         switch (addr->resource_type) {
 250         case ACPI_MEMORY_RANGE:
 251                 acpi_dev_memresource_flags(res, len, wp);
 252                 break;
 253         case ACPI_IO_RANGE:
 254                 acpi_dev_ioresource_flags(res, len, iodec,
 255                                           addr->info.io.translation_type);
 256                 break;
 257         case ACPI_BUS_NUMBER_RANGE:
 258                 res->flags = IORESOURCE_BUS;
 259                 break;
 260         default:
 261                 return false;
 262         }
 263 
 264         if (addr->producer_consumer == ACPI_PRODUCER)
 265                 res->flags |= IORESOURCE_WINDOW;
 266 
 267         if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
 268                 res->flags |= IORESOURCE_PREFETCH;
 269 
 270         return !(res->flags & IORESOURCE_DISABLED);
 271 }
 272 
 273 /**
 274  * acpi_dev_resource_address_space - Extract ACPI address space information.
 275  * @ares: Input ACPI resource object.
 276  * @win: Output generic resource object.
 277  *
 278  * Check if the given ACPI resource object represents an address space resource
 279  * and if that's the case, use the information in it to populate the generic
 280  * resource object pointed to by @win.
 281  *
 282  * Return:
 283  * 1) false with win->res.flags setting to zero: not the expected resource type
 284  * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
 285  *    resource
 286  * 3) true: valid assigned resource
 287  */
 288 bool acpi_dev_resource_address_space(struct acpi_resource *ares,
 289                                      struct resource_win *win)
 290 {
 291         struct acpi_resource_address64 addr;
 292 
 293         win->res.flags = 0;
 294         if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr)))
 295                 return false;
 296 
 297         return acpi_decode_space(win, (struct acpi_resource_address *)&addr,
 298                                  &addr.address);
 299 }
 300 EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
 301 
 302 /**
 303  * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
 304  * @ares: Input ACPI resource object.
 305  * @win: Output generic resource object.
 306  *
 307  * Check if the given ACPI resource object represents an extended address space
 308  * resource and if that's the case, use the information in it to populate the
 309  * generic resource object pointed to by @win.
 310  *
 311  * Return:
 312  * 1) false with win->res.flags setting to zero: not the expected resource type
 313  * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
 314  *    resource
 315  * 3) true: valid assigned resource
 316  */
 317 bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
 318                                          struct resource_win *win)
 319 {
 320         struct acpi_resource_extended_address64 *ext_addr;
 321 
 322         win->res.flags = 0;
 323         if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
 324                 return false;
 325 
 326         ext_addr = &ares->data.ext_address64;
 327 
 328         return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr,
 329                                  &ext_addr->address);
 330 }
 331 EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
 332 
 333 /**
 334  * acpi_dev_irq_flags - Determine IRQ resource flags.
 335  * @triggering: Triggering type as provided by ACPI.
 336  * @polarity: Interrupt polarity as provided by ACPI.
 337  * @shareable: Whether or not the interrupt is shareable.
 338  */
 339 unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
 340 {
 341         unsigned long flags;
 342 
 343         if (triggering == ACPI_LEVEL_SENSITIVE)
 344                 flags = polarity == ACPI_ACTIVE_LOW ?
 345                         IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
 346         else
 347                 flags = polarity == ACPI_ACTIVE_LOW ?
 348                         IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
 349 
 350         if (shareable == ACPI_SHARED)
 351                 flags |= IORESOURCE_IRQ_SHAREABLE;
 352 
 353         return flags | IORESOURCE_IRQ;
 354 }
 355 EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
 356 
 357 /**
 358  * acpi_dev_get_irq_type - Determine irq type.
 359  * @triggering: Triggering type as provided by ACPI.
 360  * @polarity: Interrupt polarity as provided by ACPI.
 361  */
 362 unsigned int acpi_dev_get_irq_type(int triggering, int polarity)
 363 {
 364         switch (polarity) {
 365         case ACPI_ACTIVE_LOW:
 366                 return triggering == ACPI_EDGE_SENSITIVE ?
 367                        IRQ_TYPE_EDGE_FALLING :
 368                        IRQ_TYPE_LEVEL_LOW;
 369         case ACPI_ACTIVE_HIGH:
 370                 return triggering == ACPI_EDGE_SENSITIVE ?
 371                        IRQ_TYPE_EDGE_RISING :
 372                        IRQ_TYPE_LEVEL_HIGH;
 373         case ACPI_ACTIVE_BOTH:
 374                 if (triggering == ACPI_EDGE_SENSITIVE)
 375                         return IRQ_TYPE_EDGE_BOTH;
 376                 /* fall through */
 377         default:
 378                 return IRQ_TYPE_NONE;
 379         }
 380 }
 381 EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type);
 382 
 383 static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
 384 {
 385         res->start = gsi;
 386         res->end = gsi;
 387         res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
 388 }
 389 
 390 static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
 391                                      u8 triggering, u8 polarity, u8 shareable,
 392                                      bool legacy)
 393 {
 394         int irq, p, t;
 395 
 396         if (!valid_IRQ(gsi)) {
 397                 acpi_dev_irqresource_disabled(res, gsi);
 398                 return;
 399         }
 400 
 401         /*
 402          * In IO-APIC mode, use overridden attribute. Two reasons:
 403          * 1. BIOS bug in DSDT
 404          * 2. BIOS uses IO-APIC mode Interrupt Source Override
 405          *
 406          * We do this only if we are dealing with IRQ() or IRQNoFlags()
 407          * resource (the legacy ISA resources). With modern ACPI 5 devices
 408          * using extended IRQ descriptors we take the IRQ configuration
 409          * from _CRS directly.
 410          */
 411         if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
 412                 u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
 413                 u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
 414 
 415                 if (triggering != trig || polarity != pol) {
 416                         pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
 417                                    t ? "level" : "edge", p ? "low" : "high");
 418                         triggering = trig;
 419                         polarity = pol;
 420                 }
 421         }
 422 
 423         res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
 424         irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
 425         if (irq >= 0) {
 426                 res->start = irq;
 427                 res->end = irq;
 428         } else {
 429                 acpi_dev_irqresource_disabled(res, gsi);
 430         }
 431 }
 432 
 433 /**
 434  * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
 435  * @ares: Input ACPI resource object.
 436  * @index: Index into the array of GSIs represented by the resource.
 437  * @res: Output generic resource object.
 438  *
 439  * Check if the given ACPI resource object represents an interrupt resource
 440  * and @index does not exceed the resource's interrupt count (true is returned
 441  * in that case regardless of the results of the other checks)).  If that's the
 442  * case, register the GSI corresponding to @index from the array of interrupts
 443  * represented by the resource and populate the generic resource object pointed
 444  * to by @res accordingly.  If the registration of the GSI is not successful,
 445  * IORESOURCE_DISABLED will be set it that object's flags.
 446  *
 447  * Return:
 448  * 1) false with res->flags setting to zero: not the expected resource type
 449  * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
 450  * 3) true: valid assigned resource
 451  */
 452 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 453                                  struct resource *res)
 454 {
 455         struct acpi_resource_irq *irq;
 456         struct acpi_resource_extended_irq *ext_irq;
 457 
 458         switch (ares->type) {
 459         case ACPI_RESOURCE_TYPE_IRQ:
 460                 /*
 461                  * Per spec, only one interrupt per descriptor is allowed in
 462                  * _CRS, but some firmware violates this, so parse them all.
 463                  */
 464                 irq = &ares->data.irq;
 465                 if (index >= irq->interrupt_count) {
 466                         acpi_dev_irqresource_disabled(res, 0);
 467                         return false;
 468                 }
 469                 acpi_dev_get_irqresource(res, irq->interrupts[index],
 470                                          irq->triggering, irq->polarity,
 471                                          irq->shareable, true);
 472                 break;
 473         case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 474                 ext_irq = &ares->data.extended_irq;
 475                 if (index >= ext_irq->interrupt_count) {
 476                         acpi_dev_irqresource_disabled(res, 0);
 477                         return false;
 478                 }
 479                 if (is_gsi(ext_irq))
 480                         acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
 481                                          ext_irq->triggering, ext_irq->polarity,
 482                                          ext_irq->shareable, false);
 483                 else
 484                         acpi_dev_irqresource_disabled(res, 0);
 485                 break;
 486         default:
 487                 res->flags = 0;
 488                 return false;
 489         }
 490 
 491         return true;
 492 }
 493 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
 494 
 495 /**
 496  * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
 497  * @list: The head of the resource list to free.
 498  */
 499 void acpi_dev_free_resource_list(struct list_head *list)
 500 {
 501         resource_list_free(list);
 502 }
 503 EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
 504 
 505 struct res_proc_context {
 506         struct list_head *list;
 507         int (*preproc)(struct acpi_resource *, void *);
 508         void *preproc_data;
 509         int count;
 510         int error;
 511 };
 512 
 513 static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
 514                                                struct res_proc_context *c)
 515 {
 516         struct resource_entry *rentry;
 517 
 518         rentry = resource_list_create_entry(NULL, 0);
 519         if (!rentry) {
 520                 c->error = -ENOMEM;
 521                 return AE_NO_MEMORY;
 522         }
 523         *rentry->res = win->res;
 524         rentry->offset = win->offset;
 525         resource_list_add_tail(rentry, c->list);
 526         c->count++;
 527         return AE_OK;
 528 }
 529 
 530 static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
 531                                              void *context)
 532 {
 533         struct res_proc_context *c = context;
 534         struct resource_win win;
 535         struct resource *res = &win.res;
 536         int i;
 537 
 538         if (c->preproc) {
 539                 int ret;
 540 
 541                 ret = c->preproc(ares, c->preproc_data);
 542                 if (ret < 0) {
 543                         c->error = ret;
 544                         return AE_CTRL_TERMINATE;
 545                 } else if (ret > 0) {
 546                         return AE_OK;
 547                 }
 548         }
 549 
 550         memset(&win, 0, sizeof(win));
 551 
 552         if (acpi_dev_resource_memory(ares, res)
 553             || acpi_dev_resource_io(ares, res)
 554             || acpi_dev_resource_address_space(ares, &win)
 555             || acpi_dev_resource_ext_address_space(ares, &win))
 556                 return acpi_dev_new_resource_entry(&win, c);
 557 
 558         for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
 559                 acpi_status status;
 560 
 561                 status = acpi_dev_new_resource_entry(&win, c);
 562                 if (ACPI_FAILURE(status))
 563                         return status;
 564         }
 565 
 566         return AE_OK;
 567 }
 568 
 569 static int __acpi_dev_get_resources(struct acpi_device *adev,
 570                                     struct list_head *list,
 571                                     int (*preproc)(struct acpi_resource *, void *),
 572                                     void *preproc_data, char *method)
 573 {
 574         struct res_proc_context c;
 575         acpi_status status;
 576 
 577         if (!adev || !adev->handle || !list_empty(list))
 578                 return -EINVAL;
 579 
 580         if (!acpi_has_method(adev->handle, method))
 581                 return 0;
 582 
 583         c.list = list;
 584         c.preproc = preproc;
 585         c.preproc_data = preproc_data;
 586         c.count = 0;
 587         c.error = 0;
 588         status = acpi_walk_resources(adev->handle, method,
 589                                      acpi_dev_process_resource, &c);
 590         if (ACPI_FAILURE(status)) {
 591                 acpi_dev_free_resource_list(list);
 592                 return c.error ? c.error : -EIO;
 593         }
 594 
 595         return c.count;
 596 }
 597 
 598 /**
 599  * acpi_dev_get_resources - Get current resources of a device.
 600  * @adev: ACPI device node to get the resources for.
 601  * @list: Head of the resultant list of resources (must be empty).
 602  * @preproc: The caller's preprocessing routine.
 603  * @preproc_data: Pointer passed to the caller's preprocessing routine.
 604  *
 605  * Evaluate the _CRS method for the given device node and process its output by
 606  * (1) executing the @preproc() rountine provided by the caller, passing the
 607  * resource pointer and @preproc_data to it as arguments, for each ACPI resource
 608  * returned and (2) converting all of the returned ACPI resources into struct
 609  * resource objects if possible.  If the return value of @preproc() in step (1)
 610  * is different from 0, step (2) is not applied to the given ACPI resource and
 611  * if that value is negative, the whole processing is aborted and that value is
 612  * returned as the final error code.
 613  *
 614  * The resultant struct resource objects are put on the list pointed to by
 615  * @list, that must be empty initially, as members of struct resource_entry
 616  * objects.  Callers of this routine should use %acpi_dev_free_resource_list() to
 617  * free that list.
 618  *
 619  * The number of resources in the output list is returned on success, an error
 620  * code reflecting the error condition is returned otherwise.
 621  */
 622 int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
 623                            int (*preproc)(struct acpi_resource *, void *),
 624                            void *preproc_data)
 625 {
 626         return __acpi_dev_get_resources(adev, list, preproc, preproc_data,
 627                                         METHOD_NAME__CRS);
 628 }
 629 EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
 630 
 631 static int is_memory(struct acpi_resource *ares, void *not_used)
 632 {
 633         struct resource_win win;
 634         struct resource *res = &win.res;
 635 
 636         memset(&win, 0, sizeof(win));
 637 
 638         return !(acpi_dev_resource_memory(ares, res)
 639                || acpi_dev_resource_address_space(ares, &win)
 640                || acpi_dev_resource_ext_address_space(ares, &win));
 641 }
 642 
 643 /**
 644  * acpi_dev_get_dma_resources - Get current DMA resources of a device.
 645  * @adev: ACPI device node to get the resources for.
 646  * @list: Head of the resultant list of resources (must be empty).
 647  *
 648  * Evaluate the _DMA method for the given device node and process its
 649  * output.
 650  *
 651  * The resultant struct resource objects are put on the list pointed to
 652  * by @list, that must be empty initially, as members of struct
 653  * resource_entry objects.  Callers of this routine should use
 654  * %acpi_dev_free_resource_list() to free that list.
 655  *
 656  * The number of resources in the output list is returned on success,
 657  * an error code reflecting the error condition is returned otherwise.
 658  */
 659 int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list)
 660 {
 661         return __acpi_dev_get_resources(adev, list, is_memory, NULL,
 662                                         METHOD_NAME__DMA);
 663 }
 664 EXPORT_SYMBOL_GPL(acpi_dev_get_dma_resources);
 665 
 666 /**
 667  * acpi_dev_filter_resource_type - Filter ACPI resource according to resource
 668  *                                 types
 669  * @ares: Input ACPI resource object.
 670  * @types: Valid resource types of IORESOURCE_XXX
 671  *
 672  * This is a helper function to support acpi_dev_get_resources(), which filters
 673  * ACPI resource objects according to resource types.
 674  */
 675 int acpi_dev_filter_resource_type(struct acpi_resource *ares,
 676                                   unsigned long types)
 677 {
 678         unsigned long type = 0;
 679 
 680         switch (ares->type) {
 681         case ACPI_RESOURCE_TYPE_MEMORY24:
 682         case ACPI_RESOURCE_TYPE_MEMORY32:
 683         case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 684                 type = IORESOURCE_MEM;
 685                 break;
 686         case ACPI_RESOURCE_TYPE_IO:
 687         case ACPI_RESOURCE_TYPE_FIXED_IO:
 688                 type = IORESOURCE_IO;
 689                 break;
 690         case ACPI_RESOURCE_TYPE_IRQ:
 691         case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 692                 type = IORESOURCE_IRQ;
 693                 break;
 694         case ACPI_RESOURCE_TYPE_DMA:
 695         case ACPI_RESOURCE_TYPE_FIXED_DMA:
 696                 type = IORESOURCE_DMA;
 697                 break;
 698         case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 699                 type = IORESOURCE_REG;
 700                 break;
 701         case ACPI_RESOURCE_TYPE_ADDRESS16:
 702         case ACPI_RESOURCE_TYPE_ADDRESS32:
 703         case ACPI_RESOURCE_TYPE_ADDRESS64:
 704         case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
 705                 if (ares->data.address.resource_type == ACPI_MEMORY_RANGE)
 706                         type = IORESOURCE_MEM;
 707                 else if (ares->data.address.resource_type == ACPI_IO_RANGE)
 708                         type = IORESOURCE_IO;
 709                 else if (ares->data.address.resource_type ==
 710                          ACPI_BUS_NUMBER_RANGE)
 711                         type = IORESOURCE_BUS;
 712                 break;
 713         default:
 714                 break;
 715         }
 716 
 717         return (type & types) ? 0 : 1;
 718 }
 719 EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
 720 
 721 static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res)
 722 {
 723         struct list_head resource_list;
 724         struct resource_entry *rentry;
 725         int ret, found = 0;
 726 
 727         INIT_LIST_HEAD(&resource_list);
 728         ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
 729         if (ret < 0)
 730                 return 0;
 731 
 732         list_for_each_entry(rentry, &resource_list, node) {
 733                 if (resource_contains(rentry->res, res)) {
 734                         found = 1;
 735                         break;
 736                 }
 737 
 738         }
 739 
 740         acpi_dev_free_resource_list(&resource_list);
 741         return found;
 742 }
 743 
 744 static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth,
 745                                          void *context, void **ret)
 746 {
 747         struct resource *res = context;
 748         struct acpi_device **consumer = (struct acpi_device **) ret;
 749         struct acpi_device *adev;
 750 
 751         if (acpi_bus_get_device(handle, &adev))
 752                 return AE_OK;
 753 
 754         if (acpi_dev_consumes_res(adev, res)) {
 755                 *consumer = adev;
 756                 return AE_CTRL_TERMINATE;
 757         }
 758 
 759         return AE_OK;
 760 }
 761 
 762 /**
 763  * acpi_resource_consumer - Find the ACPI device that consumes @res.
 764  * @res: Resource to search for.
 765  *
 766  * Search the current resource settings (_CRS) of every ACPI device node
 767  * for @res.  If we find an ACPI device whose _CRS includes @res, return
 768  * it.  Otherwise, return NULL.
 769  */
 770 struct acpi_device *acpi_resource_consumer(struct resource *res)
 771 {
 772         struct acpi_device *consumer = NULL;
 773 
 774         acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer);
 775         return consumer;
 776 }

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