root/drivers/gpu/drm/qxl/qxl_irq.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qxl_irq_handler
  2. qxl_client_monitors_config_work_func
  3. qxl_irq_init

   1 /*
   2  * Copyright 2013 Red Hat Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  * Authors: Dave Airlie
  23  *          Alon Levy
  24  */
  25 
  26 #include <linux/pci.h>
  27 
  28 #include <drm/drm_irq.h>
  29 
  30 #include "qxl_drv.h"
  31 
  32 irqreturn_t qxl_irq_handler(int irq, void *arg)
  33 {
  34         struct drm_device *dev = (struct drm_device *) arg;
  35         struct qxl_device *qdev = (struct qxl_device *)dev->dev_private;
  36         uint32_t pending;
  37 
  38         pending = xchg(&qdev->ram_header->int_pending, 0);
  39 
  40         if (!pending)
  41                 return IRQ_NONE;
  42 
  43         atomic_inc(&qdev->irq_received);
  44 
  45         if (pending & QXL_INTERRUPT_DISPLAY) {
  46                 atomic_inc(&qdev->irq_received_display);
  47                 wake_up_all(&qdev->display_event);
  48                 qxl_queue_garbage_collect(qdev, false);
  49         }
  50         if (pending & QXL_INTERRUPT_CURSOR) {
  51                 atomic_inc(&qdev->irq_received_cursor);
  52                 wake_up_all(&qdev->cursor_event);
  53         }
  54         if (pending & QXL_INTERRUPT_IO_CMD) {
  55                 atomic_inc(&qdev->irq_received_io_cmd);
  56                 wake_up_all(&qdev->io_cmd_event);
  57         }
  58         if (pending & QXL_INTERRUPT_ERROR) {
  59                 /* TODO: log it, reset device (only way to exit this condition)
  60                  * (do it a certain number of times, afterwards admit defeat,
  61                  * to avoid endless loops).
  62                  */
  63                 qdev->irq_received_error++;
  64                 DRM_WARN("driver is in bug mode\n");
  65         }
  66         if (pending & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG) {
  67                 schedule_work(&qdev->client_monitors_config_work);
  68         }
  69         qdev->ram_header->int_mask = QXL_INTERRUPT_MASK;
  70         outb(0, qdev->io_base + QXL_IO_UPDATE_IRQ);
  71         return IRQ_HANDLED;
  72 }
  73 
  74 static void qxl_client_monitors_config_work_func(struct work_struct *work)
  75 {
  76         struct qxl_device *qdev = container_of(work, struct qxl_device,
  77                                                client_monitors_config_work);
  78 
  79         qxl_display_read_client_monitors_config(qdev);
  80 }
  81 
  82 int qxl_irq_init(struct qxl_device *qdev)
  83 {
  84         int ret;
  85 
  86         init_waitqueue_head(&qdev->display_event);
  87         init_waitqueue_head(&qdev->cursor_event);
  88         init_waitqueue_head(&qdev->io_cmd_event);
  89         INIT_WORK(&qdev->client_monitors_config_work,
  90                   qxl_client_monitors_config_work_func);
  91         atomic_set(&qdev->irq_received, 0);
  92         atomic_set(&qdev->irq_received_display, 0);
  93         atomic_set(&qdev->irq_received_cursor, 0);
  94         atomic_set(&qdev->irq_received_io_cmd, 0);
  95         qdev->irq_received_error = 0;
  96         ret = drm_irq_install(&qdev->ddev, qdev->ddev.pdev->irq);
  97         qdev->ram_header->int_mask = QXL_INTERRUPT_MASK;
  98         if (unlikely(ret != 0)) {
  99                 DRM_ERROR("Failed installing irq: %d\n", ret);
 100                 return 1;
 101         }
 102         return 0;
 103 }

/* [<][>][^][v][top][bottom][index][help] */