diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-07-08 13:17:01 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 16:07:42 +1000 |
commit | f20ce9629f820c00e581acc4c9938fbf6e34475d (patch) | |
tree | 27809bdb64b0d6fa49f3f6a6ec3dbd1598be595c /drivers | |
parent | 3b6d83d1b9f9be1c9778c2c6fa6761b440734fdd (diff) |
drm/nvd0/disp: do modeset irq handling from tasklet
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 1a561d30821..b6a8c6def64 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c @@ -44,9 +44,12 @@ struct nvd0_display { dma_addr_t handle; u32 *ptr; } evo[1]; + + struct tasklet_struct tasklet; struct { struct dcb_entry *dis; struct dcb_entry *ena; + u32 modeset; int crtc; int pclk; u16 cfg; @@ -1115,8 +1118,23 @@ ack: } static void +nvd0_display_bh(unsigned long data) +{ + struct drm_device *dev = (struct drm_device *)data; + struct nvd0_display *disp = nvd0_display(dev); + + if (disp->irq.modeset & 0x00000001) + nvd0_display_unk1_handler(dev); + if (disp->irq.modeset & 0x00000002) + nvd0_display_unk2_handler(dev); + if (disp->irq.modeset & 0x00000004) + nvd0_display_unk4_handler(dev); +} + +static void nvd0_display_intr(struct drm_device *dev) { + struct nvd0_display *disp = nvd0_display(dev); u32 intr = nv_rd32(dev, 0x610088); if (intr & 0x00000002) { @@ -1141,14 +1159,10 @@ nvd0_display_intr(struct drm_device *dev) u32 stat = nv_rd32(dev, 0x6100ac); if (stat & 0x00000007) { - nv_wr32(dev, 0x6100ac, (stat & 0x00000007)); + disp->irq.modeset = stat; + tasklet_schedule(&disp->tasklet); - if (stat & 0x00000001) - nvd0_display_unk1_handler(dev); - if (stat & 0x00000002) - nvd0_display_unk2_handler(dev); - if (stat & 0x00000004) - nvd0_display_unk4_handler(dev); + nv_wr32(dev, 0x6100ac, (stat & 0x00000007)); stat &= ~0x00000007; } @@ -1371,6 +1385,7 @@ nvd0_display_create(struct drm_device *dev) } /* setup interrupt handling */ + tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev); nouveau_irq_register(dev, 26, nvd0_display_intr); /* hash table and dma objects for the memory areas we care about */ |