mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
279e669b3f
commit
9fd126bc74
|
@ -19,4 +19,9 @@ extern int free_memtype(u64 start, u64 end);
|
||||||
extern int kernel_map_sync_memtype(u64 base, unsigned long size,
|
extern int kernel_map_sync_memtype(u64 base, unsigned long size,
|
||||||
unsigned long flag);
|
unsigned long flag);
|
||||||
|
|
||||||
|
int io_reserve_memtype(resource_size_t start, resource_size_t end,
|
||||||
|
unsigned long *type);
|
||||||
|
|
||||||
|
void io_free_memtype(resource_size_t start, resource_size_t end);
|
||||||
|
|
||||||
#endif /* _ASM_X86_PAT_H */
|
#endif /* _ASM_X86_PAT_H */
|
||||||
|
|
|
@ -498,6 +498,55 @@ int free_memtype(u64 start, u64 end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* io_reserve_memtype - Request a memory type mapping for a region of memory
|
||||||
|
* @start: start (physical address) of the region
|
||||||
|
* @end: end (physical address) of the region
|
||||||
|
* @type: A pointer to memtype, with requested type. On success, requested
|
||||||
|
* or any other compatible type that was available for the region is returned
|
||||||
|
*
|
||||||
|
* On success, returns 0
|
||||||
|
* On failure, returns non-zero
|
||||||
|
*/
|
||||||
|
int io_reserve_memtype(resource_size_t start, resource_size_t end,
|
||||||
|
unsigned long *type)
|
||||||
|
{
|
||||||
|
unsigned long req_type = *type;
|
||||||
|
unsigned long new_type;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
WARN_ON_ONCE(iomem_map_sanity_check(start, end - start));
|
||||||
|
|
||||||
|
ret = reserve_memtype(start, end, req_type, &new_type);
|
||||||
|
if (ret)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
if (!is_new_memtype_allowed(req_type, new_type))
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
|
if (kernel_map_sync_memtype(start, end - start, new_type) < 0)
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
|
*type = new_type;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_free:
|
||||||
|
free_memtype(start, end);
|
||||||
|
ret = -EBUSY;
|
||||||
|
out_err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* io_free_memtype - Release a memory type mapping for a region of memory
|
||||||
|
* @start: start (physical address) of the region
|
||||||
|
* @end: end (physical address) of the region
|
||||||
|
*/
|
||||||
|
void io_free_memtype(resource_size_t start, resource_size_t end)
|
||||||
|
{
|
||||||
|
free_memtype(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||||
unsigned long size, pgprot_t vma_prot)
|
unsigned long size, pgprot_t vma_prot)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue