]> err.no Git - linux-2.6/blob - drivers/pnp/pnpacpi/rsparser.c
PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR
[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 <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                                             struct pnp_option *option,
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, map, flags);
424 }
425
426 static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
427                                             struct pnp_option *option,
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, &map, flags);
444 }
445
446 static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
447                                                 struct pnp_option *option,
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, &map, flags);
471 }
472
473 static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
474                                              struct pnp_option *option,
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, 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                                                    struct pnp_option *option,
490                                         struct acpi_resource_fixed_io *io)
491 {
492         if (io->address_length == 0)
493                 return;
494
495         pnp_register_port_resource(dev, option, io->address, io->address, 0,
496                                    io->address_length, IORESOURCE_IO_FIXED);
497 }
498
499 static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
500                                               struct pnp_option *option,
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, 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                                               struct pnp_option *option,
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, 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                                                     struct pnp_option *option,
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, 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                                                 struct pnp_option *option,
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, p->minimum, p->minimum,
566                                           0, p->address_length, flags);
567         } else if (p->resource_type == ACPI_IO_RANGE)
568                 pnp_register_port_resource(dev, option, p->minimum, p->minimum,
569                                            0, p->address_length,
570                                            IORESOURCE_IO_FIXED);
571 }
572
573 struct acpipnp_parse_option_s {
574         struct pnp_option *option;
575         struct pnp_option *option_independent;
576         struct pnp_dev *dev;
577 };
578
579 static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
580                                                   void *data)
581 {
582         int priority = 0;
583         struct acpipnp_parse_option_s *parse_data = data;
584         struct pnp_dev *dev = parse_data->dev;
585         struct pnp_option *option = parse_data->option;
586
587         switch (res->type) {
588         case ACPI_RESOURCE_TYPE_IRQ:
589                 pnpacpi_parse_irq_option(dev, option, &res->data.irq);
590                 break;
591
592         case ACPI_RESOURCE_TYPE_DMA:
593                 pnpacpi_parse_dma_option(dev, option, &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                 /* TBD: Consider performance/robustness bits */
614                 option = pnp_register_dependent_option(dev, priority);
615                 if (!option)
616                         return AE_ERROR;
617                 parse_data->option = option;
618                 break;
619
620         case ACPI_RESOURCE_TYPE_END_DEPENDENT:
621                 /*only one EndDependentFn is allowed */
622                 if (!parse_data->option_independent) {
623                         dev_warn(&dev->dev, "more than one EndDependentFn "
624                                  "in _PRS\n");
625                         return AE_ERROR;
626                 }
627                 parse_data->option = parse_data->option_independent;
628                 parse_data->option_independent = NULL;
629                 dev_dbg(&dev->dev, "end dependent options\n");
630                 break;
631
632         case ACPI_RESOURCE_TYPE_IO:
633                 pnpacpi_parse_port_option(dev, option, &res->data.io);
634                 break;
635
636         case ACPI_RESOURCE_TYPE_FIXED_IO:
637                 pnpacpi_parse_fixed_port_option(dev, option,
638                                                 &res->data.fixed_io);
639                 break;
640
641         case ACPI_RESOURCE_TYPE_VENDOR:
642         case ACPI_RESOURCE_TYPE_END_TAG:
643                 break;
644
645         case ACPI_RESOURCE_TYPE_MEMORY24:
646                 pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
647                 break;
648
649         case ACPI_RESOURCE_TYPE_MEMORY32:
650                 pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
651                 break;
652
653         case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
654                 pnpacpi_parse_fixed_mem32_option(dev, option,
655                                                  &res->data.fixed_memory32);
656                 break;
657
658         case ACPI_RESOURCE_TYPE_ADDRESS16:
659         case ACPI_RESOURCE_TYPE_ADDRESS32:
660         case ACPI_RESOURCE_TYPE_ADDRESS64:
661                 pnpacpi_parse_address_option(dev, option, res);
662                 break;
663
664         case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
665                 break;
666
667         case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
668                 pnpacpi_parse_ext_irq_option(dev, option,
669                                              &res->data.extended_irq);
670                 break;
671
672         case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
673                 break;
674
675         default:
676                 dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
677                          res->type);
678                 return AE_ERROR;
679         }
680
681         return AE_OK;
682 }
683
684 int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
685 {
686         acpi_handle handle = dev->data;
687         acpi_status status;
688         struct acpipnp_parse_option_s parse_data;
689
690         dev_dbg(&dev->dev, "parse resource options\n");
691
692         parse_data.option = pnp_register_independent_option(dev);
693         if (!parse_data.option)
694                 return -ENOMEM;
695
696         parse_data.option_independent = parse_data.option;
697         parse_data.dev = dev;
698         status = acpi_walk_resources(handle, METHOD_NAME__PRS,
699                                      pnpacpi_option_resource, &parse_data);
700
701         if (ACPI_FAILURE(status)) {
702                 if (status != AE_NOT_FOUND)
703                         dev_err(&dev->dev, "can't evaluate _PRS: %d", status);
704                 return -EPERM;
705         }
706         return 0;
707 }
708
709 static int pnpacpi_supported_resource(struct acpi_resource *res)
710 {
711         switch (res->type) {
712         case ACPI_RESOURCE_TYPE_IRQ:
713         case ACPI_RESOURCE_TYPE_DMA:
714         case ACPI_RESOURCE_TYPE_IO:
715         case ACPI_RESOURCE_TYPE_FIXED_IO:
716         case ACPI_RESOURCE_TYPE_MEMORY24:
717         case ACPI_RESOURCE_TYPE_MEMORY32:
718         case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
719         case ACPI_RESOURCE_TYPE_ADDRESS16:
720         case ACPI_RESOURCE_TYPE_ADDRESS32:
721         case ACPI_RESOURCE_TYPE_ADDRESS64:
722         case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
723                 return 1;
724         }
725         return 0;
726 }
727
728 /*
729  * Set resource
730  */
731 static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
732                                            void *data)
733 {
734         int *res_cnt = data;
735
736         if (pnpacpi_supported_resource(res))
737                 (*res_cnt)++;
738         return AE_OK;
739 }
740
741 static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
742 {
743         struct acpi_resource **resource = data;
744
745         if (pnpacpi_supported_resource(res)) {
746                 (*resource)->type = res->type;
747                 (*resource)->length = sizeof(struct acpi_resource);
748                 if (res->type == ACPI_RESOURCE_TYPE_IRQ)
749                         (*resource)->data.irq.descriptor_length =
750                                         res->data.irq.descriptor_length;
751                 (*resource)++;
752         }
753
754         return AE_OK;
755 }
756
757 int pnpacpi_build_resource_template(struct pnp_dev *dev,
758                                     struct acpi_buffer *buffer)
759 {
760         acpi_handle handle = dev->data;
761         struct acpi_resource *resource;
762         int res_cnt = 0;
763         acpi_status status;
764
765         status = acpi_walk_resources(handle, METHOD_NAME__CRS,
766                                      pnpacpi_count_resources, &res_cnt);
767         if (ACPI_FAILURE(status)) {
768                 dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
769                 return -EINVAL;
770         }
771         if (!res_cnt)
772                 return -EINVAL;
773         buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
774         buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
775         if (!buffer->pointer)
776                 return -ENOMEM;
777
778         resource = (struct acpi_resource *)buffer->pointer;
779         status = acpi_walk_resources(handle, METHOD_NAME__CRS,
780                                      pnpacpi_type_resources, &resource);
781         if (ACPI_FAILURE(status)) {
782                 kfree(buffer->pointer);
783                 dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
784                 return -EINVAL;
785         }
786         /* resource will pointer the end resource now */
787         resource->type = ACPI_RESOURCE_TYPE_END_TAG;
788
789         return 0;
790 }
791
792 static void pnpacpi_encode_irq(struct pnp_dev *dev,
793                                struct acpi_resource *resource,
794                                struct resource *p)
795 {
796         struct acpi_resource_irq *irq = &resource->data.irq;
797         int triggering, polarity, shareable;
798
799         if (!pnp_resource_enabled(p)) {
800                 irq->interrupt_count = 0;
801                 dev_dbg(&dev->dev, "  encode irq (%s)\n",
802                         p ? "disabled" : "missing");
803                 return;
804         }
805
806         decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
807         irq->triggering = triggering;
808         irq->polarity = polarity;
809         irq->sharable = shareable;
810         irq->interrupt_count = 1;
811         irq->interrupts[0] = p->start;
812
813         dev_dbg(&dev->dev, "  encode irq %d %s %s %s (%d-byte descriptor)\n",
814                 (int) p->start,
815                 triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
816                 polarity == ACPI_ACTIVE_LOW ? "low" : "high",
817                 irq->sharable == ACPI_SHARED ? "shared" : "exclusive",
818                 irq->descriptor_length);
819 }
820
821 static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
822                                    struct acpi_resource *resource,
823                                    struct resource *p)
824 {
825         struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
826         int triggering, polarity, shareable;
827
828         if (!pnp_resource_enabled(p)) {
829                 extended_irq->interrupt_count = 0;
830                 dev_dbg(&dev->dev, "  encode extended irq (%s)\n",
831                         p ? "disabled" : "missing");
832                 return;
833         }
834
835         decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
836         extended_irq->producer_consumer = ACPI_CONSUMER;
837         extended_irq->triggering = triggering;
838         extended_irq->polarity = polarity;
839         extended_irq->sharable = shareable;
840         extended_irq->interrupt_count = 1;
841         extended_irq->interrupts[0] = p->start;
842
843         dev_dbg(&dev->dev, "  encode irq %d %s %s %s\n", (int) p->start,
844                 triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
845                 polarity == ACPI_ACTIVE_LOW ? "low" : "high",
846                 extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
847 }
848
849 static void pnpacpi_encode_dma(struct pnp_dev *dev,
850                                struct acpi_resource *resource,
851                                struct resource *p)
852 {
853         struct acpi_resource_dma *dma = &resource->data.dma;
854
855         if (!pnp_resource_enabled(p)) {
856                 dma->channel_count = 0;
857                 dev_dbg(&dev->dev, "  encode dma (%s)\n",
858                         p ? "disabled" : "missing");
859                 return;
860         }
861
862         /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
863         switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
864         case IORESOURCE_DMA_TYPEA:
865                 dma->type = ACPI_TYPE_A;
866                 break;
867         case IORESOURCE_DMA_TYPEB:
868                 dma->type = ACPI_TYPE_B;
869                 break;
870         case IORESOURCE_DMA_TYPEF:
871                 dma->type = ACPI_TYPE_F;
872                 break;
873         default:
874                 dma->type = ACPI_COMPATIBILITY;
875         }
876
877         switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
878         case IORESOURCE_DMA_8BIT:
879                 dma->transfer = ACPI_TRANSFER_8;
880                 break;
881         case IORESOURCE_DMA_8AND16BIT:
882                 dma->transfer = ACPI_TRANSFER_8_16;
883                 break;
884         default:
885                 dma->transfer = ACPI_TRANSFER_16;
886         }
887
888         dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
889         dma->channel_count = 1;
890         dma->channels[0] = p->start;
891
892         dev_dbg(&dev->dev, "  encode dma %d "
893                 "type %#x transfer %#x master %d\n",
894                 (int) p->start, dma->type, dma->transfer, dma->bus_master);
895 }
896
897 static void pnpacpi_encode_io(struct pnp_dev *dev,
898                               struct acpi_resource *resource,
899                               struct resource *p)
900 {
901         struct acpi_resource_io *io = &resource->data.io;
902
903         if (pnp_resource_enabled(p)) {
904                 /* Note: pnp_assign_port copies pnp_port->flags into p->flags */
905                 io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
906                     ACPI_DECODE_16 : ACPI_DECODE_10;
907                 io->minimum = p->start;
908                 io->maximum = p->end;
909                 io->alignment = 0;      /* Correct? */
910                 io->address_length = p->end - p->start + 1;
911         } else {
912                 io->minimum = 0;
913                 io->address_length = 0;
914         }
915
916         dev_dbg(&dev->dev, "  encode io %#x-%#x decode %#x\n", io->minimum,
917                 io->minimum + io->address_length - 1, io->io_decode);
918 }
919
920 static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
921                                     struct acpi_resource *resource,
922                                     struct resource *p)
923 {
924         struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
925
926         if (pnp_resource_enabled(p)) {
927                 fixed_io->address = p->start;
928                 fixed_io->address_length = p->end - p->start + 1;
929         } else {
930                 fixed_io->address = 0;
931                 fixed_io->address_length = 0;
932         }
933
934         dev_dbg(&dev->dev, "  encode fixed_io %#x-%#x\n", fixed_io->address,
935                 fixed_io->address + fixed_io->address_length - 1);
936 }
937
938 static void pnpacpi_encode_mem24(struct pnp_dev *dev,
939                                  struct acpi_resource *resource,
940                                  struct resource *p)
941 {
942         struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
943
944         if (pnp_resource_enabled(p)) {
945                 /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
946                 memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
947                     ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
948                 memory24->minimum = p->start;
949                 memory24->maximum = p->end;
950                 memory24->alignment = 0;
951                 memory24->address_length = p->end - p->start + 1;
952         } else {
953                 memory24->minimum = 0;
954                 memory24->address_length = 0;
955         }
956
957         dev_dbg(&dev->dev, "  encode mem24 %#x-%#x write_protect %#x\n",
958                 memory24->minimum,
959                 memory24->minimum + memory24->address_length - 1,
960                 memory24->write_protect);
961 }
962
963 static void pnpacpi_encode_mem32(struct pnp_dev *dev,
964                                  struct acpi_resource *resource,
965                                  struct resource *p)
966 {
967         struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
968
969         if (pnp_resource_enabled(p)) {
970                 memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
971                     ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
972                 memory32->minimum = p->start;
973                 memory32->maximum = p->end;
974                 memory32->alignment = 0;
975                 memory32->address_length = p->end - p->start + 1;
976         } else {
977                 memory32->minimum = 0;
978                 memory32->alignment = 0;
979         }
980
981         dev_dbg(&dev->dev, "  encode mem32 %#x-%#x write_protect %#x\n",
982                 memory32->minimum,
983                 memory32->minimum + memory32->address_length - 1,
984                 memory32->write_protect);
985 }
986
987 static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
988                                        struct acpi_resource *resource,
989                                        struct resource *p)
990 {
991         struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
992
993         if (pnp_resource_enabled(p)) {
994                 fixed_memory32->write_protect =
995                     p->flags & IORESOURCE_MEM_WRITEABLE ?
996                     ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
997                 fixed_memory32->address = p->start;
998                 fixed_memory32->address_length = p->end - p->start + 1;
999         } else {
1000                 fixed_memory32->address = 0;
1001                 fixed_memory32->address_length = 0;
1002         }
1003
1004         dev_dbg(&dev->dev, "  encode fixed_mem32 %#x-%#x write_protect %#x\n",
1005                 fixed_memory32->address,
1006                 fixed_memory32->address + fixed_memory32->address_length - 1,
1007                 fixed_memory32->write_protect);
1008 }
1009
1010 int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
1011 {
1012         int i = 0;
1013         /* pnpacpi_build_resource_template allocates extra mem */
1014         int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
1015         struct acpi_resource *resource = buffer->pointer;
1016         int port = 0, irq = 0, dma = 0, mem = 0;
1017
1018         dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
1019         while (i < res_cnt) {
1020                 switch (resource->type) {
1021                 case ACPI_RESOURCE_TYPE_IRQ:
1022                         pnpacpi_encode_irq(dev, resource,
1023                                pnp_get_resource(dev, IORESOURCE_IRQ, irq));
1024                         irq++;
1025                         break;
1026
1027                 case ACPI_RESOURCE_TYPE_DMA:
1028                         pnpacpi_encode_dma(dev, resource,
1029                                 pnp_get_resource(dev, IORESOURCE_DMA, dma));
1030                         dma++;
1031                         break;
1032                 case ACPI_RESOURCE_TYPE_IO:
1033                         pnpacpi_encode_io(dev, resource,
1034                                 pnp_get_resource(dev, IORESOURCE_IO, port));
1035                         port++;
1036                         break;
1037                 case ACPI_RESOURCE_TYPE_FIXED_IO:
1038                         pnpacpi_encode_fixed_io(dev, resource,
1039                                 pnp_get_resource(dev, IORESOURCE_IO, port));
1040                         port++;
1041                         break;
1042                 case ACPI_RESOURCE_TYPE_MEMORY24:
1043                         pnpacpi_encode_mem24(dev, resource,
1044                                 pnp_get_resource(dev, IORESOURCE_MEM, mem));
1045                         mem++;
1046                         break;
1047                 case ACPI_RESOURCE_TYPE_MEMORY32:
1048                         pnpacpi_encode_mem32(dev, resource,
1049                                 pnp_get_resource(dev, IORESOURCE_MEM, mem));
1050                         mem++;
1051                         break;
1052                 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
1053                         pnpacpi_encode_fixed_mem32(dev, resource,
1054                                 pnp_get_resource(dev, IORESOURCE_MEM, mem));
1055                         mem++;
1056                         break;
1057                 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
1058                         pnpacpi_encode_ext_irq(dev, resource,
1059                                 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
1060                         irq++;
1061                         break;
1062                 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
1063                 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
1064                 case ACPI_RESOURCE_TYPE_VENDOR:
1065                 case ACPI_RESOURCE_TYPE_END_TAG:
1066                 case ACPI_RESOURCE_TYPE_ADDRESS16:
1067                 case ACPI_RESOURCE_TYPE_ADDRESS32:
1068                 case ACPI_RESOURCE_TYPE_ADDRESS64:
1069                 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
1070                 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
1071                 default:        /* other type */
1072                         dev_warn(&dev->dev, "can't encode unknown resource "
1073                                  "type %d\n", resource->type);
1074                         return -EINVAL;
1075                 }
1076                 resource++;
1077                 i++;
1078         }
1079         return 0;
1080 }