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

Commit 608205c0 authored by Joerg Roedel's avatar Joerg Roedel
Browse files

Merge branch 'for-joerg' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/linux into arm/omap

parents 5611cc45 fabdbca8
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <plat/board.h>
#include <plat/mcbsp.h>
#include <plat/mmc.h>
#include <plat/iommu.h>
#include <plat/dma.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
@@ -211,9 +212,15 @@ static struct platform_device omap3isp_device = {
	.resource	= omap3isp_resources,
};

static struct omap_iommu_arch_data omap3_isp_iommu = {
	.name = "isp",
};

int omap3_init_camera(struct isp_platform_data *pdata)
{
	omap3isp_device.dev.platform_data = pdata;
	omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;

	return platform_device_register(&omap3isp_device);
}

+28 −3
Original line number Diff line number Diff line
@@ -111,6 +111,32 @@ struct iommu_platform_data {
	u32 da_end;
};

/**
 * struct iommu_arch_data - omap iommu private data
 * @name: name of the iommu device
 * @iommu_dev: handle of the iommu device
 *
 * This is an omap iommu private data object, which binds an iommu user
 * to its iommu device. This object should be placed at the iommu user's
 * dev_archdata so generic IOMMU API can be used without having to
 * utilize omap-specific plumbing anymore.
 */
struct omap_iommu_arch_data {
	const char *name;
	struct omap_iommu *iommu_dev;
};

/**
 * dev_to_omap_iommu() - retrieves an omap iommu object from a user device
 * @dev: iommu client device
 */
static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
{
	struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;

	return arch_data->iommu_dev;
}

/* IOMMU errors */
#define OMAP_IOMMU_ERR_TLB_MISS		(1 << 0)
#define OMAP_IOMMU_ERR_TRANS_FAULT	(1 << 1)
@@ -163,8 +189,8 @@ extern int omap_iommu_set_isr(const char *name,
				    void *priv),
			 void *isr_priv);

extern void omap_iommu_save_ctx(struct omap_iommu *obj);
extern void omap_iommu_restore_ctx(struct omap_iommu *obj);
extern void omap_iommu_save_ctx(struct device *dev);
extern void omap_iommu_restore_ctx(struct device *dev);

extern int omap_install_iommu_arch(const struct iommu_functions *ops);
extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
@@ -176,6 +202,5 @@ extern ssize_t
omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len);
extern size_t
omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
struct device *omap_find_iommu_device(const char *name);

#endif /* __MACH_IOMMU_H */
+6 −6
Original line number Diff line number Diff line
@@ -72,18 +72,18 @@ struct iovm_struct {
#define IOVMF_DA_FIXED		(1 << (4 + IOVMF_SW_SHIFT))


extern struct iovm_struct *omap_find_iovm_area(struct omap_iommu *obj, u32 da);
extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da);
extern u32
omap_iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da,
omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
			const struct sg_table *sgt, u32 flags);
extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain,
				struct omap_iommu *obj, u32 da);
				struct device *dev, u32 da);
extern u32
omap_iommu_vmalloc(struct iommu_domain *domain, struct omap_iommu *obj,
omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev,
				u32 da, size_t bytes, u32 flags);
extern void
omap_iommu_vfree(struct iommu_domain *domain, struct omap_iommu *obj,
omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
				const u32 da);
extern void *omap_da_to_va(struct omap_iommu *obj, u32 da);
extern void *omap_da_to_va(struct device *dev, u32 da);

#endif /* __IOMMU_MMAP_H */
+26 −32
Original line number Diff line number Diff line
@@ -86,20 +86,24 @@ EXPORT_SYMBOL_GPL(omap_uninstall_iommu_arch);

/**
 * omap_iommu_save_ctx - Save registers for pm off-mode support
 * @obj:	target iommu
 * @dev:	client device
 **/
void omap_iommu_save_ctx(struct omap_iommu *obj)
void omap_iommu_save_ctx(struct device *dev)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);

	arch_iommu->save_ctx(obj);
}
EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);

/**
 * omap_iommu_restore_ctx - Restore registers for pm off-mode support
 * @obj:	target iommu
 * @dev:	client device
 **/
void omap_iommu_restore_ctx(struct omap_iommu *obj)
void omap_iommu_restore_ctx(struct device *dev)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);

	arch_iommu->restore_ctx(obj);
}
EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);
@@ -819,36 +823,24 @@ static int device_match_by_alias(struct device *dev, void *data)
	return strcmp(obj->name, name) == 0;
}

/**
 * omap_find_iommu_device() - find an omap iommu device by name
 * @name:	name of the iommu device
 *
 * The generic iommu API requires the caller to provide the device
 * he wishes to attach to a certain iommu domain.
 *
 * Drivers generally should not bother with this as it should just
 * be taken care of by the DMA-API using dev_archdata.
 *
 * This function is provided as an interim solution until the latter
 * materializes, and omap3isp is fully migrated to the DMA-API.
 */
struct device *omap_find_iommu_device(const char *name)
{
	return driver_find_device(&omap_iommu_driver.driver, NULL,
				(void *)name,
				device_match_by_alias);
}
EXPORT_SYMBOL_GPL(omap_find_iommu_device);

/**
 * omap_iommu_attach() - attach iommu device to an iommu domain
 * @dev:	target omap iommu device
 * @name:	name of target omap iommu device
 * @iopgd:	page table
 **/
static struct omap_iommu *omap_iommu_attach(struct device *dev, u32 *iopgd)
static struct omap_iommu *omap_iommu_attach(const char *name, u32 *iopgd)
{
	int err = -ENOMEM;
	struct omap_iommu *obj = to_iommu(dev);
	struct device *dev;
	struct omap_iommu *obj;

