summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile.am3
-rw-r--r--lib/intr.c80
-rw-r--r--lib/main.c75
-rw-r--r--lib/priv.h23
4 files changed, 107 insertions, 74 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 67e67c6f8..352dd9f31 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -4,4 +4,5 @@ libpciaccessos_la_CPPFLAGS = -I${top_srcdir}/nvkm/include \
-I${top_srcdir}/nvkm
libpciaccessos_la_CFLAGS = @PCIACCESS_CFLAGS@
libpciaccessos_la_LDFLAGS = @PCIACCESS_LIBS@ -lpthread
-libpciaccessos_la_SOURCES = main.c
+libpciaccessos_la_SOURCES = intr.c \
+ main.c
diff --git a/lib/intr.c b/lib/intr.c
new file mode 100644
index 000000000..5563c372b
--- /dev/null
+++ b/lib/intr.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <core/device.h>
+#include <core/client.h>
+#include "priv.h"
+
+pthread_t os_intr_thread;
+struct os_intr {
+ struct list_head head;
+ irq_handler_t handler;
+ int irq;
+ void *dev;
+};
+static LIST_HEAD(os_intr_list);
+
+int
+os_intr_init(unsigned int irq, irq_handler_t handler, unsigned long flags,
+ const char *name, void *dev)
+{
+ struct os_intr *intr = malloc(sizeof(*intr));
+ if (!intr)
+ return -ENOMEM;
+ intr->handler = handler;
+ intr->irq = irq;
+ intr->dev = dev;
+ list_add(&intr->head, &os_intr_list);
+ return 0;
+}
+
+void
+os_intr_free(unsigned int irq, void *dev)
+{
+ struct os_intr *intr;
+
+ list_for_each_entry(intr, &os_intr_list, head) {
+ if (intr->irq == irq && intr->dev == dev) {
+ list_del(&intr->head);
+ free(intr);
+ break;
+ }
+ }
+}
+
+void *
+os_intr(void *arg)
+{
+ struct os_intr *intr;
+
+ while (1) {
+ list_for_each_entry(intr, &os_intr_list, head) {
+ intr->handler(intr->irq, intr->dev);
+ }
+
+ usleep(10000);
+ }
+
+ return NULL;
+}
diff --git a/lib/main.c b/lib/main.c
index afec06d45..ed1b34d2b 100644
--- a/lib/main.c
+++ b/lib/main.c
@@ -23,7 +23,6 @@
*/
#include <core/os.h>
-#include <signal.h>
#include <core/object.h>
#include <core/client.h>
@@ -34,81 +33,13 @@
#include <engine/device.h>
#include <subdev/mc.h>
-struct os_device {
- struct nouveau_device base;
- struct list_head head;
- char *name;
- char *cfg;
- char *dbg;
-};
-
-struct os_client {
- struct nouveau_client base;
- struct list_head head;
-};
+#include "priv.h"
static LIST_HEAD(os_device_list);
static LIST_HEAD(os_client_list);
static int os_client_id = 0;
/******************************************************************************
- * "interrupt" handling
- *****************************************************************************/
-#define INTR_FREQ 10000
-
-struct os_intr {
- struct list_head head;
- irq_handler_t handler;
- int irq;
- void *dev;
-};
-static LIST_HEAD(os_intr_list);
-
-int
-os_intr_init(unsigned int irq, irq_handler_t handler, unsigned long flags,
- const char *name, void *dev)
-{
- struct os_intr *intr = malloc(sizeof(*intr));
- if (!intr)
- return -ENOMEM;
- intr->handler = handler;
- intr->irq = irq;
- intr->dev = dev;
- list_add(&intr->head, &os_intr_list);
- return 0;
-}
-
-void
-os_intr_free(unsigned int irq, void *dev)
-{
- struct os_intr *intr;
-
- list_for_each_entry(intr, &os_intr_list, head) {
- if (intr->irq == irq && intr->dev == dev) {
- list_del(&intr->head);
- free(intr);
- break;
- }
- }
-}
-
-static void
-os_intr(int signal)
-{
- struct os_intr *intr;
-
- list_for_each_entry(intr, &os_intr_list, head) {
- intr->handler(intr->irq, intr->dev);
- }
-
- ualarm(INTR_FREQ, 0);
-}
-
-static struct sigaction intr = {
- .sa_handler = os_intr,
-};
-
-/******************************************************************************
* horrific stuff to implement linux's ioremap interface on top of pciaccess
*****************************************************************************/
static struct os_ioremap_info {
@@ -248,9 +179,7 @@ os_init(char *cfg, char *dbg, bool init)
os_init_device(pdev, cfg, dbg);
}
- sigaction(SIGALRM, &intr, 0);
- ualarm(INTR_FREQ, 0);
- return 0;
+ return pthread_create(&os_intr_thread, NULL, os_intr, NULL);
}
static void
diff --git a/lib/priv.h b/lib/priv.h
new file mode 100644
index 000000000..65448b24b
--- /dev/null
+++ b/lib/priv.h
@@ -0,0 +1,23 @@
+#ifndef __OS_PRIV_H__
+#define __OS_PRIV_H__
+
+#include <pthread.h>
+#include <unistd.h>
+
+struct os_device {
+ struct nouveau_device base;
+ struct list_head head;
+ char *name;
+ char *cfg;
+ char *dbg;
+};
+
+struct os_client {
+ struct nouveau_client base;
+ struct list_head head;
+};
+
+extern pthread_t os_intr_thread;
+void *os_intr(void *arg);
+
+#endif