diff options
| author | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-23 00:16:05 +0200 | 
|---|---|---|
| committer | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-23 00:19:16 +0200 | 
| commit | 42dc62e5db80994c51e0e62d6c264ce71c655c58 (patch) | |
| tree | e7537409ef8842fd89ae568c7c23de396d086b42 | |
| parent | 340435b03e9d73597833e922a736fd7ed61d58ff (diff) | |
Add synchronization and irq
| -rw-r--r-- | pci.c | 41 | ||||
| -rw-r--r-- | private_data.h | 6 | 
2 files changed, 47 insertions, 0 deletions
| @@ -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; |