diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2015-02-01 21:42:58 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-03 16:27:21 -0500 |
commit | a49170b552423a3e85fc4f0d778c707402ee4863 (patch) | |
tree | e78aa9b2c9d8c1aa39958f82df27f3980304ea5d | |
parent | a274019fc332d7b4dcb85735978c2018522be312 (diff) |
ACPI: Return translation offset when parsing ACPI address space resources
Change function acpi_dev_resource_address_space() and
acpi_dev_resource_ext_address_space() to return address space
translation offset.
It's based on a patch from Yinghai Lu <yinghai@kernel.org>.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/resource.c | 58 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 29 | ||||
-rw-r--r-- | include/linux/acpi.h | 9 |
3 files changed, 54 insertions, 42 deletions
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 57891a621b96..c902c8eece81 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -184,13 +184,14 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) | |||
184 | } | 184 | } |
185 | EXPORT_SYMBOL_GPL(acpi_dev_resource_io); | 185 | EXPORT_SYMBOL_GPL(acpi_dev_resource_io); |
186 | 186 | ||
187 | static bool acpi_decode_space(struct resource *res, | 187 | static bool acpi_decode_space(struct resource_win *win, |
188 | struct acpi_resource_address *addr, | 188 | struct acpi_resource_address *addr, |
189 | struct acpi_address64_attribute *attr) | 189 | struct acpi_address64_attribute *attr) |
190 | { | 190 | { |
191 | u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16; | 191 | u8 iodec = attr->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16; |
192 | bool wp = addr->info.mem.write_protect; | 192 | bool wp = addr->info.mem.write_protect; |
193 | u64 len = attr->address_length; | 193 | u64 len = attr->address_length; |
194 | struct resource *res = &win->res; | ||
194 | 195 | ||
195 | /* | 196 | /* |
196 | * Filter out invalid descriptor according to ACPI Spec 5.0, section | 197 | * Filter out invalid descriptor according to ACPI Spec 5.0, section |
@@ -218,6 +219,8 @@ static bool acpi_decode_space(struct resource *res, | |||
218 | return false; | 219 | return false; |
219 | } | 220 | } |
220 | 221 | ||
222 | win->offset = attr->translation_offset; | ||
223 | |||
221 | if (addr->producer_consumer == ACPI_PRODUCER) | 224 | if (addr->producer_consumer == ACPI_PRODUCER) |
222 | res->flags |= IORESOURCE_WINDOW; | 225 | res->flags |= IORESOURCE_WINDOW; |
223 | 226 | ||
@@ -230,27 +233,28 @@ static bool acpi_decode_space(struct resource *res, | |||
230 | /** | 233 | /** |
231 | * acpi_dev_resource_address_space - Extract ACPI address space information. | 234 | * acpi_dev_resource_address_space - Extract ACPI address space information. |
232 | * @ares: Input ACPI resource object. | 235 | * @ares: Input ACPI resource object. |
233 | * @res: Output generic resource object. | 236 | * @win: Output generic resource object. |
234 | * | 237 | * |
235 | * Check if the given ACPI resource object represents an address space resource | 238 | * Check if the given ACPI resource object represents an address space resource |
236 | * and if that's the case, use the information in it to populate the generic | 239 | * and if that's the case, use the information in it to populate the generic |
237 | * resource object pointed to by @res. | 240 | * resource object pointed to by @win. |
238 | * | 241 | * |
239 | * Return: | 242 | * Return: |
240 | * 1) false with res->flags setting to zero: not the expected resource type | 243 | * 1) false with win->res.flags setting to zero: not the expected resource type |
241 | * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource | 244 | * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned |
245 | * resource | ||
242 | * 3) true: valid assigned resource | 246 | * 3) true: valid assigned resource |
243 | */ | 247 | */ |
244 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, | 248 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, |
245 | struct resource *res) | 249 | struct resource_win *win) |
246 | { | 250 | { |
247 | struct acpi_resource_address64 addr; | 251 | struct acpi_resource_address64 addr; |
248 | 252 | ||
249 | res->flags = 0; | 253 | win->res.flags = 0; |
250 | if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr))) | 254 | if (ACPI_FAILURE(acpi_resource_to_address64(ares, &addr))) |
251 | return false; | 255 | return false; |
252 | 256 | ||
253 | return acpi_decode_space(res, (struct acpi_resource_address *)&addr, | 257 | return acpi_decode_space(win, (struct acpi_resource_address *)&addr, |
254 | &addr.address); | 258 | &addr.address); |
255 | } | 259 | } |
256 | EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); | 260 | EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); |
@@ -258,29 +262,30 @@ EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); | |||
258 | /** | 262 | /** |
259 | * acpi_dev_resource_ext_address_space - Extract ACPI address space information. | 263 | * acpi_dev_resource_ext_address_space - Extract ACPI address space information. |
260 | * @ares: Input ACPI resource object. | 264 | * @ares: Input ACPI resource object. |
261 | * @res: Output generic resource object. | 265 | * @win: Output generic resource object. |
262 | * | 266 | * |
263 | * Check if the given ACPI resource object represents an extended address space | 267 | * Check if the given ACPI resource object represents an extended address space |
264 | * resource and if that's the case, use the information in it to populate the | 268 | * resource and if that's the case, use the information in it to populate the |
265 | * generic resource object pointed to by @res. | 269 | * generic resource object pointed to by @win. |
266 | * | 270 | * |
267 | * Return: | 271 | * Return: |
268 | * 1) false with res->flags setting to zero: not the expected resource type | 272 | * 1) false with win->res.flags setting to zero: not the expected resource type |
269 | * 2) false with IORESOURCE_DISABLED in res->flags: valid unassigned resource | 273 | * 2) false with IORESOURCE_DISABLED in win->res.flags: valid unassigned |
274 | * resource | ||
270 | * 3) true: valid assigned resource | 275 | * 3) true: valid assigned resource |
271 | */ | 276 | */ |
272 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, | 277 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, |
273 | struct resource *res) | 278 | struct resource_win *win) |
274 | { | 279 | { |
275 | struct acpi_resource_extended_address64 *ext_addr; | 280 | struct acpi_resource_extended_address64 *ext_addr; |
276 | 281 | ||
277 | res->flags = 0; | 282 | win->res.flags = 0; |
278 | if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) | 283 | if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) |
279 | return false; | 284 | return false; |
280 | 285 | ||
281 | ext_addr = &ares->data.ext_address64; | 286 | ext_addr = &ares->data.ext_address64; |
282 | 287 | ||
283 | return acpi_decode_space(res, (struct acpi_resource_address *)ext_addr, | 288 | return acpi_decode_space(win, (struct acpi_resource_address *)ext_addr, |
284 | &ext_addr->address); | 289 | &ext_addr->address); |
285 | } | 290 | } |
286 | EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space); | 291 | EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space); |
@@ -441,7 +446,7 @@ struct res_proc_context { | |||
441 | int error; | 446 | int error; |
442 | }; | 447 | }; |
443 | 448 | ||
444 | static acpi_status acpi_dev_new_resource_entry(struct resource *r, | 449 | static acpi_status acpi_dev_new_resource_entry(struct resource_win *win, |
445 | struct res_proc_context *c) | 450 | struct res_proc_context *c) |
446 | { | 451 | { |
447 | struct resource_list_entry *rentry; | 452 | struct resource_list_entry *rentry; |
@@ -451,7 +456,7 @@ static acpi_status acpi_dev_new_resource_entry(struct resource *r, | |||
451 | c->error = -ENOMEM; | 456 | c->error = -ENOMEM; |
452 | return AE_NO_MEMORY; | 457 | return AE_NO_MEMORY; |
453 | } | 458 | } |
454 | rentry->res = *r; | 459 | rentry->res = win->res; |
455 | list_add_tail(&rentry->node, c->list); | 460 | list_add_tail(&rentry->node, c->list); |
456 | c->count++; | 461 | c->count++; |
457 | return AE_OK; | 462 | return AE_OK; |
@@ -461,7 +466,8 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, | |||
461 | void *context) | 466 | void *context) |
462 | { | 467 | { |
463 | struct res_proc_context *c = context; | 468 | struct res_proc_context *c = context; |
464 | struct resource r; | 469 | struct resource_win win; |
470 | struct resource *res = &win.res; | ||
465 | int i; | 471 | int i; |
466 | 472 | ||
467 | if (c->preproc) { | 473 | if (c->preproc) { |
@@ -476,18 +482,18 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, | |||
476 | } | 482 | } |
477 | } | 483 | } |
478 | 484 | ||
479 | memset(&r, 0, sizeof(r)); | 485 | memset(&win, 0, sizeof(win)); |
480 | 486 | ||
481 | if (acpi_dev_resource_memory(ares, &r) | 487 | if (acpi_dev_resource_memory(ares, res) |
482 | || acpi_dev_resource_io(ares, &r) | 488 | || acpi_dev_resource_io(ares, res) |
483 | || acpi_dev_resource_address_space(ares, &r) | 489 | || acpi_dev_resource_address_space(ares, &win) |
484 | || acpi_dev_resource_ext_address_space(ares, &r)) | 490 | || acpi_dev_resource_ext_address_space(ares, &win)) |
485 | return acpi_dev_new_resource_entry(&r, c); | 491 | return acpi_dev_new_resource_entry(&win, c); |
486 | 492 | ||
487 | for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) { | 493 | for (i = 0; acpi_dev_resource_interrupt(ares, i, res); i++) { |
488 | acpi_status status; | 494 | acpi_status status; |
489 | 495 | ||
490 | status = acpi_dev_new_resource_entry(&r, c); | 496 | status = acpi_dev_new_resource_entry(&win, c); |
491 | if (ACPI_FAILURE(status)) | 497 | if (ACPI_FAILURE(status)) |
492 | return status; | 498 | return status; |
493 | } | 499 | } |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 2d9bc789af0f..ff0356fb378f 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -180,20 +180,21 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
180 | struct pnp_dev *dev = data; | 180 | struct pnp_dev *dev = data; |
181 | struct acpi_resource_dma *dma; | 181 | struct acpi_resource_dma *dma; |
182 | struct acpi_resource_vendor_typed *vendor_typed; | 182 | struct acpi_resource_vendor_typed *vendor_typed; |
183 | struct resource r = {0}; | 183 | struct resource_win win = {{0}, 0}; |
184 | struct resource *r = &win.res; | ||
184 | int i, flags; | 185 | int i, flags; |
185 | 186 | ||
186 | if (acpi_dev_resource_address_space(res, &r) | 187 | if (acpi_dev_resource_address_space(res, &win) |
187 | || acpi_dev_resource_ext_address_space(res, &r)) { | 188 | || acpi_dev_resource_ext_address_space(res, &win)) { |
188 | pnp_add_resource(dev, &r); | 189 | pnp_add_resource(dev, &win.res); |
189 | return AE_OK; | 190 | return AE_OK; |
190 | } | 191 | } |
191 | 192 | ||
192 | r.flags = 0; | 193 | r->flags = 0; |
193 | if (acpi_dev_resource_interrupt(res, 0, &r)) { | 194 | if (acpi_dev_resource_interrupt(res, 0, r)) { |
194 | pnpacpi_add_irqresource(dev, &r); | 195 | pnpacpi_add_irqresource(dev, r); |
195 | for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++) | 196 | for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++) |
196 | pnpacpi_add_irqresource(dev, &r); | 197 | pnpacpi_add_irqresource(dev, r); |
197 | 198 | ||
198 | if (i > 1) { | 199 | if (i > 1) { |
199 | /* | 200 | /* |
@@ -209,7 +210,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
209 | } | 210 | } |
210 | } | 211 | } |
211 | return AE_OK; | 212 | return AE_OK; |
212 | } else if (r.flags & IORESOURCE_DISABLED) { | 213 | } else if (r->flags & IORESOURCE_DISABLED) { |
213 | pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); | 214 | pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); |
214 | return AE_OK; | 215 | return AE_OK; |
215 | } | 216 | } |
@@ -218,13 +219,13 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
218 | case ACPI_RESOURCE_TYPE_MEMORY24: | 219 | case ACPI_RESOURCE_TYPE_MEMORY24: |
219 | case ACPI_RESOURCE_TYPE_MEMORY32: | 220 | case ACPI_RESOURCE_TYPE_MEMORY32: |
220 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 221 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
221 | if (acpi_dev_resource_memory(res, &r)) | 222 | if (acpi_dev_resource_memory(res, r)) |
222 | pnp_add_resource(dev, &r); | 223 | pnp_add_resource(dev, r); |
223 | break; | 224 | break; |
224 | case ACPI_RESOURCE_TYPE_IO: | 225 | case ACPI_RESOURCE_TYPE_IO: |
225 | case ACPI_RESOURCE_TYPE_FIXED_IO: | 226 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
226 | if (acpi_dev_resource_io(res, &r)) | 227 | if (acpi_dev_resource_io(res, r)) |
227 | pnp_add_resource(dev, &r); | 228 | pnp_add_resource(dev, r); |
228 | break; | 229 | break; |
229 | case ACPI_RESOURCE_TYPE_DMA: | 230 | case ACPI_RESOURCE_TYPE_DMA: |
230 | dma = &res->data.dma; | 231 | dma = &res->data.dma; |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d459cd17b477..be9eaee8f4ae 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -285,12 +285,17 @@ extern int pnpacpi_disabled; | |||
285 | 285 | ||
286 | #define PXM_INVAL (-1) | 286 | #define PXM_INVAL (-1) |
287 | 287 | ||
288 | struct resource_win { | ||
289 | struct resource res; | ||
290 | resource_size_t offset; | ||
291 | }; | ||
292 | |||
288 | bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res); | 293 | bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res); |
289 | bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res); | 294 | bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res); |
290 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, | 295 | bool acpi_dev_resource_address_space(struct acpi_resource *ares, |
291 | struct resource *res); | 296 | struct resource_win *win); |
292 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, | 297 | bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, |
293 | struct resource *res); | 298 | struct resource_win *win); |
294 | unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); | 299 | unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); |
295 | bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, | 300 | bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, |
296 | struct resource *res); | 301 | struct resource *res); |