From patchwork Tue Jul 20 21:41:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kanigeri, Hari" X-Patchwork-Id: 113088 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6KLV1W6032136 for ; Tue, 20 Jul 2010 21:31:01 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754742Ab0GTVa7 (ORCPT ); Tue, 20 Jul 2010 17:30:59 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:46289 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752122Ab0GTVa6 (ORCPT ); Tue, 20 Jul 2010 17:30:58 -0400 Received: from dlep33.itg.ti.com ([157.170.170.112]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o6KLUtuD029418 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 20 Jul 2010 16:30:55 -0500 Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep33.itg.ti.com (8.13.7/8.13.7) with ESMTP id o6KLUsXR001656; Tue, 20 Jul 2010 16:30:54 -0500 (CDT) Received: from localhost (matrix.am.dhcp.ti.com [128.247.75.166]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id FBAG6ZP24219; Fri, 10 Dec 1915 11:06:35 -0500 (CDT) From: Hari Kanigeri To: Linux Omap , Tony Lindgren , Hiroshi DOYU Cc: Ohad Ben-Cohen , Hari Kanigeri Subject: [PATCH 2/2] omap:mailbox-provide multiple reader support Date: Tue, 20 Jul 2010 16:41:36 -0500 Message-Id: <1279662096-3121-3-git-send-email-h-kanigeri2@ti.com> X-Mailer: git-send-email 1.7.0 In-Reply-To: <1279662096-3121-1-git-send-email-h-kanigeri2@ti.com> References: <1279662096-3121-1-git-send-email-h-kanigeri2@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 20 Jul 2010 21:31:01 +0000 (UTC) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 0486d64..c8e47d8 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -68,13 +68,15 @@ struct omap_mbox { void *priv; void (*err_notify)(void); + atomic_t 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 *, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox *); int omap_mbox_unregister(struct omap_mbox *); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index baac315..f9f2af4 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work) if (unlikely(len != sizeof(msg))) pr_err("%s: kfifo_out anomaly detected\n", __func__); - if (mq->callback) - mq->callback((void *)msg); + blocking_notifier_call_chain(&mq->mbox->notifier, len, + (void *)msg); } } @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } } - ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED, - mbox->name, mbox); - if (unlikely(ret)) { - printk(KERN_ERR - "failed to register mailbox interrupt:%d\n", ret); - goto fail_request_irq; - } + if (atomic_inc_return(&mbox->use_count) == 1) { + ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED, + mbox->name, mbox); + if (unlikely(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; + 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; - return 0; fail_alloc_rxq: @@ -281,6 +283,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox) fail_alloc_txq: free_irq(mbox->irq, mbox); fail_request_irq: + atomic_dec(&mbox->use_count); if (likely(mbox->ops->shutdown)) { if (atomic_dec_return(&mbox_refcount) == 0) mbox->ops->shutdown(mbox); @@ -291,10 +294,12 @@ static int omap_mbox_startup(struct omap_mbox *mbox) static void omap_mbox_fini(struct omap_mbox *mbox) { - mbox_queue_free(mbox->txq); - mbox_queue_free(mbox->rxq); - free_irq(mbox->irq, mbox); + if (atomic_dec_return(&mbox->use_count) == 0) { + mbox_queue_free(mbox->txq); + mbox_queue_free(mbox->rxq); + free_irq(mbox->irq, mbox); + } if (likely(mbox->ops->shutdown)) { if (atomic_dec_return(&mbox_refcount) == 0) @@ -314,7 +319,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, struct notifier_block *nb) { struct omap_mbox *mbox; int ret; @@ -325,19 +330,21 @@ struct omap_mbox *omap_mbox_get(const char *name) spin_unlock(&mboxes_lock); return ERR_PTR(-ENOENT); } - spin_unlock(&mboxes_lock); ret = omap_mbox_startup(mbox); 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); @@ -361,6 +368,8 @@ int omap_mbox_register(struct device *parent, struct omap_mbox *mbox) } *tmp = mbox; spin_unlock(&mboxes_lock); + BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier); + atomic_set(&mbox->use_count, 0); return 0;