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