2 * resource.c - Contains functions for registering and analyzing resource information
4 * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
5 * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
6 * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/errno.h>
13 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
18 #include <linux/pci.h>
19 #include <linux/ioport.h>
20 #include <linux/init.h>
22 #include <linux/pnp.h>
25 static int pnp_reserve_irq
[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
26 static int pnp_reserve_dma
[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */
27 static int pnp_reserve_io
[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */
28 static int pnp_reserve_mem
[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */
34 struct pnp_option
*pnp_build_option(struct pnp_dev
*dev
, unsigned long type
,
35 unsigned int option_flags
)
37 struct pnp_option
*option
;
39 option
= kzalloc(sizeof(struct pnp_option
), GFP_KERNEL
);
43 option
->flags
= option_flags
;
46 list_add_tail(&option
->list
, &dev
->options
);
50 int pnp_register_irq_resource(struct pnp_dev
*dev
, unsigned int option_flags
,
51 pnp_irq_mask_t
*map
, unsigned char flags
)
53 struct pnp_option
*option
;
56 option
= pnp_build_option(dev
, IORESOURCE_IRQ
, option_flags
);
68 for (i
= 0; i
< 16; i
++)
69 if (test_bit(i
, irq
->map
.bits
))
70 pcibios_penalize_isa_irq(i
, 0);
74 dbg_pnp_show_option(dev
, option
);
78 int pnp_register_dma_resource(struct pnp_dev
*dev
, unsigned int option_flags
,
79 unsigned char map
, unsigned char flags
)
81 struct pnp_option
*option
;
84 option
= pnp_build_option(dev
, IORESOURCE_DMA
, option_flags
);
92 dbg_pnp_show_option(dev
, option
);
96 int pnp_register_port_resource(struct pnp_dev
*dev
, unsigned int option_flags
,
97 resource_size_t min
, resource_size_t max
,
98 resource_size_t align
, resource_size_t size
,
101 struct pnp_option
*option
;
102 struct pnp_port
*port
;
104 option
= pnp_build_option(dev
, IORESOURCE_IO
, option_flags
);
108 port
= &option
->u
.port
;
115 dbg_pnp_show_option(dev
, option
);
119 int pnp_register_mem_resource(struct pnp_dev
*dev
, unsigned int option_flags
,
120 resource_size_t min
, resource_size_t max
,
121 resource_size_t align
, resource_size_t size
,
124 struct pnp_option
*option
;
127 option
= pnp_build_option(dev
, IORESOURCE_MEM
, option_flags
);
131 mem
= &option
->u
.mem
;
138 dbg_pnp_show_option(dev
, option
);
142 void pnp_free_options(struct pnp_dev
*dev
)
144 struct pnp_option
*option
, *tmp
;
146 list_for_each_entry_safe(option
, tmp
, &dev
->options
, list
) {
147 list_del(&option
->list
);
153 * resource validity checking
156 #define length(start, end) (*(end) - *(start) + 1)
158 /* Two ranges conflict if one doesn't end before the other starts */
159 #define ranged_conflict(starta, enda, startb, endb) \
160 !((*(enda) < *(startb)) || (*(endb) < *(starta)))
162 #define cannot_compare(flags) \
163 ((flags) & IORESOURCE_DISABLED)
165 int pnp_check_port(struct pnp_dev
*dev
, struct resource
*res
)
168 struct pnp_dev
*tdev
;
169 struct resource
*tres
;
170 resource_size_t
*port
, *end
, *tport
, *tend
;
175 /* if the resource doesn't exist, don't complain about it */
176 if (cannot_compare(res
->flags
))
179 /* check if the resource is already in use, skip if the
180 * device is active because it itself may be in use */
182 if (__check_region(&ioport_resource
, *port
, length(port
, end
)))
186 /* check if the resource is reserved */
187 for (i
= 0; i
< 8; i
++) {
188 int rport
= pnp_reserve_io
[i
<< 1];
189 int rend
= pnp_reserve_io
[(i
<< 1) + 1] + rport
- 1;
190 if (ranged_conflict(port
, end
, &rport
, &rend
))
194 /* check for internal conflicts */
195 for (i
= 0; (tres
= pnp_get_resource(dev
, IORESOURCE_IO
, i
)); i
++) {
196 if (tres
!= res
&& tres
->flags
& IORESOURCE_IO
) {
197 tport
= &tres
->start
;
199 if (ranged_conflict(port
, end
, tport
, tend
))
204 /* check for conflicts with other pnp devices */
205 pnp_for_each_dev(tdev
) {
209 (tres
= pnp_get_resource(tdev
, IORESOURCE_IO
, i
));
211 if (tres
->flags
& IORESOURCE_IO
) {
212 if (cannot_compare(tres
->flags
))
214 if (tres
->flags
& IORESOURCE_WINDOW
)
216 tport
= &tres
->start
;
218 if (ranged_conflict(port
, end
, tport
, tend
))
227 int pnp_check_mem(struct pnp_dev
*dev
, struct resource
*res
)
230 struct pnp_dev
*tdev
;
231 struct resource
*tres
;
232 resource_size_t
*addr
, *end
, *taddr
, *tend
;
237 /* if the resource doesn't exist, don't complain about it */
238 if (cannot_compare(res
->flags
))
241 /* check if the resource is already in use, skip if the
242 * device is active because it itself may be in use */
244 if (check_mem_region(*addr
, length(addr
, end
)))
248 /* check if the resource is reserved */
249 for (i
= 0; i
< 8; i
++) {
250 int raddr
= pnp_reserve_mem
[i
<< 1];
251 int rend
= pnp_reserve_mem
[(i
<< 1) + 1] + raddr
- 1;
252 if (ranged_conflict(addr
, end
, &raddr
, &rend
))
256 /* check for internal conflicts */
257 for (i
= 0; (tres
= pnp_get_resource(dev
, IORESOURCE_MEM
, i
)); i
++) {
258 if (tres
!= res
&& tres
->flags
& IORESOURCE_MEM
) {
259 taddr
= &tres
->start
;
261 if (ranged_conflict(addr
, end
, taddr
, tend
))
266 /* check for conflicts with other pnp devices */
267 pnp_for_each_dev(tdev
) {
271 (tres
= pnp_get_resource(tdev
, IORESOURCE_MEM
, i
));
273 if (tres
->flags
& IORESOURCE_MEM
) {
274 if (cannot_compare(tres
->flags
))
276 if (tres
->flags
& IORESOURCE_WINDOW
)
278 taddr
= &tres
->start
;
280 if (ranged_conflict(addr
, end
, taddr
, tend
))
289 static irqreturn_t
pnp_test_handler(int irq
, void *dev_id
)
295 static int pci_dev_uses_irq(struct pnp_dev
*pnp
, struct pci_dev
*pci
,
301 if (pci
->irq
== irq
) {
302 pnp_dbg(&pnp
->dev
, " device %s using irq %d\n",
308 * See pci_setup_device() and ata_pci_sff_activate_host() for
309 * similar IDE legacy detection.
311 pci_read_config_dword(pci
, PCI_CLASS_REVISION
, &class);
312 class >>= 8; /* discard revision ID */
313 progif
= class & 0xff;
316 if (class == PCI_CLASS_STORAGE_IDE
) {
318 * Unless both channels are native-PCI mode only,
319 * treat the compatibility IRQs as busy.
321 if ((progif
& 0x5) != 0x5)
322 if (pci_get_legacy_ide_irq(pci
, 0) == irq
||
323 pci_get_legacy_ide_irq(pci
, 1) == irq
) {
324 pnp_dbg(&pnp
->dev
, " legacy IDE device %s "
325 "using irq %d\n", pci_name(pci
), irq
);
334 static int pci_uses_irq(struct pnp_dev
*pnp
, unsigned int irq
)
337 struct pci_dev
*pci
= NULL
;
339 for_each_pci_dev(pci
) {
340 if (pci_dev_uses_irq(pnp
, pci
, irq
)) {
349 int pnp_check_irq(struct pnp_dev
*dev
, struct resource
*res
)
352 struct pnp_dev
*tdev
;
353 struct resource
*tres
;
354 resource_size_t
*irq
;
358 /* if the resource doesn't exist, don't complain about it */
359 if (cannot_compare(res
->flags
))
362 /* check if the resource is valid */
363 if (*irq
< 0 || *irq
> 15)
366 /* check if the resource is reserved */
367 for (i
= 0; i
< 16; i
++) {
368 if (pnp_reserve_irq
[i
] == *irq
)
372 /* check for internal conflicts */
373 for (i
= 0; (tres
= pnp_get_resource(dev
, IORESOURCE_IRQ
, i
)); i
++) {
374 if (tres
!= res
&& tres
->flags
& IORESOURCE_IRQ
) {
375 if (tres
->start
== *irq
)
380 /* check if the resource is being used by a pci device */
381 if (pci_uses_irq(dev
, *irq
))
384 /* check if the resource is already in use, skip if the
385 * device is active because it itself may be in use */
387 if (request_irq(*irq
, pnp_test_handler
,
388 IRQF_DISABLED
| IRQF_PROBE_SHARED
, "pnp", NULL
))
390 free_irq(*irq
, NULL
);
393 /* check for conflicts with other pnp devices */
394 pnp_for_each_dev(tdev
) {
398 (tres
= pnp_get_resource(tdev
, IORESOURCE_IRQ
, i
));
400 if (tres
->flags
& IORESOURCE_IRQ
) {
401 if (cannot_compare(tres
->flags
))
403 if (tres
->start
== *irq
)
412 #ifdef CONFIG_ISA_DMA_API
413 int pnp_check_dma(struct pnp_dev
*dev
, struct resource
*res
)
416 struct pnp_dev
*tdev
;
417 struct resource
*tres
;
418 resource_size_t
*dma
;
422 /* if the resource doesn't exist, don't complain about it */
423 if (cannot_compare(res
->flags
))
426 /* check if the resource is valid */
427 if (*dma
< 0 || *dma
== 4 || *dma
> 7)
430 /* check if the resource is reserved */
431 for (i
= 0; i
< 8; i
++) {
432 if (pnp_reserve_dma
[i
] == *dma
)
436 /* check for internal conflicts */
437 for (i
= 0; (tres
= pnp_get_resource(dev
, IORESOURCE_DMA
, i
)); i
++) {
438 if (tres
!= res
&& tres
->flags
& IORESOURCE_DMA
) {
439 if (tres
->start
== *dma
)
444 /* check if the resource is already in use, skip if the
445 * device is active because it itself may be in use */
447 if (request_dma(*dma
, "pnp"))
452 /* check for conflicts with other pnp devices */
453 pnp_for_each_dev(tdev
) {
457 (tres
= pnp_get_resource(tdev
, IORESOURCE_DMA
, i
));
459 if (tres
->flags
& IORESOURCE_DMA
) {
460 if (cannot_compare(tres
->flags
))
462 if (tres
->start
== *dma
)
470 #endif /* CONFIG_ISA_DMA_API */
472 unsigned long pnp_resource_type(struct resource
*res
)
474 return res
->flags
& (IORESOURCE_IO
| IORESOURCE_MEM
|
475 IORESOURCE_IRQ
| IORESOURCE_DMA
|
479 struct resource
*pnp_get_resource(struct pnp_dev
*dev
,
480 unsigned long type
, unsigned int num
)
482 struct pnp_resource
*pnp_res
;
483 struct resource
*res
;
485 list_for_each_entry(pnp_res
, &dev
->resources
, list
) {
487 if (pnp_resource_type(res
) == type
&& num
-- == 0)
492 EXPORT_SYMBOL(pnp_get_resource
);
494 static struct pnp_resource
*pnp_new_resource(struct pnp_dev
*dev
)
496 struct pnp_resource
*pnp_res
;
498 pnp_res
= kzalloc(sizeof(struct pnp_resource
), GFP_KERNEL
);
502 list_add_tail(&pnp_res
->list
, &dev
->resources
);
506 struct pnp_resource
*pnp_add_resource(struct pnp_dev
*dev
,
507 struct resource
*res
)
509 struct pnp_resource
*pnp_res
;
511 pnp_res
= pnp_new_resource(dev
);
513 dev_err(&dev
->dev
, "can't add resource %pR\n", res
);
518 pnp_res
->res
.name
= dev
->name
;
519 dev_dbg(&dev
->dev
, "%pR\n", res
);
523 struct pnp_resource
*pnp_add_irq_resource(struct pnp_dev
*dev
, int irq
,
526 struct pnp_resource
*pnp_res
;
527 struct resource
*res
;
529 pnp_res
= pnp_new_resource(dev
);
531 dev_err(&dev
->dev
, "can't add resource for IRQ %d\n", irq
);
536 res
->flags
= IORESOURCE_IRQ
| flags
;
540 dev_printk(KERN_DEBUG
, &dev
->dev
, "%pR\n", res
);
544 struct pnp_resource
*pnp_add_dma_resource(struct pnp_dev
*dev
, int dma
,
547 struct pnp_resource
*pnp_res
;
548 struct resource
*res
;
550 pnp_res
= pnp_new_resource(dev
);
552 dev_err(&dev
->dev
, "can't add resource for DMA %d\n", dma
);
557 res
->flags
= IORESOURCE_DMA
| flags
;
561 dev_printk(KERN_DEBUG
, &dev
->dev
, "%pR\n", res
);
565 struct pnp_resource
*pnp_add_io_resource(struct pnp_dev
*dev
,
566 resource_size_t start
,
567 resource_size_t end
, int flags
)
569 struct pnp_resource
*pnp_res
;
570 struct resource
*res
;
572 pnp_res
= pnp_new_resource(dev
);
574 dev_err(&dev
->dev
, "can't add resource for IO %#llx-%#llx\n",
575 (unsigned long long) start
,
576 (unsigned long long) end
);
581 res
->flags
= IORESOURCE_IO
| flags
;
585 dev_printk(KERN_DEBUG
, &dev
->dev
, "%pR\n", res
);
589 struct pnp_resource
*pnp_add_mem_resource(struct pnp_dev
*dev
,
590 resource_size_t start
,
591 resource_size_t end
, int flags
)
593 struct pnp_resource
*pnp_res
;
594 struct resource
*res
;
596 pnp_res
= pnp_new_resource(dev
);
598 dev_err(&dev
->dev
, "can't add resource for MEM %#llx-%#llx\n",
599 (unsigned long long) start
,
600 (unsigned long long) end
);
605 res
->flags
= IORESOURCE_MEM
| flags
;
609 dev_printk(KERN_DEBUG
, &dev
->dev
, "%pR\n", res
);
613 struct pnp_resource
*pnp_add_bus_resource(struct pnp_dev
*dev
,
614 resource_size_t start
,
617 struct pnp_resource
*pnp_res
;
618 struct resource
*res
;
620 pnp_res
= pnp_new_resource(dev
);
622 dev_err(&dev
->dev
, "can't add resource for BUS %#llx-%#llx\n",
623 (unsigned long long) start
,
624 (unsigned long long) end
);
629 res
->flags
= IORESOURCE_BUS
;
633 dev_printk(KERN_DEBUG
, &dev
->dev
, "%pR\n", res
);
638 * Determine whether the specified resource is a possible configuration
641 int pnp_possible_config(struct pnp_dev
*dev
, int type
, resource_size_t start
,
642 resource_size_t size
)
644 struct pnp_option
*option
;
645 struct pnp_port
*port
;
650 list_for_each_entry(option
, &dev
->options
, list
) {
651 if (option
->type
!= type
)
654 switch (option
->type
) {
656 port
= &option
->u
.port
;
657 if (port
->min
== start
&& port
->size
== size
)
661 mem
= &option
->u
.mem
;
662 if (mem
->min
== start
&& mem
->size
== size
)
666 irq
= &option
->u
.irq
;
667 if (start
< PNP_IRQ_NR
&&
668 test_bit(start
, irq
->map
.bits
))
672 dma
= &option
->u
.dma
;
673 if (dma
->map
& (1 << start
))
681 EXPORT_SYMBOL(pnp_possible_config
);
683 int pnp_range_reserved(resource_size_t start
, resource_size_t end
)
686 struct pnp_resource
*pnp_res
;
687 resource_size_t
*dev_start
, *dev_end
;
689 pnp_for_each_dev(dev
) {
690 list_for_each_entry(pnp_res
, &dev
->resources
, list
) {
691 dev_start
= &pnp_res
->res
.start
;
692 dev_end
= &pnp_res
->res
.end
;
693 if (ranged_conflict(&start
, &end
, dev_start
, dev_end
))
699 EXPORT_SYMBOL(pnp_range_reserved
);
701 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
702 static int __init
pnp_setup_reserve_irq(char *str
)
706 for (i
= 0; i
< 16; i
++)
707 if (get_option(&str
, &pnp_reserve_irq
[i
]) != 2)
712 __setup("pnp_reserve_irq=", pnp_setup_reserve_irq
);
714 /* format is: pnp_reserve_dma=dma1[,dma2] .... */
715 static int __init
pnp_setup_reserve_dma(char *str
)
719 for (i
= 0; i
< 8; i
++)
720 if (get_option(&str
, &pnp_reserve_dma
[i
]) != 2)
725 __setup("pnp_reserve_dma=", pnp_setup_reserve_dma
);
727 /* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */
728 static int __init
pnp_setup_reserve_io(char *str
)
732 for (i
= 0; i
< 16; i
++)
733 if (get_option(&str
, &pnp_reserve_io
[i
]) != 2)
738 __setup("pnp_reserve_io=", pnp_setup_reserve_io
);
740 /* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */
741 static int __init
pnp_setup_reserve_mem(char *str
)
745 for (i
= 0; i
< 16; i
++)
746 if (get_option(&str
, &pnp_reserve_mem
[i
]) != 2)
751 __setup("pnp_reserve_mem=", pnp_setup_reserve_mem
);