aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xarch/arm/mach-omap2/board-tuna.c3
-rwxr-xr-xarch/arm/mach-omap2/omap4_ion.c136
-rw-r--r--arch/arm/plat-omap/omap_rpmsg.c59
-rw-r--r--drivers/remoteproc/omap_remoteproc.c21
-rwxr-xr-xdrivers/remoteproc/remoteproc.c84
-rw-r--r--include/linux/omap_ion.h6
-rw-r--r--include/linux/remoteproc.h2
-rw-r--r--include/linux/rpmsg.h1
8 files changed, 286 insertions, 26 deletions
diff --git a/arch/arm/mach-omap2/board-tuna.c b/arch/arm/mach-omap2/board-tuna.c
index 3f0cbac6049..43aaf6f38e7 100755
--- a/arch/arm/mach-omap2/board-tuna.c
+++ b/arch/arm/mach-omap2/board-tuna.c
@@ -1401,10 +1401,11 @@ static void __init tuna_reserve(void)
omap_ram_console_init(OMAP_RAM_CONSOLE_START_DEFAULT,
OMAP_RAM_CONSOLE_SIZE_DEFAULT);
-
+#ifndef CONFIG_CMA
/* do the static reservations first */
memblock_remove(PHYS_ADDR_SMC_MEM, PHYS_ADDR_SMC_SIZE);
memblock_remove(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE);
+#endif
/* ipu needs to recognize secure input buffer area as well */
omap_ipu_set_static_mempool(PHYS_ADDR_DUCATI_MEM,
diff --git a/arch/arm/mach-omap2/omap4_ion.c b/arch/arm/mach-omap2/omap4_ion.c
index e5910204e53..2840c427310 100755
--- a/arch/arm/mach-omap2/omap4_ion.c
+++ b/arch/arm/mach-omap2/omap4_ion.c
@@ -14,6 +14,9 @@
#include <linux/memblock.h>
#include <linux/omap_ion.h>
#include <linux/platform_device.h>
+#ifdef CONFIG_CMA
+#include <linux/dma-contiguous.h>
+#endif
#include <plat/common.h>
#include <mach/omap4_ion.h>
@@ -46,6 +49,20 @@ static size_t omap4_ducati_heap_size;
static size_t omap4_ion_heap_tiler_mem_size;
static size_t omap4_ion_heap_nonsec_tiler_mem_size;
+#ifdef CONFIG_CMA
+static phys_addr_t omap4_ion_ipu_cma_addr;
+static size_t omap4_ion_ipu_cma_pages_count;
+static struct page* omap4_ion_ipu_cma_pages;
+
+/* See RPMSG_IPC_MEM calculation in arch/arm/plat-omap/omap_rpmsg.c */
+#define CMA_RPMSG_ADDR ((phys_addr_t)0xb3a00000)
+#define CMA_RPMSG_SIZE ((size_t)0x8c000)
+
+static phys_addr_t omap4_ion_rpmsg_cma_addr;
+static size_t omap4_ion_rpmsg_cma_pages_count;
+static struct page* omap4_ion_rpmsg_cma_pages;
+#endif
+
static struct ion_platform_data omap4_ion_data = {
.nr = 6,
.heaps = {
@@ -105,11 +122,16 @@ void __init omap4_register_ion(void)
void __init omap_ion_init(void)
{
- int i;
- int ret;
+ int i, ret = 0;
#ifndef CONFIG_ION_OMAP_TILER_DYNAMIC_ALLOC
u32 nonsecure = omap4_ion_pdata.nonsecure_tiler2d_size;
#endif
+#ifdef CONFIG_CMA
+ size_t ipu_cma_pages_count;
+ phys_addr_t cma_area_addr;
+ size_t cma_area_size;
+ const size_t cma_alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order);
+#endif
system_512m = (omap_total_ram_size() == SZ_512M);
@@ -192,6 +214,37 @@ void __init omap_ion_init(void)
omap4_ion_heap_tiler_mem_addr,
omap4_ion_heap_nonsec_tiler_mem_addr);
+#ifdef CONFIG_CMA
+ ipu_cma_pages_count = (omap4_ion_heap_secure_input_size +
+ omap4_ion_heap_secure_output_wfdhdcp_size +
+ omap4_ducati_heap_size +
+ omap4_ion_heap_nonsec_tiler_mem_size +
+ omap4_ion_heap_tiler_mem_size) / PAGE_SIZE;
+
+ cma_area_addr = round_down(omap4_ion_heap_nonsec_tiler_mem_addr, cma_alignment);
+ cma_area_size = round_up(ipu_cma_pages_count * PAGE_SIZE, cma_alignment);
+
+ pr_info("Reserving CMA IPU + RPMSG region at address = 0x%x with size = 0x%x\n",
+ cma_area_addr, cma_area_size);
+ dma_declare_contiguous(&omap4_ion_device.dev, cma_area_size, cma_area_addr, 0);
+
+ /* We need to separate RPMSG memory region from the overall Ducati range
+ * as it has to remain allocated even when the rest of Ducati is unloaded.
+ * Therefore, IPU carveout area is split into two pieces - below and above
+ * RPMSG region. */
+ omap4_ion_ipu_cma_addr = CMA_RPMSG_ADDR + CMA_RPMSG_SIZE;
+ omap4_ion_ipu_cma_pages_count = ipu_cma_pages_count - CMA_RPMSG_SIZE / PAGE_SIZE;
+
+ omap4_ion_rpmsg_cma_addr = CMA_RPMSG_ADDR;
+ omap4_ion_rpmsg_cma_pages_count = CMA_RPMSG_SIZE / PAGE_SIZE;
+
+ pr_info("CMA RPMSG region: address = 0x%x, size = 0x%lx\n", omap4_ion_rpmsg_cma_addr, omap4_ion_rpmsg_cma_pages_count * PAGE_SIZE);
+ pr_info("CMA IPU region: address = 0x%x, size = 0x%lx\n", omap4_ion_ipu_cma_addr, omap4_ion_ipu_cma_pages_count * PAGE_SIZE);
+
+ omap4_ion_ipu_cma_pages = NULL;
+ omap4_ion_rpmsg_cma_pages = NULL;
+#endif
+
for (i = 0; i < omap4_ion_data.nr; i++) {
struct ion_platform_heap *h = &omap4_ion_data.heaps[i];
@@ -223,8 +276,10 @@ void __init omap_ion_init(void)
for (i = 0; i < omap4_ion_data.nr; i++)
if (omap4_ion_data.heaps[i].type == ION_HEAP_TYPE_CARVEOUT ||
omap4_ion_data.heaps[i].type == OMAP_ION_HEAP_TYPE_TILER) {
+#ifndef CONFIG_CMA
ret = memblock_remove(omap4_ion_data.heaps[i].base,
omap4_ion_data.heaps[i].size);
+#endif
if (!omap4_ion_data.heaps[i].size)
continue;
if (omap4_ion_data.heaps[i].id ==
@@ -300,3 +355,80 @@ size_t omap_ion_heap_nonsec_tiler_mem_size(void)
{
return omap4_ion_heap_nonsec_tiler_mem_size;
}
+
+#ifdef CONFIG_CMA
+bool omap_ion_ipu_allocate_memory(void)
+{
+ if (omap4_ion_ipu_cma_pages) {
+ pr_err("%s: CMA IPU pages are already allocated\n", __func__);
+ return false;
+ }
+
+ omap4_ion_ipu_cma_pages = dma_alloc_from_contiguous_fixed_addr(&omap4_ion_device.dev,
+ omap4_ion_ipu_cma_addr, omap4_ion_ipu_cma_pages_count);
+
+ if (!omap4_ion_ipu_cma_pages) {
+ pr_err("CMA IPU region pages allocation failed\n");
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(omap_ion_ipu_allocate_memory);
+
+bool omap_ion_ipu_free_memory(void)
+{
+ if (!omap4_ion_ipu_cma_pages) {
+ pr_err("%s: CMA IPU pages are not allocated\n", __func__);
+ return false;
+ }
+
+ if (!dma_release_from_contiguous(&omap4_ion_device.dev, omap4_ion_ipu_cma_pages,
+ omap4_ion_ipu_cma_pages_count)) {
+ pr_err("CMA IPU region pages release failed\n");
+ return false;
+ }
+
+ omap4_ion_ipu_cma_pages = NULL;
+
+ return true;
+}
+EXPORT_SYMBOL(omap_ion_ipu_free_memory);
+
+bool omap_ion_rpmsg_allocate_memory(void)
+{
+ if (omap4_ion_rpmsg_cma_pages) {
+ pr_err("CMA RPMSG pages are already allocated\n");
+ return false;
+ }
+
+ omap4_ion_rpmsg_cma_pages = dma_alloc_from_contiguous_fixed_addr(&omap4_ion_device.dev,
+ omap4_ion_rpmsg_cma_addr, omap4_ion_rpmsg_cma_pages_count);
+ if (!omap4_ion_rpmsg_cma_pages) {
+ pr_err("CMA RPMSG region pages allocation failed\n");
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(omap_ion_rpmsg_allocate_memory);
+
+bool omap_ion_rpmsg_free_memory(void)
+{
+ if (!omap4_ion_rpmsg_cma_pages) {
+ pr_err("CMA RPMSG pages are not allocated\n");
+ return false;
+ }
+
+ if (!dma_release_from_contiguous(&omap4_ion_device.dev, omap4_ion_rpmsg_cma_pages,
+ omap4_ion_rpmsg_cma_pages_count)) {
+ pr_err("CMA RPMSG region pages release failed\n");
+ return false;
+ }
+
+ omap4_ion_rpmsg_cma_pages = NULL;
+
+ return true;
+}
+EXPORT_SYMBOL(omap_ion_rpmsg_free_memory);
+#endif
diff --git a/arch/arm/plat-omap/omap_rpmsg.c b/arch/arm/plat-omap/omap_rpmsg.c
index 8ece47954ff..f4bc0eabe32 100644
--- a/arch/arm/plat-omap/omap_rpmsg.c
+++ b/arch/arm/plat-omap/omap_rpmsg.c
@@ -33,6 +33,8 @@
#include <linux/memblock.h>
#include <linux/remoteproc.h>
#include <linux/delay.h>
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
#include <asm/io.h>
@@ -53,7 +55,7 @@ struct omap_rpmsg_vproc {
struct rproc *rproc;
struct notifier_block nb;
struct notifier_block rproc_nb;
- struct work_struct reset_work;
+ struct work_struct reset_work, reset_keep_rproc_work;
bool slave_reset;
struct omap_rpmsg_vproc *slave_next;
struct virtqueue *vq[2];
@@ -497,17 +499,19 @@ static void omap_rpmsg_vproc_release(struct device *dev)
/* this handler is provided so driver core doesn't yell at us */
}
-static void rpmsg_reset_work(struct work_struct *work)
+static void rpmsg_unregister_devices(struct omap_rpmsg_vproc *rpdev)
{
- struct omap_rpmsg_vproc *rpdev =
- container_of(work, struct omap_rpmsg_vproc, reset_work);
struct omap_rpmsg_vproc *tmp;
- int ret;
-
for (tmp = rpdev; tmp; tmp = tmp->slave_next) {
pr_err("reseting virtio device %d\n", tmp->vdev.index);
unregister_virtio_device(&tmp->vdev);
}
+}
+
+static void rpmsg_register_devices(struct omap_rpmsg_vproc *rpdev)
+{
+ struct omap_rpmsg_vproc *tmp;
+ int ret;
for (tmp = rpdev; tmp; tmp = tmp->slave_next) {
memset(&tmp->vdev.dev, 0, sizeof(struct device));
tmp->vdev.dev.release = omap_rpmsg_vproc_release;
@@ -517,6 +521,26 @@ static void rpmsg_reset_work(struct work_struct *work)
}
}
+static void rpmsg_reset_work(struct work_struct *work)
+{
+ struct omap_rpmsg_vproc *rpdev =
+ container_of(work, struct omap_rpmsg_vproc, reset_work);
+ rpmsg_unregister_devices(rpdev);
+ rpmsg_register_devices(rpdev);
+}
+
+static void rpmsg_reset_keep_rproc_work(struct work_struct *work)
+{
+ struct omap_rpmsg_vproc *rpdev =
+ container_of(work, struct omap_rpmsg_vproc, reset_keep_rproc_work);
+ /* Ensure there's extra reference to rproc so that
+ * we don't trigger unload of the firmware. */
+ rproc_get(rpdev->rproc->name);
+ rpmsg_unregister_devices(rpdev);
+ rpmsg_register_devices(rpdev);
+ rproc_put(rpdev->rproc);
+}
+
static struct virtio_config_ops omap_rpmsg_config_ops = {
.get_features = omap_rpmsg_get_features,
.finalize_features = omap_rpmsg_finalize_features,
@@ -562,6 +586,18 @@ static struct omap_rpmsg_vproc omap_rpmsg_vprocs[] = {
},
};
+void rpmsg_reset_all_devices(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(omap_rpmsg_vprocs); i++) {
+ struct omap_rpmsg_vproc *rpdev = &omap_rpmsg_vprocs[i];
+ if (!rpdev->slave_reset) {
+ flush_work_sync(&rpdev->reset_keep_rproc_work);
+ schedule_work(&rpdev->reset_keep_rproc_work);
+ }
+ }
+}
+
static int __init omap_rpmsg_ini(void)
{
int i, ret = 0;
@@ -570,6 +606,12 @@ static int __init omap_rpmsg_ini(void)
phys_addr_t psize = omap_ipu_get_mempool_size(
OMAP_RPROC_MEMPOOL_STATIC);
+#ifdef CONFIG_CMA
+ if (!omap_ion_rpmsg_allocate_memory()) {
+ return -ENOMEM;
+ }
+#endif
+
for (i = 0; i < ARRAY_SIZE(omap_rpmsg_vprocs); i++) {
struct omap_rpmsg_vproc *rpdev = &omap_rpmsg_vprocs[i];
@@ -587,6 +629,7 @@ static int __init omap_rpmsg_ini(void)
rpdev->vring[0] = paddr + RPMSG_BUFS_SPACE;
rpdev->vring[1] = paddr + RPMSG_BUFS_SPACE + RPMSG_RING_SIZE;
INIT_WORK(&rpdev->reset_work, rpmsg_reset_work);
+ INIT_WORK(&rpdev->reset_keep_rproc_work, rpmsg_reset_keep_rproc_work);
paddr += RPMSG_IPC_MEM;
psize -= RPMSG_IPC_MEM;
@@ -616,6 +659,10 @@ static void __exit omap_rpmsg_fini(void)
unregister_virtio_device(&rpdev->vdev);
}
+
+#ifdef CONFIG_CMA
+ omap_ion_rpmsg_free_memory();
+#endif
}
module_exit(omap_rpmsg_fini);
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index 7c10c79501e..cc62ef61ebc 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -479,6 +479,9 @@ static inline int omap_rproc_start(struct rproc *rproc, u64 bootaddr)
}
ret = omap_device_enable(pdev);
+ if (ret) {
+ dev_err(rproc->dev, "failed to enable device: %d\n", ret);
+ }
out:
if (ret) {
while (i--) {
@@ -507,10 +510,16 @@ static int omap_rproc_iommu_exit(struct rproc *rproc)
return 0;
}
+static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
+{
+ return container_of(pdev, struct omap_device, pdev);
+}
+
static inline int omap_rproc_stop(struct rproc *rproc)
{
struct device *dev = rproc->dev;
struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od = _find_by_pdev(pdev);
struct omap_rproc_pdata *pdata = dev->platform_data;
struct omap_rproc_timers_info *timers = pdata->timers;
int ret, i;
@@ -526,9 +535,15 @@ static inline int omap_rproc_stop(struct rproc *rproc)
rproc->secure_reset = false;
}
- ret = omap_device_idle(pdev);
- if (ret)
- goto err;
+ /* We might be called from the suspended state,
+ * in that case we shouldn't try to call omap_device_idle(). */
+ if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+ ret = omap_device_idle(pdev);
+ if (ret)
+ goto err;
+ } else {
+ ret = 0;
+ }
for (i = 0; i < pdata->timers_cnt; i++) {
#ifdef CONFIG_REMOTEPROC_WATCHDOG
diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c
index 65d2c79ce06..939274c434e 100755
--- a/drivers/remoteproc/remoteproc.c
+++ b/drivers/remoteproc/remoteproc.c
@@ -35,11 +35,14 @@
#include <linux/list.h>
#include <linux/debugfs.h>
#include <linux/remoteproc.h>
+#include <linux/rpmsg.h>
#include <linux/pm_runtime.h>
#include <linux/uaccess.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <plat/remoteproc.h>
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
/* list of available remote processors on this board */
static LIST_HEAD(rprocs);
@@ -1261,7 +1264,7 @@ int rproc_error_notify(struct rproc *rproc)
}
EXPORT_SYMBOL_GPL(rproc_error_notify);
-struct rproc *rproc_get(const char *name)
+static struct rproc *_rproc_get(const char *name, bool use_refcounting)
{
struct rproc *rproc, *ret = NULL;
struct device *dev;
@@ -1297,7 +1300,13 @@ struct rproc *rproc_get(const char *name)
}
/* bail if rproc is already powered up */
- if (rproc->count++) {
+ if (use_refcounting && rproc->count++) {
+ ret = rproc;
+ goto unlock_mutex;
+ }
+
+ if (use_refcounting && rproc->state != RPROC_OFFLINE) {
+ dev_info(dev, "redundant rproc restart request, ignoring\n");
ret = rproc;
goto unlock_mutex;
}
@@ -1305,6 +1314,13 @@ struct rproc *rproc_get(const char *name)
/* rproc_put() calls should wait until async loader completes */
init_completion(&rproc->firmware_loading_complete);
+#ifdef CONFIG_CMA
+ if (!omap_ion_ipu_allocate_memory()) {
+ ret = NULL;
+ goto unlock_mutex;
+ }
+#endif
+
dev_info(dev, "powering up %s\n", name);
err = rproc_loader(rproc);
@@ -1312,7 +1328,7 @@ struct rproc *rproc_get(const char *name)
dev_err(dev, "failed to load rproc %s\n", rproc->name);
complete_all(&rproc->firmware_loading_complete);
module_put(rproc->owner);
- --rproc->count;
+ rproc->count -= (use_refcounting ? 1 : 0);
goto unlock_mutex;
}
@@ -1323,9 +1339,14 @@ unlock_mutex:
mutex_unlock(&rproc->lock);
return ret;
}
+
+struct rproc *rproc_get(const char *name)
+{
+ return _rproc_get(name, true);
+}
EXPORT_SYMBOL_GPL(rproc_get);
-void rproc_put(struct rproc *rproc)
+static void _rproc_put(struct rproc *rproc, bool use_refcounting)
{
struct device *dev = rproc->dev;
int ret;
@@ -1339,14 +1360,14 @@ void rproc_put(struct rproc *rproc)
return;
}
- if (!rproc->count) {
+ if (use_refcounting && !rproc->count) {
dev_warn(dev, "asymmetric rproc_put\n");
ret = -EINVAL;
goto out;
}
/* if the remote proc is still needed, bail out */
- if (--rproc->count)
+ if (use_refcounting && --rproc->count)
goto out;
if (mutex_lock_interruptible(&rproc->tlock))
@@ -1380,13 +1401,15 @@ void rproc_put(struct rproc *rproc)
*/
if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_LOADING) {
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
- /*
- * Call resume, it will cancel any pending autosuspend,
- * so that no callback is executed after the device is stopped.
- * Device stop function takes care of shutting down the device.
- */
- pm_runtime_get_sync(rproc->dev);
- pm_runtime_put_noidle(rproc->dev);
+ if (use_refcounting) {
+ /*
+ * Call resume, it will cancel any pending autosuspend,
+ * so that no callback is executed after the device is stopped.
+ * Device stop function takes care of shutting down the device.
+ */
+ pm_runtime_get_sync(rproc->dev);
+ pm_runtime_put_noidle(rproc->dev);
+ }
if (!rproc->secure_reset)
pm_runtime_disable(rproc->dev);
@@ -1423,11 +1446,19 @@ void rproc_put(struct rproc *rproc)
dev_info(dev, "stopped remote processor %s\n", rproc->name);
+#ifdef CONFIG_CMA
+ omap_ion_ipu_free_memory();
+#endif
+
out:
mutex_unlock(&rproc->lock);
if (!ret)
module_put(rproc->owner);
}
+void rproc_put(struct rproc *rproc)
+{
+ return _rproc_put(rproc, true);
+}
EXPORT_SYMBOL_GPL(rproc_put);
static void rproc_error_work(struct work_struct *work)
@@ -1450,6 +1481,8 @@ int rproc_event_unregister(struct rproc *rproc, struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(rproc_event_unregister);
+static int rproc_runtime_resume(struct device *dev);
+
void rproc_last_busy(struct rproc *rproc)
{
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
@@ -1471,6 +1504,11 @@ void rproc_last_busy(struct rproc *rproc)
mutex_unlock(&rproc->lock);
return;
}
+ if (rproc->state == RPROC_OFFLINE) {
+ mutex_unlock(&rproc->lock);
+ rproc_runtime_resume(dev);
+ return;
+ }
mutex_unlock(&rproc->lock);
pm_runtime_get_sync(dev);
pm_runtime_mark_last_busy(dev);
@@ -1556,6 +1594,12 @@ out:
return ret;
}
+static void rproc_unload_work(struct work_struct *work)
+{
+ struct rproc *rproc = container_of(work, struct rproc, unload_work);
+ _rproc_put(rproc, false);
+}
+
static int rproc_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1564,6 +1608,12 @@ static int rproc_runtime_resume(struct device *dev)
dev_dbg(dev, "Enter %s\n", __func__);
+ if (rproc->state == RPROC_OFFLINE) {
+ dev_info(dev, "rproc_runtime_resume in RPROC_OFFLINE mode - waking up.\n");
+ _rproc_get(rproc->name, false);
+ rpmsg_reset_all_devices();
+ }
+
if (rproc->ops->resume)
ret = rproc->ops->resume(rproc);
@@ -1628,6 +1678,11 @@ static int rproc_runtime_suspend(struct device *dev)
_event_notify(rproc, RPROC_POS_SUSPEND, NULL);
mutex_unlock(&rproc->pm_lock);
+#ifdef CONFIG_CMA
+ /* Unload firmware and free memory */
+ schedule_work(&rproc->unload_work);
+#endif
+
return 0;
abort:
pm_runtime_mark_last_busy(dev);
@@ -1721,6 +1776,9 @@ int rproc_register(struct device *dev, const char *name,
mutex_init(&rproc->secure_lock);
mutex_init(&rproc->tlock);
INIT_WORK(&rproc->error_work, rproc_error_work);
+#ifdef CONFIG_CMA
+ INIT_WORK(&rproc->unload_work, rproc_unload_work);
+#endif
BLOCKING_INIT_NOTIFIER_HEAD(&rproc->nbh);
rproc->state = RPROC_OFFLINE;
diff --git a/include/linux/omap_ion.h b/include/linux/omap_ion.h
index 81c73e2f6c1..2fd3a094cc6 100644
--- a/include/linux/omap_ion.h
+++ b/include/linux/omap_ion.h
@@ -56,6 +56,12 @@ int omap_ion_share_fd_to_buffers(int fd, struct ion_buffer **buffers,
int omap_tiler_vinfo(struct ion_client *client,
struct ion_handle *handle, unsigned int *vstride,
unsigned int *vsize);
+#ifdef CONFIG_CMA
+bool omap_ion_ipu_allocate_memory(void);
+bool omap_ion_ipu_free_memory(void);
+bool omap_ion_rpmsg_allocate_memory(void);
+bool omap_ion_rpmsg_free_memory(void);
+#endif
#endif /* __KERNEL__ */
/* additional heaps used only on omap */
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index cd0105da6a8..d8ca8262f87 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -270,7 +270,7 @@ struct rproc {
int cdump_len0, cdump_len1;
struct mutex tlock;
struct completion firmware_loading_complete;
- struct work_struct error_work;
+ struct work_struct error_work, unload_work;
struct blocking_notifier_head nbh;
struct completion error_comp;
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
index 1f7ba091c50..4bc3abc85f0 100644
--- a/include/linux/rpmsg.h
+++ b/include/linux/rpmsg.h
@@ -146,6 +146,7 @@ void rpmsg_destroy_ept(struct rpmsg_endpoint *);
struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *,
void (*cb)(struct rpmsg_channel *, void *, int, void *, u32),
void *priv, u32 addr);
+void rpmsg_reset_all_devices(void);
int
rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool);