diff options
Diffstat (limited to 'arch/arm/plat-omap/mailbox.c')
-rw-r--r-- | arch/arm/plat-omap/mailbox.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 69ddc9f..653153e 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -29,6 +29,7 @@ #include <linux/kfifo.h> #include <linux/err.h> #include <linux/notifier.h> +#include <linux/pm_qos_params.h> #include <plat/mailbox.h> @@ -36,6 +37,10 @@ static struct omap_mbox **mboxes; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); +struct pm_qos_request_list mbox_qos_request; + +#define SET_MPU_CORE_CONSTRAINT 10 +#define CLEAR_MPU_CORE_CONSTRAINT -1 static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE; module_param(mbox_kfifo_size, uint, S_IRUGO); @@ -251,6 +256,8 @@ static int omap_mbox_startup(struct omap_mbox *mbox) mutex_lock(&mbox_configured_lock); if (!mbox_configured++) { + pm_qos_update_request(&mbox_qos_request, + SET_MPU_CORE_CONSTRAINT); if (likely(mbox->ops->startup)) { ret = mbox->ops->startup(mbox); if (unlikely(ret)) @@ -260,13 +267,6 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } 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; @@ -281,20 +281,29 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } mbox->rxq = mq; mq->mbox = mbox; + 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; + } } mutex_unlock(&mbox_configured_lock); return 0; +fail_request_irq: + mbox_queue_free(mbox->rxq); fail_alloc_rxq: mbox_queue_free(mbox->txq); fail_alloc_txq: - free_irq(mbox->irq, mbox); -fail_request_irq: if (mbox->ops->shutdown) mbox->ops->shutdown(mbox); mbox->use_count--; fail_startup: - mbox_configured--; + if (!--mbox_configured) + pm_qos_update_request(&mbox_qos_request, + CLEAR_MPU_CORE_CONSTRAINT); mutex_unlock(&mbox_configured_lock); return ret; } @@ -306,14 +315,17 @@ static void omap_mbox_fini(struct omap_mbox *mbox) if (!--mbox->use_count) { free_irq(mbox->irq, mbox); tasklet_kill(&mbox->txq->tasklet); - flush_work_sync(&mbox->rxq->work); + flush_work_sync(&mbox->rxq->work); mbox_queue_free(mbox->txq); mbox_queue_free(mbox->rxq); } if (likely(mbox->ops->shutdown)) { - if (!--mbox_configured) + if (!--mbox_configured) { mbox->ops->shutdown(mbox); + pm_qos_update_request(&mbox_qos_request, + CLEAR_MPU_CORE_CONSTRAINT); + } } mutex_unlock(&mbox_configured_lock); @@ -350,7 +362,8 @@ EXPORT_SYMBOL(omap_mbox_get); void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb) { - blocking_notifier_chain_unregister(&mbox->notifier, nb); + if (nb) + blocking_notifier_chain_unregister(&mbox->notifier, nb); omap_mbox_fini(mbox); } EXPORT_SYMBOL(omap_mbox_put); @@ -395,6 +408,7 @@ int omap_mbox_unregister(void) for (i = 0; mboxes[i]; i++) device_unregister(mboxes[i]->dev); + mboxes = NULL; return 0; } @@ -413,6 +427,8 @@ static int __init omap_mbox_init(void) mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + pm_qos_add_request(&mbox_qos_request, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); return 0; } subsys_initcall(omap_mbox_init); @@ -420,6 +436,7 @@ subsys_initcall(omap_mbox_init); static void __exit omap_mbox_exit(void) { class_unregister(&omap_mbox_class); + pm_qos_remove_request(&mbox_qos_request); } module_exit(omap_mbox_exit); |