summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Green <andy.green@linaro.org>2011-12-16 13:11:58 +0800
committerAndy Green <andy.green@linaro.org>2012-01-09 08:39:42 +0800
commitb4fa90cc4466f203f740a7b4d4d8577febaae96e (patch)
tree1fd24b7dc385e9851fa1119dc5853c637c36718d
parentff915b62294878722cf1d8032563ad4dbf22aa80 (diff)
3.2 iommu uplevel fixes
Signed-off-by: Andy Green <andy.green@linaro.org>
-rw-r--r--arch/arm/mach-omap2/iommu2.c22
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c103
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/dmm_user.c28
-rw-r--r--arch/arm/plat-omap/include/plat/dmm_user.h43
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h48
-rw-r--r--arch/arm/plat-omap/include/plat/iovmm.h7
-rw-r--r--arch/arm/plat-omap/iodmm.c58
-rw-r--r--drivers/dsp/syslink/devh/44xx/devh44xx.c2
-rw-r--r--drivers/dsp/syslink/ipu_pm/ipu_pm.c26
-rw-r--r--drivers/dsp/syslink/multicore_ipc/ipc_drv.c5
-rw-r--r--drivers/iommu/omap-iommu.c69
12 files changed, 267 insertions, 145 deletions
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index a884609b586..a7dead52864 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -94,7 +94,7 @@ static void __iommu_set_twl(struct omap_iommu *obj, bool on)
iommu_write_reg(obj, l, MMU_CNTL);
}
-static u32 omap2_get_version(struct iommu *obj)
+static u32 omap2_get_version(struct omap_iommu *obj)
{
return iommu_read_reg(obj, MMU_REVISION);
}
@@ -105,12 +105,20 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
unsigned long timeout;
int ret = 0;
- if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K))
+ if (!obj->iopgd) {
+ pr_err("omap2_iommu_enable: NULL obj->iopgd\n");
return -EINVAL;
+ }
+ if (!IS_ALIGNED((u32)obj->iopgd, SZ_16K)) {
+ pr_err("omap2_iommu_enable: iopgd is not 16K aligned!\n");
+ return -EINVAL;
+ }
pa = virt_to_phys(obj->iopgd);
- if (!IS_ALIGNED(pa, SZ_16K))
+ if (!IS_ALIGNED(pa, SZ_16K)) {
+ pr_err("omap2_iommu_enable: virt_to_phys not 16K aligned!\n");
return -EINVAL;
+ }
#ifdef CONFIG_OMAP_PM
if (!strcmp(obj->name, "ducati")) {
@@ -123,8 +131,10 @@ static int omap2_iommu_enable(struct omap_iommu *obj)
}
#endif
ret = omap_device_enable(obj->pdev);
- if (ret)
+ if (ret) {
+ pr_err("omap2_iommu_enable: omap_device_enable returned %d\n", ret);
return ret;
+ }
iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
@@ -336,6 +346,7 @@ out:
return p - buf;
}
+#if 0
static void omap2_iommu_save_ctx(struct omap_iommu *obj)
{
int i;
@@ -361,6 +372,7 @@ static void omap2_iommu_restore_ctx(struct omap_iommu *obj)
BUG_ON(p[0] != IOMMU_ARCH_VERSION);
}
+#endif
static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
{
@@ -374,7 +386,7 @@ static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
e->mixed = cr->ram & MMU_RAM_MIXED;
}
-static const struct iommu_functions omap2_iommu_ops = {
+static const struct omap_iommu_functions omap2_iommu_ops = {
.get_version = omap2_get_version,
.enable = omap2_iommu_enable,
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index 2d40b232580..a218a41213e 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -18,20 +18,21 @@
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
#include <plat/irqs-44xx.h>
+#include <plat/iopgtable.h>
static struct platform_device **omap_iommu_pdev;
-struct iommu_device {
+struct omap_iommu_device {
resource_size_t base;
int irq;
- struct iommu_platform_data pdata;
+ struct omap_iommu_platform_data pdata;
struct resource res[2];
};
-static struct iommu_platform_data *devices_data;
+static struct omap_iommu_platform_data *devices_data;
static int num_iommu_devices;
#ifdef CONFIG_ARCH_OMAP3
-static struct iommu_platform_data omap3_devices_data[] = {
+static struct omap_iommu_platform_data omap3_devices_data[] = {
{
.name = "isp",
.oh_name = "isp",
@@ -67,9 +68,9 @@ struct iommu_platform_data {
};
*/
-static struct iommu_platform_data omap4_devices_data[] = {
+static struct omap_iommu_platform_data omap4_devices_data[] = {
{
- .io_base = OMAP4_MMU1_BASE,
+ .io_base = (void *)OMAP4_MMU1_BASE,
.irq = OMAP44XX_IRQ_DUCATI_MMU,
/* .clk_name = "ipu_fck", */
.da_start = 0x0,
@@ -87,12 +88,12 @@ static struct iommu_platform_data omap4_devices_data[] = {
#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices_data)
static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES];
-struct device *omap_iommu_get_dev(char *dev_name)
+struct device *omap_iommu_get_dev(const char *dev_name)
{
int i;
struct platform_device *pdev;
struct device *dev = NULL;
- struct iommu_platform_data *pdata;
+ struct omap_iommu_platform_data *pdata;
for (i = 0; i < NR_OMAP4_IOMMU_DEVICES; i++) {
pdev = omap_iommu_pdev[i];
@@ -106,6 +107,90 @@ struct device *omap_iommu_get_dev(char *dev_name)
}
EXPORT_SYMBOL(omap_iommu_get_dev);
+#if 0
+
+/**
+ * * iommu_get - Get iommu handler
+ * * @name: target iommu name
+ * **/
+struct omap_iommu *iommu_get(const char *name)
+{
+ int err = -ENOMEM;
+ struct device *dev;
+ struct omap_iommu *obj;
+ int rev;
+ unsigned long flags;
+
+ dev = omap_find_iommu_device(name);
+ if (!dev) {
+ pr_err("iommu_get: no dev for %s\n", name);
+ return ERR_PTR(-ENODEV);
+ }
+ obj = to_iommu(dev);
+
+ spin_lock_irqsave(&obj->iommu_lock, flags);
+
+ if (obj->refcount++ == 0) {
+ err = iommu_enable(obj);
+ if (err) {
+ pr_err("iommu_get: iommu_enable returned %d\n", err);
+ goto err_enable;
+ }
+ if (!strcmp(obj->name, "ducati")) {
+ rev = GET_OMAP_REVISION();
+ if (rev == 0x0)
+ iommu_set_twl(obj, false);
+ }
+
+ flush_iotlb_all(obj);
+ }
+ if (!try_module_get(obj->owner)) {
+ pr_err("iommu_get: try_module_get failed\n");
+ goto err_module;
+ }
+
+ spin_unlock_irqrestore(&obj->iommu_lock, flags);
+ dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
+
+ return obj;
+
+err_module:
+ if (obj->refcount == 1)
+ iommu_disable(obj);
+err_enable:
+ obj->refcount--;
+ spin_unlock_irqrestore(&obj->iommu_lock, flags);
+
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(iommu_get);
+
+/**
+ * * iommu_put - Put back iommu handler
+ * * @obj: target iommu
+ * **/
+void iommu_put(struct omap_iommu *obj)
+{
+ unsigned long flags;
+
+ if (!obj || IS_ERR(obj))
+ return;
+
+ spin_lock_irqsave(&obj->iommu_lock, flags);
+
+ if (--obj->refcount == 0)
+ iommu_disable(obj);
+
+ module_put(obj->owner);
+
+ spin_unlock_irqrestore(&obj->iommu_lock, flags);
+
+ dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
+}
+EXPORT_SYMBOL_GPL(iommu_put);
+
+#endif
+
#else
#define omap4_devices_data NULL
#define NR_OMAP4_IOMMU_DEVICES 0
@@ -149,7 +234,7 @@ static int __init omap_iommu_init(void)
ohl_cnt = ARRAY_SIZE(omap_iommu_latency);
for (i = 0; i < num_iommu_devices; i++) {
- struct iommu_platform_data *data = &devices_data[i];
+ struct omap_iommu_platform_data *data = &devices_data[i];
oh = omap_hwmod_lookup(data->oh_name);
if (oh == NULL)
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index e3d3e9e5631..01163348cfd 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
-obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
obj-$(CONFIG_OMAP_USER_DMM) += dmm_user.o iodmm.o
diff --git a/arch/arm/plat-omap/dmm_user.c b/arch/arm/plat-omap/dmm_user.c
index c099e038e1b..8808c98a815 100644
--- a/arch/arm/plat-omap/dmm_user.c
+++ b/arch/arm/plat-omap/dmm_user.c
@@ -45,9 +45,9 @@ static dev_t omap_dmm_dev;
static long omap_dmm_ioctl(struct file *filp,
unsigned int cmd, unsigned long args)
{
- struct iodmm_struct *obj;
+ struct omap_iodmm_struct *obj;
int ret = 0;
- obj = (struct iodmm_struct *)filp->private_data;
+ obj = (struct omap_iodmm_struct *)filp->private_data;
if (!obj)
return -EINVAL;
@@ -101,18 +101,22 @@ static long omap_dmm_ioctl(struct file *filp,
static int omap_dmm_open(struct inode *inode, struct file *filp)
{
- struct iodmm_struct *iodmm;
- struct iovmm_device *obj;
+ struct omap_iodmm_struct *iodmm;
+ struct omap_iovmm_device *obj;
- obj = container_of(inode->i_cdev, struct iovmm_device, cdev);
+ obj = container_of(inode->i_cdev, struct omap_iovmm_device, cdev);
obj->refcount++;
- iodmm = kzalloc(sizeof(struct iodmm_struct), GFP_KERNEL);
+ iodmm = kzalloc(sizeof(struct omap_iodmm_struct), GFP_KERNEL);
INIT_LIST_HEAD(&iodmm->map_list);
iodmm->iovmm = obj;
iodmm->tgid = current->tgid;
obj->iommu = iommu_get(obj->name);
+ if (IS_ERR(obj->iommu)) {
+ pr_err("omap_dmm_open: failed to find %s\n", obj->name);
+ return (int)obj->iommu;
+ }
filp->private_data = iodmm;
return 0;
@@ -121,7 +125,7 @@ static int omap_dmm_open(struct inode *inode, struct file *filp)
static int omap_dmm_release(struct inode *inode, struct file *filp)
{
int status = 0;
- struct iodmm_struct *obj;
+ struct omap_iodmm_struct *obj;
if (!filp->private_data) {
status = -EIO;
@@ -175,12 +179,12 @@ static int __devinit omap_dmm_probe(struct platform_device *pdev)
int err = -ENODEV;
int major, minor;
struct device *tmpdev;
- struct iommu_platform_data *pdata =
- (struct iommu_platform_data *)pdev->dev.platform_data;
+ struct omap_iommu_platform_data *pdata =
+ (struct omap_iommu_platform_data *)pdev->dev.platform_data;
int ret = 0;
- struct iovmm_device *obj;
+ struct omap_iovmm_device *obj;
- obj = kzalloc(sizeof(struct iovmm_device), GFP_KERNEL);
+ obj = kzalloc(sizeof(struct omap_iovmm_device), GFP_KERNEL);
major = MAJOR(omap_dmm_dev);
minor = atomic_read(&num_of_iovmmus);
@@ -226,7 +230,7 @@ err_cdev:
static int __devexit omap_dmm_remove(struct platform_device *pdev)
{
- struct iovmm_device *obj = platform_get_drvdata(pdev);
+ struct omap_iovmm_device *obj = platform_get_drvdata(pdev);
int major = MAJOR(omap_dmm_dev);
device_destroy(omap_dmm_class, MKDEV(major, obj->minor));
diff --git a/arch/arm/plat-omap/include/plat/dmm_user.h b/arch/arm/plat-omap/include/plat/dmm_user.h
index 84a72f33d9f..d5cdee635ac 100644
--- a/arch/arm/plat-omap/include/plat/dmm_user.h
+++ b/arch/arm/plat-omap/include/plat/dmm_user.h
@@ -28,8 +28,8 @@
#define DMM_IOCMEMINV _IO(DMM_IOC_MAGIC, 5)
#define DMM_IOCCREATEPOOL _IO(DMM_IOC_MAGIC, 6)
#define DMM_IOCDELETEPOOL _IO(DMM_IOC_MAGIC, 7)
-#define IOMMU_IOCEVENTREG _IO(DMM_IOC_MAGIC, 10)
-#define IOMMU_IOCEVENTUNREG _IO(DMM_IOC_MAGIC, 11)
+//#define IOMMU_IOCEVENTREG _IO(DMM_IOC_MAGIC, 10)
+//#define IOMMU_IOCEVENTUNREG _IO(DMM_IOC_MAGIC, 11)
#define DMM_DA_ANON 0x1
#define DMM_DA_PHYS 0x2
@@ -85,16 +85,9 @@ struct dmm_map_object {
struct device_dma_map_info dma_info;
};
-struct iodmm_struct {
- struct iovmm_device *iovmm;
- struct list_head map_list;
- u32 pool_id;
- pid_t tgid;
-};
-
-struct iovmm_device {
+struct omap_iovmm_device {
/* iommu object which this belongs to */
- struct iommu *iommu;
+ struct omap_iommu *iommu;
const char *name;
/* List of memory pool it manages */
struct list_head mmap_pool;
@@ -104,24 +97,32 @@ struct iovmm_device {
int refcount;
};
+struct omap_iodmm_struct {
+ struct omap_iovmm_device *iovmm;
+ struct list_head map_list;
+ u32 pool_id;
+ pid_t tgid;
+};
+
+
/* user dmm functions */
-int dmm_user(struct iodmm_struct *obj, void __user *args);
+int dmm_user(struct omap_iodmm_struct *obj, void __user *args);
-void user_remove_resources(struct iodmm_struct *obj);
+void user_remove_resources(struct omap_iodmm_struct *obj);
-int user_un_map(struct iodmm_struct *obj, const void __user *args);
+int user_un_map(struct omap_iodmm_struct *obj, const void __user *args);
-int proc_begin_dma(struct iodmm_struct *obj, const void __user *args);
+int proc_begin_dma(struct omap_iodmm_struct *obj, const void __user *args);
-int proc_end_dma(struct iodmm_struct *obj, const void __user *args);
+int proc_end_dma(struct omap_iodmm_struct *obj, const void __user *args);
-int omap_create_dmm_pool(struct iodmm_struct *obj, const void __user *args);
+int omap_create_dmm_pool(struct omap_iodmm_struct *obj, const void __user *args);
-int omap_delete_dmm_pools(struct iodmm_struct *obj);
+int omap_delete_dmm_pools(struct omap_iodmm_struct *obj);
-int program_tlb_entry(struct iodmm_struct *obj, const void __user *args);
+int program_tlb_entry(struct omap_iodmm_struct *obj, const void __user *args);
-int register_mmufault(struct iodmm_struct *obj, const void __user *args);
+int register_mmufault(struct omap_iodmm_struct *obj, const void __user *args);
-int unregister_mmufault(struct iodmm_struct *obj, const void __user *args);
+int unregister_mmufault(struct omap_iodmm_struct *obj, const void __user *args);
#endif
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 11a7f98fff2..533b0695f52 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -89,8 +89,8 @@ struct iotlb_lock {
};
/* architecture specific functions */
-struct iommu_functions {
- u32 (*get_version)(struct iommu *obj);
+struct omap_iommu_functions {
+ u32 (*get_version)(struct omap_iommu *obj);
int (*enable)(struct omap_iommu *obj);
void (*disable)(struct omap_iommu *obj);
@@ -120,7 +120,7 @@ enum {
IOMMU_CLOSE,
};
-struct iommu_platform_data {
+struct omap_iommu_platform_data {
const char *name;
const char *oh_name;
const int nr_tlb_entries;
@@ -180,35 +180,26 @@ omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e);
extern int omap_iommu_set_isr(const char *name,
int (*isr)(struct omap_iommu *obj, u32 da, u32 iommu_errs,
void *priv), void *isr_priv);
-extern int iommu_register_notifier(struct iommu *obj,
+extern int iommu_register_notifier(struct omap_iommu *obj,
struct notifier_block *nb);
-extern int iommu_unregister_notifier(struct iommu *obj,
+extern int iommu_unregister_notifier(struct omap_iommu *obj,
struct notifier_block *nb);
-extern int iommu_notify_event(struct iommu *obj, int event, void *data);
+extern int iommu_notify_event(struct omap_iommu *obj, int event, void *data);
-extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
-extern void iommu_set_twl(struct iommu *obj, bool on);
-extern void flush_iotlb_page(struct iommu *obj, u32 da);
-extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
-extern void flush_iotlb_all(struct iommu *obj);
+extern void iommu_set_twl(struct omap_iommu *obj, bool on);
+extern void flush_iotlb_range(struct omap_iommu *obj, u32 start, u32 end);
-extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
-extern void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd,
- u32 **ppte);
-extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
-extern void iopgtable_clear_entry_all(struct iommu *obj);
-
-extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
-extern struct iommu *iommu_get(const char *name);
-extern void iommu_put(struct iommu *obj);
+extern int iommu_set_da_range(struct omap_iommu *obj, u32 start, u32 end);
+//extern struct omap_iommu *iommu_get(const char *name);
+//extern void iommu_put(struct omap_iommu *obj);
extern void omap_iommu_save_ctx(struct omap_iommu *obj);
extern void omap_iommu_restore_ctx(struct omap_iommu *obj);
-u32 iommu_save_tlb_entries(struct iommu *obj);
-u32 iommu_restore_tlb_entries(struct iommu *obj);
+u32 iommu_save_tlb_entries(struct omap_iommu *obj);
+u32 iommu_restore_tlb_entries(struct omap_iommu *obj);
-extern int omap_install_iommu_arch(const struct iommu_functions *ops);
-extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
+extern int omap_install_iommu_arch(const struct omap_iommu_functions *ops);
+extern void omap_uninstall_iommu_arch(const struct omap_iommu_functions *ops);
extern int omap_foreach_iommu_device(void *data,
int (*fn)(struct device *, void *));
@@ -220,6 +211,13 @@ omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
struct device *omap_find_iommu_device(const char *name);
extern int iommu_get_plat_data_size(void);
-extern struct device *omap_iommu_get_dev(char *dev_name);
+extern struct device *omap_iommu_get_dev(const char *dev_name);
+
+extern int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e);
+extern size_t iopgtable_clear_entry(struct omap_iommu *obj, u32 da);
+
+extern int iommu_enable(struct omap_iommu *obj);
+extern void iommu_disable(struct omap_iommu *obj);
+extern void flush_iotlb_all(struct omap_iommu *obj);
#endif /* __MACH_IOMMU_H */
diff --git a/arch/arm/plat-omap/include/plat/iovmm.h b/arch/arm/plat-omap/include/plat/iovmm.h
index 30b5b60bfe2..5fbae80c457 100644
--- a/arch/arm/plat-omap/include/plat/iovmm.h
+++ b/arch/arm/plat-omap/include/plat/iovmm.h
@@ -14,7 +14,8 @@
#define __IOMMU_MMAP_H
#include <linux/iommu.h>
-
+#include <linux/dma-direction.h>
+#include <linux/cdev.h>
#define IOVMM_IOC_MAGIC 'V'
@@ -31,7 +32,7 @@
#define IOMMU_IOCEVENTREG _IO(IOVMM_IOC_MAGIC, 10)
#define IOMMU_IOCEVENTUNREG _IO(IOVMM_IOC_MAGIC, 11)
-
+#if 0
struct iovmm_pool {
u32 pool_id;
u32 da_begin;
@@ -86,7 +87,7 @@ struct dmm_map_object {
struct page **pages;
struct device_dma_map_info dma_info;
};
-
+#endif
struct iodmm_struct {
struct iovmm_device *iovmm;
struct list_head map_list;
diff --git a/arch/arm/plat-omap/iodmm.c b/arch/arm/plat-omap/iodmm.c
index 25a18812d64..cfa7c89d80c 100644
--- a/arch/arm/plat-omap/iodmm.c
+++ b/arch/arm/plat-omap/iodmm.c
@@ -40,8 +40,7 @@
#include <plat/iommu.h>
#include <plat/dmm_user.h>
-
-#include "iopgtable.h"
+#include <plat/iopgtable.h>
#ifndef CONFIG_DMM_DMA_API
/* Hack hack code to handle MM buffers */
@@ -50,7 +49,7 @@ int temp_user_dma_op(unsigned long start, unsigned long end, int op)
struct mm_struct *mm = current->active_mm;
void (*inner_op)(const void *, const void *);
- void (*outer_op)(unsigned long, unsigned long);
+ void (*outer_op)(phys_addr_t, phys_addr_t);
switch (op) {
case 1:
@@ -122,7 +121,7 @@ int temp_user_dma_op(unsigned long start, unsigned long end, int op)
}
#endif
-static inline struct gen_pool *get_pool_handle(struct iovmm_device *iovmm_obj,
+static inline struct gen_pool *get_pool_handle(struct omap_iovmm_device *iovmm_obj,
int pool_id)
{
struct iovmm_pool *pool;
@@ -160,7 +159,7 @@ static u32 __user_va2_pa(struct mm_struct *mm, u32 address)
}
/* remember mapping information */
-static struct dmm_map_object *add_mapping_info(struct iodmm_struct *obj,
+static struct dmm_map_object *add_mapping_info(struct omap_iodmm_struct *obj,
struct gen_pool *gen_pool, u32 va, u32 da, u32 size)
{
struct dmm_map_object *map_obj;
@@ -211,7 +210,7 @@ static int match_exact_map_obj(struct dmm_map_object *map_obj,
return res;
}
-static void remove_mapping_information(struct iodmm_struct *obj,
+static void remove_mapping_information(struct omap_iodmm_struct *obj,
u32 da, u32 size)
{
struct dmm_map_object *map_obj;
@@ -272,7 +271,7 @@ static int match_containing_map_obj(struct dmm_map_object *map_obj,
* virtual address
*/
static struct dmm_map_object *find_containing_mapping(
- struct iodmm_struct *obj,
+ struct omap_iodmm_struct *obj,
u32 va, u32 da, bool check_va,
u32 size)
{
@@ -464,7 +463,7 @@ out:
}
#endif
-int proc_begin_dma(struct iodmm_struct *obj, const void __user *args)
+int proc_begin_dma(struct omap_iodmm_struct *obj, const void __user *args)
{
int status = 0;
struct dmm_dma_info dma_info;
@@ -509,7 +508,7 @@ err_out:
return status;
}
-int proc_end_dma(struct iodmm_struct *obj, const void __user *args)
+int proc_end_dma(struct omap_iodmm_struct *obj, const void __user *args)
{
int status = 0;
struct dmm_dma_info dma_info;
@@ -564,7 +563,7 @@ err_out:
* This function unmaps a user space buffer into DSP virtual address.
*
*/
-static int user_to_device_unmap(struct iommu *mmu, u32 da, unsigned size)
+static int user_to_device_unmap(struct omap_iommu *mmu, u32 da, unsigned size)
{
unsigned total = size;
unsigned start = da;
@@ -584,7 +583,7 @@ static int user_to_device_unmap(struct iommu *mmu, u32 da, unsigned size)
return 0;
}
-static int __user_un_map(struct iodmm_struct *obj, u32 map_addr)
+static int __user_un_map(struct omap_iodmm_struct *obj, u32 map_addr)
{
int status = 0;
u32 va_align;
@@ -642,7 +641,7 @@ err:
*
* removes user's dmm buffer mapping
**/
-int user_un_map(struct iodmm_struct *obj, const void __user *args)
+int user_un_map(struct omap_iodmm_struct *obj, const void __user *args)
{
int status = 0;
u32 map_addr;
@@ -668,7 +667,7 @@ int user_un_map(struct iodmm_struct *obj, const void __user *args)
* This function maps a user space buffer into DSP virtual address.
*
*/
-static int user_to_device_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
+static int user_to_device_map(struct omap_iommu *mmu, u32 uva, u32 da, u32 size,
struct page **usr_pgs)
{
@@ -714,7 +713,7 @@ static int user_to_device_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
MMU_RAM_ENDIAN_LITTLE |
MMU_RAM_ELSZ_32);
- iopgtable_store_entry(mmu, &tlb_entry);
+ omap_iopgtable_store_entry(mmu, &tlb_entry);
if (usr_pgs)
usr_pgs[pg_i] = mapped_page;
da += PAGE_SIZE;
@@ -748,7 +747,7 @@ static int user_to_device_map(struct iommu *mmu, u32 uva, u32 da, u32 size,
* This function maps a user space buffer into DSP virtual address.
*
*/
-static int phys_to_device_map(struct iodmm_struct *obj,
+static int phys_to_device_map(struct omap_iodmm_struct *obj,
int pool_id, u32 *mapped_addr,
u32 pa, size_t bytes, u32 flags)
{
@@ -804,7 +803,8 @@ static int phys_to_device_map(struct iodmm_struct *obj,
size_flag[i] |
MMU_RAM_ENDIAN_LITTLE |
MMU_RAM_ELSZ_32);
- iopgtable_store_entry(obj->iovmm->iommu, &e);
+ pr_err("phys_to_device_map: calling omap_iopgtable_store_entry\n");
+ omap_iopgtable_store_entry(obj->iovmm->iommu, &e);
bytes -= pg_size[i];
da += pg_size[i];
pa += pg_size[i];
@@ -828,11 +828,11 @@ exit:
*
* Maps given user buffer to Device address
**/
-int dmm_user(struct iodmm_struct *obj, void __user *args)
+int dmm_user(struct omap_iodmm_struct *obj, void __user *args)
{
struct gen_pool *gen_pool;
struct dmm_map_object *dmm_obj;
- struct iovmm_device *iovmm_obj = obj->iovmm;
+ struct omap_iovmm_device *iovmm_obj = obj->iovmm;
u32 addr_align, da_align, size_align, tmp_addr;
int err = 0;
int i, num_of_pages;
@@ -944,7 +944,7 @@ int dmm_user(struct iodmm_struct *obj, void __user *args)
MMU_CAM_PGSZ_4K |
MMU_RAM_ENDIAN_LITTLE |
MMU_RAM_ELSZ_32);
- iopgtable_store_entry(obj->iovmm->iommu, &e);
+ omap_iopgtable_store_entry(obj->iovmm->iommu, &e);
da_align += PAGE_SIZE;
addr_align += PAGE_SIZE;
dmm_obj->pages[i] = pg;
@@ -979,8 +979,10 @@ int dmm_user(struct iodmm_struct *obj, void __user *args)
#endif
exit:
- copy_to_user((void __user *)args, &map_info,
+ i = copy_to_user((void __user *)args, &map_info,
sizeof(struct dmm_map_info));
+ if (!err && i)
+ err = i;
mutex_unlock(&iovmm_obj->dmm_map_lock);
up_read(&mm->mmap_sem);
return err;
@@ -992,7 +994,7 @@ exit:
*
* removes user's dmm resources
**/
-void user_remove_resources(struct iodmm_struct *obj)
+void user_remove_resources(struct omap_iodmm_struct *obj)
{
struct dmm_map_object *temp_map, *map_obj;
@@ -1013,10 +1015,10 @@ void user_remove_resources(struct iodmm_struct *obj)
* @obj: target dmm object
* @args pool information
**/
-int omap_create_dmm_pool(struct iodmm_struct *obj, const void __user *args)
+int omap_create_dmm_pool(struct omap_iodmm_struct *obj, const void __user *args)
{
struct iovmm_pool *pool;
- struct iovmm_device *iovmm = obj->iovmm;
+ struct omap_iovmm_device *iovmm = obj->iovmm;
struct iovmm_pool_info pool_info;
if (copy_from_user(&pool_info, args, sizeof(struct iovmm_pool_info)))
@@ -1047,10 +1049,10 @@ int omap_create_dmm_pool(struct iodmm_struct *obj, const void __user *args)
* omap_delete_dmm_pool - Delete DMM pools
* @obj: target dmm object
**/
-int omap_delete_dmm_pools(struct iodmm_struct *obj)
+int omap_delete_dmm_pools(struct omap_iodmm_struct *obj)
{
struct iovmm_pool *pool;
- struct iovmm_device *iovmm_obj = obj->iovmm;
+ struct omap_iovmm_device *iovmm_obj = obj->iovmm;
struct list_head *_pool, *_next_pool;
list_for_each_safe(_pool, _next_pool, &iovmm_obj->mmap_pool) {
@@ -1070,7 +1072,7 @@ int omap_delete_dmm_pools(struct iodmm_struct *obj)
*
* Registering to MMU fault event notification
**/
-int register_mmufault(struct iodmm_struct *obj, const void __user *args)
+int register_mmufault(struct omap_iodmm_struct *obj, const void __user *args)
{
int fd;
struct iommu_event_ntfy *fd_reg;
@@ -1096,7 +1098,7 @@ int register_mmufault(struct iodmm_struct *obj, const void __user *args)
*
* Unregister to MMU fault event notification
**/
-int unregister_mmufault(struct iodmm_struct *obj, const void __user *args)
+int unregister_mmufault(struct omap_iodmm_struct *obj, const void __user *args)
{
int fd;
struct iommu_event_ntfy *fd_reg, *temp_reg;
@@ -1127,7 +1129,7 @@ int unregister_mmufault(struct iodmm_struct *obj, const void __user *args)
* This function should be used only during remote Processor
* boot time.
**/
-int program_tlb_entry(struct iodmm_struct *obj, const void __user *args)
+int program_tlb_entry(struct omap_iodmm_struct *obj, const void __user *args)
{
struct iotlb_entry e;
int ret;
diff --git a/drivers/dsp/syslink/devh/44xx/devh44xx.c b/drivers/dsp/syslink/devh/44xx/devh44xx.c
index 92ead7d71f7..f83a00ed36b 100644
--- a/drivers/dsp/syslink/devh/44xx/devh44xx.c
+++ b/drivers/dsp/syslink/devh/44xx/devh44xx.c
@@ -46,7 +46,7 @@ static struct mutex local_gate;
struct omap_devh_runtime_info {
int brd_state;
- struct iommu *iommu;
+ struct omap_iommu *iommu;
struct omap_rproc *rproc;
};
diff --git a/drivers/dsp/syslink/ipu_pm/ipu_pm.c b/drivers/dsp/syslink/ipu_pm/ipu_pm.c
index ff6ad2041c2..608f3acf7d1 100644
--- a/drivers/dsp/syslink/ipu_pm/ipu_pm.c
+++ b/drivers/dsp/syslink/ipu_pm/ipu_pm.c
@@ -314,7 +314,7 @@ static struct pm_qos_request_list *pm_qos_handle_2;
static struct omap_rproc *sys_rproc;
static struct omap_rproc *app_rproc;
static struct omap_mbox *ducati_mbox;
-static struct iommu *ducati_iommu;
+static struct omap_iommu *ducati_iommu;
static bool first_time = 1;
/* BIOS flags states for each core in IPU */
@@ -584,8 +584,8 @@ static int ipu_pm_iommu_notifier_call(struct notifier_block *nb,
* restore IOMMU since it is required the IOMMU
* is up and running for reclaiming MMU entries
*/
- if (ipu_pm_get_state(SYS_M3) & SYS_PROC_DOWN)
- iommu_restore_ctx(ducati_iommu);
+// if (ipu_pm_get_state(SYS_M3) & SYS_PROC_DOWN)
+// iommu_restore_ctx(ducati_iommu);
return 0;
case IOMMU_FAULT:
ipu_pm_recover_schedule();
@@ -2503,10 +2503,10 @@ int ipu_pm_save_ctx(int proc_id)
omap_mbox_save_ctx(ducati_mbox);
else
pr_err("Not able to save mbox");
- if (ducati_iommu)
- iommu_save_ctx(ducati_iommu);
- else
- pr_err("Not able to save iommu");
+// if (ducati_iommu)
+// iommu_save_ctx(ducati_iommu);
+// else
+// pr_err("Not able to save iommu");
} else
goto error;
@@ -2592,10 +2592,10 @@ int ipu_pm_restore_ctx(int proc_id)
omap_mbox_restore_ctx(ducati_mbox);
else
pr_err("Not able to restore mbox");
- if (ducati_iommu)
- iommu_restore_ctx(ducati_iommu);
- else
- pr_err("Not able to restore iommu");
+// if (ducati_iommu)
+// iommu_restore_ctx(ducati_iommu);
+// else
+// pr_err("Not able to restore iommu");
pr_info("Wakeup SYSM3\n");
retval = rproc_wakeup(sys_rproc);
@@ -2927,8 +2927,8 @@ int ipu_pm_detach(u16 remote_proc_id)
* Restore iommu to allow process's iommu cleanup
* after ipu_pm is shutdown
*/
- if (ipu_pm_get_state(SYS_M3) & SYS_PROC_DOWN)
- iommu_restore_ctx(ducati_iommu);
+// if (ipu_pm_get_state(SYS_M3) & SYS_PROC_DOWN)
+// iommu_restore_ctx(ducati_iommu);
iommu_unregister_notifier(ducati_iommu,
&ipu_pm_notify_nb_iommu_ducati);
pr_debug("releasing ducati_iommu\n");
diff --git a/drivers/dsp/syslink/multicore_ipc/ipc_drv.c b/drivers/dsp/syslink/multicore_ipc/ipc_drv.c
index 23852f66f49..68dd747ac65 100644
--- a/drivers/dsp/syslink/multicore_ipc/ipc_drv.c
+++ b/drivers/dsp/syslink/multicore_ipc/ipc_drv.c
@@ -32,10 +32,11 @@
#include <notify_ioctl.h>
#include <nameserver.h>
#ifdef CONFIG_SYSLINK_RECOVERY
-#include <plat/iommu.h>
#include <plat/remoteproc.h>
#endif
+#include <plat/iommu.h>
+
#define IPC_NAME "syslink_ipc"
#define IPC_MAJOR 0
#define IPC_MINOR 0
@@ -76,7 +77,7 @@ static struct work_struct ipc_recovery_work;
static DECLARE_COMPLETION(ipc_comp);
static DECLARE_COMPLETION(ipc_open_comp);
static bool recover;
-static struct iommu *piommu;
+static struct omap_iommu *piommu;
static struct omap_rproc *prproc_sysm3;
static int ipc_ducati_iommu_notifier_call(struct notifier_block *nb,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index f68b5708a68..5569084c4fe 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -47,7 +47,7 @@ struct omap_iommu_domain {
};
/* accommodate the difference between omap1 and omap2/3 */
-static const struct iommu_functions *arch_iommu;
+static const struct omap_iommu_functions *arch_iommu;
static struct platform_driver omap_iommu_driver;
static struct kmem_cache *iopte_cachep;
@@ -59,7 +59,7 @@ static struct kmem_cache *iopte_cachep;
* There are several kind of iommu algorithm(tlb, pagetable) among
* omap series. This interface installs such an iommu algorighm.
**/
-int omap_install_iommu_arch(const struct iommu_functions *ops)
+int omap_install_iommu_arch(const struct omap_iommu_functions *ops)
{
if (arch_iommu)
return -EBUSY;
@@ -75,7 +75,7 @@ EXPORT_SYMBOL_GPL(omap_install_iommu_arch);
*
* This interface uninstalls the iommu algorighm installed previously.
**/
-void omap_uninstall_iommu_arch(const struct iommu_functions *ops)
+void omap_uninstall_iommu_arch(const struct omap_iommu_functions *ops)
{
if (arch_iommu != ops)
pr_err("%s: not your arch\n", __func__);
@@ -122,31 +122,42 @@ EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);
**/
u32 omap_iommu_arch_version(void)
{
- return arch_iommu->get_version(obj);
+ return arch_iommu->get_version(NULL);
}
EXPORT_SYMBOL_GPL(omap_iommu_arch_version);
-static int iommu_enable(struct omap_iommu *obj)
+int iommu_enable(struct omap_iommu *obj)
{
int err;
- if (!obj)
+ if (!obj) {
+ pr_err("iommu_enable: tried to enable NULL iommu\n");
return -EINVAL;
+ }
- if (!arch_iommu)
+ if (!arch_iommu) {
+ pr_err("iommu_enable: NULL arch_iommu\n");
return -ENODEV;
+ }
err = arch_iommu->enable(obj);
+ if (err)
+ pr_err("iommu_enable: arch_iommu->enable(obj) returned %d\n", err);
+
return err;
}
-static void iommu_disable(struct omap_iommu *obj)
+EXPORT_SYMBOL_GPL(iommu_enable);
+
+void iommu_disable(struct omap_iommu *obj)
{
if (!obj)
return;
arch_iommu->disable(obj);
}
+EXPORT_SYMBOL_GPL(iommu_disable);
+
/*
* TLB operations
*/
@@ -258,7 +269,7 @@ static struct cr_regs __iotlb_read_cr(struct omap_iommu *obj, int n)
* @e: an iommu tlb entry info
**/
#ifdef PREFETCH_IOTLB
-static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
+int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
{
int err = 0;
struct iotlb_lock l;
@@ -312,13 +323,15 @@ out:
#else /* !PREFETCH_IOTLB */
-static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
+int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
{
return 0;
}
#endif /* !PREFETCH_IOTLB */
+EXPORT_SYMBOL_GPL(load_iotlb_entry);
+
static int prefetch_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
{
return load_iotlb_entry(obj, e);
@@ -336,6 +349,10 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
int i;
struct cr_regs cr;
+ pr_err("flush_iotlb_page: obj=%p da=0x%x\n", obj, da);
+
+ WARN_ON(1);
+
for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
u32 start;
size_t bytes;
@@ -361,7 +378,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
* flush_iotlb_all - Clear all iommu tlb entries
* @obj: target iommu
**/
-static void flush_iotlb_all(struct omap_iommu *obj)
+void flush_iotlb_all(struct omap_iommu *obj)
{
struct iotlb_lock l;
@@ -381,7 +398,7 @@ EXPORT_SYMBOL_GPL(flush_iotlb_all);
* exclusively with locked TLB entries and receive notifications
* for TLB miss then call this function to disable TWL.
*/
-void iommu_set_twl(struct iommu *obj, bool on)
+void iommu_set_twl(struct omap_iommu *obj, bool on)
{
arch_iommu->set_twl(obj, on);
}
@@ -392,7 +409,7 @@ EXPORT_SYMBOL_GPL(iommu_set_twl);
* @obj: target iommu
*
*/
-u32 iommu_save_tlb_entries(struct iommu *obj)
+u32 iommu_save_tlb_entries(struct omap_iommu *obj)
{
int i;
struct cr_regs cr_tmp;
@@ -403,7 +420,7 @@ u32 iommu_save_tlb_entries(struct iommu *obj)
e = obj->tlbs_e;
for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr_tmp) {
- iotlb_cr_to_e(&cr_tmp, e);
+ omap_iotlb_cr_to_e(&cr_tmp, e);
dev_dbg(obj->dev, "%s: %08x %08x %d %d %d", __func__, e->da,
e->pa, e->pgsz, e->prsvd,
e->valid);
@@ -423,7 +440,7 @@ error:
* based on the e->valid value
*
*/
-u32 iommu_restore_tlb_entries(struct iommu *obj)
+u32 iommu_restore_tlb_entries(struct omap_iommu *obj)
{
int i;
int status;
@@ -696,6 +713,9 @@ int omap_iopgtable_store_entry(struct omap_iommu *obj, struct iotlb_entry *e)
{
int err;
+ BUG_ON(!obj);
+ BUG_ON(!e);
+
flush_iotlb_page(obj, e->da);
err = iopgtable_store_entry_core(obj, e);
if (!err)
@@ -780,7 +800,7 @@ out:
* @obj: target iommu
* @da: iommu device virtual address
**/
-static size_t iopgtable_clear_entry(struct omap_iommu *obj, u32 da)
+size_t iopgtable_clear_entry(struct omap_iommu *obj, u32 da)
{
size_t bytes;
@@ -794,6 +814,8 @@ static size_t iopgtable_clear_entry(struct omap_iommu *obj, u32 da)
return bytes;
}
+EXPORT_SYMBOL_GPL(iopgtable_clear_entry);
+
static void iopgtable_clear_entry_all(struct omap_iommu *obj)
{
int i;
@@ -823,7 +845,7 @@ static void iopgtable_clear_entry_all(struct omap_iommu *obj)
}
EXPORT_SYMBOL_GPL(iopgtable_clear_entry_all);
-void eventfd_notification(struct iommu *obj)
+void eventfd_notification(struct omap_iommu *obj)
{
struct iommu_event_ntfy *fd_reg;
@@ -831,12 +853,12 @@ void eventfd_notification(struct iommu *obj)
eventfd_signal(fd_reg->evt_ctx, 1);
}
-int iommu_notify_event(struct iommu *obj, int event, void *data)
+int iommu_notify_event(struct omap_iommu *obj, int event, void *data)
{
return raw_notifier_call_chain(&obj->notifier, event, data);
}
-int iommu_register_notifier(struct iommu *obj, struct notifier_block *nb)
+int iommu_register_notifier(struct omap_iommu *obj, struct notifier_block *nb)
{
if (!nb)
return -EINVAL;
@@ -844,7 +866,7 @@ int iommu_register_notifier(struct iommu *obj, struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(iommu_register_notifier);
-int iommu_unregister_notifier(struct iommu *obj, struct notifier_block *nb)
+int iommu_unregister_notifier(struct omap_iommu *obj, struct notifier_block *nb)
{
if (!nb)
return -EINVAL;
@@ -1001,10 +1023,8 @@ static void omap_iommu_detach(struct omap_iommu *obj)
static int __devinit omap_iommu_probe(struct platform_device *pdev)
{
int err = -ENODEV;
- int irq;
struct omap_iommu *obj;
- struct resource *res;
- struct iommu_platform_data *pdata = pdev->dev.platform_data;
+ struct omap_iommu_platform_data *pdata = pdev->dev.platform_data;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (!obj)
@@ -1048,9 +1068,8 @@ error:
static int __devexit omap_iommu_remove(struct platform_device *pdev)
{
- int irq;
- struct resource *res;
struct omap_iommu *obj = platform_get_drvdata(pdev);
+ struct omap_iommu_platform_data *pdata = pdev->dev.platform_data;
free_irq(pdata->irq, obj);