aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_irq.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.c106
1 files changed, 23 insertions, 83 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index 3eb097efc488..249c0330d6ce 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -152,12 +152,10 @@ int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id)
152 152
153 DBG("dev=%p, crtc=%d", dev, crtc_id); 153 DBG("dev=%p, crtc=%d", dev, crtc_id);
154 154
155 dispc_runtime_get();
156 spin_lock_irqsave(&list_lock, flags); 155 spin_lock_irqsave(&list_lock, flags);
157 priv->vblank_mask |= pipe2vbl(crtc); 156 priv->vblank_mask |= pipe2vbl(crtc);
158 omap_irq_update(dev); 157 omap_irq_update(dev);
159 spin_unlock_irqrestore(&list_lock, flags); 158 spin_unlock_irqrestore(&list_lock, flags);
160 dispc_runtime_put();
161 159
162 return 0; 160 return 0;
163} 161}
@@ -179,15 +177,13 @@ void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id)
179 177
180 DBG("dev=%p, crtc=%d", dev, crtc_id); 178 DBG("dev=%p, crtc=%d", dev, crtc_id);
181 179
182 dispc_runtime_get();
183 spin_lock_irqsave(&list_lock, flags); 180 spin_lock_irqsave(&list_lock, flags);
184 priv->vblank_mask &= ~pipe2vbl(crtc); 181 priv->vblank_mask &= ~pipe2vbl(crtc);
185 omap_irq_update(dev); 182 omap_irq_update(dev);
186 spin_unlock_irqrestore(&list_lock, flags); 183 spin_unlock_irqrestore(&list_lock, flags);
187 dispc_runtime_put();
188} 184}
189 185
190irqreturn_t omap_irq_handler(int irq, void *arg) 186static irqreturn_t omap_irq_handler(int irq, void *arg)
191{ 187{
192 struct drm_device *dev = (struct drm_device *) arg; 188 struct drm_device *dev = (struct drm_device *) arg;
193 struct omap_drm_private *priv = dev->dev_private; 189 struct omap_drm_private *priv = dev->dev_private;
@@ -222,23 +218,29 @@ irqreturn_t omap_irq_handler(int irq, void *arg)
222 return IRQ_HANDLED; 218 return IRQ_HANDLED;
223} 219}
224 220
225void omap_irq_preinstall(struct drm_device *dev) 221/*
226{ 222 * We need a special version, instead of just using drm_irq_install(),
227 DBG("dev=%p", dev); 223 * because we need to register the irq via omapdss. Once omapdss and
228 dispc_runtime_get(); 224 * omapdrm are merged together we can assign the dispc hwmod data to
229 dispc_clear_irqstatus(0xffffffff); 225 * ourselves and drop these and just use drm_irq_{install,uninstall}()
230 dispc_runtime_put(); 226 */
231}
232 227
233int omap_irq_postinstall(struct drm_device *dev) 228int omap_drm_irq_install(struct drm_device *dev)
234{ 229{
235 struct omap_drm_private *priv = dev->dev_private; 230 struct omap_drm_private *priv = dev->dev_private;
236 struct omap_drm_irq *error_handler = &priv->error_handler; 231 struct omap_drm_irq *error_handler = &priv->error_handler;
237 232 int ret;
238 DBG("dev=%p", dev);
239 233
240 INIT_LIST_HEAD(&priv->irq_list); 234 INIT_LIST_HEAD(&priv->irq_list);
241 235
236 dispc_runtime_get();
237 dispc_clear_irqstatus(0xffffffff);
238 dispc_runtime_put();
239
240 ret = dispc_request_irq(omap_irq_handler, dev);
241 if (ret < 0)
242 return ret;
243
242 error_handler->irq = omap_irq_error_handler; 244 error_handler->irq = omap_irq_error_handler;
243 error_handler->irqmask = DISPC_IRQ_OCP_ERR; 245 error_handler->irqmask = DISPC_IRQ_OCP_ERR;
244 246
@@ -249,76 +251,22 @@ int omap_irq_postinstall(struct drm_device *dev)
249 251
250 omap_irq_register(dev, error_handler); 252 omap_irq_register(dev, error_handler);
251 253
252 return 0;
253}
254
255void omap_irq_uninstall(struct drm_device *dev)
256{
257 DBG("dev=%p", dev);
258 // TODO prolly need to call drm_irq_uninstall() somewhere too
259}
260
261/*
262 * We need a special version, instead of just using drm_irq_install(),
263 * because we need to register the irq via omapdss. Once omapdss and
264 * omapdrm are merged together we can assign the dispc hwmod data to
265 * ourselves and drop these and just use drm_irq_{install,uninstall}()
266 */
267
268int omap_drm_irq_install(struct drm_device *dev)
269{
270 int ret;
271
272 mutex_lock(&dev->struct_mutex);
273
274 if (dev->irq_enabled) {
275 mutex_unlock(&dev->struct_mutex);
276 return -EBUSY;
277 }
278 dev->irq_enabled = true; 254 dev->irq_enabled = true;
279 mutex_unlock(&dev->struct_mutex);
280
281 /* Before installing handler */
282 if (dev->driver->irq_preinstall)
283 dev->driver->irq_preinstall(dev);
284 255
285 ret = dispc_request_irq(dev->driver->irq_handler, dev); 256 return 0;
286
287 if (ret < 0) {
288 mutex_lock(&dev->struct_mutex);
289 dev->irq_enabled = false;
290 mutex_unlock(&dev->struct_mutex);
291 return ret;
292 }
293
294 /* After installing handler */
295 if (dev->driver->irq_postinstall)
296 ret = dev->driver->irq_postinstall(dev);
297
298 if (ret < 0) {
299 mutex_lock(&dev->struct_mutex);
300 dev->irq_enabled = false;
301 mutex_unlock(&dev->struct_mutex);
302 dispc_free_irq(dev);
303 }
304
305 return ret;
306} 257}
307 258
308int omap_drm_irq_uninstall(struct drm_device *dev) 259void omap_drm_irq_uninstall(struct drm_device *dev)
309{ 260{
310 unsigned long irqflags; 261 unsigned long irqflags;
311 bool irq_enabled;
312 int i; 262 int i;
313 263
314 mutex_lock(&dev->struct_mutex); 264 if (!dev->irq_enabled)
315 irq_enabled = dev->irq_enabled; 265 return;
266
316 dev->irq_enabled = false; 267 dev->irq_enabled = false;
317 mutex_unlock(&dev->struct_mutex);
318 268
319 /* 269 /* Wake up any waiters so they don't hang. */
320 * Wake up any waiters so they don't hang.
321 */
322 if (dev->num_crtcs) { 270 if (dev->num_crtcs) {
323 spin_lock_irqsave(&dev->vbl_lock, irqflags); 271 spin_lock_irqsave(&dev->vbl_lock, irqflags);
324 for (i = 0; i < dev->num_crtcs; i++) { 272 for (i = 0; i < dev->num_crtcs; i++) {
@@ -330,13 +278,5 @@ int omap_drm_irq_uninstall(struct drm_device *dev)
330 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 278 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
331 } 279 }
332 280
333 if (!irq_enabled)
334 return -EINVAL;
335
336 if (dev->driver->irq_uninstall)
337 dev->driver->irq_uninstall(dev);
338
339 dispc_free_irq(dev); 281 dispc_free_irq(dev);
340
341 return 0;
342} 282}