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