summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-02-18 17:50:51 -0500
committerBen Skeggs <bskeggs@redhat.com>2013-02-20 16:01:02 +1000
commit5cc027f6b1ec651c18a4322ed3e30c6e9cf01e96 (patch)
tree1f39b3fb82ea8e7d395a974584f5915c95dcfa6c /drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
parent7dcd060c0e6e4f76ce7eea94c66437ce8f546530 (diff)
downloadop-kernel-dev-5cc027f6b1ec651c18a4322ed3e30c6e9cf01e96.zip
op-kernel-dev-5cc027f6b1ec651c18a4322ed3e30c6e9cf01e96.tar.gz
drm/nv50-/disp: handle supervisor tasks from workqueue
i2c_algo_bit sleeps... Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/disp/nv50.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index c3806122d..d22f656 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -940,7 +940,6 @@ nv50_disp_intr_unk10(struct nv50_disp_priv *priv, u32 super)
exec_script(priv, head, 1);
}
- nv_wr32(priv, 0x610024, 0x00000010);
nv_wr32(priv, 0x610030, 0x80000000);
}
@@ -1097,7 +1096,6 @@ nv50_disp_intr_unk20(struct nv50_disp_priv *priv, u32 super)
}
}
- nv_wr32(priv, 0x610024, 0x00000020);
nv_wr32(priv, 0x610030, 0x80000000);
}
@@ -1136,22 +1134,23 @@ nv50_disp_intr_unk40(struct nv50_disp_priv *priv, u32 super)
}
}
- nv_wr32(priv, 0x610024, 0x00000040);
nv_wr32(priv, 0x610030, 0x80000000);
}
-static void
-nv50_disp_intr_super(struct nv50_disp_priv *priv, u32 intr1)
+void
+nv50_disp_intr_supervisor(struct work_struct *work)
{
+ struct nv50_disp_priv *priv =
+ container_of(work, struct nv50_disp_priv, supervisor);
u32 super = nv_rd32(priv, 0x610030);
- nv_debug(priv, "supervisor 0x%08x 0x%08x\n", intr1, super);
+ nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super);
- if (intr1 & 0x00000010)
+ if (priv->super & 0x00000010)
nv50_disp_intr_unk10(priv, super);
- if (intr1 & 0x00000020)
+ if (priv->super & 0x00000020)
nv50_disp_intr_unk20(priv, super);
- if (intr1 & 0x00000040)
+ if (priv->super & 0x00000040)
nv50_disp_intr_unk40(priv, super);
}
@@ -1180,7 +1179,9 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
}
if (intr1 & 0x00000070) {
- nv50_disp_intr_super(priv, intr1);
+ priv->super = (intr1 & 0x00000070);
+ schedule_work(&priv->supervisor);
+ nv_wr32(priv, 0x610024, priv->super);
intr1 &= ~0x00000070;
}
}
@@ -1202,6 +1203,7 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
nv_engine(priv)->sclass = nv50_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
+ INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
priv->sclass = nv50_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
OpenPOWER on IntegriCloud