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