summary refs log tree commit diff stats
path: root/hw/misc/edu.c
diff options
context:
space:
mode:
authorPeter Xu <peterx@redhat.com>2016-09-28 21:03:39 +0800
committerPaolo Bonzini <pbonzini@redhat.com>2016-10-04 10:00:25 +0200
commiteabb5782f70b4a10975b24ccd7129929a05ac932 (patch)
tree7c32841fbf0d48eea6383040b2dde1353446590f /hw/misc/edu.c
parent3cf294eebc98da6e2ff7976fcdf6a9b41984840e (diff)
downloadfocaccia-qemu-eabb5782f70b4a10975b24ccd7129929a05ac932.tar.gz
focaccia-qemu-eabb5782f70b4a10975b24ccd7129929a05ac932.zip
hw/misc/edu: support MSI interrupt
So now edu device can support both line or msi interrupt, depending on
how user configures it.

Signed-off-by: Peter Xu <peterx@redhat.com>
Message-Id: <1475067819-21413-1-git-send-email-peterx@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/misc/edu.c')
-rw-r--r--hw/misc/edu.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/hw/misc/edu.c b/hw/misc/edu.c
index 888ba49a0e..401039c100 100644
--- a/hw/misc/edu.c
+++ b/hw/misc/edu.c
@@ -24,6 +24,7 @@
 
 #include "qemu/osdep.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/msi.h"
 #include "qemu/timer.h"
 #include "qemu/main-loop.h" /* iothread mutex */
 #include "qapi/visitor.h"
@@ -69,11 +70,20 @@ typedef struct {
     uint64_t dma_mask;
 } EduState;
 
+static bool edu_msi_enabled(EduState *edu)
+{
+    return msi_enabled(&edu->pdev);
+}
+
 static void edu_raise_irq(EduState *edu, uint32_t val)
 {
     edu->irq_status |= val;
     if (edu->irq_status) {
-        pci_set_irq(&edu->pdev, 1);
+        if (edu_msi_enabled(edu)) {
+            msi_notify(&edu->pdev, 0);
+        } else {
+            pci_set_irq(&edu->pdev, 1);
+        }
     }
 }
 
@@ -81,7 +91,7 @@ static void edu_lower_irq(EduState *edu, uint32_t val)
 {
     edu->irq_status &= ~val;
 
-    if (!edu->irq_status) {
+    if (!edu->irq_status && !edu_msi_enabled(edu)) {
         pci_set_irq(&edu->pdev, 0);
     }
 }
@@ -342,6 +352,10 @@ static void pci_edu_realize(PCIDevice *pdev, Error **errp)
 
     pci_config_set_interrupt_pin(pci_conf, 1);
 
+    if (msi_init(pdev, 0, 1, true, false, errp)) {
+        return;
+    }
+
     memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
                     "edu-mmio", 1 << 20);
     pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);