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