2 * pnpacpi -- PnP ACPI driver
4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
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
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.
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
21 #include <linux/kernel.h>
22 #include <linux/acpi.h>
23 #include <linux/pci.h>
27 #define valid_IRQ(i) (1)
29 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
35 static int irq_flags(int triggering, int polarity)
37 if (triggering == ACPI_LEVEL_SENSITIVE) {
38 if (polarity == ACPI_ACTIVE_LOW)
39 return IORESOURCE_IRQ_LOWLEVEL;
41 return IORESOURCE_IRQ_HIGHLEVEL;
43 if (polarity == ACPI_ACTIVE_LOW)
44 return IORESOURCE_IRQ_LOWEDGE;
46 return IORESOURCE_IRQ_HIGHEDGE;
50 static void decode_irq_flags(int flag, int *triggering, int *polarity)
53 case IORESOURCE_IRQ_LOWLEVEL:
54 *triggering = ACPI_LEVEL_SENSITIVE;
55 *polarity = ACPI_ACTIVE_LOW;
57 case IORESOURCE_IRQ_HIGHLEVEL:
58 *triggering = ACPI_LEVEL_SENSITIVE;
59 *polarity = ACPI_ACTIVE_HIGH;
61 case IORESOURCE_IRQ_LOWEDGE:
62 *triggering = ACPI_EDGE_SENSITIVE;
63 *polarity = ACPI_ACTIVE_LOW;
65 case IORESOURCE_IRQ_HIGHEDGE:
66 *triggering = ACPI_EDGE_SENSITIVE;
67 *polarity = ACPI_ACTIVE_HIGH;
72 static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
73 u32 gsi, int triggering,
74 int polarity, int shareable)
82 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
88 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
89 res->irq_resource[i].flags |= irq_flags(triggering, polarity);
90 irq = acpi_register_gsi(gsi, triggering, polarity);
92 res->irq_resource[i].flags |= IORESOURCE_DISABLED;
97 res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;
99 res->irq_resource[i].start = irq;
100 res->irq_resource[i].end = irq;
101 pcibios_penalize_isa_irq(irq, 1);
104 static int dma_flags(int type, int bus_master, int transfer)
109 flags |= IORESOURCE_DMA_MASTER;
111 case ACPI_COMPATIBILITY:
112 flags |= IORESOURCE_DMA_COMPATIBLE;
115 flags |= IORESOURCE_DMA_TYPEA;
118 flags |= IORESOURCE_DMA_TYPEB;
121 flags |= IORESOURCE_DMA_TYPEF;
124 /* Set a default value ? */
125 flags |= IORESOURCE_DMA_COMPATIBLE;
126 pnp_err("Invalid DMA type");
129 case ACPI_TRANSFER_8:
130 flags |= IORESOURCE_DMA_8BIT;
132 case ACPI_TRANSFER_8_16:
133 flags |= IORESOURCE_DMA_8AND16BIT;
135 case ACPI_TRANSFER_16:
136 flags |= IORESOURCE_DMA_16BIT;
139 /* Set a default value ? */
140 flags |= IORESOURCE_DMA_8AND16BIT;
141 pnp_err("Invalid DMA transfer type");
147 static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
149 int bus_master, int transfer)
153 while (i < PNP_MAX_DMA &&
154 !(res->dma_resource[i].flags & IORESOURCE_UNSET))
156 if (i < PNP_MAX_DMA) {
157 res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
158 res->dma_resource[i].flags |=
159 dma_flags(type, bus_master, transfer);
161 res->dma_resource[i].flags |= IORESOURCE_DISABLED;
164 res->dma_resource[i].start = dma;
165 res->dma_resource[i].end = dma;
169 static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
170 u64 io, u64 len, int io_decode)
174 while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
177 if (i < PNP_MAX_PORT) {
178 res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
179 if (io_decode == ACPI_DECODE_16)
180 res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
181 if (len <= 0 || (io + len - 1) >= 0x10003) {
182 res->port_resource[i].flags |= IORESOURCE_DISABLED;
185 res->port_resource[i].start = io;
186 res->port_resource[i].end = io + len - 1;
190 static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
196 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
199 if (i < PNP_MAX_MEM) {
200 res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag
202 res->mem_resource[i].flags |= IORESOURCE_DISABLED;
205 if (write_protect == ACPI_READ_WRITE_MEMORY)
206 res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
208 res->mem_resource[i].start = mem;
209 res->mem_resource[i].end = mem + len - 1;
213 static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table,
214 struct acpi_resource *res)
216 struct acpi_resource_address64 addr, *p = &addr;
219 status = acpi_resource_to_address64(res, p);
220 if (!ACPI_SUCCESS(status)) {
221 pnp_warn("PnPACPI: failed to convert resource type %d",
226 if (p->producer_consumer == ACPI_PRODUCER)
229 if (p->resource_type == ACPI_MEMORY_RANGE)
230 pnpacpi_parse_allocated_memresource(res_table,
231 p->minimum, p->address_length,
232 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 :
240 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
243 struct pnp_resource_table *res_table =
244 (struct pnp_resource_table *)data;
248 case ACPI_RESOURCE_TYPE_IRQ:
250 * Per spec, only one interrupt per descriptor is allowed in
251 * _CRS, but some firmware violates this, so parse them all.
253 for (i = 0; i < res->data.irq.interrupt_count; i++) {
254 pnpacpi_parse_allocated_irqresource(res_table,
255 res->data.irq.interrupts[i],
256 res->data.irq.triggering,
257 res->data.irq.polarity,
258 res->data.irq.sharable);
262 case ACPI_RESOURCE_TYPE_DMA:
263 if (res->data.dma.channel_count > 0)
264 pnpacpi_parse_allocated_dmaresource(res_table,
265 res->data.dma.channels[0],
267 res->data.dma.bus_master,
268 res->data.dma.transfer);
271 case ACPI_RESOURCE_TYPE_IO:
272 pnpacpi_parse_allocated_ioresource(res_table,
273 res->data.io.minimum,
274 res->data.io.address_length,
275 res->data.io.io_decode);
278 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
279 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
282 case ACPI_RESOURCE_TYPE_FIXED_IO:
283 pnpacpi_parse_allocated_ioresource(res_table,
284 res->data.fixed_io.address,
285 res->data.fixed_io.address_length,
289 case ACPI_RESOURCE_TYPE_VENDOR:
292 case ACPI_RESOURCE_TYPE_END_TAG:
295 case ACPI_RESOURCE_TYPE_MEMORY24:
296 pnpacpi_parse_allocated_memresource(res_table,
297 res->data.memory24.minimum,
298 res->data.memory24.address_length,
299 res->data.memory24.write_protect);
301 case ACPI_RESOURCE_TYPE_MEMORY32:
302 pnpacpi_parse_allocated_memresource(res_table,
303 res->data.memory32.minimum,
304 res->data.memory32.address_length,
305 res->data.memory32.write_protect);
307 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
308 pnpacpi_parse_allocated_memresource(res_table,
309 res->data.fixed_memory32.address,
310 res->data.fixed_memory32.address_length,
311 res->data.fixed_memory32.write_protect);
313 case ACPI_RESOURCE_TYPE_ADDRESS16:
314 case ACPI_RESOURCE_TYPE_ADDRESS32:
315 case ACPI_RESOURCE_TYPE_ADDRESS64:
316 pnpacpi_parse_allocated_address_space(res_table, res);
319 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
320 if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER)
324 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
325 if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER)
328 for (i = 0; i < res->data.extended_irq.interrupt_count; i++) {
329 pnpacpi_parse_allocated_irqresource(res_table,
330 res->data.extended_irq.interrupts[i],
331 res->data.extended_irq.triggering,
332 res->data.extended_irq.polarity,
333 res->data.extended_irq.sharable);
337 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
341 pnp_warn("PnPACPI: unknown resource type %d", res->type);
348 acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle,
349 struct pnp_resource_table * res)
351 /* Blank the resource table values */
352 pnp_init_resource_table(res);
354 return acpi_walk_resources(handle, METHOD_NAME__CRS,
355 pnpacpi_allocated_resource, res);
358 static void pnpacpi_parse_dma_option(struct pnp_option *option,
359 struct acpi_resource_dma *p)
364 if (p->channel_count == 0)
366 dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
370 for (i = 0; i < p->channel_count; i++)
371 dma->map |= 1 << p->channels[i];
373 dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
375 pnp_register_dma_resource(option, dma);
378 static void pnpacpi_parse_irq_option(struct pnp_option *option,
379 struct acpi_resource_irq *p)
384 if (p->interrupt_count == 0)
386 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
390 for (i = 0; i < p->interrupt_count; i++)
391 if (p->interrupts[i])
392 __set_bit(p->interrupts[i], irq->map);
393 irq->flags = irq_flags(p->triggering, p->polarity);
395 pnp_register_irq_resource(option, irq);
398 static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
399 struct acpi_resource_extended_irq *p)
404 if (p->interrupt_count == 0)
406 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
410 for (i = 0; i < p->interrupt_count; i++)
411 if (p->interrupts[i])
412 __set_bit(p->interrupts[i], irq->map);
413 irq->flags = irq_flags(p->triggering, p->polarity);
415 pnp_register_irq_resource(option, irq);
418 static void pnpacpi_parse_port_option(struct pnp_option *option,
419 struct acpi_resource_io *io)
421 struct pnp_port *port;
423 if (io->address_length == 0)
425 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
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);
437 static void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
438 struct acpi_resource_fixed_io *io)
440 struct pnp_port *port;
442 if (io->address_length == 0)
444 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
447 port->min = port->max = io->address;
448 port->size = io->address_length;
450 port->flags = PNP_PORT_FLAG_FIXED;
451 pnp_register_port_resource(option, port);
454 static void pnpacpi_parse_mem24_option(struct pnp_option *option,
455 struct acpi_resource_memory24 *p)
459 if (p->address_length == 0)
461 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
464 mem->min = p->minimum;
465 mem->max = p->maximum;
466 mem->align = p->alignment;
467 mem->size = p->address_length;
469 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
470 IORESOURCE_MEM_WRITEABLE : 0;
472 pnp_register_mem_resource(option, mem);
475 static void pnpacpi_parse_mem32_option(struct pnp_option *option,
476 struct acpi_resource_memory32 *p)
480 if (p->address_length == 0)
482 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
485 mem->min = p->minimum;
486 mem->max = p->maximum;
487 mem->align = p->alignment;
488 mem->size = p->address_length;
490 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
491 IORESOURCE_MEM_WRITEABLE : 0;
493 pnp_register_mem_resource(option, mem);
496 static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
497 struct acpi_resource_fixed_memory32 *p)
501 if (p->address_length == 0)
503 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
506 mem->min = mem->max = p->address;
507 mem->size = p->address_length;
510 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
511 IORESOURCE_MEM_WRITEABLE : 0;
513 pnp_register_mem_resource(option, mem);
516 static void pnpacpi_parse_address_option(struct pnp_option *option,
517 struct acpi_resource *r)
519 struct acpi_resource_address64 addr, *p = &addr;
522 struct pnp_port *port;
524 status = acpi_resource_to_address64(r, p);
525 if (!ACPI_SUCCESS(status)) {
526 pnp_warn("PnPACPI: failed to convert resource type %d",
531 if (p->address_length == 0)
534 if (p->resource_type == ACPI_MEMORY_RANGE) {
535 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
538 mem->min = mem->max = p->minimum;
539 mem->size = p->address_length;
541 mem->flags = (p->info.mem.write_protect ==
542 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
544 pnp_register_mem_resource(option, mem);
545 } else if (p->resource_type == ACPI_IO_RANGE) {
546 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
549 port->min = port->max = p->minimum;
550 port->size = p->address_length;
552 port->flags = PNP_PORT_FLAG_FIXED;
553 pnp_register_port_resource(option, port);
557 struct acpipnp_parse_option_s {
558 struct pnp_option *option;
559 struct pnp_option *option_independent;
563 static acpi_status pnpacpi_option_resource(struct acpi_resource *res,
567 struct acpipnp_parse_option_s *parse_data =
568 (struct acpipnp_parse_option_s *)data;
569 struct pnp_dev *dev = parse_data->dev;
570 struct pnp_option *option = parse_data->option;
573 case ACPI_RESOURCE_TYPE_IRQ:
574 pnpacpi_parse_irq_option(option, &res->data.irq);
577 case ACPI_RESOURCE_TYPE_DMA:
578 pnpacpi_parse_dma_option(option, &res->data.dma);
581 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
582 switch (res->data.start_dpf.compatibility_priority) {
583 case ACPI_GOOD_CONFIGURATION:
584 priority = PNP_RES_PRIORITY_PREFERRED;
587 case ACPI_ACCEPTABLE_CONFIGURATION:
588 priority = PNP_RES_PRIORITY_ACCEPTABLE;
591 case ACPI_SUB_OPTIMAL_CONFIGURATION:
592 priority = PNP_RES_PRIORITY_FUNCTIONAL;
595 priority = PNP_RES_PRIORITY_INVALID;
598 /* TBD: Consider performance/robustness bits */
599 option = pnp_register_dependent_option(dev, priority);
602 parse_data->option = option;
605 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
606 /*only one EndDependentFn is allowed */
607 if (!parse_data->option_independent) {
608 pnp_warn("PnPACPI: more than one EndDependentFn");
611 parse_data->option = parse_data->option_independent;
612 parse_data->option_independent = NULL;
615 case ACPI_RESOURCE_TYPE_IO:
616 pnpacpi_parse_port_option(option, &res->data.io);
619 case ACPI_RESOURCE_TYPE_FIXED_IO:
620 pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io);
623 case ACPI_RESOURCE_TYPE_VENDOR:
624 case ACPI_RESOURCE_TYPE_END_TAG:
627 case ACPI_RESOURCE_TYPE_MEMORY24:
628 pnpacpi_parse_mem24_option(option, &res->data.memory24);
631 case ACPI_RESOURCE_TYPE_MEMORY32:
632 pnpacpi_parse_mem32_option(option, &res->data.memory32);
635 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
636 pnpacpi_parse_fixed_mem32_option(option,
637 &res->data.fixed_memory32);
640 case ACPI_RESOURCE_TYPE_ADDRESS16:
641 case ACPI_RESOURCE_TYPE_ADDRESS32:
642 case ACPI_RESOURCE_TYPE_ADDRESS64:
643 pnpacpi_parse_address_option(option, res);
646 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
649 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
650 pnpacpi_parse_ext_irq_option(option, &res->data.extended_irq);
653 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
657 pnp_warn("PnPACPI: unknown resource type %d", res->type);
664 acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle,
665 struct pnp_dev * dev)
668 struct acpipnp_parse_option_s parse_data;
670 parse_data.option = pnp_register_independent_option(dev);
671 if (!parse_data.option)
673 parse_data.option_independent = parse_data.option;
674 parse_data.dev = dev;
675 status = acpi_walk_resources(handle, METHOD_NAME__PRS,
676 pnpacpi_option_resource, &parse_data);
681 static int pnpacpi_supported_resource(struct acpi_resource *res)
684 case ACPI_RESOURCE_TYPE_IRQ:
685 case ACPI_RESOURCE_TYPE_DMA:
686 case ACPI_RESOURCE_TYPE_IO:
687 case ACPI_RESOURCE_TYPE_FIXED_IO:
688 case ACPI_RESOURCE_TYPE_MEMORY24:
689 case ACPI_RESOURCE_TYPE_MEMORY32:
690 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
691 case ACPI_RESOURCE_TYPE_ADDRESS16:
692 case ACPI_RESOURCE_TYPE_ADDRESS32:
693 case ACPI_RESOURCE_TYPE_ADDRESS64:
694 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
703 static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
706 int *res_cnt = (int *)data;
708 if (pnpacpi_supported_resource(res))
713 static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
715 struct acpi_resource **resource = (struct acpi_resource **)data;
717 if (pnpacpi_supported_resource(res)) {
718 (*resource)->type = res->type;
719 (*resource)->length = sizeof(struct acpi_resource);
726 int pnpacpi_build_resource_template(acpi_handle handle,
727 struct acpi_buffer *buffer)
729 struct acpi_resource *resource;
733 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
734 pnpacpi_count_resources, &res_cnt);
735 if (ACPI_FAILURE(status)) {
736 pnp_err("Evaluate _CRS failed");
741 buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
742 buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
743 if (!buffer->pointer)
745 pnp_dbg("Res cnt %d", res_cnt);
746 resource = (struct acpi_resource *)buffer->pointer;
747 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
748 pnpacpi_type_resources, &resource);
749 if (ACPI_FAILURE(status)) {
750 kfree(buffer->pointer);
751 pnp_err("Evaluate _CRS failed");
754 /* resource will pointer the end resource now */
755 resource->type = ACPI_RESOURCE_TYPE_END_TAG;
760 static void pnpacpi_encode_irq(struct acpi_resource *resource,
763 int triggering, polarity;
765 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
766 resource->data.irq.triggering = triggering;
767 resource->data.irq.polarity = polarity;
768 if (triggering == ACPI_EDGE_SENSITIVE)
769 resource->data.irq.sharable = ACPI_EXCLUSIVE;
771 resource->data.irq.sharable = ACPI_SHARED;
772 resource->data.irq.interrupt_count = 1;
773 resource->data.irq.interrupts[0] = p->start;
776 static void pnpacpi_encode_ext_irq(struct acpi_resource *resource,
779 int triggering, polarity;
781 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
782 resource->data.extended_irq.producer_consumer = ACPI_CONSUMER;
783 resource->data.extended_irq.triggering = triggering;
784 resource->data.extended_irq.polarity = polarity;
785 if (triggering == ACPI_EDGE_SENSITIVE)
786 resource->data.irq.sharable = ACPI_EXCLUSIVE;
788 resource->data.irq.sharable = ACPI_SHARED;
789 resource->data.extended_irq.interrupt_count = 1;
790 resource->data.extended_irq.interrupts[0] = p->start;
793 static void pnpacpi_encode_dma(struct acpi_resource *resource,
796 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
797 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
798 case IORESOURCE_DMA_TYPEA:
799 resource->data.dma.type = ACPI_TYPE_A;
801 case IORESOURCE_DMA_TYPEB:
802 resource->data.dma.type = ACPI_TYPE_B;
804 case IORESOURCE_DMA_TYPEF:
805 resource->data.dma.type = ACPI_TYPE_F;
808 resource->data.dma.type = ACPI_COMPATIBILITY;
811 switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
812 case IORESOURCE_DMA_8BIT:
813 resource->data.dma.transfer = ACPI_TRANSFER_8;
815 case IORESOURCE_DMA_8AND16BIT:
816 resource->data.dma.transfer = ACPI_TRANSFER_8_16;
819 resource->data.dma.transfer = ACPI_TRANSFER_16;
822 resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
823 resource->data.dma.channel_count = 1;
824 resource->data.dma.channels[0] = p->start;
827 static void pnpacpi_encode_io(struct acpi_resource *resource,
830 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
831 resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
832 ACPI_DECODE_16 : ACPI_DECODE_10;
833 resource->data.io.minimum = p->start;
834 resource->data.io.maximum = p->end;
835 resource->data.io.alignment = 0; /* Correct? */
836 resource->data.io.address_length = p->end - p->start + 1;
839 static void pnpacpi_encode_fixed_io(struct acpi_resource *resource,
842 resource->data.fixed_io.address = p->start;
843 resource->data.fixed_io.address_length = p->end - p->start + 1;
846 static void pnpacpi_encode_mem24(struct acpi_resource *resource,
849 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
850 resource->data.memory24.write_protect =
851 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
852 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
853 resource->data.memory24.minimum = p->start;
854 resource->data.memory24.maximum = p->end;
855 resource->data.memory24.alignment = 0;
856 resource->data.memory24.address_length = p->end - p->start + 1;
859 static void pnpacpi_encode_mem32(struct acpi_resource *resource,
862 resource->data.memory32.write_protect =
863 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
864 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
865 resource->data.memory32.minimum = p->start;
866 resource->data.memory32.maximum = p->end;
867 resource->data.memory32.alignment = 0;
868 resource->data.memory32.address_length = p->end - p->start + 1;
871 static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource,
874 resource->data.fixed_memory32.write_protect =
875 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
876 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
877 resource->data.fixed_memory32.address = p->start;
878 resource->data.fixed_memory32.address_length = p->end - p->start + 1;
881 int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
882 struct acpi_buffer *buffer)
885 /* pnpacpi_build_resource_template allocates extra mem */
886 int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
887 struct acpi_resource *resource =
888 (struct acpi_resource *)buffer->pointer;
889 int port = 0, irq = 0, dma = 0, mem = 0;
891 pnp_dbg("res cnt %d", res_cnt);
892 while (i < res_cnt) {
893 switch (resource->type) {
894 case ACPI_RESOURCE_TYPE_IRQ:
895 pnp_dbg("Encode irq");
896 pnpacpi_encode_irq(resource,
897 &res_table->irq_resource[irq]);
901 case ACPI_RESOURCE_TYPE_DMA:
902 pnp_dbg("Encode dma");
903 pnpacpi_encode_dma(resource,
904 &res_table->dma_resource[dma]);
907 case ACPI_RESOURCE_TYPE_IO:
908 pnp_dbg("Encode io");
909 pnpacpi_encode_io(resource,
910 &res_table->port_resource[port]);
913 case ACPI_RESOURCE_TYPE_FIXED_IO:
914 pnp_dbg("Encode fixed io");
915 pnpacpi_encode_fixed_io(resource,
917 port_resource[port]);
920 case ACPI_RESOURCE_TYPE_MEMORY24:
921 pnp_dbg("Encode mem24");
922 pnpacpi_encode_mem24(resource,
923 &res_table->mem_resource[mem]);
926 case ACPI_RESOURCE_TYPE_MEMORY32:
927 pnp_dbg("Encode mem32");
928 pnpacpi_encode_mem32(resource,
929 &res_table->mem_resource[mem]);
932 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
933 pnp_dbg("Encode fixed mem32");
934 pnpacpi_encode_fixed_mem32(resource,
939 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
940 pnp_dbg("Encode ext irq");
941 pnpacpi_encode_ext_irq(resource,
942 &res_table->irq_resource[irq]);
945 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
946 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
947 case ACPI_RESOURCE_TYPE_VENDOR:
948 case ACPI_RESOURCE_TYPE_END_TAG:
949 case ACPI_RESOURCE_TYPE_ADDRESS16:
950 case ACPI_RESOURCE_TYPE_ADDRESS32:
951 case ACPI_RESOURCE_TYPE_ADDRESS64:
952 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
953 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
954 default: /* other type */
955 pnp_warn("unknown resource type %d", resource->type);