aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resource.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-02-10 10:05:16 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-02-10 10:05:16 -0500
commit8fbcf5ecb336eb6da560f08d60e95b51d318795c (patch)
tree77a1b947838d60edd0e81d37327985de2e842b68 /drivers/acpi/resource.c
parentd23209680291dad6c79f1a6f187697c3884d554d (diff)
parent5c493df25a0d9e0c3bda742250ecfc5953bf4ccd (diff)
Merge branch 'acpi-resources'
* acpi-resources: (23 commits) Merge branch 'pci/host-generic' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci into acpi-resources x86/irq, ACPI: Implement ACPI driver to support IOAPIC hotplug ACPI: Add interfaces to parse IOAPIC ID for IOAPIC hotplug x86/PCI: Refine the way to release PCI IRQ resources x86/PCI/ACPI: Use common ACPI resource interfaces to simplify implementation x86/PCI: Fix the range check for IO resources PCI: Use common resource list management code instead of private implementation resources: Move struct resource_list_entry from ACPI into resource core ACPI: Introduce helper function acpi_dev_filter_resource_type() ACPI: Add field offset to struct resource_list_entry ACPI: Translate resource into master side address for bridge window resources ACPI: Return translation offset when parsing ACPI address space resources ACPI: Enforce stricter checks for address space descriptors ACPI: Set flag IORESOURCE_UNSET for unassigned resources ACPI: Normalize return value of resource parser functions ACPI: Fix a bug in parsing ACPI Memory24 resource ACPI: Add prefetch decoding to the address space parser ACPI: Move the window flag logic to the combined parser ACPI: Unify the parsing of address_space and ext_address_space ACPI: Let the parser return false for disabled resources ...
Diffstat (limited to 'drivers/acpi/resource.c')
-rw-r--r--drivers/acpi/resource.c353
1 files changed, 217 insertions, 136 deletions
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index d0a4d90c6bcc..4752b9939987 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -34,21 +34,34 @@
34#define valid_IRQ(i) (true) 34#define valid_IRQ(i) (true)
35#endif 35#endif
36 36
37static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect, 37static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io)
38 bool window)
39{ 38{
40 unsigned long flags = IORESOURCE_MEM; 39 u64 reslen = end - start + 1;
41 40
42 if (len == 0) 41 /*
43 flags |= IORESOURCE_DISABLED; 42 * CHECKME: len might be required to check versus a minimum
43 * length as well. 1 for io is fine, but for memory it does
44 * not make any sense at all.
45 */
46 if (len && reslen && reslen == len && start <= end)
47 return true;
44 48
45 if (write_protect == ACPI_READ_WRITE_MEMORY) 49 pr_info("ACPI: invalid or unassigned resource %s [%016llx - %016llx] length [%016llx]\n",
46 flags |= IORESOURCE_MEM_WRITEABLE; 50 io ? "io" : "mem", start, end, len);
51
52 return false;
53}
54
55static void acpi_dev_memresource_flags(struct resource *res, u64 len,
56 u8 write_protect)
57{
58 res->flags = IORESOURCE_MEM;
47 59
48 if (window) 60 if (!acpi_dev_resource_len_valid(res->start, res->end, len, false))
49 flags |= IORESOURCE_WINDOW; 61 res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
50 62
51 return flags; 63 if (write_protect == ACPI_READ_WRITE_MEMORY)
64 res->flags |= IORESOURCE_MEM_WRITEABLE;
52} 65}
53 66
54static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, 67static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
@@ -56,7 +69,7 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
56{ 69{
57 res->start = start; 70 res->start = start;
58 res->end = start + len - 1; 71 res->end = start + len - 1;
59 res->flags = acpi_dev_memresource_flags(len, write_protect, false); 72 acpi_dev_memresource_flags(res, len, write_protect);
60} 73}
61 74
62/** 75/**
@@ -67,6 +80,11 @@ static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
67 * Check if the given ACPI resource object represents a memory resource and 80 * Check if the given ACPI resource object represents a memory resource and
68 * if that's the case, use the information in it to populate the generic 81 * if that's the case, use the information in it to populate the generic
69 * resource object pointed to by @res. 82 * resource object pointed to by @res.
83 *
84 * Return:
85 * 1) false with res->flags setting to zero: not the expected resource type
86 * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
87 * 3) true: valid assigned resource
70 */ 88 */
71bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) 89bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
72{ 90{
@@ -77,60 +95,52 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
77 switch (ares->type) { 95 switch (ares->type) {
78 case ACPI_RESOURCE_TYPE_MEMORY24: 96 case ACPI_RESOURCE_TYPE_MEMORY24:
79 memory24 = &ares->data.memory24; 97 memory24 = &ares->data.memory24;
80 if (!memory24->minimum && !memory24->address_length) 98 acpi_dev_get_memresource(res, memory24->minimum << 8,
81 return false; 99 memory24->address_length << 8,
82 acpi_dev_get_memresource(res, memory24->minimum,
83 memory24->address_length,
84 memory24->write_protect); 100 memory24->write_protect);
85 break; 101 break;
86 case ACPI_RESOURCE_TYPE_MEMORY32: 102 case ACPI_RESOURCE_TYPE_MEMORY32:
87 memory32 = &ares->data.memory32; 103 memory32 = &ares->data.memory32;
88 if (!memory32->minimum && !memory32->address_length)
89 return false;
90 acpi_dev_get_memresource(res, memory32->minimum, 104 acpi_dev_get_memresource(res, memory32->minimum,
91 memory32->address_length, 105 memory32->address_length,
92 memory32->write_protect); 106 memory32->write_protect);
93 break; 107 break;
94 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 108 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
95 fixed_memory32 = &ares->data.fixed_memory32; 109 fixed_memory32 = &ares->data.fixed_memory32;
96 if (!fixed_memory32->address && !fixed_memory32->address_length)
97 return false;
98 acpi_dev_get_memresource(res, fixed_memory32->address, 110 acpi_dev_get_memresource(res, fixed_memory32->address,
99 fixed_memory32->address_length, 111 fixed_memory32->address_length,
100 fixed_memory32->write_protect); 112 fixed_memory32->write_protect);
101 break; 113 break;
102 default: 114 default:
115 res->flags = 0;
103 return false; 116 return false;
104 } 117 }
105 return true; 118
119 return !(res->flags & IORESOURCE_DISABLED);
106} 120}
107EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); 121EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
108 122
109static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode, 123static void acpi_dev_ioresource_flags(struct resource *res, u64 len,
110 bool window) 124 u8 io_decode)
111{ 125{
112 int flags = IORESOURCE_IO; 126 res->flags = IORESOURCE_IO;
113 127
114 if (io_decode == ACPI_DECODE_16) 128 if (!acpi_dev_resource_len_valid(res->start, res->end, len, true))
115 flags |= IORESOURCE_IO_16BIT_ADDR; 129 res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
116 130
117 if (start > end || end >= 0x10003) 131 if (res->end >= 0x10003)
118 flags |= IORESOURCE_DISABLED; 132 res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET;
119 133
120 if (window) 134 if (io_decode == ACPI_DECODE_16)
121 flags |= IORESOURCE_WINDOW; 135 res->flags |= IORESOURCE_IO_16BIT_ADDR;
122
123 return flags;
124} 136}
125 137
126static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len, 138static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
127 u8 io_decode) 139 u8 io_decode)
128{ 140{
129 u64 end = start + len - 1;
130
131 res->start = start; 141 res->start = start;
132 res->end = end; 142 res->end = start + len - 1;
133 res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false); 143 acpi_dev_ioresource_flags(res, len, io_decode);
134} 144}
135 145
136/** 146/**
@@ -141,6 +151,11 @@ static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
141 * Check if the given ACPI resource object represents an I/O resource and 151 * Check if the given ACPI resource object represents an I/O resource and
142 * if that's the case, use the information in it to populate the generic 152 * if that's the case, use the information in it to populate the generic
143 * resource object pointed to by @res. 153 * resource object pointed to by @res.
154 *
155 * Return:
156 * 1) false with res->flags setting to zero: not the expected resource type
157 * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
158 * 3) true: valid assigned resource
144 */ 159 */
145bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) 160bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
146{ 161{
@@ -150,135 +165,143 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
150 switch (ares->type) { 165 switch (ares->type) {
151 case ACPI_RESOURCE_TYPE_IO: 166 case ACPI_RESOURCE_TYPE_IO:
152 io = &ares->data.io; 167 io = &ares->data.io;
153 if (!io->minimum && !io->address_length)
154 return false;
155 acpi_dev_get_ioresource(res, io->minimum, 168 acpi_dev_get_ioresource(res, io->minimum,
156 io->address_length, 169 io->address_length,
157 io->io_decode); 170 io->io_decode);
158 break; 171 break;
159 case ACPI_RESOURCE_TYPE_FIXED_IO: 172 case ACPI_RESOURCE_TYPE_FIXED_IO:
160 fixed_io = &ares->data.fixed_io; 173 fixed_io = &ares->data.fixed_io;
161 if (!fixed_io->address && !fixed_io->address_length)
162 return false;
163 acpi_dev_get_ioresource(res, fixed_io->address, 174 acpi_dev_get_ioresource(res, fixed_io->address,
164 fixed_io->address_length, 175 fixed_io->address_length,
165 ACPI_DECODE_10); 176 ACPI_DECODE_10);
166 break; 177 break;
167 default: 178 default:
179 res->flags = 0;
168 return false; 180 return false;
169 } 181 }
170 return true; 182
183 return !(res->flags & IORESOURCE_DISABLED);
171} 184}
172EXPORT_SYMBOL_GPL(acpi_dev_resource_io); 185EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
173 186
174/** 187static bool acpi_decode_space(struct resource_win *win,
175 * acpi_dev_resource_address_space - Extract ACPI address space information. 188 struct acpi_resource_address *addr,
176 * @ares: Input ACPI resource object. 189 struct acpi_address64_attribute *attr)
177 * @res: Output generic resource object.
178 *
179 * Check if the given ACPI resource object represents an address space resource
180 * and if that's the case, use the information in it to populate the generic
181 * resource object pointed to by @res.
182 */
183bool acpi_dev_resource_address_space(struct acpi_resource *ares,
184 struct resource *res)
185{ 190{
186 acpi_status status; 191 u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16;
187 struct acpi_resource_address64 addr; 192 bool wp = addr->info.mem.write_protect;
188 bool window; 193 u64 len = attr->address_length;
189 u64 len; 194 struct resource *res = &win->res;
190 u8 io_decode;
191 195
192 switch (ares->type) { 196 /*
193 case ACPI_RESOURCE_TYPE_ADDRESS16: 197 * Filter out invalid descriptor according to ACPI Spec 5.0, section
194 case ACPI_RESOURCE_TYPE_ADDRESS32: 198 * 6.4.3.5 Address Space Resource Descriptors.
195 case ACPI_RESOURCE_TYPE_ADDRESS64: 199 */
196 break; 200 if ((addr->min_address_fixed != addr->max_address_fixed && len) ||
197 default: 201 (addr->min_address_fixed && addr->max_address_fixed && !len))
198 return false; 202 pr_debug("ACPI: Invalid address space min_addr_fix %d, max_addr_fix %d, len %llx\n",
199 } 203 addr->min_address_fixed, addr->max_address_fixed, len);
200 204
201 status = acpi_resource_to_address64(ares, &addr); 205 res->start = attr->minimum;
202 if (ACPI_FAILURE(status)) 206 res->end = attr->maximum;
203 return false;
204 207
205 res->start = addr.address.minimum; 208 /*
206 res->end = addr.address.maximum; 209 * For bridges that translate addresses across the bridge,
207 window = addr.producer_consumer == ACPI_PRODUCER; 210 * translation_offset is the offset that must be added to the
211 * address on the secondary side to obtain the address on the
212 * primary side. Non-bridge devices must list 0 for all Address
213 * Translation offset bits.
214 */
215 if (addr->producer_consumer == ACPI_PRODUCER) {
216 res->start += attr->translation_offset;
217 res->end += attr->translation_offset;
218 } else if (attr->translation_offset) {
219 pr_debug("ACPI: translation_offset(%lld) is invalid for non-bridge device.\n",
220 attr->translation_offset);
221 }
208 222
209 switch(addr.resource_type) { 223 switch (addr->resource_type) {
210 case ACPI_MEMORY_RANGE: 224 case ACPI_MEMORY_RANGE:
211 len = addr.address.maximum - addr.address.minimum + 1; 225 acpi_dev_memresource_flags(res, len, wp);
212 res->flags = acpi_dev_memresource_flags(len,
213 addr.info.mem.write_protect,
214 window);
215 break; 226 break;
216 case ACPI_IO_RANGE: 227 case ACPI_IO_RANGE:
217 io_decode = addr.address.granularity == 0xfff ? 228 acpi_dev_ioresource_flags(res, len, iodec);
218 ACPI_DECODE_10 : ACPI_DECODE_16;
219 res->flags = acpi_dev_ioresource_flags(addr.address.minimum,
220 addr.address.maximum,
221 io_decode, window);
222 break; 229 break;
223 case ACPI_BUS_NUMBER_RANGE: 230 case ACPI_BUS_NUMBER_RANGE:
224 res->flags = IORESOURCE_BUS; 231 res->flags = IORESOURCE_BUS;
225 break; 232 break;
226 default: 233 default:
227 res->flags = 0; 234 return false;
228 } 235 }
229 236
230 return true; 237 win->offset = attr->translation_offset;
238
239 if (addr->producer_consumer == ACPI_PRODUCER)
240 res->flags |= IORESOURCE_WINDOW;
241
242 if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
243 res->flags |= IORESOURCE_PREFETCH;
244
245 return !(res->flags & IORESOURCE_DISABLED);
246}
247
248/**
249 * acpi_dev_resource_address_space - Extract ACPI address space information.
250 * @ares: Input ACPI resource object.
251 * @win: Output generic resource object.
252 *
253 * Check if the given ACPI resource object represents an address space resource
254 * and if that's the case, use the information in it to populate the generic
255 * resource object pointed to by @win.
256 *
257 * Return:
258 * 1) false with win->res.flags setting to zero: not the expected resource type
259 * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
260 * resource
261 * 3) true: valid assigned resource
262 */
263bool acpi_dev_resource_address_space(struct acpi_resource *ares,
264 struct resource_win *win)
265{
266 struct acpi_resource_address64 addr;
267
268 win->res.flags = 0;
269 if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr)))
270 return false;
271
272 return acpi_decode_space(win, (struct acpi_resource_address *)&addr,
273 &addr.address);
231} 274}
232EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); 275EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
233 276
234/** 277/**
235 * acpi_dev_resource_ext_address_space - Extract ACPI address space information. 278 * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
236 * @ares: Input ACPI resource object. 279 * @ares: Input ACPI resource object.
237 * @res: Output generic resource object. 280 * @win: Output generic resource object.
238 * 281 *
239 * Check if the given ACPI resource object represents an extended address space 282 * Check if the given ACPI resource object represents an extended address space
240 * resource and if that's the case, use the information in it to populate the 283 * resource and if that's the case, use the information in it to populate the
241 * generic resource object pointed to by @res. 284 * generic resource object pointed to by @win.
285 *
286 * Return:
287 * 1) false with win->res.flags setting to zero: not the expected resource type
288 * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned
289 * resource
290 * 3) true: valid assigned resource
242 */ 291 */
243bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, 292bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
244 struct resource *res) 293 struct resource_win *win)
245{ 294{
246 struct acpi_resource_extended_address64 *ext_addr; 295 struct acpi_resource_extended_address64 *ext_addr;
247 bool window;
248 u64 len;
249 u8 io_decode;
250 296
297 win->res.flags = 0;
251 if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) 298 if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
252 return false; 299 return false;
253 300
254 ext_addr = &ares->data.ext_address64; 301 ext_addr = &ares->data.ext_address64;
255 302
256 res->start = ext_addr->address.minimum; 303 return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr,
257 res->end = ext_addr->address.maximum; 304 &ext_addr->address);
258 window = ext_addr->producer_consumer == ACPI_PRODUCER;
259
260 switch(ext_addr->resource_type) {
261 case ACPI_MEMORY_RANGE:
262 len = ext_addr->address.maximum - ext_addr->address.minimum + 1;
263 res->flags = acpi_dev_memresource_flags(len,
264 ext_addr->info.mem.write_protect,
265 window);
266 break;
267 case ACPI_IO_RANGE:
268 io_decode = ext_addr->address.granularity == 0xfff ?
269 ACPI_DECODE_10 : ACPI_DECODE_16;
270 res->flags = acpi_dev_ioresource_flags(ext_addr->address.minimum,
271 ext_addr->address.maximum,
272 io_decode, window);
273 break;
274 case ACPI_BUS_NUMBER_RANGE:
275 res->flags = IORESOURCE_BUS;
276 break;
277 default:
278 res->flags = 0;
279 }
280
281 return true;
282} 305}
283EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space); 306EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
284 307
@@ -310,7 +333,7 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
310{ 333{
311 res->start = gsi; 334 res->start = gsi;
312 res->end = gsi; 335 res->end = gsi;
313 res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED; 336 res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;
314} 337}
315 338
316static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, 339static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
@@ -369,6 +392,11 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
369 * represented by the resource and populate the generic resource object pointed 392 * represented by the resource and populate the generic resource object pointed
370 * to by @res accordingly. If the registration of the GSI is not successful, 393 * to by @res accordingly. If the registration of the GSI is not successful,
371 * IORESOURCE_DISABLED will be set it that object's flags. 394 * IORESOURCE_DISABLED will be set it that object's flags.
395 *
396 * Return:
397 * 1) false with res->flags setting to zero: not the expected resource type
398 * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource
399 * 3) true: valid assigned resource
372 */ 400 */
373bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, 401bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
374 struct resource *res) 402 struct resource *res)
@@ -402,6 +430,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
402 ext_irq->sharable, false); 430 ext_irq->sharable, false);
403 break; 431 break;
404 default: 432 default:
433 res->flags = 0;
405 return false; 434 return false;
406 } 435 }
407 436
@@ -415,12 +444,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
415 */ 444 */
416void acpi_dev_free_resource_list(struct list_head *list) 445void acpi_dev_free_resource_list(struct list_head *list)
417{ 446{
418 struct resource_list_entry *rentry, *re; 447 resource_list_free(list);
419
420 list_for_each_entry_safe(rentry, re, list, node) {
421 list_del(&rentry->node);
422 kfree(rentry);
423 }
424} 448}
425EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list); 449EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
426 450
@@ -432,18 +456,19 @@ struct res_proc_context {
432 int error; 456 int error;
433}; 457};
434 458
435static acpi_status acpi_dev_new_resource_entry(struct resource *r, 459static acpi_status acpi_dev_new_resource_entry(struct resource_win *win,
436 struct res_proc_context *c) 460 struct res_proc_context *c)
437{ 461{
438 struct resource_list_entry *rentry; 462 struct resource_entry *rentry;
439 463
440 rentry = kmalloc(sizeof(*rentry), GFP_KERNEL); 464 rentry = resource_list_create_entry(NULL, 0);
441 if (!rentry) { 465 if (!rentry) {
442 c->error = -ENOMEM; 466 c->error = -ENOMEM;
443 return AE_NO_MEMORY; 467 return AE_NO_MEMORY;
444 } 468 }
445 rentry->res = *r; 469 *rentry->res = win->res;
446 list_add_tail(&rentry->node, c->list); 470 rentry->offset = win->offset;
471 resource_list_add_tail(rentry, c->list);
447 c->count++; 472 c->count++;
448 return AE_OK; 473 return AE_OK;
449} 474}
@@ -452,7 +477,8 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
452 void *context) 477 void *context)
453{ 478{
454 struct res_proc_context *c = context; 479 struct res_proc_context *c = context;
455 struct resource r; 480 struct resource_win win;
481 struct resource *res = &win.res;
456 int i; 482 int i;
457 483
458 if (c->preproc) { 484 if (c->preproc) {
@@ -467,18 +493,18 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
467 } 493 }
468 } 494 }
469 495
470 memset(&r, 0, sizeof(r)); 496 memset(&win, 0, sizeof(win));
471 497
472 if (acpi_dev_resource_memory(ares, &r) 498 if (acpi_dev_resource_memory(ares, res)
473 || acpi_dev_resource_io(ares, &r) 499 || acpi_dev_resource_io(ares, res)
474 || acpi_dev_resource_address_space(ares, &r) 500 || acpi_dev_resource_address_space(ares, &win)
475 || acpi_dev_resource_ext_address_space(ares, &r)) 501 || acpi_dev_resource_ext_address_space(ares, &win))
476 return acpi_dev_new_resource_entry(&r, c); 502 return acpi_dev_new_resource_entry(&win, c);
477 503
478 for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) { 504 for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) {
479 acpi_status status; 505 acpi_status status;
480 506
481 status = acpi_dev_new_resource_entry(&r, c); 507 status = acpi_dev_new_resource_entry(&win, c);
482 if (ACPI_FAILURE(status)) 508 if (ACPI_FAILURE(status))
483 return status; 509 return status;
484 } 510 }
@@ -503,7 +529,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
503 * returned as the final error code. 529 * returned as the final error code.
504 * 530 *
505 * The resultant struct resource objects are put on the list pointed to by 531 * The resultant struct resource objects are put on the list pointed to by
506 * @list, that must be empty initially, as members of struct resource_list_entry 532 * @list, that must be empty initially, as members of struct resource_entry
507 * objects. Callers of this routine should use %acpi_dev_free_resource_list() to 533 * objects. Callers of this routine should use %acpi_dev_free_resource_list() to
508 * free that list. 534 * free that list.
509 * 535 *
@@ -538,3 +564,58 @@ int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
538 return c.count; 564 return c.count;
539} 565}
540EXPORT_SYMBOL_GPL(acpi_dev_get_resources); 566EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
567
568/**
569 * acpi_dev_filter_resource_type - Filter ACPI resource according to resource
570 * types
571 * @ares: Input ACPI resource object.
572 * @types: Valid resource types of IORESOURCE_XXX
573 *
574 * This is a hepler function to support acpi_dev_get_resources(), which filters
575 * ACPI resource objects according to resource types.
576 */
577int acpi_dev_filter_resource_type(struct acpi_resource *ares,
578 unsigned long types)
579{
580 unsigned long type = 0;
581
582 switch (ares->type) {
583 case ACPI_RESOURCE_TYPE_MEMORY24:
584 case ACPI_RESOURCE_TYPE_MEMORY32:
585 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
586 type = IORESOURCE_MEM;
587 break;
588 case ACPI_RESOURCE_TYPE_IO:
589 case ACPI_RESOURCE_TYPE_FIXED_IO:
590 type = IORESOURCE_IO;
591 break;
592 case ACPI_RESOURCE_TYPE_IRQ:
593 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
594 type = IORESOURCE_IRQ;
595 break;
596 case ACPI_RESOURCE_TYPE_DMA:
597 case ACPI_RESOURCE_TYPE_FIXED_DMA:
598 type = IORESOURCE_DMA;
599 break;
600 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
601 type = IORESOURCE_REG;
602 break;
603 case ACPI_RESOURCE_TYPE_ADDRESS16:
604 case ACPI_RESOURCE_TYPE_ADDRESS32:
605 case ACPI_RESOURCE_TYPE_ADDRESS64:
606 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
607 if (ares->data.address.resource_type == ACPI_MEMORY_RANGE)
608 type = IORESOURCE_MEM;
609 else if (ares->data.address.resource_type == ACPI_IO_RANGE)
610 type = IORESOURCE_IO;
611 else if (ares->data.address.resource_type ==
612 ACPI_BUS_NUMBER_RANGE)
613 type = IORESOURCE_BUS;
614 break;
615 default:
616 break;
617 }
618
619 return (type & types) ? 0 : 1;
620}
621EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);