aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-10-17 20:58:04 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 00:06:38 -0500
commitfeeb0aecfb73b5b7699c0a85ba1650e6f9c50be2 (patch)
tree9b0d496bf886399aa40c416665c61ef43db230b1 /drivers/gpu/drm
parentf175b745b50c5c5356e8b3b409b7f38aa44de6bb (diff)
drm/nouveau: Add unlocked variants of nouveau_channel_get/put.
Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c36
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h3
2 files changed, 26 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index c46a6f641964..38929fd3f4e3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -238,33 +238,39 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
238} 238}
239 239
240struct nouveau_channel * 240struct nouveau_channel *
241nouveau_channel_get_unlocked(struct nouveau_channel *ref)
242{
243 if (likely(ref && atomic_inc_not_zero(&ref->refcount)))
244 return ref;
245
246 return NULL;
247}
248
249struct nouveau_channel *
241nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) 250nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id)
242{ 251{
243 struct drm_nouveau_private *dev_priv = dev->dev_private; 252 struct drm_nouveau_private *dev_priv = dev->dev_private;
244 struct nouveau_channel *chan = ERR_PTR(-ENODEV); 253 struct nouveau_channel *chan;
245 unsigned long flags; 254 unsigned long flags;
246 255
247 spin_lock_irqsave(&dev_priv->channels.lock, flags); 256 spin_lock_irqsave(&dev_priv->channels.lock, flags);
248 chan = dev_priv->channels.ptr[id]; 257 chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]);
258 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
249 259
250 if (unlikely(!chan || (file_priv && chan->file_priv != file_priv))) { 260 if (unlikely(!chan))
251 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
252 return ERR_PTR(-EINVAL); 261 return ERR_PTR(-EINVAL);
253 }
254 262
255 if (unlikely(!atomic_inc_not_zero(&chan->refcount))) { 263 if (unlikely(file_priv && chan->file_priv != file_priv)) {
256 spin_unlock_irqrestore(&dev_priv->channels.lock, flags); 264 nouveau_channel_put_unlocked(&chan);
257 return ERR_PTR(-EINVAL); 265 return ERR_PTR(-EINVAL);
258 } 266 }
259 267
260 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
261
262 mutex_lock(&chan->mutex); 268 mutex_lock(&chan->mutex);
263 return chan; 269 return chan;
264} 270}
265 271
266void 272void
267nouveau_channel_put(struct nouveau_channel **pchan) 273nouveau_channel_put_unlocked(struct nouveau_channel **pchan)
268{ 274{
269 struct nouveau_channel *chan = *pchan; 275 struct nouveau_channel *chan = *pchan;
270 struct drm_device *dev = chan->dev; 276 struct drm_device *dev = chan->dev;
@@ -274,9 +280,6 @@ nouveau_channel_put(struct nouveau_channel **pchan)
274 unsigned long flags; 280 unsigned long flags;
275 int ret; 281 int ret;
276 282
277 /* unlock the channel */
278 mutex_unlock(&chan->mutex);
279
280 /* decrement the refcount, and we're done if there's still refs */ 283 /* decrement the refcount, and we're done if there's still refs */
281 if (likely(!atomic_dec_and_test(&chan->refcount))) { 284 if (likely(!atomic_dec_and_test(&chan->refcount))) {
282 *pchan = NULL; 285 *pchan = NULL;
@@ -348,6 +351,13 @@ nouveau_channel_put(struct nouveau_channel **pchan)
348 kfree(chan); 351 kfree(chan);
349} 352}
350 353
354void
355nouveau_channel_put(struct nouveau_channel **pchan)
356{
357 mutex_unlock(&(*pchan)->mutex);
358 nouveau_channel_put_unlocked(pchan);
359}
360
351/* cleans up all the fifos from file_priv */ 361/* cleans up all the fifos from file_priv */
352void 362void
353nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) 363nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 198dabebafb2..e6708be58bcf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -803,7 +803,10 @@ extern int nouveau_channel_alloc(struct drm_device *dev,
803 struct drm_file *file_priv, 803 struct drm_file *file_priv,
804 uint32_t fb_ctxdma, uint32_t tt_ctxdma); 804 uint32_t fb_ctxdma, uint32_t tt_ctxdma);
805extern struct nouveau_channel * 805extern struct nouveau_channel *
806nouveau_channel_get_unlocked(struct nouveau_channel *);
807extern struct nouveau_channel *
806nouveau_channel_get(struct drm_device *, struct drm_file *, int id); 808nouveau_channel_get(struct drm_device *, struct drm_file *, int id);
809extern void nouveau_channel_put_unlocked(struct nouveau_channel **);
807extern void nouveau_channel_put(struct nouveau_channel **); 810extern void nouveau_channel_put(struct nouveau_channel **);
808 811
809/* nouveau_object.c */ 812/* nouveau_object.c */