xref: /openbmc/linux/drivers/pnp/pnpacpi/rsparser.c (revision 64c70b1c)
1 /*
2  * pnpacpi -- PnP ACPI driver
3  *
4  * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
5  * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #include <linux/kernel.h>
22 #include <linux/acpi.h>
23 #include <linux/pci.h>
24 #include "pnpacpi.h"
25 
26 #ifdef CONFIG_IA64
27 #define valid_IRQ(i) (1)
28 #else
29 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
30 #endif
31 
32 /*
33  * Allocated Resources
34  */
35 static int irq_flags(int triggering, int polarity)
36 {
37 	int flag;
38 	if (triggering == ACPI_LEVEL_SENSITIVE) {
39 		if (polarity == ACPI_ACTIVE_LOW)
40 			flag = IORESOURCE_IRQ_LOWLEVEL;
41 		else
42 			flag = IORESOURCE_IRQ_HIGHLEVEL;
43 	}
44 	else {
45 		if (polarity == ACPI_ACTIVE_LOW)
46 			flag = IORESOURCE_IRQ_LOWEDGE;
47 		else
48 			flag = IORESOURCE_IRQ_HIGHEDGE;
49 	}
50 	return flag;
51 }
52 
53 static void decode_irq_flags(int flag, int *triggering, int *polarity)
54 {
55 	switch (flag) {
56 	case IORESOURCE_IRQ_LOWLEVEL:
57 		*triggering = ACPI_LEVEL_SENSITIVE;
58 		*polarity = ACPI_ACTIVE_LOW;
59 		break;
60 	case IORESOURCE_IRQ_HIGHLEVEL:
61 		*triggering = ACPI_LEVEL_SENSITIVE;
62 		*polarity = ACPI_ACTIVE_HIGH;
63 		break;
64 	case IORESOURCE_IRQ_LOWEDGE:
65 		*triggering = ACPI_EDGE_SENSITIVE;
66 		*polarity = ACPI_ACTIVE_LOW;
67 		break;
68 	case IORESOURCE_IRQ_HIGHEDGE:
69 		*triggering = ACPI_EDGE_SENSITIVE;
70 		*polarity = ACPI_ACTIVE_HIGH;
71 		break;
72 	}
73 }
74 
75 static void
76 pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi,
77 	int triggering, int polarity, int shareable)
78 {
79 	int i = 0;
80 	int irq;
81 
82 	if (!valid_IRQ(gsi))
83 		return;
84 
85 	while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
86 			i < PNP_MAX_IRQ)
87 		i++;
88 	if (i >= PNP_MAX_IRQ)
89 		return;
90 
91 	res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
92 	res->irq_resource[i].flags |= irq_flags(triggering, polarity);
93 	irq = acpi_register_gsi(gsi, triggering, polarity);
94 	if (irq < 0) {
95 		res->irq_resource[i].flags |= IORESOURCE_DISABLED;
96 		return;
97 	}
98 
99 	if (shareable)
100 		res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;
101 
102 	res->irq_resource[i].start = irq;
103 	res->irq_resource[i].end = irq;
104 	pcibios_penalize_isa_irq(irq, 1);
105 }
106 
107 static int dma_flags(int type, int bus_master, int transfer)
108 {
109 	int flags = 0;
110 
111 	if (bus_master)
112 		flags |= IORESOURCE_DMA_MASTER;
113 	switch (type) {
114 	case ACPI_COMPATIBILITY:
115 		flags |= IORESOURCE_DMA_COMPATIBLE;
116 		break;
117 	case ACPI_TYPE_A:
118 		flags |= IORESOURCE_DMA_TYPEA;
119 		break;
120 	case ACPI_TYPE_B:
121 		flags |= IORESOURCE_DMA_TYPEB;
122 		break;
123 	case ACPI_TYPE_F:
124 		flags |= IORESOURCE_DMA_TYPEF;
125 		break;
126 	default:
127 		/* Set a default value ? */
128 		flags |= IORESOURCE_DMA_COMPATIBLE;
129 		pnp_err("Invalid DMA type");
130 	}
131 	switch (transfer) {
132 	case ACPI_TRANSFER_8:
133 		flags |= IORESOURCE_DMA_8BIT;
134 		break;
135 	case ACPI_TRANSFER_8_16:
136 		flags |= IORESOURCE_DMA_8AND16BIT;
137 		break;
138 	case ACPI_TRANSFER_16:
139 		flags |= IORESOURCE_DMA_16BIT;
140 		break;
141 	default:
142 		/* Set a default value ? */
143 		flags |= IORESOURCE_DMA_8AND16BIT;
144 		pnp_err("Invalid DMA transfer type");
145 	}
146 
147 	return flags;
148 }
149 
150 static void
151 pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma,
152 	int type, int bus_master, int transfer)
153 {
154 	int i = 0;
155 	while (i < PNP_MAX_DMA &&
156 			!(res->dma_resource[i].flags & IORESOURCE_UNSET))
157 		i++;
158 	if (i < PNP_MAX_DMA) {
159 		res->dma_resource[i].flags = IORESOURCE_DMA;  // Also clears _UNSET flag
160 		res->dma_resource[i].flags |= dma_flags(type, bus_master, transfer);
161 		if (dma == -1) {
162 			res->dma_resource[i].flags |= IORESOURCE_DISABLED;
163 			return;
164 		}
165 		res->dma_resource[i].start = dma;
166 		res->dma_resource[i].end = dma;
167 	}
168 }
169 
170 static void
171 pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
172 	u64 io, u64 len, int io_decode)
173 {
174 	int i = 0;
175 	while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
176 			i < PNP_MAX_PORT)
177 		i++;
178 	if (i < PNP_MAX_PORT) {
179 		res->port_resource[i].flags = IORESOURCE_IO;  // Also clears _UNSET flag
180 		if (io_decode == ACPI_DECODE_16)
181 			res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
182 		if (len <= 0 || (io + len -1) >= 0x10003) {
183 			res->port_resource[i].flags |= IORESOURCE_DISABLED;
184 			return;
185 		}
186 		res->port_resource[i].start = io;
187 		res->port_resource[i].end = io + len - 1;
188 	}
189 }
190 
191 static void
192 pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
193 	u64 mem, u64 len, int write_protect)
194 {
195 	int i = 0;
196 	while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
197 			(i < PNP_MAX_MEM))
198 		i++;
199 	if (i < PNP_MAX_MEM) {
200 		res->mem_resource[i].flags = IORESOURCE_MEM;  // Also clears _UNSET flag
201 		if (len <= 0) {
202 			res->mem_resource[i].flags |= IORESOURCE_DISABLED;
203 			return;
204 		}
205 		if(write_protect == ACPI_READ_WRITE_MEMORY)
206 			res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
207 
208 		res->mem_resource[i].start = mem;
209 		res->mem_resource[i].end = mem + len - 1;
210 	}
211 }
212 
213 static void
214 pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
215 	struct acpi_resource *res)
216 {
217 	struct acpi_resource_address64 addr, *p = &addr;
218 	acpi_status status;
219 
220 	status = acpi_resource_to_address64(res, p);
221 	if (!ACPI_SUCCESS(status)) {
222 		pnp_warn("PnPACPI: failed to convert resource type %d",
223 			res->type);
224 		return;
225 	}
226 
227 	if (p->producer_consumer == ACPI_PRODUCER)
228 		return;
229 
230 	if (p->resource_type == ACPI_MEMORY_RANGE)
231 		pnpacpi_parse_allocated_memresource(res_table,
232 				p->minimum, p->address_length, p->info.mem.write_protect);
233 	else if (p->resource_type == ACPI_IO_RANGE)
234 		pnpacpi_parse_allocated_ioresource(res_table,
235 				p->minimum, p->address_length,
236 				p->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16);
237 }
238 
239 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
240 	void *data)
241 {
242 	struct pnp_resource_table *res_table = (struct pnp_resource_table *)data;
243 	int i;
244 
245 	switch (res->type) {
246 	case ACPI_RESOURCE_TYPE_IRQ:
247 		/*
248 		 * Per spec, only one interrupt per descriptor is allowed in
249 		 * _CRS, but some firmware violates this, so parse them all.
250 		 */
251 		for (i = 0; i < res->data.irq.interrupt_count; i++) {
252 			pnpacpi_parse_allocated_irqresource(res_table,
253 				res->data.irq.interrupts[i],
254 				res->data.irq.triggering,
255 				res->data.irq.polarity,
256 				res->data.irq.sharable);
257 		}
258 		break;
259 
260 	case ACPI_RESOURCE_TYPE_DMA:
261 		if (res->data.dma.channel_count > 0)
262 			pnpacpi_parse_allocated_dmaresource(res_table,
263 					res->data.dma.channels[0],
264 					res->data.dma.type,
265 					res->data.dma.bus_master,
266 					res->data.dma.transfer);
267 		break;
268 
269 	case ACPI_RESOURCE_TYPE_IO:
270 		pnpacpi_parse_allocated_ioresource(res_table,
271 				res->data.io.minimum,
272 				res->data.io.address_length,
273 				res->data.io.io_decode);
274 		break;
275 
276 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
277 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
278 		break;
279 
280 	case ACPI_RESOURCE_TYPE_FIXED_IO:
281 		pnpacpi_parse_allocated_ioresource(res_table,
282 				res->data.fixed_io.address,
283 				res->data.fixed_io.address_length,
284 				ACPI_DECODE_10);
285 		break;
286 
287 	case ACPI_RESOURCE_TYPE_VENDOR:
288 		break;
289 
290 	case ACPI_RESOURCE_TYPE_END_TAG:
291 		break;
292 
293 	case ACPI_RESOURCE_TYPE_MEMORY24:
294 		pnpacpi_parse_allocated_memresource(res_table,
295 				res->data.memory24.minimum,
296 				res->data.memory24.address_length,
297 				res->data.memory24.write_protect);
298 		break;
299 	case ACPI_RESOURCE_TYPE_MEMORY32:
300 		pnpacpi_parse_allocated_memresource(res_table,
301 				res->data.memory32.minimum,
302 				res->data.memory32.address_length,
303 				res->data.memory32.write_protect);
304 		break;
305 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
306 		pnpacpi_parse_allocated_memresource(res_table,
307 				res->data.fixed_memory32.address,
308 				res->data.fixed_memory32.address_length,
309 				res->data.fixed_memory32.write_protect);
310 		break;
311 	case ACPI_RESOURCE_TYPE_ADDRESS16:
312 	case ACPI_RESOURCE_TYPE_ADDRESS32:
313 	case ACPI_RESOURCE_TYPE_ADDRESS64:
314 		pnpacpi_parse_allocated_address_space(res_table, res);
315 		break;
316 
317 	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
318 		if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
319 			return AE_OK;
320 		break;
321 
322 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
323 		if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER)
324 			return AE_OK;
325 
326 		for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
327 			pnpacpi_parse_allocated_irqresource(res_table,
328 				res->data.extended_irq.interrupts[i],
329 				res->data.extended_irq.triggering,
330 				res->data.extended_irq.polarity,
331 				res->data.extended_irq.sharable);
332 		}
333 		break;
334 
335 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
336 		break;
337 
338 	default:
339 		pnp_warn("PnPACPI: unknown resource type %d", res->type);
340 		return AE_ERROR;
341 	}
342 
343 	return AE_OK;
344 }
345 
346 acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, struct pnp_resource_table *res)
347 {
348 	/* Blank the resource table values */
349 	pnp_init_resource_table(res);
350 
351 	return acpi_walk_resources(handle, METHOD_NAME__CRS, pnpacpi_allocated_resource, res);
352 }
353 
354 static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_resource_dma *p)
355 {
356 	int i;
357 	struct pnp_dma * dma;
358 
359 	if (p->channel_count == 0)
360 		return;
361 	dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
362 	if (!dma)
363 		return;
364 
365 	for(i = 0; i < p->channel_count; i++)
366 		dma->map |= 1 << p->channels[i];
367 
368 	dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
369 
370 	pnp_register_dma_resource(option, dma);
371 	return;
372 }
373 
374 
375 static void pnpacpi_parse_irq_option(struct pnp_option *option,
376 	struct acpi_resource_irq *p)
377 {
378 	int i;
379 	struct pnp_irq *irq;
380 
381 	if (p->interrupt_count == 0)
382 		return;
383 	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
384 	if (!irq)
385 		return;
386 
387 	for(i = 0; i < p->interrupt_count; i++)
388 		if (p->interrupts[i])
389 			__set_bit(p->interrupts[i], irq->map);
390 	irq->flags = irq_flags(p->triggering, p->polarity);
391 
392 	pnp_register_irq_resource(option, irq);
393 	return;
394 }
395 
396 static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
397 	struct acpi_resource_extended_irq *p)
398 {
399 	int i;
400 	struct pnp_irq *irq;
401 
402 	if (p->interrupt_count == 0)
403 		return;
404 	irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
405 	if (!irq)
406 		return;
407 
408 	for(i = 0; i < p->interrupt_count; i++)
409 		if (p->interrupts[i])
410 			__set_bit(p->interrupts[i], irq->map);
411 	irq->flags = irq_flags(p->triggering, p->polarity);
412 
413 	pnp_register_irq_resource(option, irq);
414 	return;
415 }
416 
417 static void
418 pnpacpi_parse_port_option(struct pnp_option *option,
419 	struct acpi_resource_io *io)
420 {
421 	struct pnp_port *port;
422 
423 	if (io->address_length == 0)
424 		return;
425 	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
426 	if (!port)
427 		return;
428 	port->min = io->minimum;
429 	port->max = io->maximum;
430 	port->align = io->alignment;
431 	port->size = io->address_length;
432 	port->flags = ACPI_DECODE_16 == io->io_decode ?
433 		PNP_PORT_FLAG_16BITADDR : 0;
434 	pnp_register_port_resource(option, port);
435 	return;
436 }
437 
438 static void
439 pnpacpi_parse_fixed_port_option(struct pnp_option *option,
440 	struct acpi_resource_fixed_io *io)
441 {
442 	struct pnp_port *port;
443 
444 	if (io->address_length == 0)
445 		return;
446 	port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
447 	if (!port)
448 		return;
449 	port->min = port->max = io->address;
450 	port->size = io->address_length;
451 	port->align = 0;
452 	port->flags = PNP_PORT_FLAG_FIXED;
453 	pnp_register_port_resource(option, port);
454 	return;
455 }
456 
457 static void
458 pnpacpi_parse_mem24_option(struct pnp_option *option,
459 	struct acpi_resource_memory24 *p)
460 {
461 	struct pnp_mem *mem;
462 
463 	if (p->address_length == 0)
464 		return;
465 	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
466 	if (!mem)
467 		return;
468 	mem->min = p->minimum;
469 	mem->max = p->maximum;
470 	mem->align = p->alignment;
471 	mem->size = p->address_length;
472 
473 	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
474 			IORESOURCE_MEM_WRITEABLE : 0;
475 
476 	pnp_register_mem_resource(option, mem);
477 	return;
478 }
479 
480 static void
481 pnpacpi_parse_mem32_option(struct pnp_option *option,
482 	struct acpi_resource_memory32 *p)
483 {
484 	struct pnp_mem *mem;
485 
486 	if (p->address_length == 0)
487 		return;
488 	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
489 	if (!mem)
490 		return;
491 	mem->min = p->minimum;
492 	mem->max = p->maximum;
493 	mem->align = p->alignment;
494 	mem->size = p->address_length;
495 
496 	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
497 			IORESOURCE_MEM_WRITEABLE : 0;
498 
499 	pnp_register_mem_resource(option, mem);
500 	return;
501 }
502 
503 static void
504 pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
505 	struct acpi_resource_fixed_memory32 *p)
506 {
507 	struct pnp_mem *mem;
508 
509 	if (p->address_length == 0)
510 		return;
511 	mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
512 	if (!mem)
513 		return;
514 	mem->min = mem->max = p->address;
515 	mem->size = p->address_length;
516 	mem->align = 0;
517 
518 	mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
519 			IORESOURCE_MEM_WRITEABLE : 0;
520 
521 	pnp_register_mem_resource(option, mem);
522 	return;
523 }
524 
525 static void
526 pnpacpi_parse_address_option(struct pnp_option *option, struct acpi_resource *r)
527 {
528 	struct acpi_resource_address64 addr, *p = &addr;
529 	acpi_status status;
530 	struct pnp_mem *mem;
531 	struct pnp_port *port;
532 
533 	status = acpi_resource_to_address64(r, p);
534 	if (!ACPI_SUCCESS(status)) {
535 		pnp_warn("PnPACPI: failed to convert resource type %d", r->type);
536 		return;
537 	}
538 
539 	if (p->address_length == 0)
540 		return;
541 
542 	if (p->resource_type == ACPI_MEMORY_RANGE) {
543 		mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
544 		if (!mem)
545 			return;
546 		mem->min = mem->max = p->minimum;
547 		mem->size = p->address_length;
548 		mem->align = 0;
549 		mem->flags = (p->info.mem.write_protect ==
550 		    ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE : 0;
551 		pnp_register_mem_resource(option, mem);
552 	} else if (p->resource_type == ACPI_IO_RANGE) {
553 		port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
554 		if (!port)
555 			return;
556 		port->min = port->max = p->minimum;
557 		port->size = p->address_length;
558 		port->align = 0;
559 		port->flags = PNP_PORT_FLAG_FIXED;
560 		pnp_register_port_resource(option, port);
561 	}
562 }
563 
564 struct acpipnp_parse_option_s {
565 	struct pnp_option *option;
566 	struct pnp_option *option_independent;
567 	struct pnp_dev *dev;
568 };
569 
570 static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
571 	void *data)
572 {
573 	int priority = 0;
574 	struct acpipnp_parse_option_s *parse_data = (struct acpipnp_parse_option_s *)data;
575 	struct pnp_dev *dev = parse_data->dev;
576 	struct pnp_option *option = parse_data->option;
577 
578 	switch (res->type) {
579 		case ACPI_RESOURCE_TYPE_IRQ:
580 			pnpacpi_parse_irq_option(option, &res->data.irq);
581 			break;
582 
583 		case ACPI_RESOURCE_TYPE_DMA:
584 			pnpacpi_parse_dma_option(option, &res->data.dma);
585 			break;
586 
587 		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
588 			switch (res->data.start_dpf.compatibility_priority) {
589 				case ACPI_GOOD_CONFIGURATION:
590 					priority = PNP_RES_PRIORITY_PREFERRED;
591 					break;
592 
593 				case ACPI_ACCEPTABLE_CONFIGURATION:
594 					priority = PNP_RES_PRIORITY_ACCEPTABLE;
595 					break;
596 
597 				case ACPI_SUB_OPTIMAL_CONFIGURATION:
598 					priority = PNP_RES_PRIORITY_FUNCTIONAL;
599 					break;
600 				default:
601 					priority = PNP_RES_PRIORITY_INVALID;
602 					break;
603 			}
604 			/* TBD: Considering performace/robustness bits */
605 			option = pnp_register_dependent_option(dev, priority);
606 			if (!option)
607 				return AE_ERROR;
608 			parse_data->option = option;
609 			break;
610 
611 		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
612 			/*only one EndDependentFn is allowed*/
613 			if (!parse_data->option_independent) {
614 				pnp_warn("PnPACPI: more than one EndDependentFn");
615 				return AE_ERROR;
616 			}
617 			parse_data->option = parse_data->option_independent;
618 			parse_data->option_independent = NULL;
619 			break;
620 
621 		case ACPI_RESOURCE_TYPE_IO:
622 			pnpacpi_parse_port_option(option, &res->data.io);
623 			break;
624 
625 		case ACPI_RESOURCE_TYPE_FIXED_IO:
626 			pnpacpi_parse_fixed_port_option(option,
627 				&res->data.fixed_io);
628 			break;
629 
630 		case ACPI_RESOURCE_TYPE_VENDOR:
631 		case ACPI_RESOURCE_TYPE_END_TAG:
632 			break;
633 
634 		case ACPI_RESOURCE_TYPE_MEMORY24:
635 			pnpacpi_parse_mem24_option(option, &res->data.memory24);
636 			break;
637 
638 		case ACPI_RESOURCE_TYPE_MEMORY32:
639 			pnpacpi_parse_mem32_option(option, &res->data.memory32);
640 			break;
641 
642 		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
643 			pnpacpi_parse_fixed_mem32_option(option,
644 				&res->data.fixed_memory32);
645 			break;
646 
647 		case ACPI_RESOURCE_TYPE_ADDRESS16:
648 		case ACPI_RESOURCE_TYPE_ADDRESS32:
649 		case ACPI_RESOURCE_TYPE_ADDRESS64:
650 			pnpacpi_parse_address_option(option, res);
651 			break;
652 
653 		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
654 			break;
655 
656 		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
657 			pnpacpi_parse_ext_irq_option(option,
658 				&res->data.extended_irq);
659 			break;
660 
661 		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
662 			break;
663 
664 		default:
665 			pnp_warn("PnPACPI: unknown resource type %d", res->type);
666 			return AE_ERROR;
667 	}
668 
669 	return AE_OK;
670 }
671 
672 acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle,
673 	struct pnp_dev *dev)
674 {
675 	acpi_status status;
676 	struct acpipnp_parse_option_s parse_data;
677 
678 	parse_data.option = pnp_register_independent_option(dev);
679 	if (!parse_data.option)
680 		return AE_ERROR;
681 	parse_data.option_independent = parse_data.option;
682 	parse_data.dev = dev;
683 	status = acpi_walk_resources(handle, METHOD_NAME__PRS,
684 		pnpacpi_option_resource, &parse_data);
685 
686 	return status;
687 }
688 
689 static int pnpacpi_supported_resource(struct acpi_resource *res)
690 {
691 	switch (res->type) {
692 	case ACPI_RESOURCE_TYPE_IRQ:
693 	case ACPI_RESOURCE_TYPE_DMA:
694 	case ACPI_RESOURCE_TYPE_IO:
695 	case ACPI_RESOURCE_TYPE_FIXED_IO:
696 	case ACPI_RESOURCE_TYPE_MEMORY24:
697 	case ACPI_RESOURCE_TYPE_MEMORY32:
698 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
699 	case ACPI_RESOURCE_TYPE_ADDRESS16:
700 	case ACPI_RESOURCE_TYPE_ADDRESS32:
701 	case ACPI_RESOURCE_TYPE_ADDRESS64:
702 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
703 		return 1;
704 	}
705 	return 0;
706 }
707 
708 /*
709  * Set resource
710  */
711 static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
712 	void *data)
713 {
714 	int *res_cnt = (int *)data;
715 
716 	if (pnpacpi_supported_resource(res))
717 		(*res_cnt)++;
718 	return AE_OK;
719 }
720 
721 static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
722 {
723 	struct acpi_resource **resource = (struct acpi_resource **)data;
724 
725 	if (pnpacpi_supported_resource(res)) {
726 		(*resource)->type = res->type;
727 		(*resource)->length = sizeof(struct acpi_resource);
728 		(*resource)++;
729 	}
730 
731 	return AE_OK;
732 }
733 
734 int pnpacpi_build_resource_template(acpi_handle handle,
735 	struct acpi_buffer *buffer)
736 {
737 	struct acpi_resource *resource;
738 	int res_cnt = 0;
739 	acpi_status status;
740 
741 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
742 		pnpacpi_count_resources, &res_cnt);
743 	if (ACPI_FAILURE(status)) {
744 		pnp_err("Evaluate _CRS failed");
745 		return -EINVAL;
746 	}
747 	if (!res_cnt)
748 		return -EINVAL;
749 	buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
750 	buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
751 	if (!buffer->pointer)
752 		return -ENOMEM;
753 	pnp_dbg("Res cnt %d", res_cnt);
754 	resource = (struct acpi_resource *)buffer->pointer;
755 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
756 		pnpacpi_type_resources, &resource);
757 	if (ACPI_FAILURE(status)) {
758 		kfree(buffer->pointer);
759 		pnp_err("Evaluate _CRS failed");
760 		return -EINVAL;
761 	}
762 	/* resource will pointer the end resource now */
763 	resource->type = ACPI_RESOURCE_TYPE_END_TAG;
764 
765 	return 0;
766 }
767 
768 static void pnpacpi_encode_irq(struct acpi_resource *resource,
769 	struct resource *p)
770 {
771 	int triggering, polarity;
772 
773 	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
774 	resource->data.irq.triggering = triggering;
775 	resource->data.irq.polarity = polarity;
776 	if (triggering == ACPI_EDGE_SENSITIVE)
777 		resource->data.irq.sharable = ACPI_EXCLUSIVE;
778 	else
779 		resource->data.irq.sharable = ACPI_SHARED;
780 	resource->data.irq.interrupt_count = 1;
781 	resource->data.irq.interrupts[0] = p->start;
782 }
783 
784 static void pnpacpi_encode_ext_irq(struct acpi_resource *resource,
785 	struct resource *p)
786 {
787 	int triggering, polarity;
788 
789 	decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
790 	resource->data.extended_irq.producer_consumer = ACPI_CONSUMER;
791 	resource->data.extended_irq.triggering = triggering;
792 	resource->data.extended_irq.polarity = polarity;
793 	if (triggering == ACPI_EDGE_SENSITIVE)
794 		resource->data.irq.sharable = ACPI_EXCLUSIVE;
795 	else
796 		resource->data.irq.sharable = ACPI_SHARED;
797 	resource->data.extended_irq.interrupt_count = 1;
798 	resource->data.extended_irq.interrupts[0] = p->start;
799 }
800 
801 static void pnpacpi_encode_dma(struct acpi_resource *resource,
802 	struct resource *p)
803 {
804 	/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
805 	switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
806 		case IORESOURCE_DMA_TYPEA:
807 			resource->data.dma.type = ACPI_TYPE_A;
808 			break;
809 		case IORESOURCE_DMA_TYPEB:
810 			resource->data.dma.type = ACPI_TYPE_B;
811 			break;
812 		case IORESOURCE_DMA_TYPEF:
813 			resource->data.dma.type = ACPI_TYPE_F;
814 			break;
815 		default:
816 			resource->data.dma.type = ACPI_COMPATIBILITY;
817 	}
818 
819 	switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
820 		case IORESOURCE_DMA_8BIT:
821 			resource->data.dma.transfer = ACPI_TRANSFER_8;
822 			break;
823 		case IORESOURCE_DMA_8AND16BIT:
824 			resource->data.dma.transfer = ACPI_TRANSFER_8_16;
825 			break;
826 		default:
827 			resource->data.dma.transfer = ACPI_TRANSFER_16;
828 	}
829 
830 	resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
831 	resource->data.dma.channel_count = 1;
832 	resource->data.dma.channels[0] = p->start;
833 }
834 
835 static void pnpacpi_encode_io(struct acpi_resource *resource,
836 	struct resource *p)
837 {
838 	/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
839 	resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR)?
840 		ACPI_DECODE_16 : ACPI_DECODE_10;
841 	resource->data.io.minimum = p->start;
842 	resource->data.io.maximum = p->end;
843 	resource->data.io.alignment = 0; /* Correct? */
844 	resource->data.io.address_length = p->end - p->start + 1;
845 }
846 
847 static void pnpacpi_encode_fixed_io(struct acpi_resource *resource,
848 	struct resource *p)
849 {
850 	resource->data.fixed_io.address = p->start;
851 	resource->data.fixed_io.address_length = p->end - p->start + 1;
852 }
853 
854 static void pnpacpi_encode_mem24(struct acpi_resource *resource,
855 	struct resource *p)
856 {
857 	/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
858 	resource->data.memory24.write_protect =
859 		(p->flags & IORESOURCE_MEM_WRITEABLE) ?
860 		ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
861 	resource->data.memory24.minimum = p->start;
862 	resource->data.memory24.maximum = p->end;
863 	resource->data.memory24.alignment = 0;
864 	resource->data.memory24.address_length = p->end - p->start + 1;
865 }
866 
867 static void pnpacpi_encode_mem32(struct acpi_resource *resource,
868 	struct resource *p)
869 {
870 	resource->data.memory32.write_protect =
871 		(p->flags & IORESOURCE_MEM_WRITEABLE) ?
872 		ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
873 	resource->data.memory32.minimum = p->start;
874 	resource->data.memory32.maximum = p->end;
875 	resource->data.memory32.alignment = 0;
876 	resource->data.memory32.address_length = p->end - p->start + 1;
877 }
878 
879 static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource,
880 	struct resource *p)
881 {
882 	resource->data.fixed_memory32.write_protect =
883 		(p->flags & IORESOURCE_MEM_WRITEABLE) ?
884 		ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
885 	resource->data.fixed_memory32.address = p->start;
886 	resource->data.fixed_memory32.address_length = p->end - p->start + 1;
887 }
888 
889 int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
890 	struct acpi_buffer *buffer)
891 {
892 	int i = 0;
893 	/* pnpacpi_build_resource_template allocates extra mem */
894 	int res_cnt = (buffer->length - 1)/sizeof(struct acpi_resource) - 1;
895 	struct acpi_resource *resource = (struct acpi_resource*)buffer->pointer;
896 	int port = 0, irq = 0, dma = 0, mem = 0;
897 
898 	pnp_dbg("res cnt %d", res_cnt);
899 	while (i < res_cnt) {
900 		switch(resource->type) {
901 		case ACPI_RESOURCE_TYPE_IRQ:
902 			pnp_dbg("Encode irq");
903 			pnpacpi_encode_irq(resource,
904 				&res_table->irq_resource[irq]);
905 			irq++;
906 			break;
907 
908 		case ACPI_RESOURCE_TYPE_DMA:
909 			pnp_dbg("Encode dma");
910 			pnpacpi_encode_dma(resource,
911 				&res_table->dma_resource[dma]);
912 			dma++;
913 			break;
914 		case ACPI_RESOURCE_TYPE_IO:
915 			pnp_dbg("Encode io");
916 			pnpacpi_encode_io(resource,
917 				&res_table->port_resource[port]);
918 			port++;
919 			break;
920 		case ACPI_RESOURCE_TYPE_FIXED_IO:
921 			pnp_dbg("Encode fixed io");
922 			pnpacpi_encode_fixed_io(resource,
923 				&res_table->port_resource[port]);
924 			port++;
925 			break;
926 		case ACPI_RESOURCE_TYPE_MEMORY24:
927 			pnp_dbg("Encode mem24");
928 			pnpacpi_encode_mem24(resource,
929 				&res_table->mem_resource[mem]);
930 			mem++;
931 			break;
932 		case ACPI_RESOURCE_TYPE_MEMORY32:
933 			pnp_dbg("Encode mem32");
934 			pnpacpi_encode_mem32(resource,
935 				&res_table->mem_resource[mem]);
936 			mem++;
937 			break;
938 		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
939 			pnp_dbg("Encode fixed mem32");
940 			pnpacpi_encode_fixed_mem32(resource,
941 				&res_table->mem_resource[mem]);
942 			mem++;
943 			break;
944 		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
945 			pnp_dbg("Encode ext irq");
946 			pnpacpi_encode_ext_irq(resource,
947 				&res_table->irq_resource[irq]);
948 			irq++;
949 			break;
950 		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
951 		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
952 		case ACPI_RESOURCE_TYPE_VENDOR:
953 		case ACPI_RESOURCE_TYPE_END_TAG:
954 		case ACPI_RESOURCE_TYPE_ADDRESS16:
955 		case ACPI_RESOURCE_TYPE_ADDRESS32:
956 		case ACPI_RESOURCE_TYPE_ADDRESS64:
957 		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
958 		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
959 		default: /* other type */
960 			pnp_warn("unknown resource type %d", resource->type);
961 			return -EINVAL;
962 		}
963 		resource++;
964 		i++;
965 	}
966 	return 0;
967 }
968