summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/msm/mdss_util.c
diff options
context:
space:
mode:
authorShivaraj Shetty <shivaraj@codeaurora.org>2014-07-18 17:21:33 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:33:26 -0700
commit29e5a92bb220354b6875071b980b65e40b9b520a (patch)
treec55f808601cfde8e932dad03b8252024e92272c7 /drivers/video/fbdev/msm/mdss_util.c
parent0e9966adb0505aef3f7b07c202ece77aa011b31a (diff)
msm: mdss: Cleanup the interface given by mdss/mdp
Change irq interface provided by mdp from exporting symbols to function pointers. This will help in making mdp3 work with dsi 6G. Change-Id: I07a2acf56b75a2a6d83c0522d38efe3754bb8765 Signed-off-by: Shivaraj Shetty <shivaraj@codeaurora.org> [cip@codeaurora.org: Moved mdss_util.c file location] Signed-off-by: Clarence Ip <cip@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev/msm/mdss_util.c')
-rw-r--r--drivers/video/fbdev/msm/mdss_util.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdss_util.c b/drivers/video/fbdev/msm/mdss_util.c
new file mode 100644
index 000000000000..f09bbd0da87b
--- /dev/null
+++ b/drivers/video/fbdev/msm/mdss_util.c
@@ -0,0 +1,158 @@
+
+/* Copyright (c) 2007-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/interrupt.h>
+#include "mdss_mdp.h"
+
+struct mdss_hw *mdss_irq_handlers[MDSS_MAX_HW_BLK];
+static DEFINE_SPINLOCK(mdss_lock);
+
+int mdss_register_irq(struct mdss_hw *hw)
+{
+ unsigned long irq_flags;
+ u32 ndx_bit;
+
+ if (!hw || hw->hw_ndx >= MDSS_MAX_HW_BLK)
+ return -EINVAL;
+
+ ndx_bit = BIT(hw->hw_ndx);
+
+ spin_lock_irqsave(&mdss_lock, irq_flags);
+ if (!mdss_irq_handlers[hw->hw_ndx])
+ mdss_irq_handlers[hw->hw_ndx] = hw;
+ else
+ pr_err("panel %d's irq at %p is already registered\n",
+ hw->hw_ndx, hw->irq_handler);
+ spin_unlock_irqrestore(&mdss_lock, irq_flags);
+
+ return 0;
+}
+
+void mdss_enable_irq(struct mdss_hw *hw)
+{
+ unsigned long irq_flags;
+ u32 ndx_bit;
+
+ if (hw->hw_ndx >= MDSS_MAX_HW_BLK)
+ return;
+
+ if (!mdss_irq_handlers[hw->hw_ndx]) {
+ pr_err("failed. First register the irq then enable it.\n");
+ return;
+ }
+
+ ndx_bit = BIT(hw->hw_ndx);
+
+ pr_debug("Enable HW=%d irq ena=%d mask=%x\n", hw->hw_ndx,
+ mdss_res->irq_ena, mdss_res->irq_mask);
+
+ spin_lock_irqsave(&mdss_lock, irq_flags);
+ if (mdss_res->irq_mask & ndx_bit) {
+ pr_debug("MDSS HW ndx=%d is already set, mask=%x\n",
+ hw->hw_ndx, mdss_res->irq_mask);
+ } else {
+ mdss_res->irq_mask |= ndx_bit;
+ if (!mdss_res->irq_ena) {
+ mdss_res->irq_ena = true;
+ enable_irq(mdss_res->irq);
+ }
+ }
+ spin_unlock_irqrestore(&mdss_lock, irq_flags);
+}
+
+void mdss_disable_irq(struct mdss_hw *hw)
+{
+ unsigned long irq_flags;
+ u32 ndx_bit;
+
+ if (hw->hw_ndx >= MDSS_MAX_HW_BLK)
+ return;
+
+ ndx_bit = BIT(hw->hw_ndx);
+
+ pr_debug("Disable HW=%d irq ena=%d mask=%x\n", hw->hw_ndx,
+ mdss_res->irq_ena, mdss_res->irq_mask);
+
+ spin_lock_irqsave(&mdss_lock, irq_flags);
+ if (!(mdss_res->irq_mask & ndx_bit)) {
+ pr_warn("MDSS HW ndx=%d is NOT set, mask=%x, hist mask=%x\n",
+ hw->hw_ndx, mdss_res->mdp_irq_mask,
+ mdss_res->mdp_hist_irq_mask);
+ } else {
+ mdss_res->irq_mask &= ~ndx_bit;
+ if (mdss_res->irq_mask == 0) {
+ mdss_res->irq_ena = false;
+ disable_irq_nosync(mdss_res->irq);
+ }
+ }
+ spin_unlock_irqrestore(&mdss_lock, irq_flags);
+}
+
+/* called from interrupt context */
+void mdss_disable_irq_nosync(struct mdss_hw *hw)
+{
+ u32 ndx_bit;
+
+ if (hw->hw_ndx >= MDSS_MAX_HW_BLK)
+ return;
+
+ ndx_bit = BIT(hw->hw_ndx);
+
+ pr_debug("Disable HW=%d irq ena=%d mask=%x\n", hw->hw_ndx,
+ mdss_res->irq_ena, mdss_res->irq_mask);
+
+ spin_lock(&mdss_lock);
+ if (!(mdss_res->irq_mask & ndx_bit)) {
+ pr_warn("MDSS HW ndx=%d is NOT set, mask=%x, hist mask=%x\n",
+ hw->hw_ndx, mdss_res->mdp_irq_mask,
+ mdss_res->mdp_hist_irq_mask);
+ } else {
+ mdss_res->irq_mask &= ~ndx_bit;
+ if (mdss_res->irq_mask == 0) {
+ mdss_res->irq_ena = false;
+ disable_irq_nosync(mdss_res->irq);
+ }
+ }
+ spin_unlock(&mdss_lock);
+}
+
+int mdss_irq_dispatch(u32 hw_ndx, int irq, void *ptr)
+{
+ struct mdss_hw *hw;
+ int rc = -ENODEV;
+
+ spin_lock(&mdss_lock);
+ hw = mdss_irq_handlers[hw_ndx];
+ spin_unlock(&mdss_lock);
+
+ if (hw)
+ rc = hw->irq_handler(irq, hw->ptr);
+
+ return rc;
+}
+
+struct mdss_util_intf mdss_util = {
+ mdss_register_irq,
+ mdss_enable_irq,
+ mdss_disable_irq,
+ mdss_disable_irq_nosync,
+ mdss_irq_dispatch
+};
+
+struct mdss_util_intf *mdss_get_util_intf()
+{
+ return &mdss_util;
+}
+EXPORT_SYMBOL(mdss_get_util_intf);