Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 226527
b: refs/heads/master
c: 5825630
h: refs/heads/master
i:
  226525: 0a42190
  226523: e6c896d
  226519: 238295c
  226511: 60256e9
  226495: 83194c9
v: v3
  • Loading branch information
Kanigeri, Hari committed Dec 2, 2010
1 parent e0b506d commit 90f2f7c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a42743c26a53a2a5f2b2018a9659ab3fb604d5bc
refs/heads/master: 582563074a691eb45cb22d2eca70eed8f2091c5f
7 changes: 4 additions & 3 deletions trunk/arch/arm/plat-omap/include/plat/mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ struct omap_mbox_queue {
struct kfifo fifo;
struct work_struct work;
struct tasklet_struct tasklet;
int (*callback)(void *);
struct omap_mbox *mbox;
bool full;
};
Expand All @@ -58,13 +57,15 @@ struct omap_mbox {
struct omap_mbox_ops *ops;
struct device *dev;
void *priv;
int use_count;
struct blocking_notifier_head notifier;
};

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 *);
void omap_mbox_put(struct omap_mbox *);
struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);

int omap_mbox_register(struct device *parent, struct omap_mbox **);
int omap_mbox_unregister(void);
Expand Down
103 changes: 57 additions & 46 deletions trunk/arch/arm/plat-omap/mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/kfifo.h>
#include <linux/err.h>
#include <linux/notifier.h>

#include <plat/mailbox.h>

Expand Down Expand Up @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work)
len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
WARN_ON(len != sizeof(msg));

if (mq->callback)
mq->callback((void *)msg);
blocking_notifier_call_chain(&mq->mbox->notifier, len,
(void *)msg);
spin_lock_irq(&mq->lock);
if (mq->full) {
mq->full = false;
Expand Down Expand Up @@ -249,41 +250,40 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
int ret = 0;
struct omap_mbox_queue *mq;

if (mbox->ops->startup) {
mutex_lock(&mbox_configured_lock);
if (!mbox_configured)
mutex_lock(&mbox_configured_lock);
if (!mbox_configured++) {
if (likely(mbox->ops->startup)) {
ret = mbox->ops->startup(mbox);

if (ret) {
mutex_unlock(&mbox_configured_lock);
return ret;
}
mbox_configured++;
mutex_unlock(&mbox_configured_lock);
if (unlikely(ret))
goto fail_startup;
} else
goto fail_startup;
}

ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
mbox->name, mbox);
if (ret) {
printk(KERN_ERR
"failed to register mailbox interrupt:%d\n", ret);
goto fail_request_irq;
}

mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
if (!mq) {
ret = -ENOMEM;
goto fail_alloc_txq;
}
mbox->txq = mq;
if (!mbox->use_count++) {
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
mbox->name, mbox);
if (unlikely(ret)) {
pr_err("failed to register mailbox interrupt:%d\n",
ret);
goto fail_request_irq;
}
mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
if (!mq) {
ret = -ENOMEM;
goto fail_alloc_txq;
}
mbox->txq = mq;

mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
if (!mq) {
ret = -ENOMEM;
goto fail_alloc_rxq;
mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
if (!mq) {
ret = -ENOMEM;
goto fail_alloc_rxq;
}
mbox->rxq = mq;
mq->mbox = mbox;
}
mbox->rxq = mq;

mutex_unlock(&mbox_configured_lock);
return 0;

fail_alloc_rxq:
Expand All @@ -293,29 +293,34 @@ static int omap_mbox_startup(struct omap_mbox *mbox)
fail_request_irq:
if (mbox->ops->shutdown)
mbox->ops->shutdown(mbox);

mbox->use_count--;
fail_startup:
mbox_configured--;
mutex_unlock(&mbox_configured_lock);
return ret;
}

static void omap_mbox_fini(struct omap_mbox *mbox)
{
free_irq(mbox->irq, mbox);
tasklet_kill(&mbox->txq->tasklet);
flush_work(&mbox->rxq->work);
mbox_queue_free(mbox->txq);
mbox_queue_free(mbox->rxq);
mutex_lock(&mbox_configured_lock);

if (!--mbox->use_count) {
free_irq(mbox->irq, mbox);
tasklet_kill(&mbox->txq->tasklet);
flush_work(&mbox->rxq->work);
mbox_queue_free(mbox->txq);
mbox_queue_free(mbox->rxq);
}

if (mbox->ops->shutdown) {
mutex_lock(&mbox_configured_lock);
if (mbox_configured > 0)
mbox_configured--;
if (!mbox_configured)
if (likely(mbox->ops->shutdown)) {
if (!--mbox_configured)
mbox->ops->shutdown(mbox);
mutex_unlock(&mbox_configured_lock);
}

mutex_unlock(&mbox_configured_lock);
}

struct omap_mbox *omap_mbox_get(const char *name)
struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
{
struct omap_mbox *mbox;
int ret;
Expand All @@ -334,12 +339,16 @@ struct omap_mbox *omap_mbox_get(const char *name)
if (ret)
return ERR_PTR(-ENODEV);

if (nb)
blocking_notifier_chain_register(&mbox->notifier, nb);

return mbox;
}
EXPORT_SYMBOL(omap_mbox_get);

void omap_mbox_put(struct omap_mbox *mbox)
void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
{
blocking_notifier_chain_unregister(&mbox->notifier, nb);
omap_mbox_fini(mbox);
}
EXPORT_SYMBOL(omap_mbox_put);
Expand All @@ -363,6 +372,8 @@ int omap_mbox_register(struct device *parent, struct omap_mbox **list)
ret = PTR_ERR(mbox->dev);
goto err_out;
}

BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
}
return 0;

Expand Down

0 comments on commit 90f2f7c

Please sign in to comment.