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