11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * resource.c - Contains functions for registering and analyzing resource information 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4c1017a4cdb68ae5368fbc9ee42c77f1f5dca8916Jaroslav Kysela * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 61f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 71f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas * Bjorn Helgaas <bjorn.helgaas@hp.com> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 115a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/dma.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pnp.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "base.h" 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2507d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaasstatic int pnp_reserve_irq[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */ 2607d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaasstatic int pnp_reserve_dma[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */ 2707d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaasstatic int pnp_reserve_io[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */ 2807d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaasstatic int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * option registration 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasstruct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, 351f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas unsigned int option_flags) 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 371f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL); 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!option) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option->flags = option_flags; 441f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option->type = type; 4507d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 461f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas list_add_tail(&option->list, &dev->options); 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return option; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasint pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, 51c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas pnp_irq_mask_t *map, unsigned char flags) 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 531f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option; 541f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_irq *irq; 5507d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 561f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags); 571f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (!option) 58c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas return -ENOMEM; 59c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 601f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas irq = &option->u.irq; 612d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas irq->map = *map; 622d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas irq->flags = flags; 63c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PCI 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 16; i++) 692d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas if (test_bit(i, irq->map.bits)) 70c9c3e457de24cca2ca688fa397d93a241f472048David Shaohua Li pcibios_penalize_isa_irq(i, 0); 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 73c1caf06ccfd3a4efd4b489f89bcdabd2362f31d0Bjorn Helgaas 741f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas dbg_pnp_show_option(dev, option); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasint pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, 79c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char map, unsigned char flags) 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 811f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option; 821f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_dma *dma; 83c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 841f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option = pnp_build_option(dev, IORESOURCE_DMA, option_flags); 851f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (!option) 86c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas return -ENOMEM; 87c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 881f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas dma = &option->u.dma; 892d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas dma->map = map; 902d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas dma->flags = flags; 9107d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 921f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas dbg_pnp_show_option(dev, option); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 961f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasint pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, 97c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas resource_size_t min, resource_size_t max, 98c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas resource_size_t align, resource_size_t size, 99c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags) 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1011f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option; 1021f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_port *port; 103c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 1041f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option = pnp_build_option(dev, IORESOURCE_IO, option_flags); 1051f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (!option) 106c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas return -ENOMEM; 107c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 1081f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas port = &option->u.port; 1092d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas port->min = min; 1102d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas port->max = max; 1112d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas port->align = align; 1122d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas port->size = size; 1132d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas port->flags = flags; 11407d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 1151f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas dbg_pnp_show_option(dev, option); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasint pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, 120c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas resource_size_t min, resource_size_t max, 121c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas resource_size_t align, resource_size_t size, 122c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas unsigned char flags) 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1241f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option; 1251f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_mem *mem; 126c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 1271f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas option = pnp_build_option(dev, IORESOURCE_MEM, option_flags); 1281f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (!option) 129c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas return -ENOMEM; 130c227536b4cc2600fc9d22ba0067f699165f6621fBjorn Helgaas 1311f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas mem = &option->u.mem; 1322d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas mem->min = min; 1332d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas mem->max = max; 1342d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas mem->align = align; 1352d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas mem->size = size; 1362d29a7a794c5bae982955cd5dd0a76e766e57f39Bjorn Helgaas mem->flags = flags; 13707d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 1381f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas dbg_pnp_show_option(dev, option); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasvoid pnp_free_options(struct pnp_dev *dev) 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1441f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option, *tmp; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas list_for_each_entry_safe(option, tmp, &dev->options, list) { 1471f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas list_del(&option->list); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(option); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * resource validity checking 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define length(start, end) (*(end) - *(start) + 1) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Two ranges conflict if one doesn't end before the other starts */ 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ranged_conflict(starta, enda, startb, endb) \ 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds !((*(enda) < *(startb)) || (*(endb) < *(starta))) 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define cannot_compare(flags) \ 163aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas((flags) & IORESOURCE_DISABLED) 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 165f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaasint pnp_check_port(struct pnp_dev *dev, struct resource *res) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 167ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int i; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *tdev; 169f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaas struct resource *tres; 170b60ba8343b78b182c03cf239d4342785376c1ad1Greg Kroah-Hartman resource_size_t *port, *end, *tport, *tend; 17107d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 17230c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas port = &res->start; 17330c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas end = &res->end; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if the resource doesn't exist, don't complain about it */ 17630c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(res->flags)) 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is already in use, skip if the 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device is active because it itself may be in use */ 1819dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!dev->active) { 1829dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (__check_region(&ioport_resource, *port, length(port, end))) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is reserved */ 187ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas for (i = 0; i < 8; i++) { 188ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int rport = pnp_reserve_io[i << 1]; 189ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1; 1909dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (ranged_conflict(port, end, &rport, &rend)) 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for internal conflicts */ 19595ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 19695ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres != res && tres->flags & IORESOURCE_IO) { 19730c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas tport = &tres->start; 19830c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas tend = &tres->end; 1999dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (ranged_conflict(port, end, tport, tend)) 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for conflicts with other pnp devices */ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_for_each_dev(tdev) { 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tdev == dev) 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 20895ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; 20995ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (tres = pnp_get_resource(tdev, IORESOURCE_IO, i)); 21095ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas i++) { 21195ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres->flags & IORESOURCE_IO) { 21230c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(tres->flags)) 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 21411439a6fd90b4861df64b4f983726e1c54977ab7Bjorn Helgaas if (tres->flags & IORESOURCE_WINDOW) 21511439a6fd90b4861df64b4f983726e1c54977ab7Bjorn Helgaas continue; 21630c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas tport = &tres->start; 21730c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas tend = &tres->end; 2189dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (ranged_conflict(port, end, tport, tend)) 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 227f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaasint pnp_check_mem(struct pnp_dev *dev, struct resource *res) 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 229ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int i; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *tdev; 231f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaas struct resource *tres; 232b60ba8343b78b182c03cf239d4342785376c1ad1Greg Kroah-Hartman resource_size_t *addr, *end, *taddr, *tend; 23307d4e9af109221ab731c5aaf832e89776c64b013Bjorn Helgaas 23430c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas addr = &res->start; 23530c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas end = &res->end; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if the resource doesn't exist, don't complain about it */ 23830c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(res->flags)) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is already in use, skip if the 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device is active because it itself may be in use */ 2439dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!dev->active) { 2449dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (check_mem_region(*addr, length(addr, end))) 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is reserved */ 249ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas for (i = 0; i < 8; i++) { 250ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int raddr = pnp_reserve_mem[i << 1]; 251ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1; 2529dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (ranged_conflict(addr, end, &raddr, &rend)) 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for internal conflicts */ 25795ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 25895ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres != res && tres->flags & IORESOURCE_MEM) { 25930c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas taddr = &tres->start; 26030c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas tend = &tres->end; 2619dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (ranged_conflict(addr, end, taddr, tend)) 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for conflicts with other pnp devices */ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_for_each_dev(tdev) { 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tdev == dev) 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 27095ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; 27195ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i)); 27295ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas i++) { 27395ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres->flags & IORESOURCE_MEM) { 27430c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(tres->flags)) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 27611439a6fd90b4861df64b4f983726e1c54977ab7Bjorn Helgaas if (tres->flags & IORESOURCE_WINDOW) 27711439a6fd90b4861df64b4f983726e1c54977ab7Bjorn Helgaas continue; 27830c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas taddr = &tres->start; 27930c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas tend = &tres->end; 2809dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (ranged_conflict(addr, end, taddr, tend)) 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2897d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t pnp_test_handler(int irq, void *dev_id) 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return IRQ_HANDLED; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29484684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas#ifdef CONFIG_PCI 29584684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaasstatic int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, 29684684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas unsigned int irq) 29784684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas{ 29884684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas u32 class; 29984684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas u8 progif; 30084684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 30184684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas if (pci->irq == irq) { 3022f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&pnp->dev, " device %s using irq %d\n", 30384684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas pci_name(pci), irq); 30484684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas return 1; 30584684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas } 30684684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 30784684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas /* 30884684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas * See pci_setup_device() and ata_pci_sff_activate_host() for 30984684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas * similar IDE legacy detection. 31084684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas */ 31184684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas pci_read_config_dword(pci, PCI_CLASS_REVISION, &class); 31284684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas class >>= 8; /* discard revision ID */ 31384684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas progif = class & 0xff; 31484684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas class >>= 8; 31584684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 31684684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas if (class == PCI_CLASS_STORAGE_IDE) { 31784684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas /* 31884684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas * Unless both channels are native-PCI mode only, 31984684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas * treat the compatibility IRQs as busy. 32084684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas */ 32184684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas if ((progif & 0x5) != 0x5) 32284684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas if (pci_get_legacy_ide_irq(pci, 0) == irq || 32384684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas pci_get_legacy_ide_irq(pci, 1) == irq) { 3242f53432c2aedbe79020e44525eb069d9138a01ddBjorn Helgaas pnp_dbg(&pnp->dev, " legacy IDE device %s " 32584684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas "using irq %d\n", pci_name(pci), irq); 32684684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas return 1; 32784684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas } 32884684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas } 32984684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 33084684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas return 0; 33184684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas} 33284684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas#endif 33384684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 33484684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaasstatic int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq) 33584684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas{ 33684684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas#ifdef CONFIG_PCI 33784684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas struct pci_dev *pci = NULL; 33884684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 33984684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas for_each_pci_dev(pci) { 34084684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas if (pci_dev_uses_irq(pnp, pci, irq)) { 34184684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas pci_dev_put(pci); 34284684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas return 1; 34384684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas } 34484684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas } 34584684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas#endif 34684684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas return 0; 34784684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas} 34884684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas 349f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaasint pnp_check_irq(struct pnp_dev *dev, struct resource *res) 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 351ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int i; 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *tdev; 353f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaas struct resource *tres; 35430c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas resource_size_t *irq; 35530c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas 35630c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas irq = &res->start; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if the resource doesn't exist, don't complain about it */ 35930c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(res->flags)) 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is valid */ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*irq < 0 || *irq > 15) 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is reserved */ 367ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas for (i = 0; i < 16; i++) { 368ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas if (pnp_reserve_irq[i] == *irq) 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for internal conflicts */ 37395ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { 37495ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres != res && tres->flags & IORESOURCE_IRQ) { 37530c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (tres->start == *irq) 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is being used by a pci device */ 38184684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas if (pci_uses_irq(dev, *irq)) 38284684c7469a2e6fcbf8c808ac5030ba2de14ff77Bjorn Helgaas return 0; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is already in use, skip if the 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device is active because it itself may be in use */ 3869dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!dev->active) { 3870cadaf45bd7c19f0bef49d1eebfff38a046b9ba4Andrew Morton if (request_irq(*irq, pnp_test_handler, 3889dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL)) 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(*irq, NULL); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for conflicts with other pnp devices */ 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_for_each_dev(tdev) { 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tdev == dev) 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 39795ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; 39895ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i)); 39995ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas i++) { 40095ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres->flags & IORESOURCE_IRQ) { 40130c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(tres->flags)) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 40330c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (tres->start == *irq) 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 412586f83e2b4c080073b115c1a0fcc2757f52839b8David Rientjes#ifdef CONFIG_ISA_DMA_API 413f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaasint pnp_check_dma(struct pnp_dev *dev, struct resource *res) 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 415ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas int i; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pnp_dev *tdev; 417f5d94ff014cb7e6212f40fc6644f3fd68507df33Bjorn Helgaas struct resource *tres; 41830c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas resource_size_t *dma; 41930c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas 42030c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas dma = &res->start; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if the resource doesn't exist, don't complain about it */ 42330c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(res->flags)) 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is valid */ 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*dma < 0 || *dma == 4 || *dma > 7) 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is reserved */ 431ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas for (i = 0; i < 8; i++) { 432ecfa935a2f7ef89543608f3ca05340c158c9a236Bjorn Helgaas if (pnp_reserve_dma[i] == *dma) 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for internal conflicts */ 43795ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 43895ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres != res && tres->flags & IORESOURCE_DMA) { 43930c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (tres->start == *dma) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the resource is already in use, skip if the 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device is active because it itself may be in use */ 4469dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (!dev->active) { 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_dma(*dma, "pnp")) 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_dma(*dma); 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check for conflicts with other pnp devices */ 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pnp_for_each_dev(tdev) { 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tdev == dev) 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 45695ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas for (i = 0; 45795ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i)); 45895ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas i++) { 45995ab3669f7830682c7762e9c305a0c1dd44454ccBjorn Helgaas if (tres->flags & IORESOURCE_DMA) { 46030c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (cannot_compare(tres->flags)) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 46230c016a0c8d2aae10be6a87bb98f0e85db8b09d5Bjorn Helgaas if (tres->start == *dma) 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 470586f83e2b4c080073b115c1a0fcc2757f52839b8David Rientjes#endif /* CONFIG_ISA_DMA_API */ 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 472b563cf59c4d67da7d671788a9848416bfa4180abRene Hermanunsigned long pnp_resource_type(struct resource *res) 473940e98dbc616f1df7b63b73858a966969baf261dBjorn Helgaas{ 474940e98dbc616f1df7b63b73858a966969baf261dBjorn Helgaas return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | 4757e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas IORESOURCE_IRQ | IORESOURCE_DMA | 4767e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas IORESOURCE_BUS); 477940e98dbc616f1df7b63b73858a966969baf261dBjorn Helgaas} 478940e98dbc616f1df7b63b73858a966969baf261dBjorn Helgaas 4790a977f15469457d9a19eed992caf71995c674064Bjorn Helgaasstruct resource *pnp_get_resource(struct pnp_dev *dev, 480b563cf59c4d67da7d671788a9848416bfa4180abRene Herman unsigned long type, unsigned int num) 4810a977f15469457d9a19eed992caf71995c674064Bjorn Helgaas{ 4820a977f15469457d9a19eed992caf71995c674064Bjorn Helgaas struct pnp_resource *pnp_res; 483aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas struct resource *res; 4840a977f15469457d9a19eed992caf71995c674064Bjorn Helgaas 485aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas list_for_each_entry(pnp_res, &dev->resources, list) { 486aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas res = &pnp_res->res; 487aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (pnp_resource_type(res) == type && num-- == 0) 488aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas return res; 489aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas } 4900a977f15469457d9a19eed992caf71995c674064Bjorn Helgaas return NULL; 4910a977f15469457d9a19eed992caf71995c674064Bjorn Helgaas} 492b90eca0a61ebd010036242e29610bc6a909e3f19Bjorn HelgaasEXPORT_SYMBOL(pnp_get_resource); 493b90eca0a61ebd010036242e29610bc6a909e3f19Bjorn Helgaas 494aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaasstatic struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) 495a50b6d7b8d7e1a8b13bd1be65a865b115e1190d9Bjorn Helgaas{ 496a50b6d7b8d7e1a8b13bd1be65a865b115e1190d9Bjorn Helgaas struct pnp_resource *pnp_res; 497a50b6d7b8d7e1a8b13bd1be65a865b115e1190d9Bjorn Helgaas 498aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL); 499aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas if (!pnp_res) 500aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas return NULL; 501aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas 502aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas list_add_tail(&pnp_res->list, &dev->resources); 503aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas return pnp_res; 504a50b6d7b8d7e1a8b13bd1be65a865b115e1190d9Bjorn Helgaas} 505a50b6d7b8d7e1a8b13bd1be65a865b115e1190d9Bjorn Helgaas 506dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaasstruct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 507dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas int flags) 508dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas{ 509dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas struct pnp_resource *pnp_res; 510dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas struct resource *res; 511dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas 512aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas pnp_res = pnp_new_resource(dev); 513dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas if (!pnp_res) { 51425d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq); 515dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas return NULL; 516dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas } 517dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas 518dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas res = &pnp_res->res; 519dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas res->flags = IORESOURCE_IRQ | flags; 520dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas res->start = irq; 521dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas res->end = irq; 522dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas 523c1f3f2819667a238585c65bba96c8b16af39a442Bjorn Helgaas dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 524dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas return pnp_res; 525dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas} 526dbddd0383c59d588f8db5e773b062756e39117ecBjorn Helgaas 527dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaasstruct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 528dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas int flags) 529dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas{ 530dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas struct pnp_resource *pnp_res; 531dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas struct resource *res; 532dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas 533aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas pnp_res = pnp_new_resource(dev); 534dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas if (!pnp_res) { 53525d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas dev_err(&dev->dev, "can't add resource for DMA %d\n", dma); 536dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas return NULL; 537dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas } 538dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas 539dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas res = &pnp_res->res; 540dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas res->flags = IORESOURCE_DMA | flags; 541dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas res->start = dma; 542dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas res->end = dma; 543dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas 544c1f3f2819667a238585c65bba96c8b16af39a442Bjorn Helgaas dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 545dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas return pnp_res; 546dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas} 547dc16f5f2ede8cc2acf8ac22857a7fecf3a4296c2Bjorn Helgaas 548cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaasstruct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 549cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas resource_size_t start, 550cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas resource_size_t end, int flags) 551cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas{ 552cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas struct pnp_resource *pnp_res; 553cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas struct resource *res; 554cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas 555aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas pnp_res = pnp_new_resource(dev); 556cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas if (!pnp_res) { 55725d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n", 55825d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas (unsigned long long) start, 55925d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas (unsigned long long) end); 560cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas return NULL; 561cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas } 562cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas 563cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas res = &pnp_res->res; 564cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas res->flags = IORESOURCE_IO | flags; 565cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas res->start = start; 566cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas res->end = end; 567cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas 568c1f3f2819667a238585c65bba96c8b16af39a442Bjorn Helgaas dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 569cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas return pnp_res; 570cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas} 571cc8c2e308194f0997c718c7c735550ff06754d20Bjorn Helgaas 572d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaasstruct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 573d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas resource_size_t start, 574d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas resource_size_t end, int flags) 575d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas{ 576d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas struct pnp_resource *pnp_res; 577d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas struct resource *res; 578d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas 579aee3ad815dd291a7193ab01da0f1a30c84d00061Bjorn Helgaas pnp_res = pnp_new_resource(dev); 580d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas if (!pnp_res) { 58125d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n", 58225d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas (unsigned long long) start, 58325d39c39d82d062f4be685146abd054a3bafdf12Bjorn Helgaas (unsigned long long) end); 584d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas return NULL; 585d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas } 586d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas 587d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas res = &pnp_res->res; 588d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas res->flags = IORESOURCE_MEM | flags; 589d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas res->start = start; 590d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas res->end = end; 591d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas 592c1f3f2819667a238585c65bba96c8b16af39a442Bjorn Helgaas dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 593d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas return pnp_res; 594d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas} 595d6180f36617953990bf90d4c1ff85b77e9995cd1Bjorn Helgaas 5967e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaasstruct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 5977e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas resource_size_t start, 5987e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas resource_size_t end) 5997e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas{ 6007e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas struct pnp_resource *pnp_res; 6017e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas struct resource *res; 6027e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas 6037e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas pnp_res = pnp_new_resource(dev); 6047e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas if (!pnp_res) { 6057e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", 6067e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas (unsigned long long) start, 6077e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas (unsigned long long) end); 6087e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas return NULL; 6097e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas } 6107e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas 6117e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas res = &pnp_res->res; 6127e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas res->flags = IORESOURCE_BUS; 6137e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas res->start = start; 6147e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas res->end = end; 6157e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas 616c1f3f2819667a238585c65bba96c8b16af39a442Bjorn Helgaas dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 6177e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas return pnp_res; 6187e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas} 6197e0e9c042790d4ea44c6a00ddaad8b8bbcc3f17fBjorn Helgaas 6201f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas/* 6211f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas * Determine whether the specified resource is a possible configuration 6221f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas * for this device. 6231f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas */ 6241f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaasint pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, 6251f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas resource_size_t size) 62657fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas{ 6271f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas struct pnp_option *option; 62857fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas struct pnp_port *port; 62957fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas struct pnp_mem *mem; 63057fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas struct pnp_irq *irq; 63157fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas struct pnp_dma *dma; 63257fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas 6331f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas list_for_each_entry(option, &dev->options, list) { 6341f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (option->type != type) 6351f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas continue; 63657fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas 6371f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas switch (option->type) { 63857fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas case IORESOURCE_IO: 6391f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas port = &option->u.port; 6401f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (port->min == start && port->size == size) 6411f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas return 1; 64257fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas break; 64357fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas case IORESOURCE_MEM: 6441f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas mem = &option->u.mem; 6451f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (mem->min == start && mem->size == size) 6461f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas return 1; 64757fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas break; 64857fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas case IORESOURCE_IRQ: 6491f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas irq = &option->u.irq; 6501f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (start < PNP_IRQ_NR && 6511f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas test_bit(start, irq->map.bits)) 6521f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas return 1; 65357fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas break; 65457fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas case IORESOURCE_DMA: 6551f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas dma = &option->u.dma; 6561f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas if (dma->map & (1 << start)) 6571f32ca31e7409d37c1b25e5f81840fb184380cdfBjorn Helgaas return 1; 65857fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas break; 65957fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas } 66057fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas } 66157fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas 66257fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas return 0; 66357fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas} 66457fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn HelgaasEXPORT_SYMBOL(pnp_possible_config); 66557fd51a8be26921b56747ddd09d1d9e01c11c9e0Bjorn Helgaas 6661b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas atint pnp_range_reserved(resource_size_t start, resource_size_t end) 6671b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at{ 6681b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at struct pnp_dev *dev; 6691b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at struct pnp_resource *pnp_res; 6701b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at resource_size_t *dev_start, *dev_end; 6711b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at 6721b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at pnp_for_each_dev(dev) { 6731b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at list_for_each_entry(pnp_res, &dev->resources, list) { 6741b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at dev_start = &pnp_res->res.start; 6751b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at dev_end = &pnp_res->res.end; 6761b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at if (ranged_conflict(&start, &end, dev_start, dev_end)) 6771b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at return 1; 6781b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at } 6791b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at } 6801b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at return 0; 6811b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at} 6821b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas atEXPORT_SYMBOL(pnp_range_reserved); 6831b8e69662e1a086878bf930a6042daf7f8a076ccBjorn Helgaas <bjorn.helgaas at 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pnp_setup_reserve_irq(char *str) 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 16; i++) 6909dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (get_option(&str, &pnp_reserve_irq[i]) != 2) 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__setup("pnp_reserve_irq=", pnp_setup_reserve_irq); 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* format is: pnp_reserve_dma=dma1[,dma2] .... */ 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pnp_setup_reserve_dma(char *str) 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 8; i++) 7039dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (get_option(&str, &pnp_reserve_dma[i]) != 2) 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__setup("pnp_reserve_dma=", pnp_setup_reserve_dma); 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */ 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pnp_setup_reserve_io(char *str) 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 16; i++) 7169dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (get_option(&str, &pnp_reserve_io[i]) != 2) 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__setup("pnp_reserve_io=", pnp_setup_reserve_io); 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */ 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pnp_setup_reserve_mem(char *str) 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 16; i++) 7299dd78466c956ac4b4f38e12032dc4249ccf57ad1Bjorn Helgaas if (get_option(&str, &pnp_reserve_mem[i]) != 2) 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__setup("pnp_reserve_mem=", pnp_setup_reserve_mem); 735