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