summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-07-08 13:17:01 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 16:07:42 +1000
commitf20ce9629f820c00e581acc4c9938fbf6e34475d (patch)
tree27809bdb64b0d6fa49f3f6a6ec3dbd1598be595c /drivers
parent3b6d83d1b9f9be1c9778c2c6fa6761b440734fdd (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.c29
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 */