Project

General

Profile

RE: Using PREEMPT_RT on MitySOM 5CSX Dev Board » fpga_uinput.c

V J, 12/18/2017 12:48 PM

 
1
#include <linux/init.h>
2
#include <linux/module.h>
3
#include <linux/kernel.h>
4
#include <linux/device.h>
5
#include <linux/platform_device.h>
6
#include <linux/ioport.h>
7
#include <linux/io.h>
8
#include <linux/wait.h>
9
#include <linux/sched.h>
10
#include <linux/semaphore.h>
11
#include <linux/interrupt.h>
12
#include <linux/spinlock_types.h>
13

    
14
#define UINPUT_BASE 0xff200000
15
#define UINPUT_SIZE PAGE_SIZE
16
//#define UINPUT_INT_NUM 72
17
//#define UINPUT_INT_NUM 352
18

    
19
//#define UINPUT_INT_NUM 40 //no irq
20
//#define UINPUT_INT_NUM 41 //no irq
21
//#define UINPUT_INT_NUM 71 //HANG
22
//#define UINPUT_INT_NUM 72 //HANG
23
//#define UINPUT_INT_NUM 65 //no irq
24
//#define UINPUT_INT_NUM 0 //not able to insmood
25
//#define UINPUT_INT_NUM 1 //not able to insmood
26
//#define UINPUT_INT_NUM 15 //not able to insmood
27
//#define UINPUT_INT_NUM 40 //working when enabling irq?
28
//#define UINPUT_INT_NUM 35 //Working
29
//#define UINPUT_INT_NUM 77 //HANG
30
//#define UINPUT_INT_NUM 79 //HANG
31
//#define UINPUT_INT_NUM 42 // no irq
32
//#define UINPUT_INT_NUM 89 // itq line 2, nbr 17
33
//#define UINPUT_INT_NUM 43 //no irq
34
//#define UINPUT_INT_NUM 38 // no_irq
35
//#define UINPUT_INT_NUM 74 // HANG
36
//#define UINPUT_INT_NUM 34  // no_irq
37
//#define UINPUT_INT_NUM 36  // no_irq
38
//#define UINPUT_INT_NUM 37  // no_irq
39
//#define UINPUT_INT_NUM 38  // no_irq
40
//#define UINPUT_INT_NUM 33  // no_irq
41
//#define UINPUT_INT_NUM 32  // no_irq
42
//#define UINPUT_INT_NUM 39  // no_irq
43
//#define UINPUT_INT_NUM 41  // no_irq
44
//#define UINPUT_INT_NUM 68  // Error not instert, 122??
45
#define UINPUT_INT_NUM 43  // Error not instert, 123
46
//#define UINPUT_INT_NUM 40  // Error not instert, 123
47

    
48
void *fpga_uinput_mem;
49

    
50
static DEFINE_SEMAPHORE(interrupt_mutex);
51
static DECLARE_WAIT_QUEUE_HEAD(interrupt_wq);
52

    
53
static int interrupt_flag = 0;
54
static DEFINE_SPINLOCK(interrupt_flag_lock);
55
static uint8_t input_state;
56
//static int irq_cnt = 0;
57

    
58
static irqreturn_t fpga_uinput_interrupt(int irq, void *dev_id)
59
{
60
	if (irq != UINPUT_INT_NUM)
61
   {
62
		return IRQ_NONE;
63
   }
64
	spin_lock(&interrupt_flag_lock);
65
	interrupt_flag = 1;
66
	input_state = ioread8(fpga_uinput_mem);
67
	spin_unlock(&interrupt_flag_lock);
68

    
69
	wake_up_interruptible(&interrupt_wq);
70

    
71
	return IRQ_HANDLED;
72
}
73

    
74
static struct device_driver fpga_uinput_driver = {
75
	.name = "fpga_uinput",
76
	.bus = &platform_bus_type,
77
};
78

    
79
static ssize_t fpga_uinput_show(struct device_driver *drv, char *buf)
80
{
81
	int ret;
82
	if (down_trylock(&interrupt_mutex))
83
   {
84
     // irq_cnt++;
85
	  // if (irq_cnt == 1000)
86
		//{	
87
		  // irq_cnt = 0;
88
		   printk(KERN_ALERT "KERNEL DEBUG down_trylock: Passed %s %d \n",__FUNCTION__,__LINE__);					
89
		//}	
90
		return -EAGAIN;
91
   }
92

    
93
   if (wait_event_interruptible(interrupt_wq, interrupt_flag != 0)) {
94
		ret = -ERESTART;
95
      printk(KERN_ALERT "KERNEL DEBUG release_and_exit: Passed %s %d \n",__FUNCTION__,__LINE__);			
96
		goto release_and_exit;
97
	}
98

    
99
	spin_lock(&interrupt_flag_lock);
100
	interrupt_flag = 0;
101
	spin_unlock(&interrupt_flag_lock);
102

    
103
	buf[0] = input_state;
104
	ret = 1;
105

    
106
release_and_exit:
107
	up(&interrupt_mutex);
108
	return ret;
109
}
110

    
111
static ssize_t fpga_uinput_store(struct device_driver *drv,
112
		const char *buf, size_t count)
