X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fpnp%2Fresource.c;h=390b50096e30890f57d6cf6f55dc730d18013b47;hb=5d9bac8ece5e2a64a2a450c7e2d6901ed9152052;hp=93bf45e01f2c07f88fa3906e82f2c25e26a1b0d9;hpb=f5d94ff014cb7e6212f40fc6644f3fd68507df33;p=linux-2.6-omap-h63xx.git diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 93bf45e01f2..390b50096e3 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -28,7 +28,7 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some * option registration */ -static struct pnp_option *pnp_build_option(int priority) +struct pnp_option *pnp_build_option(int priority) { struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); @@ -269,8 +269,7 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res) } /* check for internal conflicts */ - for (i = 0; i < PNP_MAX_PORT; i++) { - tres = &dev->res.port_resource[i]; + for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { if (tres != res && tres->flags & IORESOURCE_IO) { tport = &tres->start; tend = &tres->end; @@ -283,8 +282,9 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res) pnp_for_each_dev(tdev) { if (tdev == dev) continue; - for (i = 0; i < PNP_MAX_PORT; i++) { - tres = &tdev->res.port_resource[i]; + for (i = 0; + (tres = pnp_get_resource(tdev, IORESOURCE_IO, i)); + i++) { if (tres->flags & IORESOURCE_IO) { if (cannot_compare(tres->flags)) continue; @@ -329,8 +329,7 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res) } /* check for internal conflicts */ - for (i = 0; i < PNP_MAX_MEM; i++) { - tres = &dev->res.mem_resource[i]; + for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { if (tres != res && tres->flags & IORESOURCE_MEM) { taddr = &tres->start; tend = &tres->end; @@ -343,8 +342,9 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res) pnp_for_each_dev(tdev) { if (tdev == dev) continue; - for (i = 0; i < PNP_MAX_MEM; i++) { - tres = &tdev->res.mem_resource[i]; + for (i = 0; + (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i)); + i++) { if (tres->flags & IORESOURCE_MEM) { if (cannot_compare(tres->flags)) continue; @@ -388,8 +388,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res) } /* check for internal conflicts */ - for (i = 0; i < PNP_MAX_IRQ; i++) { - tres = &dev->res.irq_resource[i]; + for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) { if (tres != res && tres->flags & IORESOURCE_IRQ) { if (tres->start == *irq) return 0; @@ -422,8 +421,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res) pnp_for_each_dev(tdev) { if (tdev == dev) continue; - for (i = 0; i < PNP_MAX_IRQ; i++) { - tres = &tdev->res.irq_resource[i]; + for (i = 0; + (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i)); + i++) { if (tres->flags & IORESOURCE_IRQ) { if (cannot_compare(tres->flags)) continue; @@ -461,8 +461,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) } /* check for internal conflicts */ - for (i = 0; i < PNP_MAX_DMA; i++) { - tres = &dev->res.dma_resource[i]; + for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { if (tres != res && tres->flags & IORESOURCE_DMA) { if (tres->start == *dma) return 0; @@ -481,8 +480,9 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) pnp_for_each_dev(tdev) { if (tdev == dev) continue; - for (i = 0; i < PNP_MAX_DMA; i++) { - tres = &tdev->res.dma_resource[i]; + for (i = 0; + (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i)); + i++) { if (tres->flags & IORESOURCE_DMA) { if (cannot_compare(tres->flags)) continue; @@ -499,33 +499,193 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) #endif } -struct resource *pnp_get_resource(struct pnp_dev *dev, - unsigned int type, unsigned int num) +struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, + unsigned int type, unsigned int num) { - struct pnp_resource_table *res = &dev->res; + struct pnp_resource_table *res = dev->res; switch (type) { case IORESOURCE_IO: if (num >= PNP_MAX_PORT) return NULL; - return &res->port_resource[num]; + return &res->port[num]; case IORESOURCE_MEM: if (num >= PNP_MAX_MEM) return NULL; - return &res->mem_resource[num]; + return &res->mem[num]; case IORESOURCE_IRQ: if (num >= PNP_MAX_IRQ) return NULL; - return &res->irq_resource[num]; + return &res->irq[num]; case IORESOURCE_DMA: if (num >= PNP_MAX_DMA) return NULL; - return &res->dma_resource[num]; + return &res->dma[num]; } return NULL; } + +struct resource *pnp_get_resource(struct pnp_dev *dev, + unsigned int type, unsigned int num) +{ + struct pnp_resource *pnp_res; + + pnp_res = pnp_get_pnp_resource(dev, type, num); + if (pnp_res) + return &pnp_res->res; + + return NULL; +} EXPORT_SYMBOL(pnp_get_resource); +static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) +{ + struct pnp_resource *pnp_res; + int i; + + switch (type) { + case IORESOURCE_IO: + for (i = 0; i < PNP_MAX_PORT; i++) { + pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i); + if (pnp_res && !pnp_resource_valid(&pnp_res->res)) + return pnp_res; + } + break; + case IORESOURCE_MEM: + for (i = 0; i < PNP_MAX_MEM; i++) { + pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i); + if (pnp_res && !pnp_resource_valid(&pnp_res->res)) + return pnp_res; + } + break; + case IORESOURCE_IRQ: + for (i = 0; i < PNP_MAX_IRQ; i++) { + pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i); + if (pnp_res && !pnp_resource_valid(&pnp_res->res)) + return pnp_res; + } + break; + case IORESOURCE_DMA: + for (i = 0; i < PNP_MAX_DMA; i++) { + pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i); + if (pnp_res && !pnp_resource_valid(&pnp_res->res)) + return pnp_res; + } + break; + } + return NULL; +} + +struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, + int flags) +{ + struct pnp_resource *pnp_res; + struct resource *res; + static unsigned char warned; + + pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); + if (!pnp_res) { + if (!warned) { + dev_err(&dev->dev, "can't add resource for IRQ %d\n", + irq); + warned = 1; + } + return NULL; + } + + res = &pnp_res->res; + res->flags = IORESOURCE_IRQ | flags; + res->start = irq; + res->end = irq; + + dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags); + return pnp_res; +} + +struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, + int flags) +{ + struct pnp_resource *pnp_res; + struct resource *res; + static unsigned char warned; + + pnp_res = pnp_new_resource(dev, IORESOURCE_DMA); + if (!pnp_res) { + if (!warned) { + dev_err(&dev->dev, "can't add resource for DMA %d\n", + dma); + warned = 1; + } + return NULL; + } + + res = &pnp_res->res; + res->flags = IORESOURCE_DMA | flags; + res->start = dma; + res->end = dma; + + dev_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags); + return pnp_res; +} + +struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, + resource_size_t start, + resource_size_t end, int flags) +{ + struct pnp_resource *pnp_res; + struct resource *res; + static unsigned char warned; + + pnp_res = pnp_new_resource(dev, IORESOURCE_IO); + if (!pnp_res) { + if (!warned) { + dev_err(&dev->dev, "can't add resource for IO " + "%#llx-%#llx\n",(unsigned long long) start, + (unsigned long long) end); + warned = 1; + } + return NULL; + } + + res = &pnp_res->res; + res->flags = IORESOURCE_IO | flags; + res->start = start; + res->end = end; + + dev_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n", + (unsigned long long) start, (unsigned long long) end, flags); + return pnp_res; +} + +struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, + resource_size_t start, + resource_size_t end, int flags) +{ + struct pnp_resource *pnp_res; + struct resource *res; + static unsigned char warned; + + pnp_res = pnp_new_resource(dev, IORESOURCE_MEM); + if (!pnp_res) { + if (!warned) { + dev_err(&dev->dev, "can't add resource for MEM " + "%#llx-%#llx\n",(unsigned long long) start, + (unsigned long long) end); + warned = 1; + } + return NULL; + } + + res = &pnp_res->res; + res->flags = IORESOURCE_MEM | flags; + res->start = start; + res->end = end; + + dev_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n", + (unsigned long long) start, (unsigned long long) end, flags); + return pnp_res; +} + /* format is: pnp_reserve_irq=irq1[,irq2] .... */ static int __init pnp_setup_reserve_irq(char *str) {