aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/omap_rpmsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/omap_rpmsg.c')
-rw-r--r--arch/arm/plat-omap/omap_rpmsg.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/arm/plat-omap/omap_rpmsg.c b/arch/arm/plat-omap/omap_rpmsg.c
index 3653833..269f206 100644
--- a/arch/arm/plat-omap/omap_rpmsg.c
+++ b/arch/arm/plat-omap/omap_rpmsg.c
@@ -47,6 +47,7 @@ struct omap_rpmsg_vproc {
char *mbox_name;
char *rproc_name;
struct omap_mbox *mbox;
+ struct mutex lock;
struct rproc *rproc;
struct notifier_block nb;
struct notifier_block rproc_nb;
@@ -145,13 +146,25 @@ static void omap_rpmsg_notify(struct virtqueue *vq)
{
struct omap_rpmsg_vq_info *rpvq = vq->priv;
int ret;
+ int count = 5;
pr_debug("sending mailbox msg: %d\n", rpvq->vq_id);
- rproc_last_busy(rpvq->rpdev->rproc);
+ do {
+ rproc_last_busy(rpvq->rpdev->rproc);
+ mutex_lock(&rpvq->rpdev->lock);
+ if (rpvq->rpdev->mbox)
+ break;
+ mutex_unlock(&rpvq->rpdev->lock);
+ } while (--count);
+ if (!count) {
+ pr_err("mbox handle is NULL\n");
+ return;
+ }
/* send the index of the triggered virtqueue as the mailbox payload */
ret = omap_mbox_msg_send(rpvq->rpdev->mbox, rpvq->vq_id);
if (ret)
pr_err("ugh, omap_mbox_msg_send() failed: %d\n", ret);
+ mutex_unlock(&rpvq->rpdev->lock);
}
static int omap_rpmsg_mbox_callback(struct notifier_block *this,
@@ -228,18 +241,22 @@ static int rpmsg_rproc_suspend(struct omap_rpmsg_vproc *rpdev)
static int rpmsg_rproc_pos_suspend(struct omap_rpmsg_vproc *rpdev)
{
+ mutex_lock(&rpdev->lock);
if (rpdev->mbox) {
omap_mbox_put(rpdev->mbox, &rpdev->nb);
rpdev->mbox = NULL;
}
+ mutex_unlock(&rpdev->lock);
return NOTIFY_DONE;
}
static int rpmsg_rproc_resume(struct omap_rpmsg_vproc *rpdev)
{
+ mutex_lock(&rpdev->lock);
if (!rpdev->mbox)
rpdev->mbox = omap_mbox_get(rpdev->mbox_name, &rpdev->nb);
+ mutex_unlock(&rpdev->lock);
return NOTIFY_DONE;
}
@@ -315,6 +332,7 @@ static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
/* system-wide unique id for this virtqueue */
rpvq->vq_id = rpdev->base_vq_id + index;
rpvq->rpdev = rpdev;
+ mutex_init(&rpdev->lock);
return vq;