diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-02-18 17:50:51 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-02-20 16:01:02 +1000 |
commit | 5cc027f6b1ec651c18a4322ed3e30c6e9cf01e96 (patch) | |
tree | 1f39b3fb82ea8e7d395a974584f5915c95dcfa6c /drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |
parent | 7dcd060c0e6e4f76ce7eea94c66437ce8f546530 (diff) | |
download | op-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.c | 22 |
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; |