	dev = driver_find_device(&omap_iommu_driver.driver, NULL,
				(void *)name,
				device_match_by_alias);
	if (!dev)
		return NULL;

	obj = to_iommu(dev);

	spin_lock(&obj->iommu_lock);

@@ -1069,6 +1061,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{
	struct omap_iommu_domain *omap_domain = domain->priv;
	struct omap_iommu *oiommu;
	struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
	int ret = 0;

	spin_lock(&omap_domain->lock);
@@ -1081,14 +1074,14 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
	}

	/* get a handle to and enable the omap iommu */
	oiommu = omap_iommu_attach(dev, omap_domain->pgtable);
	oiommu = omap_iommu_attach(arch_data->name, omap_domain->pgtable);
	if (IS_ERR(oiommu)) {
		ret = PTR_ERR(oiommu);
		dev_err(dev, "can't get omap iommu: %d\n", ret);
		goto out;
	}

	omap_domain->iommu_dev = oiommu;
	omap_domain->iommu_dev = arch_data->iommu_dev = oiommu;
	oiommu->domain = domain;

out:
@@ -1100,7 +1093,8 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain,
				 struct device *dev)
{
	struct omap_iommu_domain *omap_domain = domain->priv;
	struct omap_iommu *oiommu = to_iommu(dev);
	struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
	struct omap_iommu *oiommu = dev_to_omap_iommu(dev);

	spin_lock(&omap_domain->lock);

@@ -1114,7 +1108,7 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain,

	omap_iommu_detach(oiommu);

	omap_domain->iommu_dev = NULL;
	omap_domain->iommu_dev = arch_data->iommu_dev = NULL;

out:
	spin_unlock(&omap_domain->lock);
+20 −11
Original line number Diff line number Diff line
@@ -231,12 +231,14 @@ static struct iovm_struct *__find_iovm_area(struct omap_iommu *obj,

/**
 * omap_find_iovm_area  -  find iovma which includes @da
 * @dev:	client device
 * @da:		iommu device virtual address
 *
 * Find the existing iovma starting at @da
 */
struct iovm_struct *omap_find_iovm_area(struct omap_iommu *obj, u32 da)
struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	struct iovm_struct *area;

	mutex_lock(&obj->mmap_lock);
@@ -343,14 +345,15 @@ static void free_iovm_area(struct omap_iommu *obj, struct iovm_struct *area)

/**
 * omap_da_to_va - convert (d) to (v)
 * @obj:	objective iommu
 * @dev:	client device
 * @da:		iommu device virtual address
 * @va:		mpu virtual address
 *
 * Returns mpu virtual addr which corresponds to a given device virtual addr
 */
void *omap_da_to_va(struct omap_iommu *obj, u32 da)
void *omap_da_to_va(struct device *dev, u32 da)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	void *va = NULL;
	struct iovm_struct *area;

@@ -582,16 +585,18 @@ __iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj,

/**
 * omap_iommu_vmap  -  (d)-(p)-(v) address mapper
 * @obj:	objective iommu
 * @domain:	iommu domain
 * @dev:	client device
 * @sgt:	address of scatter gather table
 * @flags:	iovma and page property
 *
 * Creates 1-n-1 mapping with given @sgt and returns @da.
 * All @sgt element must be io page size aligned.
 */
u32 omap_iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da,
u32 omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
		const struct sg_table *sgt, u32 flags)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	size_t bytes;
	void *va = NULL;

@@ -622,15 +627,17 @@ EXPORT_SYMBOL_GPL(omap_iommu_vmap);

/**
 * omap_iommu_vunmap  -  release virtual mapping obtained by 'omap_iommu_vmap()'
 * @obj:	objective iommu
 * @domain:	iommu domain
 * @dev:	client device
 * @da:		iommu device virtual address
 *
 * Free the iommu virtually contiguous memory area starting at
 * @da, which was returned by 'omap_iommu_vmap()'.
 */
struct sg_table *
omap_iommu_vunmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da)
omap_iommu_vunmap(struct iommu_domain *domain, struct device *dev, u32 da)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	struct sg_table *sgt;
	/*
	 * 'sgt' is allocated before 'omap_iommu_vmalloc()' is called.
@@ -647,7 +654,7 @@ EXPORT_SYMBOL_GPL(omap_iommu_vunmap);

/**
 * omap_iommu_vmalloc  -  (d)-(p)-(v) address allocator and mapper
 * @obj:	objective iommu
 * @dev:	client device
 * @da:		contiguous iommu virtual memory
 * @bytes:	allocation size
 * @flags:	iovma and page property
@@ -656,9 +663,10 @@ EXPORT_SYMBOL_GPL(omap_iommu_vunmap);
 * @da again, which might be adjusted if 'IOVMF_DA_FIXED' is not set.
 */
u32
omap_iommu_vmalloc(struct iommu_domain *domain, struct omap_iommu *obj, u32 da,
omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev, u32 da,
						size_t bytes, u32 flags)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	void *va;
	struct sg_table *sgt;

@@ -698,15 +706,16 @@ EXPORT_SYMBOL_GPL(omap_iommu_vmalloc);

/**
 * omap_iommu_vfree  -  release memory allocated by 'omap_iommu_vmalloc()'
 * @obj:	objective iommu
 * @dev:	client device
 * @da:		iommu device virtual address
 *
 * Frees the iommu virtually continuous memory area starting at
 * @da, as obtained from 'omap_iommu_vmalloc()'.
 */
void omap_iommu_vfree(struct iommu_domain *domain, struct omap_iommu *obj,
void omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
								const u32 da)
{
	struct omap_iommu *obj = dev_to_omap_iommu(dev);
	struct sg_table *sgt;

	sgt = unmap_vm_area(domain, obj, da, vfree,
Loading