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

Commit cafaf14a authored by Chris Wilson's avatar Chris Wilson
Browse files

io-mapping: Always create a struct to hold metadata about the io-mapping



Currently, we only allocate a structure to hold metadata if we need to
allocate an ioremap for every access, such as on x86-32. However, it
would be useful to store basic information about the io-mapping, such as
its page protection, on all platforms.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: linux-mm@kvack.org
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160819155428.1670-4-chris@chris-wilson.co.uk
parent 8678fdaf
Loading
Loading
Loading
Loading
+57 −35
Original line number Diff line number Diff line
@@ -31,16 +31,16 @@
 * See Documentation/io-mapping.txt
 */

#ifdef CONFIG_HAVE_ATOMIC_IOMAP

#include <asm/iomap.h>

struct io_mapping {
	resource_size_t base;
	unsigned long size;
	pgprot_t prot;
	void __iomem *iomem;
};

#ifdef CONFIG_HAVE_ATOMIC_IOMAP

#include <asm/iomap.h>
/*
 * For small address space machines, mapping large objects
 * into the kernel virtual space isn't practical. Where
@@ -49,34 +49,25 @@ struct io_mapping {
 */

static inline struct io_mapping *
io_mapping_create_wc(resource_size_t base, unsigned long size)
io_mapping_init_wc(struct io_mapping *iomap,
		   resource_size_t base,
		   unsigned long size)
{
	struct io_mapping *iomap;
	pgprot_t prot;

	iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
	if (!iomap)
		goto out_err;

	if (iomap_create_wc(base, size, &prot))
		goto out_free;
		return NULL;

	iomap->base = base;
	iomap->size = size;
	iomap->prot = prot;
	return iomap;

out_free:
	kfree(iomap);
out_err:
	return NULL;
}

static inline void
io_mapping_free(struct io_mapping *mapping)
io_mapping_fini(struct io_mapping *mapping)
{
	iomap_free(mapping->base, mapping->size);
	kfree(mapping);
}

/* Atomic map/unmap */
@@ -121,21 +112,40 @@ io_mapping_unmap(void __iomem *vaddr)
#else

#include <linux/uaccess.h>

/* this struct isn't actually defined anywhere */
struct io_mapping;
#include <asm/pgtable_types.h>

/* Create the io_mapping object*/
static inline struct io_mapping *
io_mapping_create_wc(resource_size_t base, unsigned long size)
io_mapping_init_wc(struct io_mapping *iomap,
		   resource_size_t base,
		   unsigned long size)
{
	return (struct io_mapping __force *) ioremap_wc(base, size);
	iomap->base = base;
	iomap->size = size;
	iomap->iomem = ioremap_wc(base, size);
	iomap->prot = pgprot_writecombine(PAGE_KERNEL_IO);

	return iomap;
}

static inline void
io_mapping_free(struct io_mapping *mapping)
io_mapping_fini(struct io_mapping *mapping)
{
	iounmap(mapping->iomem);
}

/* Non-atomic map/unmap */
static inline void __iomem *
io_mapping_map_wc(struct io_mapping *mapping,
		  unsigned long offset,
		  unsigned long size)
{
	return mapping->iomem + offset;
}

static inline void
io_mapping_unmap(void __iomem *vaddr)
{
	iounmap((void __force __iomem *) mapping);
}

/* Atomic map/unmap */
@@ -145,30 +155,42 @@ io_mapping_map_atomic_wc(struct io_mapping *mapping,
{
	preempt_disable();
	pagefault_disable();
	return ((char __force __iomem *) mapping) + offset;
	return io_mapping_map_wc(mapping, offset, PAGE_SIZE);
}

static inline void
io_mapping_unmap_atomic(void __iomem *vaddr)
{
	io_mapping_unmap(vaddr);
	pagefault_enable();
	preempt_enable();
}

/* Non-atomic map/unmap */
static inline void __iomem *
io_mapping_map_wc(struct io_mapping *mapping,
		  unsigned long offset,
#endif /* HAVE_ATOMIC_IOMAP */

static inline struct io_mapping *
io_mapping_create_wc(resource_size_t base,
		     unsigned long size)
{
	return ((char __force __iomem *) mapping) + offset;
	struct io_mapping *iomap;

	iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
	if (!iomap)
		return NULL;

	if (!io_mapping_init_wc(iomap, base, size)) {
		kfree(iomap);
		return NULL;
	}

	return iomap;
}

static inline void
io_mapping_unmap(void __iomem *vaddr)
io_mapping_free(struct io_mapping *iomap)
{
	io_mapping_fini(iomap);
	kfree(iomap);
}

#endif /* HAVE_ATOMIC_IOMAP */

#endif /* _LINUX_IO_MAPPING_H */