Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * drivers/acpi/resource.c - ACPI device resources interpretation.
0004  *
0005  * Copyright (C) 2012, Intel Corp.
0006  * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
0007  *
0008  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0009  *
0010  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0011  */
0012 
0013 #include <linux/acpi.h>
0014 #include <linux/device.h>
0015 #include <linux/export.h>
0016 #include <linux/ioport.h>
0017 #include <linux/slab.h>
0018 #include <linux/irq.h>
0019 #include <linux/dmi.h>
0020 
0021 #ifdef CONFIG_X86
0022 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
0023 static inline bool acpi_iospace_resource_valid(struct resource *res)
0024 {
0025     /* On X86 IO space is limited to the [0 - 64K] IO port range */
0026     return res->end < 0x10003;
0027 }
0028 #else
0029 #define valid_IRQ(i) (true)
0030 /*
0031  * ACPI IO descriptors on arches other than X86 contain MMIO CPU physical
0032  * addresses mapping IO space in CPU physical address space, IO space
0033  * resources can be placed anywhere in the 64-bit physical address space.
0034  */
0035 static inline bool
0036 acpi_iospace_resource_valid(struct resource *res) { return true; }
0037 #endif
0038 
0039 #if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
0040 static inline bool is_gsi(struct acpi_resource_extended_irq *ext_irq)
0041 {
0042     return ext_irq->resource_source.string_length == 0 &&
0043            ext_irq->producer_consumer == ACPI_CONSUMER;
0044 }
0045 #else
0046 static inline bool is_gsi(struct acpi_resource_extended_irq *ext_irq)
0047 {
0048     return true;
0049 }
0050 #endif
0051 
0052 static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
0053 {
0054     u64 reslen = end - start + 1;
0055 
0056     /*
0057      * CHECKME: len might be required to check versus a minimum
0058      * length as well. 1 for io is fine, but for memory it does
0059      * not make any sense at all.
0060      * Note: some BIOSes report incorrect length for ACPI address space
0061      * descriptor, so remove check of 'reslen == len' to avoid regression.
0062      */
0063     if (len && reslen && start <= end)
0064         return true;
0065 
0066     pr_debug("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
0067         io ? "io" : "mem", start, end, len);
0068 
0069     return false;
0070 }
0071 
0072 static void acpi_dev_memresource_flags(struct resource *res, u64 len,
0073                        u8 write_protect)
0074 {
0075     res->flags = IORESOURCE_MEM;
0076 
0077     if (!acpi_dev_resource_len_valid(res->start, res->end, len, false))
0078         res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
0079 
0080     if (write_protect == ACPI_READ_WRITE_MEMORY)
0081         res->flags |= IORESOURCE_MEM_WRITEABLE;
0082 }
0083 
0084 static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
0085                      u8 write_protect)
0086 {
0087     res->start = start;
0088     res->end = start + len - 1;
0089     acpi_dev_memresource_flags(res, len, write_protect);
0090 }
0091 
0092 /**
0093  * acpi_dev_resource_memory - Extract ACPI memory resource information.
0094  * @ares: Input ACPI resource object.
0095  * @res: Output generic resource object.
0096  *
0097  * Check if the given ACPI resource object represents a memory resource and
0098  * if that's the case, use the information in it to populate the generic
0099  * resource object pointed to by @res.
0100  *
0101  * Return:
0102  * 1) false with res->flags setting to zero: not the expected resource type
0103  * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
0104  * 3) true: valid assigned resource
0105  */
0106 bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
0107 {
0108     struct acpi_resource_memory24 *memory24;
0109     struct acpi_resource_memory32 *memory32;
0110     struct acpi_resource_fixed_memory32 *fixed_memory32;
0111 
0112     switch (ares->type) {
0113     case ACPI_RESOURCE_TYPE_MEMORY24:
0114         memory24 = &ares->data.memory24;
0115         acpi_dev_get_memresource(res, memory24->minimum << 8,
0116                      memory24->address_length << 8,
0117                      memory24->write_protect);
0118         break;
0119     case ACPI_RESOURCE_TYPE_MEMORY32:
0120         memory32 = &ares->data.memory32;
0121         acpi_dev_get_memresource(res, memory32->minimum,
0122                      memory32->address_length,
0123                      memory32->write_protect);
0124         break;
0125     case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
0126         fixed_memory32 = &ares->data.fixed_memory32;
0127         acpi_dev_get_memresource(res, fixed_memory32->address,
0128                      fixed_memory32->address_length,
0129                      fixed_memory32->write_protect);
0130         break;
0131     default:
0132         res->flags = 0;
0133         return false;
0134     }
0135 
0136     return !(res->flags & IORESOURCE_DISABLED);
0137 }
0138 EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
0139 
0140 static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
0141                       u8 io_decode, u8 translation_type)
0142 {
0143     res->flags = IORESOURCE_IO;
0144 
0145     if (!acpi_dev_resource_len_valid(res->start, res->end, len, true))
0146         res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
0147 
0148     if (!acpi_iospace_resource_valid(res))
0149         res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
0150 
0151     if (io_decode == ACPI_DECODE_16)
0152         res->flags |= IORESOURCE_IO_16BIT_ADDR;
0153     if (translation_type == ACPI_SPARSE_TRANSLATION)
0154         res->flags |= IORESOURCE_IO_SPARSE;
0155 }
0156 
0157 static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
0158                     u8 io_decode)
0159 {
0160     res->start = start;
0161     res->end = start + len - 1;
0162     acpi_dev_ioresource_flags(res, len, io_decode, 0);
0163 }
0164 
0165 /**
0166  * acpi_dev_resource_io - Extract ACPI I/O resource information.
0167  * @ares: Input ACPI resource object.
0168  * @res: Output generic resource object.
0169  *
0170  * Check if the given ACPI resource object represents an I/O resource and
0171  * if that's the case, use the information in it to populate the generic
0172  * resource object pointed to by @res.
0173  *
0174  * Return:
0175  * 1) false with res->flags setting to zero: not the expected resource type
0176  * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
0177  * 3) true: valid assigned resource
0178  */
0179 bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
0180 {
0181     struct acpi_resource_io *io;
0182     struct acpi_resource_fixed_io *fixed_io;
0183 
0184     switch (ares->type) {
0185     case ACPI_RESOURCE_TYPE_IO:
0186         io = &ares->data.io;
0187         acpi_dev_get_ioresource(res, io->minimum,
0188                     io->address_length,
0189                     io->io_decode);
0190         break;
0191     case ACPI_RESOURCE_TYPE_FIXED_IO:
0192         fixed_io = &ares->data.fixed_io;
0193         acpi_dev_get_ioresource(res, fixed_io->address,
0194                     fixed_io->address_length,
0195                     ACPI_DECODE_10);
0196         break;
0197     default:
0198         res->flags = 0;
0199         return false;
0200     }
0201 
0202     return !(res->flags & IORESOURCE_DISABLED);
0203 }
0204 EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
0205 
0206 static bool acpi_decode_space(struct resource_win *win,
0207                   struct acpi_resource_address *addr,
0208                   struct acpi_address64_attribute *attr)
0209 {
0210     u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16;
0211     bool wp = addr->info.mem.write_protect;
0212     u64 len = attr->address_length;
0213     u64 start, end, offset = 0;
0214     struct resource *res = &win->res;
0215 
0216     /*
0217      * Filter out invalid descriptor according to ACPI Spec 5.0, section
0218      * 6.4.3.5 Address Space Resource Descriptors.
0219      */
0220     if ((addr->min_address_fixed != addr->max_address_fixed && len) ||
0221         (addr->min_address_fixed && addr->max_address_fixed && !len))
0222         pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n",
0223              addr->min_address_fixed, addr->max_address_fixed, len);
0224 
0225     /*
0226      * For bridges that translate addresses across the bridge,
0227      * translation_offset is the offset that must be added to the
0228      * address on the secondary side to obtain the address on the
0229      * primary side. Non-bridge devices must list 0 for all Address
0230      * Translation offset bits.
0231      */
0232     if (addr->producer_consumer == ACPI_PRODUCER)
0233         offset = attr->translation_offset;
0234     else if (attr->translation_offset)
0235         pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n",
0236              attr->translation_offset);
0237     start = attr->minimum + offset;
0238     end = attr->maximum + offset;
0239 
0240     win->offset = offset;
0241     res->start = start;
0242     res->end = end;
0243     if (sizeof(resource_size_t) < sizeof(u64) &&
0244         (offset != win->offset || start != res->start || end != res->end)) {
0245         pr_warn("acpi resource window ([%#llx-%#llx] ignored, not CPU addressable)\n",
0246             attr->minimum, attr->maximum);
0247         return false;
0248     }
0249 
0250     switch (addr->resource_type) {
0251     case ACPI_MEMORY_RANGE:
0252         acpi_dev_memresource_flags(res, len, wp);
0253         break;
0254     case ACPI_IO_RANGE:
0255         acpi_dev_ioresource_flags(res, len, iodec,
0256                       addr->info.io.translation_type);
0257         break;
0258     case ACPI_BUS_NUMBER_RANGE:
0259         res->flags = IORESOURCE_BUS;
0260         break;
0261     default:
0262         return false;
0263     }
0264 
0265     if (addr->producer_consumer == ACPI_PRODUCER)
0266         res->flags |= IORESOURCE_WINDOW;
0267 
0268     if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
0269         res->flags |= IORESOURCE_PREFETCH;
0270 
0271     return !(res->flags & IORESOURCE_DISABLED);
0272 }
0273 
0274 /**
0275  * acpi_dev_resource_address_space - Extract ACPI address space information.
0276  * @ares: Input ACPI resource object.
0277  * @win: Output generic resource object.
0278  *
0279  * Check if the given ACPI resource object represents an address space resource
0280  * and if that's the case, use the information in it to populate the generic
0281  * resource object pointed to by @win.
0282  *
0283  * Return:
0284  * 1) false with win->res.flags setting to zero: not the expected resource type
0285  * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
0286  *    resource
0287  * 3) true: valid assigned resource
0288  */
0289 bool acpi_dev_resource_address_space(struct acpi_resource *ares,
0290                      struct resource_win *win)
0291 {
0292     struct acpi_resource_address64 addr;
0293 
0294     win->res.flags = 0;
0295     if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr)))
0296         return false;
0297 
0298     return acpi_decode_space(win, (struct acpi_resource_address *)&addr,
0299                  &addr.address);
0300 }
0301 EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
0302 
0303 /**
0304  * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
0305  * @ares: Input ACPI resource object.
0306  * @win: Output generic resource object.
0307  *
0308  * Check if the given ACPI resource object represents an extended address space
0309  * resource and if that's the case, use the information in it to populate the
0310  * generic resource object pointed to by @win.
0311  *
0312  * Return:
0313  * 1) false with win->res.flags setting to zero: not the expected resource type
0314  * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
0315  *    resource
0316  * 3) true: valid assigned resource
0317  */
0318 bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
0319                      struct resource_win *win)
0320 {
0321     struct acpi_resource_extended_address64 *ext_addr;
0322 
0323     win->res.flags = 0;
0324     if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
0325         return false;
0326 
0327     ext_addr = &ares->data.ext_address64;
0328 
0329     return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr,
0330                  &ext_addr->address);
0331 }
0332 EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
0333 
0334 /**
0335  * acpi_dev_irq_flags - Determine IRQ resource flags.
0336  * @triggering: Triggering type as provided by ACPI.
0337  * @polarity: Interrupt polarity as provided by ACPI.
0338  * @shareable: Whether or not the interrupt is shareable.
0339  */
0340 unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
0341 {
0342     unsigned long flags;
0343 
0344     if (triggering == ACPI_LEVEL_SENSITIVE)
0345         flags = polarity == ACPI_ACTIVE_LOW ?
0346             IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
0347     else
0348         flags = polarity == ACPI_ACTIVE_LOW ?
0349             IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
0350 
0351     if (shareable == ACPI_SHARED)
0352         flags |= IORESOURCE_IRQ_SHAREABLE;
0353 
0354     return flags | IORESOURCE_IRQ;
0355 }
0356 EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
0357 
0358 /**
0359  * acpi_dev_get_irq_type - Determine irq type.
0360  * @triggering: Triggering type as provided by ACPI.
0361  * @polarity: Interrupt polarity as provided by ACPI.
0362  */
0363 unsigned int acpi_dev_get_irq_type(int triggering, int polarity)
0364 {
0365     switch (polarity) {
0366     case ACPI_ACTIVE_LOW:
0367         return triggering == ACPI_EDGE_SENSITIVE ?
0368                IRQ_TYPE_EDGE_FALLING :
0369                IRQ_TYPE_LEVEL_LOW;
0370     case ACPI_ACTIVE_HIGH:
0371         return triggering == ACPI_EDGE_SENSITIVE ?
0372                IRQ_TYPE_EDGE_RISING :
0373                IRQ_TYPE_LEVEL_HIGH;
0374     case ACPI_ACTIVE_BOTH:
0375         if (triggering == ACPI_EDGE_SENSITIVE)
0376             return IRQ_TYPE_EDGE_BOTH;
0377         fallthrough;
0378     default:
0379         return IRQ_TYPE_NONE;
0380     }
0381 }
0382 EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type);
0383 
0384 static const struct dmi_system_id medion_laptop[] = {
0385     {
0386         .ident = "MEDION P15651",
0387         .matches = {
0388             DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
0389             DMI_MATCH(DMI_BOARD_NAME, "M15T"),
0390         },
0391     },
0392     {
0393         .ident = "MEDION S17405",
0394         .matches = {
0395             DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
0396             DMI_MATCH(DMI_BOARD_NAME, "M17T"),
0397         },
0398     },
0399     { }
0400 };
0401 
0402 struct irq_override_cmp {
0403     const struct dmi_system_id *system;
0404     unsigned char irq;
0405     unsigned char triggering;
0406     unsigned char polarity;
0407     unsigned char shareable;
0408 };
0409 
0410 static const struct irq_override_cmp skip_override_table[] = {
0411     { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
0412 };
0413 
0414 static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
0415                   u8 shareable)
0416 {
0417     int i;
0418 
0419 #ifdef CONFIG_X86
0420     /*
0421      * IRQ override isn't needed on modern AMD Zen systems and
0422      * this override breaks active low IRQs on AMD Ryzen 6000 and
0423      * newer systems. Skip it.
0424      */
0425     if (boot_cpu_has(X86_FEATURE_ZEN))
0426         return false;
0427 #endif
0428 
0429     for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) {
0430         const struct irq_override_cmp *entry = &skip_override_table[i];
0431 
0432         if (dmi_check_system(entry->system) &&
0433             entry->irq == gsi &&
0434             entry->triggering == triggering &&
0435             entry->polarity == polarity &&
0436             entry->shareable == shareable)
0437             return false;
0438     }
0439 
0440     return true;
0441 }
0442 
0443 static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
0444                      u8 triggering, u8 polarity, u8 shareable,
0445                      bool check_override)
0446 {
0447     int irq, p, t;
0448 
0449     if (!valid_IRQ(gsi)) {
0450         irqresource_disabled(res, gsi);
0451         return;
0452     }
0453 
0454     /*
0455      * In IO-APIC mode, use overridden attribute. Two reasons:
0456      * 1. BIOS bug in DSDT
0457      * 2. BIOS uses IO-APIC mode Interrupt Source Override
0458      *
0459      * We do this only if we are dealing with IRQ() or IRQNoFlags()
0460      * resource (the legacy ISA resources). With modern ACPI 5 devices
0461      * using extended IRQ descriptors we take the IRQ configuration
0462      * from _CRS directly.
0463      */
0464     if (check_override &&
0465         acpi_dev_irq_override(gsi, triggering, polarity, shareable) &&
0466         !acpi_get_override_irq(gsi, &t, &p)) {
0467         u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
0468         u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
0469 
0470         if (triggering != trig || polarity != pol) {
0471             pr_warn("ACPI: IRQ %d override to %s, %s\n", gsi,
0472                 t ? "level" : "edge", p ? "low" : "high");
0473             triggering = trig;
0474             polarity = pol;
0475         }
0476     }
0477 
0478     res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
0479     irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
0480     if (irq >= 0) {
0481         res->start = irq;
0482         res->end = irq;
0483     } else {
0484         irqresource_disabled(res, gsi);
0485     }
0486 }
0487 
0488 /**
0489  * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
0490  * @ares: Input ACPI resource object.
0491  * @index: Index into the array of GSIs represented by the resource.
0492  * @res: Output generic resource object.
0493  *
0494  * Check if the given ACPI resource object represents an interrupt resource
0495  * and @index does not exceed the resource's interrupt count (true is returned
0496  * in that case regardless of the results of the other checks)).  If that's the
0497  * case, register the GSI corresponding to @index from the array of interrupts
0498  * represented by the resource and populate the generic resource object pointed
0499  * to by @res accordingly.  If the registration of the GSI is not successful,
0500  * IORESOURCE_DISABLED will be set it that object's flags.
0501  *
0502  * Return:
0503  * 1) false with res->flags setting to zero: not the expected resource type
0504  * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
0505  * 3) true: valid assigned resource
0506  */
0507 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
0508                  struct resource *res)
0509 {
0510     struct acpi_resource_irq *irq;
0511     struct acpi_resource_extended_irq *ext_irq;
0512 
0513     switch (ares->type) {
0514     case ACPI_RESOURCE_TYPE_IRQ:
0515         /*
0516          * Per spec, only one interrupt per descriptor is allowed in
0517          * _CRS, but some firmware violates this, so parse them all.
0518          */
0519         irq = &ares->data.irq;
0520         if (index >= irq->interrupt_count) {
0521             irqresource_disabled(res, 0);
0522             return false;
0523         }
0524         acpi_dev_get_irqresource(res, irq->interrupts[index],
0525                      irq->triggering, irq->polarity,
0526                      irq->shareable, true);
0527         break;
0528     case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
0529         ext_irq = &ares->data.extended_irq;
0530         if (index >= ext_irq->interrupt_count) {
0531             irqresource_disabled(res, 0);
0532             return false;
0533         }
0534         if (is_gsi(ext_irq))
0535             acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
0536                      ext_irq->triggering, ext_irq->polarity,
0537                      ext_irq->shareable, false);
0538         else
0539             irqresource_disabled(res, 0);
0540         break;
0541     default:
0542         res->flags = 0;
0543         return false;
0544     }
0545 
0546     return true;
0547 }
0548 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
0549 
0550 /**
0551  * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
0552  * @list: The head of the resource list to free.
0553  */
0554 void acpi_dev_free_resource_list(struct list_head *list)
0555 {
0556     resource_list_free(list);
0557 }
0558 EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
0559 
0560 struct res_proc_context {
0561     struct list_head *list;
0562     int (*preproc)(struct acpi_resource *, void *);
0563     void *preproc_data;
0564     int count;
0565     int error;
0566 };
0567 
0568 static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
0569                            struct res_proc_context *c)
0570 {
0571     struct resource_entry *rentry;
0572 
0573     rentry = resource_list_create_entry(NULL, 0);
0574     if (!rentry) {
0575         c->error = -ENOMEM;
0576         return AE_NO_MEMORY;
0577     }
0578     *rentry->res = win->res;
0579     rentry->offset = win->offset;
0580     resource_list_add_tail(rentry, c->list);
0581     c->count++;
0582     return AE_OK;
0583 }
0584 
0585 static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
0586                          void *context)
0587 {
0588     struct res_proc_context *c = context;
0589     struct resource_win win;
0590     struct resource *res = &win.res;
0591     int i;
0592 
0593     if (c->preproc) {
0594         int ret;
0595 
0596         ret = c->preproc(ares, c->preproc_data);
0597         if (ret < 0) {
0598             c->error = ret;
0599             return AE_ABORT_METHOD;
0600         } else if (ret > 0) {
0601             return AE_OK;
0602         }
0603     }
0604 
0605     memset(&win, 0, sizeof(win));
0606 
0607     if (acpi_dev_resource_memory(ares, res)
0608         || acpi_dev_resource_io(ares, res)
0609         || acpi_dev_resource_address_space(ares, &win)
0610         || acpi_dev_resource_ext_address_space(ares, &win))
0611         return acpi_dev_new_resource_entry(&win, c);
0612 
0613     for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
0614         acpi_status status;
0615 
0616         status = acpi_dev_new_resource_entry(&win, c);
0617         if (ACPI_FAILURE(status))
0618             return status;
0619     }
0620 
0621     return AE_OK;
0622 }
0623 
0624 static int __acpi_dev_get_resources(struct acpi_device *adev,
0625                     struct list_head *list,
0626                     int (*preproc)(struct acpi_resource *, void *),
0627                     void *preproc_data, char *method)
0628 {
0629     struct res_proc_context c;
0630     acpi_status status;
0631 
0632     if (!adev || !adev->handle || !list_empty(list))
0633         return -EINVAL;
0634 
0635     if (!acpi_has_method(adev->handle, method))
0636         return 0;
0637 
0638     c.list = list;
0639     c.preproc = preproc;
0640     c.preproc_data = preproc_data;
0641     c.count = 0;
0642     c.error = 0;
0643     status = acpi_walk_resources(adev->handle, method,
0644                      acpi_dev_process_resource, &c);
0645     if (ACPI_FAILURE(status)) {
0646         acpi_dev_free_resource_list(list);
0647         return c.error ? c.error : -EIO;
0648     }
0649 
0650     return c.count;
0651 }
0652 
0653 /**
0654  * acpi_dev_get_resources - Get current resources of a device.
0655  * @adev: ACPI device node to get the resources for.
0656  * @list: Head of the resultant list of resources (must be empty).
0657  * @preproc: The caller's preprocessing routine.
0658  * @preproc_data: Pointer passed to the caller's preprocessing routine.
0659  *
0660  * Evaluate the _CRS method for the given device node and process its output by
0661  * (1) executing the @preproc() routine provided by the caller, passing the
0662  * resource pointer and @preproc_data to it as arguments, for each ACPI resource
0663  * returned and (2) converting all of the returned ACPI resources into struct
0664  * resource objects if possible.  If the return value of @preproc() in step (1)
0665  * is different from 0, step (2) is not applied to the given ACPI resource and
0666  * if that value is negative, the whole processing is aborted and that value is
0667  * returned as the final error code.
0668  *
0669  * The resultant struct resource objects are put on the list pointed to by
0670  * @list, that must be empty initially, as members of struct resource_entry
0671  * objects.  Callers of this routine should use %acpi_dev_free_resource_list() to
0672  * free that list.
0673  *
0674  * The number of resources in the output list is returned on success, an error
0675  * code reflecting the error condition is returned otherwise.
0676  */
0677 int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
0678                int (*preproc)(struct acpi_resource *, void *),
0679                void *preproc_data)
0680 {
0681     return __acpi_dev_get_resources(adev, list, preproc, preproc_data,
0682                     METHOD_NAME__CRS);
0683 }
0684 EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
0685 
0686 static int is_memory(struct acpi_resource *ares, void *not_used)
0687 {
0688     struct resource_win win;
0689     struct resource *res = &win.res;
0690 
0691     memset(&win, 0, sizeof(win));
0692 
0693     return !(acpi_dev_resource_memory(ares, res)
0694            || acpi_dev_resource_address_space(ares, &win)
0695            || acpi_dev_resource_ext_address_space(ares, &win));
0696 }
0697 
0698 /**
0699  * acpi_dev_get_dma_resources - Get current DMA resources of a device.
0700  * @adev: ACPI device node to get the resources for.
0701  * @list: Head of the resultant list of resources (must be empty).
0702  *
0703  * Evaluate the _DMA method for the given device node and process its
0704  * output.
0705  *
0706  * The resultant struct resource objects are put on the list pointed to
0707  * by @list, that must be empty initially, as members of struct
0708  * resource_entry objects.  Callers of this routine should use
0709  * %acpi_dev_free_resource_list() to free that list.
0710  *
0711  * The number of resources in the output list is returned on success,
0712  * an error code reflecting the error condition is returned otherwise.
0713  */
0714 int acpi_dev_get_dma_resources(struct acpi_device *adev, struct list_head *list)
0715 {
0716     return __acpi_dev_get_resources(adev, list, is_memory, NULL,
0717                     METHOD_NAME__DMA);
0718 }
0719 EXPORT_SYMBOL_GPL(acpi_dev_get_dma_resources);
0720 
0721 /**
0722  * acpi_dev_filter_resource_type - Filter ACPI resource according to resource
0723  *                 types
0724  * @ares: Input ACPI resource object.
0725  * @types: Valid resource types of IORESOURCE_XXX
0726  *
0727  * This is a helper function to support acpi_dev_get_resources(), which filters
0728  * ACPI resource objects according to resource types.
0729  */
0730 int acpi_dev_filter_resource_type(struct acpi_resource *ares,
0731                   unsigned long types)
0732 {
0733     unsigned long type = 0;
0734 
0735     switch (ares->type) {
0736     case ACPI_RESOURCE_TYPE_MEMORY24:
0737     case ACPI_RESOURCE_TYPE_MEMORY32:
0738     case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
0739         type = IORESOURCE_MEM;
0740         break;
0741     case ACPI_RESOURCE_TYPE_IO:
0742     case ACPI_RESOURCE_TYPE_FIXED_IO:
0743         type = IORESOURCE_IO;
0744         break;
0745     case ACPI_RESOURCE_TYPE_IRQ:
0746     case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
0747         type = IORESOURCE_IRQ;
0748         break;
0749     case ACPI_RESOURCE_TYPE_DMA:
0750     case ACPI_RESOURCE_TYPE_FIXED_DMA:
0751         type = IORESOURCE_DMA;
0752         break;
0753     case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
0754         type = IORESOURCE_REG;
0755         break;
0756     case ACPI_RESOURCE_TYPE_ADDRESS16:
0757     case ACPI_RESOURCE_TYPE_ADDRESS32:
0758     case ACPI_RESOURCE_TYPE_ADDRESS64:
0759     case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
0760         if (ares->data.address.resource_type == ACPI_MEMORY_RANGE)
0761             type = IORESOURCE_MEM;
0762         else if (ares->data.address.resource_type == ACPI_IO_RANGE)
0763             type = IORESOURCE_IO;
0764         else if (ares->data.address.resource_type ==
0765              ACPI_BUS_NUMBER_RANGE)
0766             type = IORESOURCE_BUS;
0767         break;
0768     default:
0769         break;
0770     }
0771 
0772     return (type & types) ? 0 : 1;
0773 }
0774 EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
0775 
0776 static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res)
0777 {
0778     struct list_head resource_list;
0779     struct resource_entry *rentry;
0780     int ret, found = 0;
0781 
0782     INIT_LIST_HEAD(&resource_list);
0783     ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
0784     if (ret < 0)
0785         return 0;
0786 
0787     list_for_each_entry(rentry, &resource_list, node) {
0788         if (resource_contains(rentry->res, res)) {
0789             found = 1;
0790             break;
0791         }
0792 
0793     }
0794 
0795     acpi_dev_free_resource_list(&resource_list);
0796     return found;
0797 }
0798 
0799 static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth,
0800                      void *context, void **ret)
0801 {
0802     struct resource *res = context;
0803     struct acpi_device **consumer = (struct acpi_device **) ret;
0804     struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
0805 
0806     if (!adev)
0807         return AE_OK;
0808 
0809     if (acpi_dev_consumes_res(adev, res)) {
0810         *consumer = adev;
0811         return AE_CTRL_TERMINATE;
0812     }
0813 
0814     return AE_OK;
0815 }
0816 
0817 /**
0818  * acpi_resource_consumer - Find the ACPI device that consumes @res.
0819  * @res: Resource to search for.
0820  *
0821  * Search the current resource settings (_CRS) of every ACPI device node
0822  * for @res.  If we find an ACPI device whose _CRS includes @res, return
0823  * it.  Otherwise, return NULL.
0824  */
0825 struct acpi_device *acpi_resource_consumer(struct resource *res)
0826 {
0827     struct acpi_device *consumer = NULL;
0828 
0829     acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer);
0830     return consumer;
0831 }