113
{
114
	return -EROFS;
115
}
116

    
117
static DRIVER_ATTR(fpga_uinput, S_IRUSR, fpga_uinput_show, fpga_uinput_store);
118

    
119
static int __init fpga_uinput_init(void)
120
{
121
	int ret;
122
	struct resource *res;
123

    
124
    printk(KERN_ALERT "KERNEL DEBUG fpga_uinput_init: Passed %s %d \n",__FUNCTION__,__LINE__);	
125
	ret = driver_register(&fpga_uinput_driver);
126
	if (ret < 0)
127
		goto fail_driver_register;
128

    
129
	ret = driver_create_file(&fpga_uinput_driver,
130
			&driver_attr_fpga_uinput);
131
	if (ret < 0)
132
		goto fail_create_file;
133

    
134
	res = request_mem_region(UINPUT_BASE, UINPUT_SIZE, "fpga_uinput");
135
	if (res == NULL) {
136
		ret = -EBUSY;
137
		goto fail_request_mem;
138
	}
139

    
140
	fpga_uinput_mem = ioremap(UINPUT_BASE, UINPUT_SIZE);
141
	if (fpga_uinput_mem == NULL) {
142
		ret = -EFAULT;
143
		goto fail_ioremap;
144
	}
145

    
146
	ret = request_irq(UINPUT_INT_NUM, fpga_uinput_interrupt,
147
			0, "fpga_uinput", NULL);
148
	if (ret < 0)
149
		goto fail_request_irq;
150

    
151
	return 0;
152

    
153
fail_request_irq:
154
	iounmap(fpga_uinput_mem);
155
fail_ioremap:
156
	release_mem_region(UINPUT_BASE, UINPUT_SIZE);
157
fail_request_mem:
158
	driver_remove_file(&fpga_uinput_driver, &driver_attr_fpga_uinput);
159
fail_create_file:
160
	driver_unregister(&fpga_uinput_driver);
161
fail_driver_register:
162
	return ret;
163
}
164

    
165
static void __exit fpga_uinput_exit(void)
166
{
167
	free_irq(UINPUT_INT_NUM, NULL);
168
	iounmap(fpga_uinput_mem);
169
	release_mem_region(UINPUT_BASE, UINPUT_SIZE);
170
	driver_remove_file(&fpga_uinput_driver, &driver_attr_fpga_uinput);
171
	driver_unregister(&fpga_uinput_driver);
172
}
173

    
174
MODULE_LICENSE("Dual BSD/GPL");
175

    
176
module_init(fpga_uinput_init);
177
module_exit(fpga_uinput_exit);
(1-1/3) Go to top
Add picture from clipboard (Maximum size: 1 GB)