diff options
author | Andy Green <andy.green@linaro.org> | 2011-12-16 13:11:58 +0800 |
---|---|---|
committer | Andy Green <andy.green@linaro.org> | 2012-01-09 08:39:42 +0800 |
commit | b4fa90cc4466f203f740a7b4d4d8577febaae96e (patch) | |
tree | 1fd24b7dc385e9851fa1119dc5853c637c36718d | |
parent | ff915b62294878722cf1d8032563ad4dbf22aa80 (diff) |
3.2 iommu uplevel fixes
Signed-off-by: Andy Green <andy.green@linaro.org>
-rw-r--r-- | arch/arm/mach-omap2/iommu2.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-iommu.c | 103 | ||||
-rw-r--r-- | arch/arm/plat-omap/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-omap/dmm_user.c | 28 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmm_user.h | 43 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/iommu.h | 48 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/iovmm.h | 7 | ||||
-rw-r--r-- | arch/arm/plat-omap/iodmm.c | 58 | ||||
-rw-r--r-- | drivers/dsp/syslink/devh/44xx/devh44xx.c | 2 | ||||
-rw-r--r-- | drivers/dsp/syslink/ipu_pm/ipu_pm.c | 26 | ||||
-rw-r--r-- | drivers/dsp/syslink/multicore_ipc/ipc_drv.c | 5 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 69 |
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); |