diff options
| author | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 2009-07-10 12:57:34 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@zytor.com> | 2009-08-26 18:41:10 -0400 |
| commit | 9fd126bc742f74a95d2ba610247712ff05da02fe (patch) | |
| tree | 2be99f0b80d6f5d07d2cff6bfddbb1b9313f026c | |
| parent | 279e669b3fc0068cc3509e8e53036999e1e86588 (diff) | |
x86, pat: New i/f for driver to request memtype for IO regions
Add new routines to request memtype for IO regions. This will currently
be a backend for io_mapping_* routines. But, it can also be made available
to drivers directly in future, in case it is needed.
reserve interface reserves the memory, makes sure we have a compatible
memory type available and keeps the identity map in sync when needed.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
| -rw-r--r-- | arch/x86/include/asm/pat.h | 5 | ||||
| -rw-r--r-- | arch/x86/mm/pat.c | 49 |
2 files changed, 54 insertions, 0 deletions
diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h index 7af14e512f97..e2c1668dde7a 100644 --- a/arch/x86/include/asm/pat.h +++ b/arch/x86/include/asm/pat.h | |||
| @@ -19,4 +19,9 @@ extern int free_memtype(u64 start, u64 end); | |||
| 19 | extern int kernel_map_sync_memtype(u64 base, unsigned long size, | 19 | extern int kernel_map_sync_memtype(u64 base, unsigned long size, |
| 20 | unsigned long flag); | 20 | unsigned long flag); |
| 21 | 21 | ||
| 22 | int io_reserve_memtype(resource_size_t start, resource_size_t end, | ||
| 23 | unsigned long *type); | ||
| 24 | |||
| 25 | void io_free_memtype(resource_size_t start, resource_size_t end); | ||
| 26 | |||
| 22 | #endif /* _ASM_X86_PAT_H */ | 27 | #endif /* _ASM_X86_PAT_H */ |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index d5af2792d2fd..82d097ce3091 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
| @@ -498,6 +498,55 @@ int free_memtype(u64 start, u64 end) | |||
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | 500 | ||
| 501 | /** | ||
| 502 | * io_reserve_memtype - Request a memory type mapping for a region of memory | ||
| 503 | * @start: start (physical address) of the region | ||
| 504 | * @end: end (physical address) of the region | ||
| 505 | * @type: A pointer to memtype, with requested type. On success, requested | ||
| 506 | * or any other compatible type that was available for the region is returned | ||
| 507 | * | ||
| 508 | * On success, returns 0 | ||
| 509 | * On failure, returns non-zero | ||
| 510 | */ | ||
| 511 | int io_reserve_memtype(resource_size_t start, resource_size_t end, | ||
| 512 | unsigned long *type) | ||
| 513 | { | ||
| 514 | unsigned long req_type = *type; | ||
| 515 | unsigned long new_type; | ||
| 516 | int ret; | ||
| 517 | |||
| 518 | WARN_ON_ONCE(iomem_map_sanity_check(start, end - start)); | ||
| 519 | |||
| 520 | ret = reserve_memtype(start, end, req_type, &new_type); | ||
| 521 | if (ret) | ||
| 522 | goto out_err; | ||
| 523 | |||
| 524 | if (!is_new_memtype_allowed(req_type, new_type)) | ||
| 525 | goto out_free; | ||
| 526 | |||
| 527 | if (kernel_map_sync_memtype(start, end - start, new_type) < 0) | ||
| 528 | goto out_free; | ||
| 529 | |||
| 530 | *type = new_type; | ||
| 531 | return 0; | ||
| 532 | |||
| 533 | out_free: | ||
| 534 | free_memtype(start, end); | ||
| 535 | ret = -EBUSY; | ||
| 536 | out_err: | ||
| 537 | return ret; | ||
| 538 | } | ||
| 539 | |||
| 540 | /** | ||
| 541 | * io_free_memtype - Release a memory type mapping for a region of memory | ||
| 542 | * @start: start (physical address) of the region | ||
| 543 | * @end: end (physical address) of the region | ||
| 544 | */ | ||
| 545 | void io_free_memtype(resource_size_t start, resource_size_t end) | ||
| 546 | { | ||
| 547 | free_memtype(start, end); | ||
| 548 | } | ||
| 549 | |||
| 501 | pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | 550 | pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, |
| 502 | unsigned long size, pgprot_t vma_prot) | 551 | unsigned long size, pgprot_t vma_prot) |
| 503 | { | 552 | { |
