From: Steve Longerbeam <steve_longerbeam@mentor.com>
Date: Mon, 26 Aug 2013 18:42:09 +0000 (-0700)
Subject: gpu: ipu-v3: Implement use counter for ipu_dc_enable(), ipu_dc_disable()
X-Git-Tag: v4.0-rc1~74^2~39^2~22
X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f853f3daac748daa339bc8b64ba39db82160524a;p=users%2Fjedix%2Flinux-maple.git

gpu: ipu-v3: Implement use counter for ipu_dc_enable(), ipu_dc_disable()

The functions ipu_dc_enable() and ipu_dc_disable() enable/disable the DC
globally in the IPU_CONF register, but the DC is used by multiple clients
on different DC channels. So make sure to only disable/enable the DC
globally based on a use counter.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---

diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
index 2326c752d89b..323203d0503a 100644
--- a/drivers/gpu/ipu-v3/ipu-dc.c
+++ b/drivers/gpu/ipu-v3/ipu-dc.c
@@ -114,6 +114,7 @@ struct ipu_dc_priv {
 	struct completion	comp;
 	int			dc_irq;
 	int			dp_irq;
+	int			use_count;
 };
 
 static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority)
@@ -232,7 +233,16 @@ EXPORT_SYMBOL_GPL(ipu_dc_init_sync);
 
 void ipu_dc_enable(struct ipu_soc *ipu)
 {
-	ipu_module_enable(ipu, IPU_CONF_DC_EN);
+	struct ipu_dc_priv *priv = ipu->dc_priv;
+
+	mutex_lock(&priv->mutex);
+
+	if (!priv->use_count)
+		ipu_module_enable(priv->ipu, IPU_CONF_DC_EN);
+
+	priv->use_count++;
+
+	mutex_unlock(&priv->mutex);
 }
 EXPORT_SYMBOL_GPL(ipu_dc_enable);
 
@@ -294,7 +304,18 @@ EXPORT_SYMBOL_GPL(ipu_dc_disable_channel);
 
 void ipu_dc_disable(struct ipu_soc *ipu)
 {
-	ipu_module_disable(ipu, IPU_CONF_DC_EN);
+	struct ipu_dc_priv *priv = ipu->dc_priv;
+
+	mutex_lock(&priv->mutex);
+
+	priv->use_count--;
+	if (!priv->use_count)
+		ipu_module_disable(priv->ipu, IPU_CONF_DC_EN);
+
+	if (priv->use_count < 0)
+		priv->use_count = 0;
+
+	mutex_unlock(&priv->mutex);
 }
 EXPORT_SYMBOL_GPL(ipu_dc_disable);