m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-23 00:16:05 +0200
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-23 00:19:16 +0200
commit42dc62e5db80994c51e0e62d6c264ce71c655c58 (patch)
treee7537409ef8842fd89ae568c7c23de396d086b42
parent340435b03e9d73597833e922a736fd7ed61d58ff (diff)
Add synchronization and irq
-rw-r--r--pci.c41
-rw-r--r--private_data.h6
2 files changed, 47 insertions, 0 deletions
diff --git a/pci.c b/pci.c
index e747118..0402647 100644
--- a/pci.c
+++ b/pci.c
@@ -2,6 +2,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
#include "char.h"
#include "harddoom.h"
@@ -9,6 +10,34 @@
#include "harddoomdev.h"
#include "private_data.h"
+void handle_pong_sync(struct doom_data *doom_data)
+{
+ up(&doom_data->pong_sem);
+}
+
+irqreturn_t doom_irq(int irq, void *dev)
+{
+ uint32_t interrupts;
+ struct doom_data *doom_data;
+
+
+ doom_data = dev;
+
+ interrupts = get_interrupts(doom_data->iomem);
+ if (!interrupts) {
+ return IRQ_NONE;
+ }
+
+ if (interrupts & HARDDOOM_INTR_PONG_SYNC) {
+ handle_pong_sync(doom_data);
+ interrupts &= ~HARDDOOM_INTR_PONG_SYNC;
+ }
+
+ deactivate_intr(doom_data->iomem, HARDDOOM_INTR_MASK);
+
+ return IRQ_HANDLED;
+}
+
int init_pci(struct pci_dev *dev)
{
struct doom_data *doom_data;
@@ -30,8 +59,19 @@ int init_pci(struct pci_dev *dev)
pci_set_dma_mask(dev, DMA_BIT_MASK(32));
pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(32));
+ mutex_init(&doom_data->mutex);
+ sema_init(&doom_data->ping_sem, 1);
+ sema_init(&doom_data->pong_sem, 0);
+
+ ORFAIL(request_irq(dev->irq, doom_irq, IRQF_SHARED,
+ "doom", doom_data), error_irq);
+
return 0;
+error_irq:
+ pci_clear_master(dev);
+ pci_iounmap(dev, doom_data->iomem);
+ kfree(doom_data);
error_kmalloc:
pci_release_regions(dev);
error_regions:
@@ -46,6 +86,7 @@ void cleanup_pci(struct pci_dev *dev)
doom_data = pci_get_drvdata(dev);
+ free_irq(dev->irq, doom_data);
pci_clear_master(dev);
pci_iounmap(dev, doom_data->iomem);
kfree(doom_data);
diff --git a/private_data.h b/private_data.h
index 38148bd..39ceba8 100644
--- a/private_data.h
+++ b/private_data.h
@@ -9,13 +9,19 @@ struct doom_data {
struct device *device;
struct device *pci_device;
void __iomem *iomem;
+ struct mutex mutex;
+ struct semaphore ping_sem;
+ struct semaphore pong_sem;
};
struct surface_data {
struct doom_data *doom_data;
int surface_size;
+ int width;
+ int height;
int pages;
+ int total_bytes;
uint8_t *surface_cpu;
uint32_t *page_table_cpu;