diff options
author | Michael Karcher <bugzilla-kernel@mkarcher.dialup.fu-berlin.de> | 2007-03-08 23:29:29 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-03-08 23:29:29 -0500 |
commit | 362ea087db9d99bb0cf79479544dfafa9e18c300 (patch) | |
tree | 1affc8e5b410f629b62fc1c515de1118f06ed226 /drivers/pnp/pnpacpi/rsparser.c | |
parent | 908e0a8a265fe8057604a9a30aec3f0be7bb5ebb (diff) |
ACPI: fix parallel port IRQ after resume from S3
The PNPACPI resource flags were broken.
This would apply to re-enabling a device any-time after boot,
not just after resume from S3.
http://bugzilla.kernel.org/show_bug.cgi?id=6316
Acked-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/pnp/pnpacpi/rsparser.c')
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 120 |
1 files changed, 73 insertions, 47 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 7a535542fe92..118ac9779b3c 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -89,6 +89,7 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, | |||
89 | return; | 89 | return; |
90 | 90 | ||
91 | res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag | 91 | res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag |
92 | res->irq_resource[i].flags |= irq_flags(triggering, polarity); | ||
92 | irq = acpi_register_gsi(gsi, triggering, polarity); | 93 | irq = acpi_register_gsi(gsi, triggering, polarity); |
93 | if (irq < 0) { | 94 | if (irq < 0) { |
94 | res->irq_resource[i].flags |= IORESOURCE_DISABLED; | 95 | res->irq_resource[i].flags |= IORESOURCE_DISABLED; |
@@ -103,8 +104,52 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, | |||
103 | pcibios_penalize_isa_irq(irq, 1); | 104 | pcibios_penalize_isa_irq(irq, 1); |
104 | } | 105 | } |
105 | 106 | ||
107 | static int dma_flags(int type, int bus_master, int transfer) | ||
108 | { | ||
109 | int flags = 0; | ||
110 | |||
111 | if (bus_master) | ||
112 | flags |= IORESOURCE_DMA_MASTER; | ||
113 | switch (type) { | ||
114 | case ACPI_COMPATIBILITY: | ||
115 | flags |= IORESOURCE_DMA_COMPATIBLE; | ||
116 | break; | ||
117 | case ACPI_TYPE_A: | ||
118 | flags |= IORESOURCE_DMA_TYPEA; | ||
119 | break; | ||
120 | case ACPI_TYPE_B: | ||
121 | flags |= IORESOURCE_DMA_TYPEB; | ||
122 | break; | ||
123 | case ACPI_TYPE_F: | ||
124 | flags |= IORESOURCE_DMA_TYPEF; | ||
125 | break; | ||
126 | default: | ||
127 | /* Set a default value ? */ | ||
128 | flags |= IORESOURCE_DMA_COMPATIBLE; | ||
129 | pnp_err("Invalid DMA type"); | ||
130 | } | ||
131 | switch (transfer) { | ||
132 | case ACPI_TRANSFER_8: | ||
133 | flags |= IORESOURCE_DMA_8BIT; | ||
134 | break; | ||
135 | case ACPI_TRANSFER_8_16: | ||
136 | flags |= IORESOURCE_DMA_8AND16BIT; | ||
137 | break; | ||
138 | case ACPI_TRANSFER_16: | ||
139 | flags |= IORESOURCE_DMA_16BIT; | ||
140 | break; | ||
141 | default: | ||
142 | /* Set a default value ? */ | ||
143 | flags |= IORESOURCE_DMA_8AND16BIT; | ||
144 | pnp_err("Invalid DMA transfer type"); | ||
145 | } | ||
146 | |||
147 | return flags; | ||
148 | } | ||
149 | |||
106 | static void | 150 | static void |
107 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma) | 151 | pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma, |
152 | int type, int bus_master, int transfer) | ||
108 | { | 153 | { |
109 | int i = 0; | 154 | int i = 0; |
110 | while (i < PNP_MAX_DMA && | 155 | while (i < PNP_MAX_DMA && |
@@ -112,6 +157,7 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma) | |||
112 | i++; | 157 | i++; |
113 | if (i < PNP_MAX_DMA) { | 158 | if (i < PNP_MAX_DMA) { |
114 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag | 159 | res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag |
160 | res->dma_resource[i].flags |= dma_flags(type, bus_master, transfer); | ||
115 | if (dma == -1) { | 161 | if (dma == -1) { |
116 | res->dma_resource[i].flags |= IORESOURCE_DISABLED; | 162 | res->dma_resource[i].flags |= IORESOURCE_DISABLED; |
117 | return; | 163 | return; |
@@ -123,7 +169,7 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma) | |||
123 | 169 | ||
124 | static void | 170 | static void |
125 | pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, | 171 | pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, |
126 | u64 io, u64 len) | 172 | u64 io, u64 len, int io_decode) |
127 | { | 173 | { |
128 | int i = 0; | 174 | int i = 0; |
129 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && | 175 | while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && |
@@ -131,6 +177,8 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, | |||
131 | i++; | 177 | i++; |
132 | if (i < PNP_MAX_PORT) { | 178 | if (i < PNP_MAX_PORT) { |
133 | res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag | 179 | res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag |
180 | if (io_decode == ACPI_DECODE_16) | ||
181 | res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR; | ||
134 | if (len <= 0 || (io + len -1) >= 0x10003) { | 182 | if (len <= 0 || (io + len -1) >= 0x10003) { |
135 | res->port_resource[i].flags |= IORESOURCE_DISABLED; | 183 | res->port_resource[i].flags |= IORESOURCE_DISABLED; |
136 | return; | 184 | return; |
@@ -142,7 +190,7 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, | |||
142 | 190 | ||
143 | static void | 191 | static void |
144 | pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, | 192 | pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, |
145 | u64 mem, u64 len) | 193 | u64 mem, u64 len, int write_protect) |
146 | { | 194 | { |
147 | int i = 0; | 195 | int i = 0; |
148 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && | 196 | while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && |
@@ -154,6 +202,9 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, | |||
154 | res->mem_resource[i].flags |= IORESOURCE_DISABLED; | 202 | res->mem_resource[i].flags |= IORESOURCE_DISABLED; |
155 | return; | 203 | return; |
156 | } | 204 | } |
205 | if(write_protect == ACPI_READ_WRITE_MEMORY) | ||
206 | res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE; | ||
207 | |||
157 | res->mem_resource[i].start = mem; | 208 | res->mem_resource[i].start = mem; |
158 | res->mem_resource[i].end = mem + len - 1; | 209 | res->mem_resource[i].end = mem + len - 1; |
159 | } | 210 | } |
@@ -178,10 +229,11 @@ pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, | |||
178 | 229 | ||
179 | if (p->resource_type == ACPI_MEMORY_RANGE) | 230 | if (p->resource_type == ACPI_MEMORY_RANGE) |
180 | pnpacpi_parse_allocated_memresource(res_table, | 231 | pnpacpi_parse_allocated_memresource(res_table, |
181 | p->minimum, p->address_length); | 232 | p->minimum, p->address_length, p->info.mem.write_protect); |
182 | else if (p->resource_type == ACPI_IO_RANGE) | 233 | else if (p->resource_type == ACPI_IO_RANGE) |
183 | pnpacpi_parse_allocated_ioresource(res_table, | 234 | pnpacpi_parse_allocated_ioresource(res_table, |
184 | p->minimum, p->address_length); | 235 | p->minimum, p->address_length, |
236 | p->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16); | ||
185 | } | 237 | } |
186 | 238 | ||
187 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | 239 | static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, |
@@ -208,13 +260,17 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
208 | case ACPI_RESOURCE_TYPE_DMA: | 260 | case ACPI_RESOURCE_TYPE_DMA: |
209 | if (res->data.dma.channel_count > 0) | 261 | if (res->data.dma.channel_count > 0) |
210 | pnpacpi_parse_allocated_dmaresource(res_table, | 262 | pnpacpi_parse_allocated_dmaresource(res_table, |
211 | res->data.dma.channels[0]); | 263 | res->data.dma.channels[0], |
264 | res->data.dma.type, | ||
265 | res->data.dma.bus_master, | ||
266 | res->data.dma.transfer); | ||
212 | break; | 267 | break; |
213 | 268 | ||
214 | case ACPI_RESOURCE_TYPE_IO: | 269 | case ACPI_RESOURCE_TYPE_IO: |
215 | pnpacpi_parse_allocated_ioresource(res_table, | 270 | pnpacpi_parse_allocated_ioresource(res_table, |
216 | res->data.io.minimum, | 271 | res->data.io.minimum, |
217 | res->data.io.address_length); | 272 | res->data.io.address_length, |
273 | res->data.io.io_decode); | ||
218 | break; | 274 | break; |
219 | 275 | ||
220 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | 276 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
@@ -224,7 +280,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
224 | case ACPI_RESOURCE_TYPE_FIXED_IO: | 280 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
225 | pnpacpi_parse_allocated_ioresource(res_table, | 281 | pnpacpi_parse_allocated_ioresource(res_table, |
226 | res->data.fixed_io.address, | 282 | res->data.fixed_io.address, |
227 | res->data.fixed_io.address_length); | 283 | res->data.fixed_io.address_length, |
284 | ACPI_DECODE_10); | ||
228 | break; | 285 | break; |
229 | 286 | ||
230 | case ACPI_RESOURCE_TYPE_VENDOR: | 287 | case ACPI_RESOURCE_TYPE_VENDOR: |
@@ -236,17 +293,20 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
236 | case ACPI_RESOURCE_TYPE_MEMORY24: | 293 | case ACPI_RESOURCE_TYPE_MEMORY24: |
237 | pnpacpi_parse_allocated_memresource(res_table, | 294 | pnpacpi_parse_allocated_memresource(res_table, |
238 | res->data.memory24.minimum, | 295 | res->data.memory24.minimum, |
239 | res->data.memory24.address_length); | 296 | res->data.memory24.address_length, |
297 | res->data.memory24.write_protect); | ||
240 | break; | 298 | break; |
241 | case ACPI_RESOURCE_TYPE_MEMORY32: | 299 | case ACPI_RESOURCE_TYPE_MEMORY32: |
242 | pnpacpi_parse_allocated_memresource(res_table, | 300 | pnpacpi_parse_allocated_memresource(res_table, |
243 | res->data.memory32.minimum, | 301 | res->data.memory32.minimum, |
244 | res->data.memory32.address_length); | 302 | res->data.memory32.address_length, |
303 | res->data.memory32.write_protect); | ||
245 | break; | 304 | break; |
246 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 305 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
247 | pnpacpi_parse_allocated_memresource(res_table, | 306 | pnpacpi_parse_allocated_memresource(res_table, |
248 | res->data.fixed_memory32.address, | 307 | res->data.fixed_memory32.address, |
249 | res->data.fixed_memory32.address_length); | 308 | res->data.fixed_memory32.address_length, |
309 | res->data.fixed_memory32.write_protect); | ||
250 | break; | 310 | break; |
251 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 311 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
252 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 312 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
@@ -304,42 +364,8 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso | |||
304 | 364 | ||
305 | for(i = 0; i < p->channel_count; i++) | 365 | for(i = 0; i < p->channel_count; i++) |
306 | dma->map |= 1 << p->channels[i]; | 366 | dma->map |= 1 << p->channels[i]; |
307 | dma->flags = 0; | 367 | |
308 | if (p->bus_master) | 368 | dma->flags = dma_flags(p->type, p->bus_master, p->transfer); |
309 | dma->flags |= IORESOURCE_DMA_MASTER; | ||
310 | switch (p->type) { | ||
311 | case ACPI_COMPATIBILITY: | ||
312 | dma->flags |= IORESOURCE_DMA_COMPATIBLE; | ||
313 | break; | ||
314 | case ACPI_TYPE_A: | ||
315 | dma->flags |= IORESOURCE_DMA_TYPEA; | ||
316 | break; | ||
317 | case ACPI_TYPE_B: | ||
318 | dma->flags |= IORESOURCE_DMA_TYPEB; | ||
319 | break; | ||
320 | case ACPI_TYPE_F: | ||
321 | dma->flags |= IORESOURCE_DMA_TYPEF; | ||
322 | break; | ||
323 | default: | ||
324 | /* Set a default value ? */ | ||
325 | dma->flags |= IORESOURCE_DMA_COMPATIBLE; | ||
326 | pnp_err("Invalid DMA type"); | ||
327 | } | ||
328 | switch (p->transfer) { | ||
329 | case ACPI_TRANSFER_8: | ||
330 | dma->flags |= IORESOURCE_DMA_8BIT; | ||
331 | break; | ||
332 | case ACPI_TRANSFER_8_16: | ||
333 | dma->flags |= IORESOURCE_DMA_8AND16BIT; | ||
334 | break; | ||
335 | case ACPI_TRANSFER_16: | ||
336 | dma->flags |= IORESOURCE_DMA_16BIT; | ||
337 | break; | ||
338 | default: | ||
339 | /* Set a default value ? */ | ||
340 | dma->flags |= IORESOURCE_DMA_8AND16BIT; | ||
341 | pnp_err("Invalid DMA transfer type"); | ||
342 | } | ||
343 | 369 | ||
344 | pnp_register_dma_resource(option, dma); | 370 | pnp_register_dma_resource(option, dma); |
345 | return; | 371 | return; |