Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fd126bc authored by Venkatesh Pallipadi's avatar Venkatesh Pallipadi Committed by H. Peter Anvin
Browse files

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: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
parent 279e669b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -19,4 +19,9 @@ extern int free_memtype(u64 start, u64 end);
extern int kernel_map_sync_memtype(u64 base, unsigned long size,
		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 */
+49 −0
Original line number Diff line number Diff line
@@ -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,
				unsigned long size, pgprot_t vma_prot)
{