]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/pnp/resource.c
391828c7f2079a6a0a3727ae5a1f7fdfdbbc4f2a
[linux-2.6-omap-h63xx.git] / drivers / pnp / resource.c
1 /*
2  * resource.c - Contains functions for registering and analyzing resource information
3  *
4  * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
5  * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6  */
7
8 #include <linux/module.h>
9 #include <linux/errno.h>
10 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
12 #include <asm/io.h>
13 #include <asm/dma.h>
14 #include <asm/irq.h>
15 #include <linux/pci.h>
16 #include <linux/ioport.h>
17 #include <linux/init.h>
18
19 #include <linux/pnp.h>
20 #include "base.h"
21
22 static int pnp_reserve_irq[16] = {[0 ... 15] = -1 };    /* reserve (don't use) some IRQ */
23 static int pnp_reserve_dma[8] = {[0 ... 7] = -1 };      /* reserve (don't use) some DMA */
24 static int pnp_reserve_io[16] = {[0 ... 15] = -1 };     /* reserve (don't use) some I/O region */
25 static int pnp_reserve_mem[16] = {[0 ... 15] = -1 };    /* reserve (don't use) some memory region */
26
27 /*
28  * option registration
29  */
30
31 struct pnp_option *pnp_build_option(int priority)
32 {
33         struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option));
34
35         if (!option)
36                 return NULL;
37
38         option->priority = priority & 0xff;
39         /* make sure the priority is valid */
40         if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
41                 option->priority = PNP_RES_PRIORITY_INVALID;
42
43         return option;
44 }
45
46 struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
47 {
48         struct pnp_option *option;
49
50         option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
51
52         /* this should never happen but if it does we'll try to continue */
53         if (dev->independent)
54                 dev_err(&dev->dev, "independent resource already registered\n");
55         dev->independent = option;
56
57         dev_dbg(&dev->dev, "new independent option\n");
58         return option;
59 }
60
61 struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
62                                                  int priority)
63 {
64         struct pnp_option *option;
65
66         option = pnp_build_option(priority);
67
68         if (dev->dependent) {
69                 struct pnp_option *parent = dev->dependent;
70                 while (parent->next)
71                         parent = parent->next;
72                 parent->next = option;
73         } else
74                 dev->dependent = option;
75
76         dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
77         return option;
78 }
79
80 int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
81                               struct pnp_irq *data)
82 {
83         struct pnp_irq *ptr;
84 #ifdef DEBUG
85         char buf[PNP_IRQ_NR];   /* hex-encoded, so this is overkill but safe */
86 #endif
87
88         ptr = option->irq;
89         while (ptr && ptr->next)
90                 ptr = ptr->next;
91         if (ptr)
92                 ptr->next = data;
93         else
94                 option->irq = data;
95
96 #ifdef CONFIG_PCI
97         {
98                 int i;
99
100                 for (i = 0; i < 16; i++)
101                         if (test_bit(i, data->map.bits))
102                                 pcibios_penalize_isa_irq(i, 0);
103         }
104 #endif
105
106 #ifdef DEBUG
107         bitmap_scnprintf(buf, sizeof(buf), data->map.bits, PNP_IRQ_NR);
108         dev_dbg(&dev->dev, "  irq bitmask %s flags %#x\n", buf,
109                 data->flags);
110 #endif
111         return 0;
112 }
113
114 int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
115                               struct pnp_dma *data)
116 {
117         struct pnp_dma *ptr;
118
119         ptr = option->dma;
120         while (ptr && ptr->next)
121                 ptr = ptr->next;
122         if (ptr)
123                 ptr->next = data;
124         else
125                 option->dma = data;
126
127         dev_dbg(&dev->dev, "  dma bitmask %#x flags %#x\n", data->map,
128                 data->flags);
129         return 0;
130 }
131
132 int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
133                                struct pnp_port *data)
134 {
135         struct pnp_port *ptr;
136
137         ptr = option->port;
138         while (ptr && ptr->next)
139                 ptr = ptr->next;
140         if (ptr)
141                 ptr->next = data;
142         else
143                 option->port = data;
144
145         dev_dbg(&dev->dev, "  io  "
146                 "min %#llx max %#llx align %lld size %lld flags %#x\n",
147                 (unsigned long long) data->min,
148                 (unsigned long long) data->max,
149                 (unsigned long long) data->align,
150                 (unsigned long long) data->size, data->flags);
151         return 0;
152 }
153
154 int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
155                               struct pnp_mem *data)
156 {
157         struct pnp_mem *ptr;
158
159         ptr = option->mem;
160         while (ptr && ptr->next)
161                 ptr = ptr->next;
162         if (ptr)
163                 ptr->next = data;
164         else
165                 option->mem = data;
166
167         dev_dbg(&dev->dev, "  mem "
168                 "min %#llx max %#llx align %lld size %lld flags %#x\n",
169                 (unsigned long long) data->min,
170                 (unsigned long long) data->max,
171                 (unsigned long long) data->align,
172                 (unsigned long long) data->size, data->flags);
173         return 0;
174 }
175
176 static void pnp_free_port(struct pnp_port *port)
177 {
178         struct pnp_port *next;
179
180         while (port) {
181                 next = port->next;
182                 kfree(port);
183                 port = next;
184         }
185 }
186
187 static void pnp_free_irq(struct pnp_irq *irq)
188 {
189         struct pnp_irq *next;
190
191         while (irq) {
192                 next = irq->next;
193                 kfree(irq);
194                 irq = next;
195         }
196 }
197
198 static void pnp_free_dma(struct pnp_dma *dma)
199 {
200         struct pnp_dma *next;
201
202         while (dma) {
203                 next = dma->next;
204                 kfree(dma);
205                 dma = next;
206         }
207 }
208
209 static void pnp_free_mem(struct pnp_mem *mem)
210 {
211         struct pnp_mem *next;
212
213         while (mem) {
214                 next = mem->next;
215                 kfree(mem);
216                 mem = next;
217         }
218 }
219
220 void pnp_free_option(struct pnp_option *option)
221 {
222         struct pnp_option *next;
223
224         while (option) {
225                 next = option->next;
226                 pnp_free_port(option->port);
227                 pnp_free_irq(option->irq);
228                 pnp_free_dma(option->dma);
229                 pnp_free_mem(option->mem);
230                 kfree(option);
231                 option = next;
232         }
233 }
234
235 /*
236  * resource validity checking
237  */
238
239 #define length(start, end) (*(end) - *(start) + 1)
240
241 /* Two ranges conflict if one doesn't end before the other starts */
242 #define ranged_conflict(starta, enda, startb, endb) \
243         !((*(enda) < *(startb)) || (*(endb) < *(starta)))
244
245 #define cannot_compare(flags) \
246 ((flags) & IORESOURCE_DISABLED)
247
248 int pnp_check_port(struct pnp_dev *dev, struct resource *res)
249 {
250         int i;
251         struct pnp_dev *tdev;
252         struct resource *tres;
253         resource_size_t *port, *end, *tport, *tend;
254
255         port = &res->start;
256         end = &res->end;
257
258         /* if the resource doesn't exist, don't complain about it */
259         if (cannot_compare(res->flags))
260                 return 1;
261
262         /* check if the resource is already in use, skip if the
263          * device is active because it itself may be in use */
264         if (!dev->active) {
265                 if (__check_region(&ioport_resource, *port, length(port, end)))
266                         return 0;
267         }
268
269         /* check if the resource is reserved */
270         for (i = 0; i < 8; i++) {
271                 int rport = pnp_reserve_io[i << 1];
272                 int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1;
273                 if (ranged_conflict(port, end, &rport, &rend))
274                         return 0;
275         }
276
277         /* check for internal conflicts */
278         for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
279                 if (tres != res && tres->flags & IORESOURCE_IO) {
280                         tport = &tres->start;
281                         tend = &tres->end;
282                         if (ranged_conflict(port, end, tport, tend))
283                                 return 0;
284                 }
285         }
286
287         /* check for conflicts with other pnp devices */
288         pnp_for_each_dev(tdev) {
289                 if (tdev == dev)
290                         continue;
291                 for (i = 0;
292                      (tres = pnp_get_resource(tdev, IORESOURCE_IO, i));
293                      i++) {
294                         if (tres->flags & IORESOURCE_IO) {
295                                 if (cannot_compare(tres->flags))
296                                         continue;
297                                 tport = &tres->start;
298                                 tend = &tres->end;
299                                 if (ranged_conflict(port, end, tport, tend))
300                                         return 0;
301                         }
302                 }
303         }
304
305         return 1;
306 }
307
308 int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
309 {
310         int i;
311         struct pnp_dev *tdev;
312         struct resource *tres;
313         resource_size_t *addr, *end, *taddr, *tend;
314
315         addr = &res->start;
316         end = &res->end;
317
318         /* if the resource doesn't exist, don't complain about it */
319         if (cannot_compare(res->flags))
320                 return 1;
321
322         /* check if the resource is already in use, skip if the
323          * device is active because it itself may be in use */
324         if (!dev->active) {
325                 if (check_mem_region(*addr, length(addr, end)))
326                         return 0;
327         }
328
329         /* check if the resource is reserved */
330         for (i = 0; i < 8; i++) {
331                 int raddr = pnp_reserve_mem[i << 1];
332                 int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
333                 if (ranged_conflict(addr, end, &raddr, &rend))
334                         return 0;
335         }
336
337         /* check for internal conflicts */
338         for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
339                 if (tres != res && tres->flags & IORESOURCE_MEM) {
340                         taddr = &tres->start;
341                         tend = &tres->end;
342                         if (ranged_conflict(addr, end, taddr, tend))
343                                 return 0;
344                 }
345         }
346
347         /* check for conflicts with other pnp devices */
348         pnp_for_each_dev(tdev) {
349                 if (tdev == dev)
350                         continue;
351                 for (i = 0;
352                      (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
353                      i++) {
354                         if (tres->flags & IORESOURCE_MEM) {
355                                 if (cannot_compare(tres->flags))
356                                         continue;
357                                 taddr = &tres->start;
358                                 tend = &tres->end;
359                                 if (ranged_conflict(addr, end, taddr, tend))
360                                         return 0;
361                         }
362                 }
363         }
364
365         return 1;
366 }
367
368 static irqreturn_t pnp_test_handler(int irq, void *dev_id)
369 {
370         return IRQ_HANDLED;
371 }
372
373 int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
374 {
375         int i;
376         struct pnp_dev *tdev;
377         struct resource *tres;
378         resource_size_t *irq;
379
380         irq = &res->start;
381
382         /* if the resource doesn't exist, don't complain about it */
383         if (cannot_compare(res->flags))
384                 return 1;
385
386         /* check if the resource is valid */
387         if (*irq < 0 || *irq > 15)
388                 return 0;
389
390         /* check if the resource is reserved */
391         for (i = 0; i < 16; i++) {
392                 if (pnp_reserve_irq[i] == *irq)
393                         return 0;
394         }
395
396         /* check for internal conflicts */
397         for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
398                 if (tres != res && tres->flags & IORESOURCE_IRQ) {
399                         if (tres->start == *irq)
400                                 return 0;
401                 }
402         }
403
404 #ifdef CONFIG_PCI
405         /* check if the resource is being used by a pci device */
406         {
407                 struct pci_dev *pci = NULL;
408                 for_each_pci_dev(pci) {
409                         if (pci->irq == *irq) {
410                                 pci_dev_put(pci);
411                                 return 0;
412                         }
413                 }
414         }
415 #endif
416
417         /* check if the resource is already in use, skip if the
418          * device is active because it itself may be in use */
419         if (!dev->active) {
420                 if (request_irq(*irq, pnp_test_handler,
421                                 IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL))
422                         return 0;
423                 free_irq(*irq, NULL);
424         }
425
426         /* check for conflicts with other pnp devices */
427         pnp_for_each_dev(tdev) {
428                 if (tdev == dev)
429                         continue;
430                 for (i = 0;
431                      (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i));
432                      i++) {
433                         if (tres->flags & IORESOURCE_IRQ) {
434                                 if (cannot_compare(tres->flags))
435                                         continue;
436                                 if (tres->start == *irq)
437                                         return 0;
438                         }
439                 }
440         }
441
442         return 1;
443 }
444
445 int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
446 {
447 #ifndef CONFIG_IA64
448         int i;
449         struct pnp_dev *tdev;
450         struct resource *tres;
451         resource_size_t *dma;
452
453         dma = &res->start;
454
455         /* if the resource doesn't exist, don't complain about it */
456         if (cannot_compare(res->flags))
457                 return 1;
458
459         /* check if the resource is valid */
460         if (*dma < 0 || *dma == 4 || *dma > 7)
461                 return 0;
462
463         /* check if the resource is reserved */
464         for (i = 0; i < 8; i++) {
465                 if (pnp_reserve_dma[i] == *dma)
466                         return 0;
467         }
468
469         /* check for internal conflicts */
470         for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
471                 if (tres != res && tres->flags & IORESOURCE_DMA) {
472                         if (tres->start == *dma)
473                                 return 0;
474                 }
475         }
476
477         /* check if the resource is already in use, skip if the
478          * device is active because it itself may be in use */
479         if (!dev->active) {
480                 if (request_dma(*dma, "pnp"))
481                         return 0;
482                 free_dma(*dma);
483         }
484
485         /* check for conflicts with other pnp devices */
486         pnp_for_each_dev(tdev) {
487                 if (tdev == dev)
488                         continue;
489                 for (i = 0;
490                      (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i));
491                      i++) {
492                         if (tres->flags & IORESOURCE_DMA) {
493                                 if (cannot_compare(tres->flags))
494                                         continue;
495                                 if (tres->start == *dma)
496                                         return 0;
497                         }
498                 }
499         }
500
501         return 1;
502 #else
503         /* IA64 does not have legacy DMA */
504         return 0;
505 #endif
506 }
507
508 int pnp_resource_type(struct resource *res)
509 {
510         return res->flags & (IORESOURCE_IO  | IORESOURCE_MEM |
511                              IORESOURCE_IRQ | IORESOURCE_DMA);
512 }
513
514 struct resource *pnp_get_resource(struct pnp_dev *dev,
515                                   unsigned int type, unsigned int num)
516 {
517         struct pnp_resource *pnp_res;
518         struct resource *res;
519
520         list_for_each_entry(pnp_res, &dev->resources, list) {
521                 res = &pnp_res->res;
522                 if (pnp_resource_type(res) == type && num-- == 0)
523                         return res;
524         }
525         return NULL;
526 }
527 EXPORT_SYMBOL(pnp_get_resource);
528
529 static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
530 {
531         struct pnp_resource *pnp_res;
532
533         pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
534         if (!pnp_res)
535                 return NULL;
536
537         list_add_tail(&pnp_res->list, &dev->resources);
538         return pnp_res;
539 }
540
541 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
542                                           int flags)
543 {
544         struct pnp_resource *pnp_res;
545         struct resource *res;
546
547         pnp_res = pnp_new_resource(dev);
548         if (!pnp_res) {
549                 dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
550                 return NULL;
551         }
552
553         res = &pnp_res->res;
554         res->flags = IORESOURCE_IRQ | flags;
555         res->start = irq;
556         res->end = irq;
557
558         dev_dbg(&dev->dev, "  add irq %d flags %#x\n", irq, flags);
559         return pnp_res;
560 }
561
562 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
563                                           int flags)
564 {
565         struct pnp_resource *pnp_res;
566         struct resource *res;
567
568         pnp_res = pnp_new_resource(dev);
569         if (!pnp_res) {
570                 dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
571                 return NULL;
572         }
573
574         res = &pnp_res->res;
575         res->flags = IORESOURCE_DMA | flags;
576         res->start = dma;
577         res->end = dma;
578
579         dev_dbg(&dev->dev, "  add dma %d flags %#x\n", dma, flags);
580         return pnp_res;
581 }
582
583 struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
584                                          resource_size_t start,
585                                          resource_size_t end, int flags)
586 {
587         struct pnp_resource *pnp_res;
588         struct resource *res;
589
590         pnp_res = pnp_new_resource(dev);
591         if (!pnp_res) {
592                 dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
593                         (unsigned long long) start,
594                         (unsigned long long) end);
595                 return NULL;
596         }
597
598         res = &pnp_res->res;
599         res->flags = IORESOURCE_IO | flags;
600         res->start = start;
601         res->end = end;
602
603         dev_dbg(&dev->dev, "  add io  %#llx-%#llx flags %#x\n",
604                 (unsigned long long) start, (unsigned long long) end, flags);
605         return pnp_res;
606 }
607
608 struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
609                                           resource_size_t start,
610                                           resource_size_t end, int flags)
611 {
612         struct pnp_resource *pnp_res;
613         struct resource *res;
614
615         pnp_res = pnp_new_resource(dev);
616         if (!pnp_res) {
617                 dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
618                         (unsigned long long) start,
619                         (unsigned long long) end);
620                 return NULL;
621         }
622
623         res = &pnp_res->res;
624         res->flags = IORESOURCE_MEM | flags;
625         res->start = start;
626         res->end = end;
627
628         dev_dbg(&dev->dev, "  add mem %#llx-%#llx flags %#x\n",
629                 (unsigned long long) start, (unsigned long long) end, flags);
630         return pnp_res;
631 }
632
633 static int pnp_possible_option(struct pnp_option *option, int type,
634                                resource_size_t start, resource_size_t size)
635 {
636         struct pnp_option *tmp;
637         struct pnp_port *port;
638         struct pnp_mem *mem;
639         struct pnp_irq *irq;
640         struct pnp_dma *dma;
641
642         if (!option)
643                 return 0;
644
645         for (tmp = option; tmp; tmp = tmp->next) {
646                 switch (type) {
647                 case IORESOURCE_IO:
648                         for (port = tmp->port; port; port = port->next) {
649                                 if (port->min == start && port->size == size)
650                                         return 1;
651                         }
652                         break;
653                 case IORESOURCE_MEM:
654                         for (mem = tmp->mem; mem; mem = mem->next) {
655                                 if (mem->min == start && mem->size == size)
656                                         return 1;
657                         }
658                         break;
659                 case IORESOURCE_IRQ:
660                         for (irq = tmp->irq; irq; irq = irq->next) {
661                                 if (start < PNP_IRQ_NR &&
662                                     test_bit(start, irq->map.bits))
663                                         return 1;
664                         }
665                         break;
666                 case IORESOURCE_DMA:
667                         for (dma = tmp->dma; dma; dma = dma->next) {
668                                 if (dma->map & (1 << start))
669                                         return 1;
670                         }
671                         break;
672                 }
673         }
674
675         return 0;
676 }
677
678 /*
679  * Determine whether the specified resource is a possible configuration
680  * for this device.
681  */
682 int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
683                         resource_size_t size)
684 {
685         if (pnp_possible_option(dev->independent, type, start, size))
686                 return 1;
687
688         if (pnp_possible_option(dev->dependent, type, start, size))
689                 return 1;
690
691         return 0;
692 }
693 EXPORT_SYMBOL(pnp_possible_config);
694
695 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
696 static int __init pnp_setup_reserve_irq(char *str)
697 {
698         int i;
699
700         for (i = 0; i < 16; i++)
701                 if (get_option(&str, &pnp_reserve_irq[i]) != 2)
702                         break;
703         return 1;
704 }
705
706 __setup("pnp_reserve_irq=", pnp_setup_reserve_irq);
707
708 /* format is: pnp_reserve_dma=dma1[,dma2] .... */
709 static int __init pnp_setup_reserve_dma(char *str)
710 {
711         int i;
712
713         for (i = 0; i < 8; i++)
714                 if (get_option(&str, &pnp_reserve_dma[i]) != 2)
715                         break;
716         return 1;
717 }
718
719 __setup("pnp_reserve_dma=", pnp_setup_reserve_dma);
720
721 /* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */
722 static int __init pnp_setup_reserve_io(char *str)
723 {
724         int i;
725
726         for (i = 0; i < 16; i++)
727                 if (get_option(&str, &pnp_reserve_io[i]) != 2)
728                         break;
729         return 1;
730 }
731
732 __setup("pnp_reserve_io=", pnp_setup_reserve_io);
733
734 /* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */
735 static int __init pnp_setup_reserve_mem(char *str)
736 {
737         int i;
738
739         for (i = 0; i < 16; i++)
740                 if (get_option(&str, &pnp_reserve_mem[i]) != 2)
741                         break;
742         return 1;
743 }
744
745 __setup("pnp_reserve_mem=", pnp_setup_reserve_mem);