diff options
| -rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 75 |
1 files changed, 43 insertions, 32 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 1e296cbef004..6db549c9480c 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
| @@ -73,25 +73,35 @@ static void decode_irq_flags(int flag, int *edge_level, int *active_high_low) | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | static void | 75 | static void |
| 76 | pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, int irq) | 76 | pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi, |
| 77 | int edge_level, int active_high_low) | ||
| 77 | { | 78 | { |
| 78 | int i = 0; | 79 | int i = 0; |
| 80 | int irq; | ||
| 81 | |||
| 82 | if (!valid_IRQ(gsi)) | ||
| 83 | return; | ||
| 84 | |||
| 79 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && | 85 | while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && |
| 80 | i < PNP_MAX_IRQ) | 86 | i < PNP_MAX_IRQ) |
| 81 | i++; | 87 | i++; |
| 82 | if (i < PNP_MAX_IRQ) { | 88 | if (i >= PNP_MAX_IRQ) |
| 83 | res->irq_resource[i].flags = IORESOURCE_IRQ; //Also clears _UNSET flag | 89 | return; |
| 84 | if (irq < 0) { | 90 | |
| 85 | res->irq_resource[i].flags |= IORESOURCE_DISABLED; | 91 | res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag |
| 86 | return; | 92 | irq = acpi_register_gsi(gsi, edge_level, active_high_low); |
| 87 | } | 93 | if (irq < 0) { |
| 88 | res->irq_resource[i].start =(unsigned long) irq; | 94 | res->irq_resource[i].flags |= IORESOURCE_DISABLED; |
| 89 | res->irq_resource[i].end = (unsigned long) irq; | 95 | return; |
| 90 | } | 96 | } |
| 97 | |||
| 98 | res->irq_resource[i].start = irq; | ||
| 99 | res->irq_resource[i].end = irq; | ||
| 100 | pcibios_penalize_isa_irq(irq, 1); | ||
| 91 | } | 101 | } |
| 92 | 102 | ||
| 93 | static void | 103 | static void |
| 94 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) | 104 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, u32 dma) |
| 95 | { | 105 | { |
| 96 | int i = 0; | 106 | int i = 0; |
| 97 | while (i < PNP_MAX_DMA && | 107 | while (i < PNP_MAX_DMA && |
| @@ -103,14 +113,14 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) | |||
| 103 | res->dma_resource[i].flags |= IORESOURCE_DISABLED; | 113 | res->dma_resource[i].flags |= IORESOURCE_DISABLED; |
| 104 | return; | 114 | return; |
| 105 | } | 115 | } |
| 106 | res->dma_resource[i].start =(unsigned long) dma; | 116 | res->dma_resource[i].start = dma; |
| 107 | res->dma_resource[i].end = (unsigned long) dma; | 117 | res->dma_resource[i].end = dma; |
| 108 | } | 118 | } |
| 109 | } | 119 | } |
| 110 | 120 | ||
| 111 | static void | 121 | static void |
| 112 | pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res, | 122 | pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res, |
| 113 | int io, int len) | 123 | u32 io, u32 len) |
| 114 | { | 124 | { |
| 115 | int i = 0; | 125 | int i = 0; |
| 116 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && | 126 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && |
| @@ -122,14 +132,14 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res, | |||
| 122 | res->port_resource[i].flags |= IORESOURCE_DISABLED; | 132 | res->port_resource[i].flags |= IORESOURCE_DISABLED; |
| 123 | return; | 133 | return; |
| 124 | } | 134 | } |
| 125 | res->port_resource[i].start = (unsigned long) io; | 135 | res->port_resource[i].start = io; |
| 126 | res->port_resource[i].end = (unsigned long)(io + len - 1); | 136 | res->port_resource[i].end = io + len - 1; |
| 127 | } | 137 | } |
| 128 | } | 138 | } |
| 129 | 139 | ||
| 130 | static void | 140 | static void |
| 131 | pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res, | 141 | pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res, |
| 132 | int mem, int len) | 142 | u64 mem, u64 len) |
| 133 | { | 143 | { |
| 134 | int i = 0; | 144 | int i = 0; |
| 135 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && | 145 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && |
| @@ -141,8 +151,8 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res, | |||
| 141 | res->mem_resource[i].flags |= IORESOURCE_DISABLED; | 151 | res->mem_resource[i].flags |= IORESOURCE_DISABLED; |
| 142 | return; | 152 | return; |
| 143 | } | 153 | } |
| 144 | res->mem_resource[i].start = (unsigned long) mem; | 154 | res->mem_resource[i].start = mem; |
| 145 | res->mem_resource[i].end = (unsigned long)(mem + len - 1); | 155 | res->mem_resource[i].end = mem + len - 1; |
| 146 | } | 156 | } |
| 147 | } | 157 | } |
| 148 | 158 | ||
| @@ -151,27 +161,28 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
| 151 | void *data) | 161 | void *data) |
| 152 | { | 162 | { |
| 153 | struct pnp_resource_table * res_table = (struct pnp_resource_table *)data; | 163 | struct pnp_resource_table * res_table = (struct pnp_resource_table *)data; |
| 164 | int i; | ||
| 154 | 165 | ||
| 155 | switch (res->id) { | 166 | switch (res->id) { |
| 156 | case ACPI_RSTYPE_IRQ: | 167 | case ACPI_RSTYPE_IRQ: |
| 157 | if ((res->data.irq.number_of_interrupts > 0) && | 168 | /* |
| 158 | valid_IRQ(res->data.irq.interrupts[0])) { | 169 | * Per spec, only one interrupt per descriptor is allowed in |
| 159 | pnpacpi_parse_allocated_irqresource(res_table, | 170 | * _CRS, but some firmware violates this, so parse them all. |
| 160 | acpi_register_gsi(res->data.irq.interrupts[0], | 171 | */ |
| 161 | res->data.irq.edge_level, | 172 | for (i = 0; i < res->data.irq.number_of_interrupts; i++) { |
| 162 | res->data.irq.active_high_low)); | 173 | pnpacpi_parse_allocated_irqresource(res_table, |
| 163 | pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1); | 174 | res->data.irq.interrupts[i], |
| 175 | res->data.irq.edge_level, | ||
| 176 | res->data.irq.active_high_low); | ||
| 164 | } | 177 | } |
| 165 | break; | 178 | break; |
| 166 | 179 | ||
| 167 | case ACPI_RSTYPE_EXT_IRQ: | 180 | case ACPI_RSTYPE_EXT_IRQ: |
| 168 | if ((res->data.extended_irq.number_of_interrupts > 0) && | 181 | for (i = 0; i < res->data.extended_irq.number_of_interrupts; i++) { |
| 169 | valid_IRQ(res->data.extended_irq.interrupts[0])) { | 182 | pnpacpi_parse_allocated_irqresource(res_table, |
| 170 | pnpacpi_parse_allocated_irqresource(res_table, | 183 | res->data.extended_irq.interrupts[i], |
| 171 | acpi_register_gsi(res->data.extended_irq.interrupts[0], | 184 | res->data.extended_irq.edge_level, |
| 172 | res->data.extended_irq.edge_level, | 185 | res->data.extended_irq.active_high_low); |
| 173 | res->data.extended_irq.active_high_low)); | ||
| 174 | pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1); | ||
| 175 | } | 186 | } |
| 176 | break; | 187 | break; |
| 177 | case ACPI_RSTYPE_DMA: | 188 | case ACPI_RSTYPE_DMA: |
