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