b/arch/arm/plat-omap/include/plat/mailbox.h
@@ -45,7 +45,6 @@ struct omap_mbox_queue {
struct request_queue *queue;
struct work_struct work;
struct tasklet_struct tasklet;
- int (*callback)(void *);
struct omap_mbox *mbox;
};
@@ -65,12 +64,14 @@ struct omap_mbox {
void *priv;
void (*err_notify)(void);
+ int (*callback)(void *);
+ atomic_t count;
};
int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
void omap_mbox_init_seq(struct omap_mbox *);
-struct omap_mbox *omap_mbox_get(const char *);
+struct omap_mbox *omap_mbox_get(const char *, int (*)(void *));
void omap_mbox_put(struct omap_mbox *);
int omap_mbox_register(struct device *parent, struct omap_mbox *);
@@ -33,8 +33,6 @@ static struct workqueue_struct *mboxd;
static struct omap_mbox *mboxes;
static DEFINE_RWLOCK(mboxes_lock);
-static int mbox_configured;
-
/* Mailbox FIFO handle functions */
static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
{
@@ -146,7 +144,7 @@ static void mbox_rx_work(struct work_struct *work)
msg = (mbox_msg_t)rq->special;
blk_end_request_all(rq, 0);
- mbox->rxq->callback((void *)msg);
+ mbox->callback((void *)msg);
}
}
@@ -249,16 +247,10 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
struct omap_mbox_queue *mq;
if (likely(mbox->ops->startup)) {
- write_lock(&mboxes_lock);
- if (!mbox_configured)
- ret = mbox->ops->startup(mbox);
-
+ ret = mbox->ops->startup(mbox);
if (unlikely(ret)) {
- write_unlock(&mboxes_lock);
return ret;
}
- mbox_configured++;
- write_unlock(&mboxes_lock);
}
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
@@ -304,13 +296,10 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
free_irq(mbox->irq, mbox);
if (unlikely(mbox->ops->shutdown)) {
- write_lock(&mboxes_lock);
- if (mbox_configured > 0)
- mbox_configured--;
- if (!mbox_configured)
- mbox->ops->shutdown(mbox);
- write_unlock(&mboxes_lock);
+ mbox->ops->shutdown(mbox);
}
+
+ atomic_dec(&mbox->count);
}
static struct omap_mbox **find_mboxes(const char *name)
@@ -325,7 +314,7 @@ static struct omap_mbox **find_mboxes(const char *name)
return p;
}
-struct omap_mbox *omap_mbox_get(const char *name)
+struct omap_mbox *omap_mbox_get(const char *name, int (*callback)(void *))
{
struct omap_mbox *mbox;
int ret;
@@ -339,9 +328,19 @@ struct omap_mbox *omap_mbox_get(const char *name)
read_unlock(&mboxes_lock);
+ if (atomic_inc_return(&mbox->count) > 1) {
+ pr_err("%s: mbox %s already in use\n", __func__, mbox->name);
+ atomic_dec(&mbox->count);
+ return ERR_PTR(-EBUSY);
+ }
+
ret = omap_mbox_startup(mbox);
- if (ret)
+ if (ret) {
+ atomic_dec(&mbox->count);
return ERR_PTR(-ENODEV);
+ }
+
+ mbox->callback = callback;
return mbox;
}
@@ -370,6 +369,9 @@ int omap_mbox_register(struct device *parent,
struct omap_mbox *mbox)
write_unlock(&mboxes_lock);
goto err_find;
}
+
+ atomic_set(&mbox->count, 0);
+
*tmp = mbox;
write_unlock