18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * resource.c - Contains functions for registering and analyzing resource information 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> 68c2ecf20Sopenharmony_ci * Copyright 2003 Adam Belay <ambx1@neo.rr.com> 78c2ecf20Sopenharmony_ci * Copyright (C) 2008 Hewlett-Packard Development Company, L.P. 88c2ecf20Sopenharmony_ci * Bjorn Helgaas <bjorn.helgaas@hp.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/slab.h> 138c2ecf20Sopenharmony_ci#include <linux/errno.h> 148c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 158c2ecf20Sopenharmony_ci#include <linux/kernel.h> 168c2ecf20Sopenharmony_ci#include <asm/io.h> 178c2ecf20Sopenharmony_ci#include <asm/dma.h> 188c2ecf20Sopenharmony_ci#include <asm/irq.h> 198c2ecf20Sopenharmony_ci#include <linux/pci.h> 208c2ecf20Sopenharmony_ci#include <linux/ioport.h> 218c2ecf20Sopenharmony_ci#include <linux/init.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <linux/pnp.h> 248c2ecf20Sopenharmony_ci#include "base.h" 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic int pnp_reserve_irq[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */ 278c2ecf20Sopenharmony_cistatic int pnp_reserve_dma[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */ 288c2ecf20Sopenharmony_cistatic int pnp_reserve_io[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */ 298c2ecf20Sopenharmony_cistatic int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci * option registration 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type, 368c2ecf20Sopenharmony_ci unsigned int option_flags) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci struct pnp_option *option; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL); 418c2ecf20Sopenharmony_ci if (!option) 428c2ecf20Sopenharmony_ci return NULL; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci option->flags = option_flags; 458c2ecf20Sopenharmony_ci option->type = type; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci list_add_tail(&option->list, &dev->options); 488c2ecf20Sopenharmony_ci return option; 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ciint pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags, 528c2ecf20Sopenharmony_ci pnp_irq_mask_t *map, unsigned char flags) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci struct pnp_option *option; 558c2ecf20Sopenharmony_ci struct pnp_irq *irq; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags); 588c2ecf20Sopenharmony_ci if (!option) 598c2ecf20Sopenharmony_ci return -ENOMEM; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci irq = &option->u.irq; 628c2ecf20Sopenharmony_ci irq->map = *map; 638c2ecf20Sopenharmony_ci irq->flags = flags; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI 668c2ecf20Sopenharmony_ci { 678c2ecf20Sopenharmony_ci int i; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) 708c2ecf20Sopenharmony_ci if (test_bit(i, irq->map.bits)) 718c2ecf20Sopenharmony_ci pcibios_penalize_isa_irq(i, 0); 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci#endif 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci dbg_pnp_show_option(dev, option); 768c2ecf20Sopenharmony_ci return 0; 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ciint pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags, 808c2ecf20Sopenharmony_ci unsigned char map, unsigned char flags) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci struct pnp_option *option; 838c2ecf20Sopenharmony_ci struct pnp_dma *dma; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci option = pnp_build_option(dev, IORESOURCE_DMA, option_flags); 868c2ecf20Sopenharmony_ci if (!option) 878c2ecf20Sopenharmony_ci return -ENOMEM; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci dma = &option->u.dma; 908c2ecf20Sopenharmony_ci dma->map = map; 918c2ecf20Sopenharmony_ci dma->flags = flags; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci dbg_pnp_show_option(dev, option); 948c2ecf20Sopenharmony_ci return 0; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ciint pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags, 988c2ecf20Sopenharmony_ci resource_size_t min, resource_size_t max, 998c2ecf20Sopenharmony_ci resource_size_t align, resource_size_t size, 1008c2ecf20Sopenharmony_ci unsigned char flags) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci struct pnp_option *option; 1038c2ecf20Sopenharmony_ci struct pnp_port *port; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci option = pnp_build_option(dev, IORESOURCE_IO, option_flags); 1068c2ecf20Sopenharmony_ci if (!option) 1078c2ecf20Sopenharmony_ci return -ENOMEM; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci port = &option->u.port; 1108c2ecf20Sopenharmony_ci port->min = min; 1118c2ecf20Sopenharmony_ci port->max = max; 1128c2ecf20Sopenharmony_ci port->align = align; 1138c2ecf20Sopenharmony_ci port->size = size; 1148c2ecf20Sopenharmony_ci port->flags = flags; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci dbg_pnp_show_option(dev, option); 1178c2ecf20Sopenharmony_ci return 0; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ciint pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags, 1218c2ecf20Sopenharmony_ci resource_size_t min, resource_size_t max, 1228c2ecf20Sopenharmony_ci resource_size_t align, resource_size_t size, 1238c2ecf20Sopenharmony_ci unsigned char flags) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci struct pnp_option *option; 1268c2ecf20Sopenharmony_ci struct pnp_mem *mem; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci option = pnp_build_option(dev, IORESOURCE_MEM, option_flags); 1298c2ecf20Sopenharmony_ci if (!option) 1308c2ecf20Sopenharmony_ci return -ENOMEM; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci mem = &option->u.mem; 1338c2ecf20Sopenharmony_ci mem->min = min; 1348c2ecf20Sopenharmony_ci mem->max = max; 1358c2ecf20Sopenharmony_ci mem->align = align; 1368c2ecf20Sopenharmony_ci mem->size = size; 1378c2ecf20Sopenharmony_ci mem->flags = flags; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci dbg_pnp_show_option(dev, option); 1408c2ecf20Sopenharmony_ci return 0; 1418c2ecf20Sopenharmony_ci} 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_civoid pnp_free_options(struct pnp_dev *dev) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci struct pnp_option *option, *tmp; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci list_for_each_entry_safe(option, tmp, &dev->options, list) { 1488c2ecf20Sopenharmony_ci list_del(&option->list); 1498c2ecf20Sopenharmony_ci kfree(option); 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci} 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci/* 1548c2ecf20Sopenharmony_ci * resource validity checking 1558c2ecf20Sopenharmony_ci */ 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci#define length(start, end) (*(end) - *(start) + 1) 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* Two ranges conflict if one doesn't end before the other starts */ 1608c2ecf20Sopenharmony_ci#define ranged_conflict(starta, enda, startb, endb) \ 1618c2ecf20Sopenharmony_ci !((*(enda) < *(startb)) || (*(endb) < *(starta))) 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci#define cannot_compare(flags) \ 1648c2ecf20Sopenharmony_ci((flags) & IORESOURCE_DISABLED) 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ciint pnp_check_port(struct pnp_dev *dev, struct resource *res) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci int i; 1698c2ecf20Sopenharmony_ci struct pnp_dev *tdev; 1708c2ecf20Sopenharmony_ci struct resource *tres; 1718c2ecf20Sopenharmony_ci resource_size_t *port, *end, *tport, *tend; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci port = &res->start; 1748c2ecf20Sopenharmony_ci end = &res->end; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* if the resource doesn't exist, don't complain about it */ 1778c2ecf20Sopenharmony_ci if (cannot_compare(res->flags)) 1788c2ecf20Sopenharmony_ci return 1; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci /* check if the resource is already in use, skip if the 1818c2ecf20Sopenharmony_ci * device is active because it itself may be in use */ 1828c2ecf20Sopenharmony_ci if (!dev->active) { 1838c2ecf20Sopenharmony_ci if (!request_region(*port, length(port, end), "pnp")) 1848c2ecf20Sopenharmony_ci return 0; 1858c2ecf20Sopenharmony_ci release_region(*port, length(port, end)); 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci /* check if the resource is reserved */ 1898c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) { 1908c2ecf20Sopenharmony_ci int rport = pnp_reserve_io[i << 1]; 1918c2ecf20Sopenharmony_ci int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1; 1928c2ecf20Sopenharmony_ci if (ranged_conflict(port, end, &rport, &rend)) 1938c2ecf20Sopenharmony_ci return 0; 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci /* check for internal conflicts */ 1978c2ecf20Sopenharmony_ci for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { 1988c2ecf20Sopenharmony_ci if (tres != res && tres->flags & IORESOURCE_IO) { 1998c2ecf20Sopenharmony_ci tport = &tres->start; 2008c2ecf20Sopenharmony_ci tend = &tres->end; 2018c2ecf20Sopenharmony_ci if (ranged_conflict(port, end, tport, tend)) 2028c2ecf20Sopenharmony_ci return 0; 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci /* check for conflicts with other pnp devices */ 2078c2ecf20Sopenharmony_ci pnp_for_each_dev(tdev) { 2088c2ecf20Sopenharmony_ci if (tdev == dev) 2098c2ecf20Sopenharmony_ci continue; 2108c2ecf20Sopenharmony_ci for (i = 0; 2118c2ecf20Sopenharmony_ci (tres = pnp_get_resource(tdev, IORESOURCE_IO, i)); 2128c2ecf20Sopenharmony_ci i++) { 2138c2ecf20Sopenharmony_ci if (tres->flags & IORESOURCE_IO) { 2148c2ecf20Sopenharmony_ci if (cannot_compare(tres->flags)) 2158c2ecf20Sopenharmony_ci continue; 2168c2ecf20Sopenharmony_ci if (tres->flags & IORESOURCE_WINDOW) 2178c2ecf20Sopenharmony_ci continue; 2188c2ecf20Sopenharmony_ci tport = &tres->start; 2198c2ecf20Sopenharmony_ci tend = &tres->end; 2208c2ecf20Sopenharmony_ci if (ranged_conflict(port, end, tport, tend)) 2218c2ecf20Sopenharmony_ci return 0; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci return 1; 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ciint pnp_check_mem(struct pnp_dev *dev, struct resource *res) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci int i; 2328c2ecf20Sopenharmony_ci struct pnp_dev *tdev; 2338c2ecf20Sopenharmony_ci struct resource *tres; 2348c2ecf20Sopenharmony_ci resource_size_t *addr, *end, *taddr, *tend; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci addr = &res->start; 2378c2ecf20Sopenharmony_ci end = &res->end; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci /* if the resource doesn't exist, don't complain about it */ 2408c2ecf20Sopenharmony_ci if (cannot_compare(res->flags)) 2418c2ecf20Sopenharmony_ci return 1; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci /* check if the resource is already in use, skip if the 2448c2ecf20Sopenharmony_ci * device is active because it itself may be in use */ 2458c2ecf20Sopenharmony_ci if (!dev->active) { 2468c2ecf20Sopenharmony_ci if (!request_mem_region(*addr, length(addr, end), "pnp")) 2478c2ecf20Sopenharmony_ci return 0; 2488c2ecf20Sopenharmony_ci release_mem_region(*addr, length(addr, end)); 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci /* check if the resource is reserved */ 2528c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) { 2538c2ecf20Sopenharmony_ci int raddr = pnp_reserve_mem[i << 1]; 2548c2ecf20Sopenharmony_ci int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1; 2558c2ecf20Sopenharmony_ci if (ranged_conflict(addr, end, &raddr, &rend)) 2568c2ecf20Sopenharmony_ci return 0; 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci /* check for internal conflicts */ 2608c2ecf20Sopenharmony_ci for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { 2618c2ecf20Sopenharmony_ci if (tres != res && tres->flags & IORESOURCE_MEM) { 2628c2ecf20Sopenharmony_ci taddr = &tres->start; 2638c2ecf20Sopenharmony_ci tend = &tres->end; 2648c2ecf20Sopenharmony_ci if (ranged_conflict(addr, end, taddr, tend)) 2658c2ecf20Sopenharmony_ci return 0; 2668c2ecf20Sopenharmony_ci } 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci /* check for conflicts with other pnp devices */ 2708c2ecf20Sopenharmony_ci pnp_for_each_dev(tdev) { 2718c2ecf20Sopenharmony_ci if (tdev == dev) 2728c2ecf20Sopenharmony_ci continue; 2738c2ecf20Sopenharmony_ci for (i = 0; 2748c2ecf20Sopenharmony_ci (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i)); 2758c2ecf20Sopenharmony_ci i++) { 2768c2ecf20Sopenharmony_ci if (tres->flags & IORESOURCE_MEM) { 2778c2ecf20Sopenharmony_ci if (cannot_compare(tres->flags)) 2788c2ecf20Sopenharmony_ci continue; 2798c2ecf20Sopenharmony_ci if (tres->flags & IORESOURCE_WINDOW) 2808c2ecf20Sopenharmony_ci continue; 2818c2ecf20Sopenharmony_ci taddr = &tres->start; 2828c2ecf20Sopenharmony_ci tend = &tres->end; 2838c2ecf20Sopenharmony_ci if (ranged_conflict(addr, end, taddr, tend)) 2848c2ecf20Sopenharmony_ci return 0; 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci } 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci return 1; 2908c2ecf20Sopenharmony_ci} 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic irqreturn_t pnp_test_handler(int irq, void *dev_id) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci return IRQ_HANDLED; 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI 2988c2ecf20Sopenharmony_cistatic int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci, 2998c2ecf20Sopenharmony_ci unsigned int irq) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci u32 class; 3028c2ecf20Sopenharmony_ci u8 progif; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci if (pci->irq == irq) { 3058c2ecf20Sopenharmony_ci pnp_dbg(&pnp->dev, " device %s using irq %d\n", 3068c2ecf20Sopenharmony_ci pci_name(pci), irq); 3078c2ecf20Sopenharmony_ci return 1; 3088c2ecf20Sopenharmony_ci } 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci /* 3118c2ecf20Sopenharmony_ci * See pci_setup_device() and ata_pci_sff_activate_host() for 3128c2ecf20Sopenharmony_ci * similar IDE legacy detection. 3138c2ecf20Sopenharmony_ci */ 3148c2ecf20Sopenharmony_ci pci_read_config_dword(pci, PCI_CLASS_REVISION, &class); 3158c2ecf20Sopenharmony_ci class >>= 8; /* discard revision ID */ 3168c2ecf20Sopenharmony_ci progif = class & 0xff; 3178c2ecf20Sopenharmony_ci class >>= 8; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci if (class == PCI_CLASS_STORAGE_IDE) { 3208c2ecf20Sopenharmony_ci /* 3218c2ecf20Sopenharmony_ci * Unless both channels are native-PCI mode only, 3228c2ecf20Sopenharmony_ci * treat the compatibility IRQs as busy. 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_ci if ((progif & 0x5) != 0x5) 3258c2ecf20Sopenharmony_ci if (pci_get_legacy_ide_irq(pci, 0) == irq || 3268c2ecf20Sopenharmony_ci pci_get_legacy_ide_irq(pci, 1) == irq) { 3278c2ecf20Sopenharmony_ci pnp_dbg(&pnp->dev, " legacy IDE device %s " 3288c2ecf20Sopenharmony_ci "using irq %d\n", pci_name(pci), irq); 3298c2ecf20Sopenharmony_ci return 1; 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci } 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci return 0; 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci#endif 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_cistatic int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq) 3388c2ecf20Sopenharmony_ci{ 3398c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI 3408c2ecf20Sopenharmony_ci struct pci_dev *pci = NULL; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci for_each_pci_dev(pci) { 3438c2ecf20Sopenharmony_ci if (pci_dev_uses_irq(pnp, pci, irq)) { 3448c2ecf20Sopenharmony_ci pci_dev_put(pci); 3458c2ecf20Sopenharmony_ci return 1; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci#endif 3498c2ecf20Sopenharmony_ci return 0; 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ciint pnp_check_irq(struct pnp_dev *dev, struct resource *res) 3538c2ecf20Sopenharmony_ci{ 3548c2ecf20Sopenharmony_ci int i; 3558c2ecf20Sopenharmony_ci struct pnp_dev *tdev; 3568c2ecf20Sopenharmony_ci struct resource *tres; 3578c2ecf20Sopenharmony_ci resource_size_t *irq; 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci irq = &res->start; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci /* if the resource doesn't exist, don't complain about it */ 3628c2ecf20Sopenharmony_ci if (cannot_compare(res->flags)) 3638c2ecf20Sopenharmony_ci return 1; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci /* check if the resource is valid */ 3668c2ecf20Sopenharmony_ci if (*irq > 15) 3678c2ecf20Sopenharmony_ci return 0; 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci /* check if the resource is reserved */ 3708c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) { 3718c2ecf20Sopenharmony_ci if (pnp_reserve_irq[i] == *irq) 3728c2ecf20Sopenharmony_ci return 0; 3738c2ecf20Sopenharmony_ci } 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci /* check for internal conflicts */ 3768c2ecf20Sopenharmony_ci for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { 3778c2ecf20Sopenharmony_ci if (tres != res && tres->flags & IORESOURCE_IRQ) { 3788c2ecf20Sopenharmony_ci if (tres->start == *irq) 3798c2ecf20Sopenharmony_ci return 0; 3808c2ecf20Sopenharmony_ci } 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci /* check if the resource is being used by a pci device */ 3848c2ecf20Sopenharmony_ci if (pci_uses_irq(dev, *irq)) 3858c2ecf20Sopenharmony_ci return 0; 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci /* check if the resource is already in use, skip if the 3888c2ecf20Sopenharmony_ci * device is active because it itself may be in use */ 3898c2ecf20Sopenharmony_ci if (!dev->active) { 3908c2ecf20Sopenharmony_ci if (request_irq(*irq, pnp_test_handler, 3918c2ecf20Sopenharmony_ci IRQF_PROBE_SHARED, "pnp", NULL)) 3928c2ecf20Sopenharmony_ci return 0; 3938c2ecf20Sopenharmony_ci free_irq(*irq, NULL); 3948c2ecf20Sopenharmony_ci } 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci /* check for conflicts with other pnp devices */ 3978c2ecf20Sopenharmony_ci pnp_for_each_dev(tdev) { 3988c2ecf20Sopenharmony_ci if (tdev == dev) 3998c2ecf20Sopenharmony_ci continue; 4008c2ecf20Sopenharmony_ci for (i = 0; 4018c2ecf20Sopenharmony_ci (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i)); 4028c2ecf20Sopenharmony_ci i++) { 4038c2ecf20Sopenharmony_ci if (tres->flags & IORESOURCE_IRQ) { 4048c2ecf20Sopenharmony_ci if (cannot_compare(tres->flags)) 4058c2ecf20Sopenharmony_ci continue; 4068c2ecf20Sopenharmony_ci if (tres->start == *irq) 4078c2ecf20Sopenharmony_ci return 0; 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci } 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci return 1; 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci#ifdef CONFIG_ISA_DMA_API 4168c2ecf20Sopenharmony_ciint pnp_check_dma(struct pnp_dev *dev, struct resource *res) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci int i; 4198c2ecf20Sopenharmony_ci struct pnp_dev *tdev; 4208c2ecf20Sopenharmony_ci struct resource *tres; 4218c2ecf20Sopenharmony_ci resource_size_t *dma; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci dma = &res->start; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci /* if the resource doesn't exist, don't complain about it */ 4268c2ecf20Sopenharmony_ci if (cannot_compare(res->flags)) 4278c2ecf20Sopenharmony_ci return 1; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci /* check if the resource is valid */ 4308c2ecf20Sopenharmony_ci if (*dma == 4 || *dma > 7) 4318c2ecf20Sopenharmony_ci return 0; 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci /* check if the resource is reserved */ 4348c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) { 4358c2ecf20Sopenharmony_ci if (pnp_reserve_dma[i] == *dma) 4368c2ecf20Sopenharmony_ci return 0; 4378c2ecf20Sopenharmony_ci } 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci /* check for internal conflicts */ 4408c2ecf20Sopenharmony_ci for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { 4418c2ecf20Sopenharmony_ci if (tres != res && tres->flags & IORESOURCE_DMA) { 4428c2ecf20Sopenharmony_ci if (tres->start == *dma) 4438c2ecf20Sopenharmony_ci return 0; 4448c2ecf20Sopenharmony_ci } 4458c2ecf20Sopenharmony_ci } 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci /* check if the resource is already in use, skip if the 4488c2ecf20Sopenharmony_ci * device is active because it itself may be in use */ 4498c2ecf20Sopenharmony_ci if (!dev->active) { 4508c2ecf20Sopenharmony_ci if (request_dma(*dma, "pnp")) 4518c2ecf20Sopenharmony_ci return 0; 4528c2ecf20Sopenharmony_ci free_dma(*dma); 4538c2ecf20Sopenharmony_ci } 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci /* check for conflicts with other pnp devices */ 4568c2ecf20Sopenharmony_ci pnp_for_each_dev(tdev) { 4578c2ecf20Sopenharmony_ci if (tdev == dev) 4588c2ecf20Sopenharmony_ci continue; 4598c2ecf20Sopenharmony_ci for (i = 0; 4608c2ecf20Sopenharmony_ci (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i)); 4618c2ecf20Sopenharmony_ci i++) { 4628c2ecf20Sopenharmony_ci if (tres->flags & IORESOURCE_DMA) { 4638c2ecf20Sopenharmony_ci if (cannot_compare(tres->flags)) 4648c2ecf20Sopenharmony_ci continue; 4658c2ecf20Sopenharmony_ci if (tres->start == *dma) 4668c2ecf20Sopenharmony_ci return 0; 4678c2ecf20Sopenharmony_ci } 4688c2ecf20Sopenharmony_ci } 4698c2ecf20Sopenharmony_ci } 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci return 1; 4728c2ecf20Sopenharmony_ci} 4738c2ecf20Sopenharmony_ci#endif /* CONFIG_ISA_DMA_API */ 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ciunsigned long pnp_resource_type(struct resource *res) 4768c2ecf20Sopenharmony_ci{ 4778c2ecf20Sopenharmony_ci return res->flags & (IORESOURCE_IO | IORESOURCE_MEM | 4788c2ecf20Sopenharmony_ci IORESOURCE_IRQ | IORESOURCE_DMA | 4798c2ecf20Sopenharmony_ci IORESOURCE_BUS); 4808c2ecf20Sopenharmony_ci} 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_cistruct resource *pnp_get_resource(struct pnp_dev *dev, 4838c2ecf20Sopenharmony_ci unsigned long type, unsigned int num) 4848c2ecf20Sopenharmony_ci{ 4858c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 4868c2ecf20Sopenharmony_ci struct resource *res; 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci list_for_each_entry(pnp_res, &dev->resources, list) { 4898c2ecf20Sopenharmony_ci res = &pnp_res->res; 4908c2ecf20Sopenharmony_ci if (pnp_resource_type(res) == type && num-- == 0) 4918c2ecf20Sopenharmony_ci return res; 4928c2ecf20Sopenharmony_ci } 4938c2ecf20Sopenharmony_ci return NULL; 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pnp_get_resource); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) 4988c2ecf20Sopenharmony_ci{ 4998c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL); 5028c2ecf20Sopenharmony_ci if (!pnp_res) 5038c2ecf20Sopenharmony_ci return NULL; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci list_add_tail(&pnp_res->list, &dev->resources); 5068c2ecf20Sopenharmony_ci return pnp_res; 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_cistruct pnp_resource *pnp_add_resource(struct pnp_dev *dev, 5108c2ecf20Sopenharmony_ci struct resource *res) 5118c2ecf20Sopenharmony_ci{ 5128c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci pnp_res = pnp_new_resource(dev); 5158c2ecf20Sopenharmony_ci if (!pnp_res) { 5168c2ecf20Sopenharmony_ci dev_err(&dev->dev, "can't add resource %pR\n", res); 5178c2ecf20Sopenharmony_ci return NULL; 5188c2ecf20Sopenharmony_ci } 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci pnp_res->res = *res; 5218c2ecf20Sopenharmony_ci pnp_res->res.name = dev->name; 5228c2ecf20Sopenharmony_ci dev_dbg(&dev->dev, "%pR\n", res); 5238c2ecf20Sopenharmony_ci return pnp_res; 5248c2ecf20Sopenharmony_ci} 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_cistruct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, 5278c2ecf20Sopenharmony_ci int flags) 5288c2ecf20Sopenharmony_ci{ 5298c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 5308c2ecf20Sopenharmony_ci struct resource *res; 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci pnp_res = pnp_new_resource(dev); 5338c2ecf20Sopenharmony_ci if (!pnp_res) { 5348c2ecf20Sopenharmony_ci dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq); 5358c2ecf20Sopenharmony_ci return NULL; 5368c2ecf20Sopenharmony_ci } 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci res = &pnp_res->res; 5398c2ecf20Sopenharmony_ci res->flags = IORESOURCE_IRQ | flags; 5408c2ecf20Sopenharmony_ci res->start = irq; 5418c2ecf20Sopenharmony_ci res->end = irq; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 5448c2ecf20Sopenharmony_ci return pnp_res; 5458c2ecf20Sopenharmony_ci} 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_cistruct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, 5488c2ecf20Sopenharmony_ci int flags) 5498c2ecf20Sopenharmony_ci{ 5508c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 5518c2ecf20Sopenharmony_ci struct resource *res; 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci pnp_res = pnp_new_resource(dev); 5548c2ecf20Sopenharmony_ci if (!pnp_res) { 5558c2ecf20Sopenharmony_ci dev_err(&dev->dev, "can't add resource for DMA %d\n", dma); 5568c2ecf20Sopenharmony_ci return NULL; 5578c2ecf20Sopenharmony_ci } 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci res = &pnp_res->res; 5608c2ecf20Sopenharmony_ci res->flags = IORESOURCE_DMA | flags; 5618c2ecf20Sopenharmony_ci res->start = dma; 5628c2ecf20Sopenharmony_ci res->end = dma; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 5658c2ecf20Sopenharmony_ci return pnp_res; 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cistruct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, 5698c2ecf20Sopenharmony_ci resource_size_t start, 5708c2ecf20Sopenharmony_ci resource_size_t end, int flags) 5718c2ecf20Sopenharmony_ci{ 5728c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 5738c2ecf20Sopenharmony_ci struct resource *res; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci pnp_res = pnp_new_resource(dev); 5768c2ecf20Sopenharmony_ci if (!pnp_res) { 5778c2ecf20Sopenharmony_ci dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n", 5788c2ecf20Sopenharmony_ci (unsigned long long) start, 5798c2ecf20Sopenharmony_ci (unsigned long long) end); 5808c2ecf20Sopenharmony_ci return NULL; 5818c2ecf20Sopenharmony_ci } 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci res = &pnp_res->res; 5848c2ecf20Sopenharmony_ci res->flags = IORESOURCE_IO | flags; 5858c2ecf20Sopenharmony_ci res->start = start; 5868c2ecf20Sopenharmony_ci res->end = end; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 5898c2ecf20Sopenharmony_ci return pnp_res; 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistruct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, 5938c2ecf20Sopenharmony_ci resource_size_t start, 5948c2ecf20Sopenharmony_ci resource_size_t end, int flags) 5958c2ecf20Sopenharmony_ci{ 5968c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 5978c2ecf20Sopenharmony_ci struct resource *res; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci pnp_res = pnp_new_resource(dev); 6008c2ecf20Sopenharmony_ci if (!pnp_res) { 6018c2ecf20Sopenharmony_ci dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n", 6028c2ecf20Sopenharmony_ci (unsigned long long) start, 6038c2ecf20Sopenharmony_ci (unsigned long long) end); 6048c2ecf20Sopenharmony_ci return NULL; 6058c2ecf20Sopenharmony_ci } 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci res = &pnp_res->res; 6088c2ecf20Sopenharmony_ci res->flags = IORESOURCE_MEM | flags; 6098c2ecf20Sopenharmony_ci res->start = start; 6108c2ecf20Sopenharmony_ci res->end = end; 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 6138c2ecf20Sopenharmony_ci return pnp_res; 6148c2ecf20Sopenharmony_ci} 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_cistruct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, 6178c2ecf20Sopenharmony_ci resource_size_t start, 6188c2ecf20Sopenharmony_ci resource_size_t end) 6198c2ecf20Sopenharmony_ci{ 6208c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 6218c2ecf20Sopenharmony_ci struct resource *res; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci pnp_res = pnp_new_resource(dev); 6248c2ecf20Sopenharmony_ci if (!pnp_res) { 6258c2ecf20Sopenharmony_ci dev_err(&dev->dev, "can't add resource for BUS %#llx-%#llx\n", 6268c2ecf20Sopenharmony_ci (unsigned long long) start, 6278c2ecf20Sopenharmony_ci (unsigned long long) end); 6288c2ecf20Sopenharmony_ci return NULL; 6298c2ecf20Sopenharmony_ci } 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci res = &pnp_res->res; 6328c2ecf20Sopenharmony_ci res->flags = IORESOURCE_BUS; 6338c2ecf20Sopenharmony_ci res->start = start; 6348c2ecf20Sopenharmony_ci res->end = end; 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); 6378c2ecf20Sopenharmony_ci return pnp_res; 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci/* 6418c2ecf20Sopenharmony_ci * Determine whether the specified resource is a possible configuration 6428c2ecf20Sopenharmony_ci * for this device. 6438c2ecf20Sopenharmony_ci */ 6448c2ecf20Sopenharmony_ciint pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start, 6458c2ecf20Sopenharmony_ci resource_size_t size) 6468c2ecf20Sopenharmony_ci{ 6478c2ecf20Sopenharmony_ci struct pnp_option *option; 6488c2ecf20Sopenharmony_ci struct pnp_port *port; 6498c2ecf20Sopenharmony_ci struct pnp_mem *mem; 6508c2ecf20Sopenharmony_ci struct pnp_irq *irq; 6518c2ecf20Sopenharmony_ci struct pnp_dma *dma; 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci list_for_each_entry(option, &dev->options, list) { 6548c2ecf20Sopenharmony_ci if (option->type != type) 6558c2ecf20Sopenharmony_ci continue; 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci switch (option->type) { 6588c2ecf20Sopenharmony_ci case IORESOURCE_IO: 6598c2ecf20Sopenharmony_ci port = &option->u.port; 6608c2ecf20Sopenharmony_ci if (port->min == start && port->size == size) 6618c2ecf20Sopenharmony_ci return 1; 6628c2ecf20Sopenharmony_ci break; 6638c2ecf20Sopenharmony_ci case IORESOURCE_MEM: 6648c2ecf20Sopenharmony_ci mem = &option->u.mem; 6658c2ecf20Sopenharmony_ci if (mem->min == start && mem->size == size) 6668c2ecf20Sopenharmony_ci return 1; 6678c2ecf20Sopenharmony_ci break; 6688c2ecf20Sopenharmony_ci case IORESOURCE_IRQ: 6698c2ecf20Sopenharmony_ci irq = &option->u.irq; 6708c2ecf20Sopenharmony_ci if (start < PNP_IRQ_NR && 6718c2ecf20Sopenharmony_ci test_bit(start, irq->map.bits)) 6728c2ecf20Sopenharmony_ci return 1; 6738c2ecf20Sopenharmony_ci break; 6748c2ecf20Sopenharmony_ci case IORESOURCE_DMA: 6758c2ecf20Sopenharmony_ci dma = &option->u.dma; 6768c2ecf20Sopenharmony_ci if (dma->map & (1 << start)) 6778c2ecf20Sopenharmony_ci return 1; 6788c2ecf20Sopenharmony_ci break; 6798c2ecf20Sopenharmony_ci } 6808c2ecf20Sopenharmony_ci } 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_ci return 0; 6838c2ecf20Sopenharmony_ci} 6848c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pnp_possible_config); 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ciint pnp_range_reserved(resource_size_t start, resource_size_t end) 6878c2ecf20Sopenharmony_ci{ 6888c2ecf20Sopenharmony_ci struct pnp_dev *dev; 6898c2ecf20Sopenharmony_ci struct pnp_resource *pnp_res; 6908c2ecf20Sopenharmony_ci resource_size_t *dev_start, *dev_end; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci pnp_for_each_dev(dev) { 6938c2ecf20Sopenharmony_ci list_for_each_entry(pnp_res, &dev->resources, list) { 6948c2ecf20Sopenharmony_ci dev_start = &pnp_res->res.start; 6958c2ecf20Sopenharmony_ci dev_end = &pnp_res->res.end; 6968c2ecf20Sopenharmony_ci if (ranged_conflict(&start, &end, dev_start, dev_end)) 6978c2ecf20Sopenharmony_ci return 1; 6988c2ecf20Sopenharmony_ci } 6998c2ecf20Sopenharmony_ci } 7008c2ecf20Sopenharmony_ci return 0; 7018c2ecf20Sopenharmony_ci} 7028c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pnp_range_reserved); 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 7058c2ecf20Sopenharmony_cistatic int __init pnp_setup_reserve_irq(char *str) 7068c2ecf20Sopenharmony_ci{ 7078c2ecf20Sopenharmony_ci int i; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) 7108c2ecf20Sopenharmony_ci if (get_option(&str, &pnp_reserve_irq[i]) != 2) 7118c2ecf20Sopenharmony_ci break; 7128c2ecf20Sopenharmony_ci return 1; 7138c2ecf20Sopenharmony_ci} 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci__setup("pnp_reserve_irq=", pnp_setup_reserve_irq); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci/* format is: pnp_reserve_dma=dma1[,dma2] .... */ 7188c2ecf20Sopenharmony_cistatic int __init pnp_setup_reserve_dma(char *str) 7198c2ecf20Sopenharmony_ci{ 7208c2ecf20Sopenharmony_ci int i; 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) 7238c2ecf20Sopenharmony_ci if (get_option(&str, &pnp_reserve_dma[i]) != 2) 7248c2ecf20Sopenharmony_ci break; 7258c2ecf20Sopenharmony_ci return 1; 7268c2ecf20Sopenharmony_ci} 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci__setup("pnp_reserve_dma=", pnp_setup_reserve_dma); 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci/* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */ 7318c2ecf20Sopenharmony_cistatic int __init pnp_setup_reserve_io(char *str) 7328c2ecf20Sopenharmony_ci{ 7338c2ecf20Sopenharmony_ci int i; 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) 7368c2ecf20Sopenharmony_ci if (get_option(&str, &pnp_reserve_io[i]) != 2) 7378c2ecf20Sopenharmony_ci break; 7388c2ecf20Sopenharmony_ci return 1; 7398c2ecf20Sopenharmony_ci} 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci__setup("pnp_reserve_io=", pnp_setup_reserve_io); 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci/* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */ 7448c2ecf20Sopenharmony_cistatic int __init pnp_setup_reserve_mem(char *str) 7458c2ecf20Sopenharmony_ci{ 7468c2ecf20Sopenharmony_ci int i; 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci for (i = 0; i < 16; i++) 7498c2ecf20Sopenharmony_ci if (get_option(&str, &pnp_reserve_mem[i]) != 2) 7508c2ecf20Sopenharmony_ci break; 7518c2ecf20Sopenharmony_ci return 1; 7528c2ecf20Sopenharmony_ci} 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci__setup("pnp_reserve_mem=", pnp_setup_reserve_mem); 755