diff options
| author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2008-04-28 18:34:34 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2008-04-29 03:22:28 -0400 |
| commit | dbddd0383c59d588f8db5e773b062756e39117ec (patch) | |
| tree | 77009fb218b4fc21090ae83105aa0f84664ae61c | |
| parent | a50b6d7b8d7e1a8b13bd1be65a865b115e1190d9 (diff) | |
PNP: make generic pnp_add_irq_resource()
Add a pnp_add_irq_resource() that can be used by all the PNP
backends. This consolidates a little more pnp_resource_table
knowledge into one place.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/pnp/base.h | 3 | ||||
| -rw-r--r-- | drivers/pnp/interface.c | 15 | ||||
| -rw-r--r-- | drivers/pnp/isapnp/core.c | 9 | ||||
| -rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 33 | ||||
| -rw-r--r-- | drivers/pnp/pnpbios/rsparser.c | 31 | ||||
| -rw-r--r-- | drivers/pnp/resource.c | 26 |
6 files changed, 51 insertions, 66 deletions
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index 786735770684..3dd5d849c30f 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h | |||
| @@ -40,3 +40,6 @@ struct pnp_resource_table { | |||
| 40 | struct pnp_resource dma[PNP_MAX_DMA]; | 40 | struct pnp_resource dma[PNP_MAX_DMA]; |
| 41 | struct pnp_resource irq[PNP_MAX_IRQ]; | 41 | struct pnp_resource irq[PNP_MAX_IRQ]; |
| 42 | }; | 42 | }; |
| 43 | |||
| 44 | struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, | ||
| 45 | int flags); | ||
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index ead151242a64..e8134c286207 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
| @@ -324,6 +324,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
| 324 | struct resource *res; | 324 | struct resource *res; |
| 325 | char *buf = (void *)ubuf; | 325 | char *buf = (void *)ubuf; |
| 326 | int retval = 0; | 326 | int retval = 0; |
| 327 | resource_size_t start; | ||
| 327 | 328 | ||
| 328 | if (dev->status & PNP_ATTACHED) { | 329 | if (dev->status & PNP_ATTACHED) { |
| 329 | retval = -EBUSY; | 330 | retval = -EBUSY; |
| @@ -429,16 +430,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
| 429 | buf += 3; | 430 | buf += 3; |
| 430 | while (isspace(*buf)) | 431 | while (isspace(*buf)) |
| 431 | ++buf; | 432 | ++buf; |
| 432 | pnp_res = pnp_get_pnp_resource(dev, | 433 | start = simple_strtoul(buf, &buf, 0); |
| 433 | IORESOURCE_IRQ, nirq); | 434 | pnp_res = pnp_add_irq_resource(dev, start, 0); |
| 434 | if (!pnp_res) | 435 | if (pnp_res) |
| 435 | break; | 436 | nirq++; |
| 436 | pnp_res->index = nirq; | ||
| 437 | res = &pnp_res->res; | ||
| 438 | res->start = res->end = | ||
| 439 | simple_strtoul(buf, &buf, 0); | ||
| 440 | res->flags = IORESOURCE_IRQ; | ||
| 441 | nirq++; | ||
| 442 | continue; | 437 | continue; |
| 443 | } | 438 | } |
| 444 | if (!strnicmp(buf, "dma", 3)) { | 439 | if (!strnicmp(buf, "dma", 3)) { |
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index f949a538ccde..2cf750f077a4 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c | |||
| @@ -965,12 +965,9 @@ static int isapnp_read_resources(struct pnp_dev *dev) | |||
| 965 | 8); | 965 | 8); |
| 966 | if (!ret) | 966 | if (!ret) |
| 967 | continue; | 967 | continue; |
| 968 | pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, | 968 | pnp_res = pnp_add_irq_resource(dev, ret, 0); |
| 969 | tmp); | 969 | if (pnp_res) |
| 970 | pnp_res->index = tmp; | 970 | pnp_res->index = tmp; |
| 971 | res = &pnp_res->res; | ||
| 972 | res->start = res->end = ret; | ||
| 973 | res->flags = IORESOURCE_IRQ; | ||
| 974 | } | 971 | } |
| 975 | for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { | 972 | for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { |
| 976 | ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); | 973 | ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 3634f2f3f745..0b67dff1e7c3 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
| @@ -82,28 +82,12 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, | |||
| 82 | u32 gsi, int triggering, | 82 | u32 gsi, int triggering, |
| 83 | int polarity, int shareable) | 83 | int polarity, int shareable) |
| 84 | { | 84 | { |
| 85 | struct resource *res; | 85 | int irq, flags; |
| 86 | int i; | ||
| 87 | int irq; | ||
| 88 | int p, t; | 86 | int p, t; |
| 89 | static unsigned char warned; | ||
| 90 | 87 | ||
| 91 | if (!valid_IRQ(gsi)) | 88 | if (!valid_IRQ(gsi)) |
| 92 | return; | 89 | return; |
| 93 | 90 | ||
| 94 | for (i = 0; i < PNP_MAX_IRQ; i++) { | ||
| 95 | res = pnp_get_resource(dev, IORESOURCE_IRQ, i); | ||
| 96 | if (!pnp_resource_valid(res)) | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | if (i >= PNP_MAX_IRQ) { | ||
| 100 | if (!warned) { | ||
| 101 | printk(KERN_WARNING "pnpacpi: exceeded the max number" | ||
| 102 | " of IRQ resources: %d\n", PNP_MAX_IRQ); | ||
| 103 | warned = 1; | ||
| 104 | } | ||
| 105 | return; | ||
| 106 | } | ||
| 107 | /* | 91 | /* |
| 108 | * in IO-APIC mode, use overrided attribute. Two reasons: | 92 | * in IO-APIC mode, use overrided attribute. Two reasons: |
| 109 | * 1. BIOS bug in DSDT | 93 | * 1. BIOS bug in DSDT |
| @@ -121,17 +105,14 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, | |||
| 121 | } | 105 | } |
| 122 | } | 106 | } |
| 123 | 107 | ||
| 124 | res->flags = IORESOURCE_IRQ; // Also clears _UNSET flag | 108 | flags = irq_flags(triggering, polarity, shareable); |
| 125 | res->flags |= irq_flags(triggering, polarity, shareable); | ||
| 126 | irq = acpi_register_gsi(gsi, triggering, polarity); | 109 | irq = acpi_register_gsi(gsi, triggering, polarity); |
| 127 | if (irq < 0) { | 110 | if (irq >= 0) |
| 128 | res->flags |= IORESOURCE_DISABLED; | 111 | pcibios_penalize_isa_irq(irq, 1); |
| 129 | return; | 112 | else |
| 130 | } | 113 | flags |= IORESOURCE_DISABLED; |
| 131 | 114 | ||
| 132 | res->start = irq; | 115 | pnp_add_irq_resource(dev, irq, flags); |
| 133 | res->end = irq; | ||
| 134 | pcibios_penalize_isa_irq(irq, 1); | ||
| 135 | } | 116 | } |
| 136 | 117 | ||
| 137 | static int dma_flags(int type, int bus_master, int transfer) | 118 | static int dma_flags(int type, int bus_master, int transfer) |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index d3b0a4e53692..845730c57edc 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
| @@ -54,28 +54,6 @@ inline void pcibios_penalize_isa_irq(int irq, int active) | |||
| 54 | * Allocated Resources | 54 | * Allocated Resources |
| 55 | */ | 55 | */ |
| 56 | 56 | ||
| 57 | static void pnpbios_parse_allocated_irqresource(struct pnp_dev *dev, int irq) | ||
| 58 | { | ||
| 59 | struct resource *res; | ||
| 60 | int i; | ||
| 61 | |||
| 62 | for (i = 0; i < PNP_MAX_IRQ; i++) { | ||
| 63 | res = pnp_get_resource(dev, IORESOURCE_IRQ, i); | ||
| 64 | if (!pnp_resource_valid(res)) | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | |||
| 68 | if (i < PNP_MAX_IRQ) { | ||
| 69 | res->flags = IORESOURCE_IRQ; // Also clears _UNSET flag | ||
| 70 | if (irq == -1) { | ||
| 71 | res->flags |= IORESOURCE_DISABLED; | ||
| 72 | return; | ||
| 73 | } | ||
| 74 | res->start = res->end = (unsigned long)irq; | ||
| 75 | pcibios_penalize_isa_irq(irq, 1); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | static void pnpbios_parse_allocated_dmaresource(struct pnp_dev *dev, int dma) | 57 | static void pnpbios_parse_allocated_dmaresource(struct pnp_dev *dev, int dma) |
| 80 | { | 58 | { |
| 81 | struct resource *res; | 59 | struct resource *res; |
| @@ -148,7 +126,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev, | |||
| 148 | unsigned char *end) | 126 | unsigned char *end) |
| 149 | { | 127 | { |
| 150 | unsigned int len, tag; | 128 | unsigned int len, tag; |
| 151 | int io, size, mask, i; | 129 | int io, size, mask, i, flags; |
| 152 | 130 | ||
| 153 | if (!p) | 131 | if (!p) |
| 154 | return NULL; | 132 | return NULL; |
| @@ -205,12 +183,17 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev, | |||
| 205 | case SMALL_TAG_IRQ: | 183 | case SMALL_TAG_IRQ: |
| 206 | if (len < 2 || len > 3) | 184 | if (len < 2 || len > 3) |
| 207 | goto len_err; | 185 | goto len_err; |
| 186 | flags = 0; | ||
| 208 | io = -1; | 187 | io = -1; |
| 209 | mask = p[1] + p[2] * 256; | 188 | mask = p[1] + p[2] * 256; |
| 210 | for (i = 0; i < 16; i++, mask = mask >> 1) | 189 | for (i = 0; i < 16; i++, mask = mask >> 1) |
| 211 | if (mask & 0x01) | 190 | if (mask & 0x01) |
| 212 | io = i; | 191 | io = i; |
| 213 | pnpbios_parse_allocated_irqresource(dev, io); | 192 | if (io != -1) |
| 193 | pcibios_penalize_isa_irq(io, 1); | ||
| 194 | else | ||
| 195 | flags = IORESOURCE_DISABLED; | ||
| 196 | pnp_add_irq_resource(dev, io, flags); | ||
| 214 | break; | 197 | break; |
| 215 | 198 | ||
| 216 | case SMALL_TAG_DMA: | 199 | case SMALL_TAG_DMA: |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 1f4134eea7b7..082a556b9dcc 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
| @@ -576,6 +576,32 @@ static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) | |||
| 576 | return NULL; | 576 | return NULL; |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, | ||
| 580 | int flags) | ||
| 581 | { | ||
| 582 | struct pnp_resource *pnp_res; | ||
| 583 | struct resource *res; | ||
| 584 | static unsigned char warned; | ||
| 585 | |||
| 586 | pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); | ||
| 587 | if (!pnp_res) { | ||
| 588 | if (!warned) { | ||
| 589 | dev_err(&dev->dev, "can't add resource for IRQ %d\n", | ||
| 590 | irq); | ||
| 591 | warned = 1; | ||
| 592 | } | ||
| 593 | return NULL; | ||
| 594 | } | ||
| 595 | |||
| 596 | res = &pnp_res->res; | ||
| 597 | res->flags = IORESOURCE_IRQ | flags; | ||
| 598 | res->start = irq; | ||
| 599 | res->end = irq; | ||
| 600 | |||
| 601 | dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags); | ||
| 602 | return pnp_res; | ||
| 603 | } | ||
| 604 | |||
| 579 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ | 605 | /* format is: pnp_reserve_irq=irq1[,irq2] .... */ |
| 580 | static int __init pnp_setup_reserve_irq(char *str) | 606 | static int __init pnp_setup_reserve_irq(char *str) |
| 581 | { | 607 | { |
