diff options
author | Steve Longerbeam <steve_longerbeam@mentor.com> | 2013-08-26 14:42:09 -0400 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2015-01-06 11:36:14 -0500 |
commit | f853f3daac748daa339bc8b64ba39db82160524a (patch) | |
tree | 558b955d3db3d9eb89c64223080f54234012759f | |
parent | 6457b9716bca99b95a07e85ff8b00f9bf471ac2c (diff) |
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>
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-dc.c | 25 |
1 files changed, 23 insertions, 2 deletions
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 { | |||
114 | struct completion comp; | 114 | struct completion comp; |
115 | int dc_irq; | 115 | int dc_irq; |
116 | int dp_irq; | 116 | int dp_irq; |
117 | int use_count; | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority) | 120 | 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); | |||
232 | 233 | ||
233 | void ipu_dc_enable(struct ipu_soc *ipu) | 234 | void ipu_dc_enable(struct ipu_soc *ipu) |
234 | { | 235 | { |
235 | ipu_module_enable(ipu, IPU_CONF_DC_EN); | 236 | struct ipu_dc_priv *priv = ipu->dc_priv; |
237 | |||
238 | mutex_lock(&priv->mutex); | ||
239 | |||
240 | if (!priv->use_count) | ||
241 | ipu_module_enable(priv->ipu, IPU_CONF_DC_EN); | ||
242 | |||
243 | priv->use_count++; | ||
244 | |||
245 | mutex_unlock(&priv->mutex); | ||
236 | } | 246 | } |
237 | EXPORT_SYMBOL_GPL(ipu_dc_enable); | 247 | EXPORT_SYMBOL_GPL(ipu_dc_enable); |
238 | 248 | ||
@@ -294,7 +304,18 @@ EXPORT_SYMBOL_GPL(ipu_dc_disable_channel); | |||
294 | 304 | ||
295 | void ipu_dc_disable(struct ipu_soc *ipu) | 305 | void ipu_dc_disable(struct ipu_soc *ipu) |
296 | { | 306 | { |
297 | ipu_module_disable(ipu, IPU_CONF_DC_EN); | 307 | struct ipu_dc_priv *priv = ipu->dc_priv; |
308 | |||
309 | mutex_lock(&priv->mutex); | ||
310 | |||
311 | priv->use_count--; | ||
312 | if (!priv->use_count) | ||
313 | ipu_module_disable(priv->ipu, IPU_CONF_DC_EN); | ||
314 | |||
315 | if (priv->use_count < 0) | ||
316 | priv->use_count = 0; | ||
317 | |||
318 | mutex_unlock(&priv->mutex); | ||
298 | } | 319 | } |
299 | EXPORT_SYMBOL_GPL(ipu_dc_disable); | 320 | EXPORT_SYMBOL_GPL(ipu_dc_disable); |
300 | 321 | ||