|
@@ -62,11 +62,13 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
|
|
|
|
|
|
ret = -ENODEV;
|
|
|
if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) {
|
|
|
+ mutex_lock(&dev_priv->channel->mutex);
|
|
|
if (dev_priv->card_type < NV_50)
|
|
|
ret = nv04_fbcon_fillrect(info, rect);
|
|
|
else
|
|
|
if (dev_priv->card_type < NV_C0)
|
|
|
ret = nv50_fbcon_fillrect(info, rect);
|
|
|
+ mutex_unlock(&dev_priv->channel->mutex);
|
|
|
}
|
|
|
|
|
|
if (ret == 0)
|
|
@@ -90,11 +92,13 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
|
|
|
|
|
|
ret = -ENODEV;
|
|
|
if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) {
|
|
|
+ mutex_lock(&dev_priv->channel->mutex);
|
|
|
if (dev_priv->card_type < NV_50)
|
|
|
ret = nv04_fbcon_copyarea(info, image);
|
|
|
else
|
|
|
if (dev_priv->card_type < NV_C0)
|
|
|
ret = nv50_fbcon_copyarea(info, image);
|
|
|
+ mutex_unlock(&dev_priv->channel->mutex);
|
|
|
}
|
|
|
|
|
|
if (ret == 0)
|
|
@@ -118,11 +122,13 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|
|
|
|
|
ret = -ENODEV;
|
|
|
if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) {
|
|
|
+ mutex_lock(&dev_priv->channel->mutex);
|
|
|
if (dev_priv->card_type < NV_50)
|
|
|
ret = nv04_fbcon_imageblit(info, image);
|
|
|
else
|
|
|
if (dev_priv->card_type < NV_C0)
|
|
|
ret = nv50_fbcon_imageblit(info, image);
|
|
|
+ mutex_unlock(&dev_priv->channel->mutex);
|
|
|
}
|
|
|
|
|
|
if (ret == 0)
|
|
@@ -142,12 +148,15 @@ nouveau_fbcon_sync(struct fb_info *info)
|
|
|
struct nouveau_channel *chan = dev_priv->channel;
|
|
|
int ret, i;
|
|
|
|
|
|
- if (!chan || !chan->accel_done ||
|
|
|
+ if (!chan || !chan->accel_done || in_interrupt() ||
|
|
|
info->state != FBINFO_STATE_RUNNING ||
|
|
|
info->flags & FBINFO_HWACCEL_DISABLED)
|
|
|
return 0;
|
|
|
|
|
|
- if (RING_SPACE(chan, 4)) {
|
|
|
+ mutex_lock(&chan->mutex);
|
|
|
+ ret = RING_SPACE(chan, 4);
|
|
|
+ if (ret) {
|
|
|
+ mutex_unlock(&chan->mutex);
|
|
|
nouveau_fbcon_gpu_lockup(info);
|
|
|
return 0;
|
|
|
}
|
|
@@ -158,6 +167,7 @@ nouveau_fbcon_sync(struct fb_info *info)
|
|
|
OUT_RING(chan, 0);
|
|
|
nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff);
|
|
|
FIRE_RING(chan);
|
|
|
+ mutex_unlock(&chan->mutex);
|
|
|
|
|
|
ret = -EBUSY;
|
|
|
for (i = 0; i < 100000; i++) {
|
|
@@ -353,6 +363,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
|
|
|
info->pixmap.flags = FB_PIXMAP_SYSTEM;
|
|
|
info->pixmap.scan_align = 1;
|
|
|
|
|
|
+ mutex_unlock(&dev->struct_mutex);
|
|
|
+
|
|
|
if (dev_priv->channel && !nouveau_nofbaccel) {
|
|
|
ret = -ENODEV;
|
|
|
if (dev_priv->card_type < NV_50)
|
|
@@ -373,7 +385,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
|
|
|
nouveau_fb->base.height,
|
|
|
nvbo->bo.offset, nvbo);
|
|
|
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
vga_switcheroo_client_fb_set(dev->pdev, info);
|
|
|
return 0;
|
|
|
|