Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[linux-block.git] / drivers / remoteproc / remoteproc_core.c
index 2d2f3bab588852c37a19a895578146db88fa6511..e5279ed9a8d7c7ace6f396795833a0379762177a 100644 (file)
@@ -59,6 +59,7 @@ static int rproc_release_carveout(struct rproc *rproc,
 
 /* Unique indices for remoteproc devices */
 static DEFINE_IDA(rproc_dev_index);
+static struct workqueue_struct *rproc_recovery_wq;
 
 static const char * const rproc_crash_names[] = {
        [RPROC_MMUFAULT]        = "mmufault",
@@ -461,6 +462,7 @@ static void rproc_rvdev_release(struct device *dev)
        struct rproc_vdev *rvdev = container_of(dev, struct rproc_vdev, dev);
 
        of_reserved_mem_device_release(dev);
+       dma_release_coherent_memory(dev);
 
        kfree(rvdev);
 }
@@ -970,7 +972,7 @@ static int rproc_handle_carveout(struct rproc *rproc,
                return 0;
        }
 
-       /* Register carveout in in list */
+       /* Register carveout in list */
        carveout = rproc_mem_entry_init(dev, NULL, 0, rsc->len, rsc->da,
                                        rproc_alloc_carveout,
                                        rproc_release_carveout, rsc->name);
@@ -2434,7 +2436,7 @@ static void rproc_type_release(struct device *dev)
        idr_destroy(&rproc->notifyids);
 
        if (rproc->index >= 0)
-               ida_simple_remove(&rproc_dev_index, rproc->index);
+               ida_free(&rproc_dev_index, rproc->index);
 
        kfree_const(rproc->firmware);
        kfree_const(rproc->name);
@@ -2551,9 +2553,9 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
                goto put_device;
 
        /* Assign a unique device index and name */
-       rproc->index = ida_simple_get(&rproc_dev_index, 0, 0, GFP_KERNEL);
+       rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL);
        if (rproc->index < 0) {
-               dev_err(dev, "ida_simple_get failed: %d\n", rproc->index);
+               dev_err(dev, "ida_alloc failed: %d\n", rproc->index);
                goto put_device;
        }
 
@@ -2762,8 +2764,7 @@ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type)
        dev_err(&rproc->dev, "crash detected in %s: type %s\n",
                rproc->name, rproc_crash_to_string(type));
 
-       /* Have a worker handle the error; ensure system is not suspended */
-       queue_work(system_freezable_wq, &rproc->crash_handler);
+       queue_work(rproc_recovery_wq, &rproc->crash_handler);
 }
 EXPORT_SYMBOL(rproc_report_crash);
 
@@ -2812,6 +2813,13 @@ static void __exit rproc_exit_panic(void)
 
 static int __init remoteproc_init(void)
 {
+       rproc_recovery_wq = alloc_workqueue("rproc_recovery_wq",
+                                               WQ_UNBOUND | WQ_FREEZABLE, 0);
+       if (!rproc_recovery_wq) {
+               pr_err("remoteproc: creation of rproc_recovery_wq failed\n");
+               return -ENOMEM;
+       }
+
        rproc_init_sysfs();
        rproc_init_debugfs();
        rproc_init_cdev();
@@ -2825,9 +2833,13 @@ static void __exit remoteproc_exit(void)
 {
        ida_destroy(&rproc_dev_index);
 
+       if (!rproc_recovery_wq)
+               return;
+
        rproc_exit_panic();
        rproc_exit_debugfs();
        rproc_exit_sysfs();
+       destroy_workqueue(rproc_recovery_wq);
 }
 module_exit(remoteproc_exit);