aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorLuden <luden@ghostmail.com>2016-01-30 01:07:26 +0100
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:54 +0200
commit0ff6b8dd50f90858213cca674a1865b2b6c7391f (patch)
tree530eb344e15c1102e9750d91f6d6f4d69d27d85c /arch/arm/plat-omap
parent980a74e2c46a5f8b8ae8ef4e73dbcc4bf26443b9 (diff)
downloadkernel_samsung_tuna-0ff6b8dd50f90858213cca674a1865b2b6c7391f.zip
kernel_samsung_tuna-0ff6b8dd50f90858213cca674a1865b2b6c7391f.tar.gz
kernel_samsung_tuna-0ff6b8dd50f90858213cca674a1865b2b6c7391f.tar.bz2
OMAP: switch Ducati allocations to CMA
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/omap_rpmsg.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/arch/arm/plat-omap/omap_rpmsg.c b/arch/arm/plat-omap/omap_rpmsg.c
index 8ece479..f4bc0ea 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);