aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-11-30 16:00:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-11-30 16:00:21 -0500
commit8639dad84e4fe83577006e8e2bd9da79c6c2c41e (patch)
treed14feb296d595582a940d34d5aad57fa791500e7 /drivers
parent9297524f6a2885bfb4e2431d658cd1ffaefbda41 (diff)
parent461cba2d294fe83297edf8a6556912812903dce1 (diff)
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: drm/i915: Save/restore HWS_PGA on suspend/resume drm: move drm vblank initialization/cleanup to driver load/unload drm/i915: execbuffer pins objects, no need to ensure they're still in the GTT drm/i915: Always read pipestat in irq_handler drm/i915: Subtract total pinned bytes from available aperture size drm/i915: Avoid BUG_ONs on VT switch with a wedged chipset. drm/i915: Remove IMR masking during interrupt handler, and restart it if needed. drm/i915: Manage PIPESTAT to control vblank interrupts instead of IMR.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_drv.c2
-rw-r--r--drivers/gpu/drm/drm_irq.c4
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c7
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h11
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c74
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c293
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c18
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c6
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c8
-rw-r--r--drivers/gpu/drm/mga/mga_irq.c5
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c6
-rw-r--r--drivers/gpu/drm/r128/r128_drv.h1
-rw-r--r--drivers/gpu/drm/r128/r128_irq.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c5
-rw-r--r--drivers/gpu/drm/via/via_irq.c1
-rw-r--r--drivers/gpu/drm/via/via_map.c11
17 files changed, 261 insertions, 199 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 3ab1e9cc4692..996097acb5e7 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -305,6 +305,8 @@ static void drm_cleanup(struct drm_device * dev)
305 return; 305 return;
306 } 306 }
307 307
308 drm_vblank_cleanup(dev);
309
308 drm_lastclose(dev); 310 drm_lastclose(dev);
309 311
310 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && 312 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 15c8dabc3e97..1e787f894b3c 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -94,7 +94,7 @@ static void vblank_disable_fn(unsigned long arg)
94 } 94 }
95} 95}
96 96
97static void drm_vblank_cleanup(struct drm_device *dev) 97void drm_vblank_cleanup(struct drm_device *dev)
98{ 98{
99 /* Bail if the driver didn't call drm_vblank_init() */ 99 /* Bail if the driver didn't call drm_vblank_init() */
100 if (dev->num_crtcs == 0) 100 if (dev->num_crtcs == 0)
@@ -278,8 +278,6 @@ int drm_irq_uninstall(struct drm_device * dev)
278 278
279 free_irq(dev->pdev->irq, dev); 279 free_irq(dev->pdev->irq, dev);
280 280
281 drm_vblank_cleanup(dev);
282
283 return 0; 281 return 0;
284} 282}
285EXPORT_SYMBOL(drm_irq_uninstall); 283EXPORT_SYMBOL(drm_irq_uninstall);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 0d215e38606a..ba89b42f790a 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -856,6 +856,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
856 856
857 spin_lock_init(&dev_priv->user_irq_lock); 857 spin_lock_init(&dev_priv->user_irq_lock);
858 858
859 ret = drm_vblank_init(dev, I915_NUM_PIPE);
860
861 if (ret) {
862 (void) i915_driver_unload(dev);
863 return ret;
864 }
865
859 return ret; 866 return ret;
860} 867}
861 868
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ef1c0b8f8d07..0a4f39b9a0ec 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -47,6 +47,8 @@ enum pipe {
47 PIPE_B, 47 PIPE_B,
48}; 48};
49 49
50#define I915_NUM_PIPE 2
51
50/* Interface history: 52/* Interface history:
51 * 53 *
52 * 1.1: Original. 54 * 1.1: Original.
@@ -132,6 +134,7 @@ typedef struct drm_i915_private {
132 int user_irq_refcount; 134 int user_irq_refcount;
133 /** Cached value of IMR to avoid reads in updating the bitfield */ 135 /** Cached value of IMR to avoid reads in updating the bitfield */
134 u32 irq_mask_reg; 136 u32 irq_mask_reg;
137 u32 pipestat[2];
135 138
136 int tex_lru_log_granularity; 139 int tex_lru_log_granularity;
137 int allow_batchbuffer; 140 int allow_batchbuffer;
@@ -147,6 +150,7 @@ typedef struct drm_i915_private {
147 u32 saveDSPBCNTR; 150 u32 saveDSPBCNTR;
148 u32 saveDSPARB; 151 u32 saveDSPARB;
149 u32 saveRENDERSTANDBY; 152 u32 saveRENDERSTANDBY;
153 u32 saveHWS;
150 u32 savePIPEACONF; 154 u32 savePIPEACONF;
151 u32 savePIPEBCONF; 155 u32 savePIPEBCONF;
152 u32 savePIPEASRC; 156 u32 savePIPEASRC;
@@ -446,6 +450,13 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data,
446 struct drm_file *file_priv); 450 struct drm_file *file_priv);
447extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); 451extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
448 452
453void
454i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
455
456void
457i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
458
459
449/* i915_mem.c */ 460/* i915_mem.c */
450extern int i915_mem_alloc(struct drm_device *dev, void *data, 461extern int i915_mem_alloc(struct drm_device *dev, void *data,
451 struct drm_file *file_priv); 462 struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6b4a2bd20640..54bb0d0e49b8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -31,6 +31,8 @@
31#include "i915_drv.h" 31#include "i915_drv.h"
32#include <linux/swap.h> 32#include <linux/swap.h>
33 33
34#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
35
34static int 36static int
35i915_gem_object_set_domain(struct drm_gem_object *obj, 37i915_gem_object_set_domain(struct drm_gem_object *obj,
36 uint32_t read_domains, 38 uint32_t read_domains,
@@ -83,20 +85,14 @@ int
83i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, 85i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
84 struct drm_file *file_priv) 86 struct drm_file *file_priv)
85{ 87{
86 drm_i915_private_t *dev_priv = dev->dev_private;
87 struct drm_i915_gem_get_aperture *args = data; 88 struct drm_i915_gem_get_aperture *args = data;
88 struct drm_i915_gem_object *obj_priv;
89 89
90 if (!(dev->driver->driver_features & DRIVER_GEM)) 90 if (!(dev->driver->driver_features & DRIVER_GEM))
91 return -ENODEV; 91 return -ENODEV;
92 92
93 args->aper_size = dev->gtt_total; 93 args->aper_size = dev->gtt_total;
94 args->aper_available_size = args->aper_size; 94 args->aper_available_size = (args->aper_size -
95 95 atomic_read(&dev->pin_memory));
96 list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
97 if (obj_priv->pin_count > 0)
98 args->aper_available_size -= obj_priv->obj->size;
99 }
100 96
101 return 0; 97 return 0;
102} 98}
@@ -1870,17 +1866,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
1870 1866
1871 for (i = 0; i < args->buffer_count; i++) { 1867 for (i = 0; i < args->buffer_count; i++) {
1872 struct drm_gem_object *obj = object_list[i]; 1868 struct drm_gem_object *obj = object_list[i];
1873 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1874
1875 if (obj_priv->gtt_space == NULL) {
1876 /* We evicted the buffer in the process of validating
1877 * our set of buffers in. We could try to recover by
1878 * kicking them everything out and trying again from
1879 * the start.
1880 */
1881 ret = -ENOMEM;
1882 goto err;
1883 }
1884 1869
1885 /* make sure all previous memory operations have passed */ 1870 /* make sure all previous memory operations have passed */
1886 ret = i915_gem_object_set_domain(obj, 1871 ret = i915_gem_object_set_domain(obj,
@@ -2299,29 +2284,52 @@ i915_gem_idle(struct drm_device *dev)
2299 2284
2300 i915_gem_retire_requests(dev); 2285 i915_gem_retire_requests(dev);
2301 2286
2302 /* Active and flushing should now be empty as we've 2287 if (!dev_priv->mm.wedged) {
2303 * waited for a sequence higher than any pending execbuffer 2288 /* Active and flushing should now be empty as we've
2304 */ 2289 * waited for a sequence higher than any pending execbuffer
2305 BUG_ON(!list_empty(&dev_priv->mm.active_list)); 2290 */
2306 BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); 2291 WARN_ON(!list_empty(&dev_priv->mm.active_list));
2292 WARN_ON(!list_empty(&dev_priv->mm.flushing_list));
2293 /* Request should now be empty as we've also waited
2294 * for the last request in the list
2295 */
2296 WARN_ON(!list_empty(&dev_priv->mm.request_list));
2297 }
2307 2298
2308 /* Request should now be empty as we've also waited 2299 /* Empty the active and flushing lists to inactive. If there's
2309 * for the last request in the list 2300 * anything left at this point, it means that we're wedged and
2301 * nothing good's going to happen by leaving them there. So strip
2302 * the GPU domains and just stuff them onto inactive.
2310 */ 2303 */
2311 BUG_ON(!list_empty(&dev_priv->mm.request_list)); 2304 while (!list_empty(&dev_priv->mm.active_list)) {
2305 struct drm_i915_gem_object *obj_priv;
2312 2306
2313 /* Move all buffers out of the GTT. */ 2307 obj_priv = list_first_entry(&dev_priv->mm.active_list,
2308 struct drm_i915_gem_object,
2309 list);
2310 obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
2311 i915_gem_object_move_to_inactive(obj_priv->obj);
2312 }
2313
2314 while (!list_empty(&dev_priv->mm.flushing_list)) {
2315 struct drm_i915_gem_object *obj_priv;
2316
2317 obj_priv = list_first_entry(&dev_priv->mm.active_list,
2318 struct drm_i915_gem_object,
2319 list);
2320 obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
2321 i915_gem_object_move_to_inactive(obj_priv->obj);
2322 }
2323
2324
2325 /* Move all inactive buffers out of the GTT. */
2314 ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); 2326 ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
2327 WARN_ON(!list_empty(&dev_priv->mm.inactive_list));
2315 if (ret) { 2328 if (ret) {
2316 mutex_unlock(&dev->struct_mutex); 2329 mutex_unlock(&dev->struct_mutex);
2317 return ret; 2330 return ret;
2318 } 2331 }
2319 2332
2320 BUG_ON(!list_empty(&dev_priv->mm.active_list));
2321 BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
2322 BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
2323 BUG_ON(!list_empty(&dev_priv->mm.request_list));
2324
2325 i915_gem_cleanup_ringbuffer(dev); 2333 i915_gem_cleanup_ringbuffer(dev);
2326 mutex_unlock(&dev->struct_mutex); 2334 mutex_unlock(&dev->struct_mutex);
2327 2335
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 82752d6177a4..fe3d9cc72bf5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -33,11 +33,23 @@
33 33
34#define MAX_NOPID ((u32)~0) 34#define MAX_NOPID ((u32)~0)
35 35
36/** These are the interrupts used by the driver */ 36/**
37#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ 37 * Interrupts that are always left unmasked.
38 I915_ASLE_INTERRUPT | \ 38 *
39 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ 39 * Since pipe events are edge-triggered from the PIPESTAT register to IIR,
40 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) 40 * we leave them always unmasked in IMR and then control enabling them through
41 * PIPESTAT alone.
42 */
43#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
44 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
45 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
46
47/** Interrupts that we mask and unmask at runtime. */
48#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
49
50/** These are all of the interrupts used by the driver */
51#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
52 I915_INTERRUPT_ENABLE_VAR)
41 53
42void 54void
43i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) 55i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
@@ -59,6 +71,41 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
59 } 71 }
60} 72}
61 73
74static inline u32
75i915_pipestat(int pipe)
76{
77 if (pipe == 0)
78 return PIPEASTAT;
79 if (pipe == 1)
80 return PIPEBSTAT;
81 BUG_ON(1);
82}
83
84void
85i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
86{
87 if ((dev_priv->pipestat[pipe] & mask) != mask) {
88 u32 reg = i915_pipestat(pipe);
89
90 dev_priv->pipestat[pipe] |= mask;
91 /* Enable the interrupt, clear any pending status */
92 I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16));
93 (void) I915_READ(reg);
94 }
95}
96
97void
98i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
99{
100 if ((dev_priv->pipestat[pipe] & mask) != 0) {
101 u32 reg = i915_pipestat(pipe);
102
103 dev_priv->pipestat[pipe] &= ~mask;
104 I915_WRITE(reg, dev_priv->pipestat[pipe]);
105 (void) I915_READ(reg);
106 }
107}
108
62/** 109/**
63 * i915_pipe_enabled - check if a pipe is enabled 110 * i915_pipe_enabled - check if a pipe is enabled
64 * @dev: DRM device 111 * @dev: DRM device
@@ -121,80 +168,102 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
121{ 168{
122 struct drm_device *dev = (struct drm_device *) arg; 169 struct drm_device *dev = (struct drm_device *) arg;
123 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 170 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
124 u32 iir; 171 u32 iir, new_iir;
125 u32 pipea_stats, pipeb_stats; 172 u32 pipea_stats, pipeb_stats;
173 u32 vblank_status;
174 u32 vblank_enable;
126 int vblank = 0; 175 int vblank = 0;
176 unsigned long irqflags;
177 int irq_received;
178 int ret = IRQ_NONE;
127 179
128 atomic_inc(&dev_priv->irq_received); 180 atomic_inc(&dev_priv->irq_received);
129 181
130 if (dev->pdev->msi_enabled)
131 I915_WRITE(IMR, ~0);
132 iir = I915_READ(IIR); 182 iir = I915_READ(IIR);
133 183
134 if (iir == 0) { 184 if (IS_I965G(dev)) {
135 if (dev->pdev->msi_enabled) { 185 vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
136 I915_WRITE(IMR, dev_priv->irq_mask_reg); 186 vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
137 (void) I915_READ(IMR); 187 } else {
138 } 188 vblank_status = I915_VBLANK_INTERRUPT_STATUS;
139 return IRQ_NONE; 189 vblank_enable = I915_VBLANK_INTERRUPT_ENABLE;
140 } 190 }
141 191
142 /* 192 for (;;) {
143 * Clear the PIPE(A|B)STAT regs before the IIR otherwise 193 irq_received = iir != 0;
144 * we may get extra interrupts. 194
145 */ 195 /* Can't rely on pipestat interrupt bit in iir as it might
146 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { 196 * have been cleared after the pipestat interrupt was received.
197 * It doesn't set the bit in iir again, but it still produces
198 * interrupts (for non-MSI).
199 */
200 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
147 pipea_stats = I915_READ(PIPEASTAT); 201 pipea_stats = I915_READ(PIPEASTAT);
148 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)) 202 pipeb_stats = I915_READ(PIPEBSTAT);
149 pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | 203 /*
150 PIPE_VBLANK_INTERRUPT_ENABLE); 204 * Clear the PIPE(A|B)STAT regs before the IIR
151 else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| 205 */
152 PIPE_VBLANK_INTERRUPT_STATUS)) { 206 if (pipea_stats & 0x8000ffff) {
207 I915_WRITE(PIPEASTAT, pipea_stats);
208 irq_received = 1;
209 }
210
211 if (pipeb_stats & 0x8000ffff) {
212 I915_WRITE(PIPEBSTAT, pipeb_stats);
213 irq_received = 1;
214 }
215 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
216
217 if (!irq_received)
218 break;
219
220 ret = IRQ_HANDLED;
221
222 I915_WRITE(IIR, iir);
223 new_iir = I915_READ(IIR); /* Flush posted writes */
224
225 if (dev_priv->sarea_priv)
226 dev_priv->sarea_priv->last_dispatch =
227 READ_BREADCRUMB(dev_priv);
228
229 if (iir & I915_USER_INTERRUPT) {
230 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
231 DRM_WAKEUP(&dev_priv->irq_queue);
232 }
233
234 if (pipea_stats & vblank_status) {
153 vblank++; 235 vblank++;
154 drm_handle_vblank(dev, 0); 236 drm_handle_vblank(dev, 0);
155 } 237 }
156 238
157 I915_WRITE(PIPEASTAT, pipea_stats); 239 if (pipeb_stats & vblank_status) {
158 }
159 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
160 pipeb_stats = I915_READ(PIPEBSTAT);
161 /* Ack the event */
162 I915_WRITE(PIPEBSTAT, pipeb_stats);
163
164 /* The vblank interrupt gets enabled even if we didn't ask for
165 it, so make sure it's shut down again */
166 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
167 pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
168 PIPE_VBLANK_INTERRUPT_ENABLE);
169 else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
170 PIPE_VBLANK_INTERRUPT_STATUS)) {
171 vblank++; 240 vblank++;
172 drm_handle_vblank(dev, 1); 241 drm_handle_vblank(dev, 1);
173 } 242 }
174 243
175 if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) 244 if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
245 (iir & I915_ASLE_INTERRUPT))
176 opregion_asle_intr(dev); 246 opregion_asle_intr(dev);
177 I915_WRITE(PIPEBSTAT, pipeb_stats);
178 }
179
180 I915_WRITE(IIR, iir);
181 if (dev->pdev->msi_enabled)
182 I915_WRITE(IMR, dev_priv->irq_mask_reg);
183 (void) I915_READ(IIR); /* Flush posted writes */
184
185 if (dev_priv->sarea_priv)
186 dev_priv->sarea_priv->last_dispatch =
187 READ_BREADCRUMB(dev_priv);
188 247
189 if (iir & I915_USER_INTERRUPT) { 248 /* With MSI, interrupts are only generated when iir
190 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); 249 * transitions from zero to nonzero. If another bit got
191 DRM_WAKEUP(&dev_priv->irq_queue); 250 * set while we were handling the existing iir bits, then
251 * we would never get another interrupt.
252 *
253 * This is fine on non-MSI as well, as if we hit this path
254 * we avoid exiting the interrupt handler only to generate
255 * another one.
256 *
257 * Note that for MSI this could cause a stray interrupt report
258 * if an interrupt landed in the time between writing IIR and
259 * the posting read. This should be rare enough to never
260 * trigger the 99% of 100,000 interrupts test for disabling
261 * stray interrupts.
262 */
263 iir = new_iir;
192 } 264 }
193 265
194 if (iir & I915_ASLE_INTERRUPT) 266 return ret;
195 opregion_asle_intr(dev);
196
197 return IRQ_HANDLED;
198} 267}
199 268
200static int i915_emit_irq(struct drm_device * dev) 269static int i915_emit_irq(struct drm_device * dev)
@@ -330,48 +399,16 @@ int i915_irq_wait(struct drm_device *dev, void *data,
330int i915_enable_vblank(struct drm_device *dev, int pipe) 399int i915_enable_vblank(struct drm_device *dev, int pipe)
331{ 400{
332 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 401 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
333 u32 pipestat_reg = 0;
334 u32 pipestat;
335 u32 interrupt = 0;
336 unsigned long irqflags; 402 unsigned long irqflags;
337 403
338 switch (pipe) {
339 case 0:
340 pipestat_reg = PIPEASTAT;
341 interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
342 break;
343 case 1:
344 pipestat_reg = PIPEBSTAT;
345 interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
346 break;
347 default:
348 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
349 pipe);
350 return 0;
351 }
352
353 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 404 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
354 /* Enabling vblank events in IMR comes before PIPESTAT write, or
355 * there's a race where the PIPESTAT vblank bit gets set to 1, so
356 * the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in
357 * ISR flashes to 1, but the IIR bit doesn't get set to 1 because
358 * IMR masks it. It doesn't ever get set after we clear the masking
359 * in IMR because the ISR bit is edge, not level-triggered, on the
360 * OR of PIPESTAT bits.
361 */
362 i915_enable_irq(dev_priv, interrupt);
363 pipestat = I915_READ(pipestat_reg);
364 if (IS_I965G(dev)) 405 if (IS_I965G(dev))
365 pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; 406 i915_enable_pipestat(dev_priv, pipe,
407 PIPE_START_VBLANK_INTERRUPT_ENABLE);
366 else 408 else
367 pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; 409 i915_enable_pipestat(dev_priv, pipe,
368 /* Clear any stale interrupt status */ 410 PIPE_VBLANK_INTERRUPT_ENABLE);
369 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
370 PIPE_VBLANK_INTERRUPT_STATUS);
371 I915_WRITE(pipestat_reg, pipestat);
372 (void) I915_READ(pipestat_reg); /* Posting read */
373 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 411 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
374
375 return 0; 412 return 0;
376} 413}
377 414
@@ -381,37 +418,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
381void i915_disable_vblank(struct drm_device *dev, int pipe) 418void i915_disable_vblank(struct drm_device *dev, int pipe)
382{ 419{
383 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 420 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
384 u32 pipestat_reg = 0;
385 u32 pipestat;
386 u32 interrupt = 0;
387 unsigned long irqflags; 421 unsigned long irqflags;
388 422
389 switch (pipe) {
390 case 0:
391 pipestat_reg = PIPEASTAT;
392 interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
393 break;
394 case 1:
395 pipestat_reg = PIPEBSTAT;
396 interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
397 break;
398 default:
399 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
400 pipe);
401 return;
402 break;
403 }
404
405 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 423 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
406 i915_disable_irq(dev_priv, interrupt); 424 i915_disable_pipestat(dev_priv, pipe,
407 pipestat = I915_READ(pipestat_reg); 425 PIPE_VBLANK_INTERRUPT_ENABLE |
408 pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | 426 PIPE_START_VBLANK_INTERRUPT_ENABLE);
409 PIPE_VBLANK_INTERRUPT_ENABLE);
410 /* Clear any stale interrupt status */
411 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
412 PIPE_VBLANK_INTERRUPT_STATUS);
413 I915_WRITE(pipestat_reg, pipestat);
414 (void) I915_READ(pipestat_reg); /* Posting read */
415 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 427 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
416} 428}
417 429
@@ -476,32 +488,35 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
476 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 488 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
477 489
478 I915_WRITE(HWSTAM, 0xeffe); 490 I915_WRITE(HWSTAM, 0xeffe);
491 I915_WRITE(PIPEASTAT, 0);
492 I915_WRITE(PIPEBSTAT, 0);
479 I915_WRITE(IMR, 0xffffffff); 493 I915_WRITE(IMR, 0xffffffff);
480 I915_WRITE(IER, 0x0); 494 I915_WRITE(IER, 0x0);
495 (void) I915_READ(IER);
481} 496}
482 497
483int i915_driver_irq_postinstall(struct drm_device *dev) 498int i915_driver_irq_postinstall(struct drm_device *dev)
484{ 499{
485 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 500 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
486 int ret, num_pipes = 2;
487
488 /* Set initial unmasked IRQs to just the selected vblank pipes. */
489 dev_priv->irq_mask_reg = ~0;
490
491 ret = drm_vblank_init(dev, num_pipes);
492 if (ret)
493 return ret;
494 501
495 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; 502 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
496 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
497 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
498 503
499 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 504 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
500 505
501 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK; 506 /* Unmask the interrupts that we always want on. */
507 dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
508
509 dev_priv->pipestat[0] = 0;
510 dev_priv->pipestat[1] = 0;
511
512 /* Disable pipe interrupt enables, clear pending pipe status */
513 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
514 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
515 /* Clear pending interrupt status */
516 I915_WRITE(IIR, I915_READ(IIR));
502 517
503 I915_WRITE(IMR, dev_priv->irq_mask_reg);
504 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); 518 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
519 I915_WRITE(IMR, dev_priv->irq_mask_reg);
505 (void) I915_READ(IER); 520 (void) I915_READ(IER);
506 521
507 opregion_enable_asle(dev); 522 opregion_enable_asle(dev);
@@ -513,7 +528,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
513void i915_driver_irq_uninstall(struct drm_device * dev) 528void i915_driver_irq_uninstall(struct drm_device * dev)
514{ 529{
515 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 530 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
516 u32 temp;
517 531
518 if (!dev_priv) 532 if (!dev_priv)
519 return; 533 return;
@@ -521,13 +535,12 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
521 dev_priv->vblank_pipe = 0; 535 dev_priv->vblank_pipe = 0;
522 536
523 I915_WRITE(HWSTAM, 0xffffffff); 537 I915_WRITE(HWSTAM, 0xffffffff);
538 I915_WRITE(PIPEASTAT, 0);
539 I915_WRITE(PIPEBSTAT, 0);
524 I915_WRITE(IMR, 0xffffffff); 540 I915_WRITE(IMR, 0xffffffff);
525 I915_WRITE(IER, 0x0); 541 I915_WRITE(IER, 0x0);
526 542
527 temp = I915_READ(PIPEASTAT); 543 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
528 I915_WRITE(PIPEASTAT, temp); 544 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
529 temp = I915_READ(PIPEBSTAT); 545 I915_WRITE(IIR, I915_READ(IIR));
530 I915_WRITE(PIPEBSTAT, temp);
531 temp = I915_READ(IIR);
532 I915_WRITE(IIR, temp);
533} 546}
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 1787a0c7e3ab..13ae731a33db 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -235,17 +235,15 @@ void opregion_enable_asle(struct drm_device *dev)
235 struct opregion_asle *asle = dev_priv->opregion.asle; 235 struct opregion_asle *asle = dev_priv->opregion.asle;
236 236
237 if (asle) { 237 if (asle) {
238 u32 pipeb_stats = I915_READ(PIPEBSTAT);
239 if (IS_MOBILE(dev)) { 238 if (IS_MOBILE(dev)) {
240 /* Many devices trigger events with a write to the 239 unsigned long irqflags;
241 legacy backlight controller, so we need to ensure 240
242 that it's able to generate interrupts */ 241 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
243 I915_WRITE(PIPEBSTAT, pipeb_stats |= 242 i915_enable_pipestat(dev_priv, 1,
244 I915_LEGACY_BLC_EVENT_ENABLE); 243 I915_LEGACY_BLC_EVENT_ENABLE);
245 i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT | 244 spin_unlock_irqrestore(&dev_priv->user_irq_lock,
246 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); 245 irqflags);
247 } else 246 }
248 i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
249 247
250 asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | 248 asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
251 ASLE_PFMB_EN; 249 ASLE_PFMB_EN;
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 5ddc6e595c0c..5d84027ee8f3 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -244,6 +244,9 @@ int i915_save_state(struct drm_device *dev)
244 if (IS_I965G(dev) && IS_MOBILE(dev)) 244 if (IS_I965G(dev) && IS_MOBILE(dev))
245 dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); 245 dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
246 246
247 /* Hardware status page */
248 dev_priv->saveHWS = I915_READ(HWS_PGA);
249
247 /* Display arbitration control */ 250 /* Display arbitration control */
248 dev_priv->saveDSPARB = I915_READ(DSPARB); 251 dev_priv->saveDSPARB = I915_READ(DSPARB);
249 252
@@ -373,6 +376,9 @@ int i915_restore_state(struct drm_device *dev)
373 if (IS_I965G(dev) && IS_MOBILE(dev)) 376 if (IS_I965G(dev) && IS_MOBILE(dev))
374 I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); 377 I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
375 378
379 /* Hardware status page */
380 I915_WRITE(HWS_PGA, dev_priv->saveHWS);
381
376 /* Display arbitration */ 382 /* Display arbitration */
377 I915_WRITE(DSPARB, dev_priv->saveDSPARB); 383 I915_WRITE(DSPARB, dev_priv->saveDSPARB);
378 384
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index c1d12dbfa8d8..b49c5ff29585 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -396,6 +396,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
396int mga_driver_load(struct drm_device * dev, unsigned long flags) 396int mga_driver_load(struct drm_device * dev, unsigned long flags)
397{ 397{
398 drm_mga_private_t *dev_priv; 398 drm_mga_private_t *dev_priv;
399 int ret;
399 400
400 dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); 401 dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
401 if (!dev_priv) 402 if (!dev_priv)
@@ -415,6 +416,13 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags)
415 dev->types[7] = _DRM_STAT_PRIMARY; 416 dev->types[7] = _DRM_STAT_PRIMARY;
416 dev->types[8] = _DRM_STAT_SECONDARY; 417 dev->types[8] = _DRM_STAT_SECONDARY;
417 418
419 ret = drm_vblank_init(dev, 1);
420
421 if (ret) {
422 (void) mga_driver_unload(dev);
423 return ret;
424 }
425
418 return 0; 426 return 0;
419} 427}
420 428
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c
index bab42f41188b..daa6041a483a 100644
--- a/drivers/gpu/drm/mga/mga_irq.c
+++ b/drivers/gpu/drm/mga/mga_irq.c
@@ -152,11 +152,6 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
152int mga_driver_irq_postinstall(struct drm_device *dev) 152int mga_driver_irq_postinstall(struct drm_device *dev)
153{ 153{
154 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; 154 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
155 int ret;
156
157 ret = drm_vblank_init(dev, 1);
158 if (ret)
159 return ret;
160 155
161 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); 156 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
162 157
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index 3265d53ba91f..601f4c0e5da5 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -45,6 +45,7 @@ static struct drm_driver driver = {
45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | 45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, 46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
47 .dev_priv_size = sizeof(drm_r128_buf_priv_t), 47 .dev_priv_size = sizeof(drm_r128_buf_priv_t),
48 .load = r128_driver_load,
48 .preclose = r128_driver_preclose, 49 .preclose = r128_driver_preclose,
49 .lastclose = r128_driver_lastclose, 50 .lastclose = r128_driver_lastclose,
50 .get_vblank_counter = r128_get_vblank_counter, 51 .get_vblank_counter = r128_get_vblank_counter,
@@ -84,6 +85,11 @@ static struct drm_driver driver = {
84 .patchlevel = DRIVER_PATCHLEVEL, 85 .patchlevel = DRIVER_PATCHLEVEL,
85}; 86};
86 87
88int r128_driver_load(struct drm_device * dev, unsigned long flags)
89{
90 return drm_vblank_init(dev, 1);
91}
92
87static int __init r128_init(void) 93static int __init r128_init(void)
88{ 94{
89 driver.num_ioctls = r128_max_ioctl; 95 driver.num_ioctls = r128_max_ioctl;
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h
index 5898b274279d..797a26c42dab 100644
--- a/drivers/gpu/drm/r128/r128_drv.h
+++ b/drivers/gpu/drm/r128/r128_drv.h
@@ -159,6 +159,7 @@ extern void r128_driver_irq_preinstall(struct drm_device * dev);
159extern int r128_driver_irq_postinstall(struct drm_device *dev); 159extern int r128_driver_irq_postinstall(struct drm_device *dev);
160extern void r128_driver_irq_uninstall(struct drm_device * dev); 160extern void r128_driver_irq_uninstall(struct drm_device * dev);
161extern void r128_driver_lastclose(struct drm_device * dev); 161extern void r128_driver_lastclose(struct drm_device * dev);
162extern int r128_driver_load(struct drm_device * dev, unsigned long flags);
162extern void r128_driver_preclose(struct drm_device * dev, 163extern void r128_driver_preclose(struct drm_device * dev,
163 struct drm_file *file_priv); 164 struct drm_file *file_priv);
164 165
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c
index d7349012a680..69810fb8ac49 100644
--- a/drivers/gpu/drm/r128/r128_irq.c
+++ b/drivers/gpu/drm/r128/r128_irq.c
@@ -102,7 +102,7 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
102 102
103int r128_driver_irq_postinstall(struct drm_device *dev) 103int r128_driver_irq_postinstall(struct drm_device *dev)
104{ 104{
105 return drm_vblank_init(dev, 1); 105 return 0;
106} 106}
107 107
108void r128_driver_irq_uninstall(struct drm_device * dev) 108void r128_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index abdc1ae38467..dcebb4bee7aa 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -1757,6 +1757,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
1757 if (ret != 0) 1757 if (ret != 0)
1758 return ret; 1758 return ret;
1759 1759
1760 ret = drm_vblank_init(dev, 2);
1761 if (ret) {
1762 radeon_driver_unload(dev);
1763 return ret;
1764 }
1765
1760 DRM_DEBUG("%s card detected\n", 1766 DRM_DEBUG("%s card detected\n",
1761 ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); 1767 ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
1762 return ret; 1768 return ret;
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 5079f7054a2f..97c0599fdb1e 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -337,15 +337,10 @@ int radeon_driver_irq_postinstall(struct drm_device *dev)
337{ 337{
338 drm_radeon_private_t *dev_priv = 338 drm_radeon_private_t *dev_priv =
339 (drm_radeon_private_t *) dev->dev_private; 339 (drm_radeon_private_t *) dev->dev_private;
340 int ret;
341 340
342 atomic_set(&dev_priv->swi_emitted, 0); 341 atomic_set(&dev_priv->swi_emitted, 0);
343 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); 342 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
344 343
345 ret = drm_vblank_init(dev, 2);
346 if (ret)
347 return ret;
348
349 dev->max_vblank_count = 0x001fffff; 344 dev->max_vblank_count = 0x001fffff;
350 345
351 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); 346 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index 665d319b927b..c248c1d37268 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -314,7 +314,6 @@ int via_driver_irq_postinstall(struct drm_device *dev)
314 if (!dev_priv) 314 if (!dev_priv)
315 return -EINVAL; 315 return -EINVAL;
316 316
317 drm_vblank_init(dev, 1);
318 status = VIA_READ(VIA_REG_INTERRUPT); 317 status = VIA_READ(VIA_REG_INTERRUPT);
319 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL 318 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
320 | dev_priv->irq_enable_mask); 319 | dev_priv->irq_enable_mask);
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index a967556be014..2c4f0b485792 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -107,8 +107,17 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
107 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); 107 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
108 if (ret) { 108 if (ret) {
109 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); 109 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
110 return ret;
110 } 111 }
111 return ret; 112
113 ret = drm_vblank_init(dev, 1);
114 if (ret) {
115 drm_sman_takedown(&dev_priv->sman);
116 drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
117 return ret;
118 }
119
120 return 0;
112} 121}
113 122
114int via_driver_unload(struct drm_device *dev) 123int via_driver_unload(struct drm_device *dev)