1 #include <linux/version.h>
2 #include <linux/module.h>
3 #include <linux/moduleparam.h>
4 #include <asm-generic/iomap.h>
6 #include "../include/vmebus.h"
9 #define PFX "CtrPPSIrq: "
10 #define DRV_MODULE_VERSION "1.0"
12 static struct vme_mapping ctr_desc
= {
13 .data_width
= VME_D32
,
14 .am
= VME_A24_USER_DATA_SCT
,
15 .read_prefetch_enabled
= 0,
22 static void *vmeaddr
= NULL
; /* Point to CTR hardware */
23 CtrDrvrMemoryMap
*mmap
;
25 #define CTR_IRQ_LEVEL 2
26 #define CTR_IRQ_VECTOR 0xb8
29 unsigned int ClearInterrupt(void)
33 source
= ioread32be((unsigned int *)&mmap
->InterruptSource
);
38 void EnableCtrInterrupt(void) {
42 printk(KERN_DEBUG PFX
"Enabling PPS interrupt on IRQ%d Vector %d\n",
43 CTR_IRQ_LEVEL
, CTR_IRQ_VECTOR
);
45 /* Setup the IRQ level and vector */
46 val
= (unsigned long)((CTR_IRQ_LEVEL
<< 8) | (CTR_IRQ_VECTOR
& 0xff));
47 iowrite32be(val
, &mmap
->Setup
);
49 if (vme_bus_error_check(1))
50 printk(KERN_ERR PFX
"Bus error writing Setup\n");
52 /* Will interrupt once per second */
53 iowrite32be(CtrDrvrInterruptMaskPPS
, &mmap
->InterruptEnable
);
55 if (vme_bus_error_check(1))
56 printk(KERN_ERR PFX
"Bus error writing InterruptEnable\n");
58 val
= ioread32be(&mmap
->InterruptEnable
);
60 if (vme_bus_error_check(1))
61 printk(KERN_ERR PFX
"Bus error reading InterruptEnable\n");
63 if (val
!= CtrDrvrInterruptMaskPPS
)
64 printk(KERN_DEBUG PFX
"Failed to enable PPS interrupt %08x\n",
68 void DisableCtrInterrupt(void)
70 printk(KERN_DEBUG PFX
"Disabling PPS interrupt\n");
71 iowrite32be(0, &mmap
->InterruptEnable
);
73 if (vme_bus_error_check(1))
74 printk(KERN_ERR PFX
"Bus error writing InterruptEnable\n");
77 void EnableCtrModule(void)
79 int val
= ioread32be(&mmap
->Command
);
81 printk(KERN_DEBUG PFX
"Enabling CTR module\n");
83 if (vme_bus_error_check(1))
84 printk(KERN_ERR PFX
"Bus error reading Command\n");
86 val
|= CtrDrvrCommandENABLE
;
87 val
&= ~CtrDrvrCommandDISABLE
;
89 iowrite32be(val
, &mmap
->Command
);
91 if (vme_bus_error_check(1))
92 printk(KERN_ERR PFX
"Bus error writing Command\n");
95 void DisableCtrModule(void)
97 int val
= ioread32be(&mmap
->Command
);
99 printk(KERN_DEBUG PFX
"Disabling CTR module\n");
101 if (vme_bus_error_check(1))
102 printk(KERN_ERR PFX
"Bus error reading Command\n");
104 val
&= ~CtrDrvrCommandENABLE
;
105 val
|= CtrDrvrCommandDISABLE
;
107 iowrite32be(val
, &mmap
->Command
);
109 if (vme_bus_error_check(1))
110 printk(KERN_ERR PFX
"Bus error writing Command\n");
115 printk(KERN_DEBUG PFX
"Resetting CTR module\n");
116 iowrite32be(CtrDrvrCommandRESET
, &mmap
->Command
);
118 if (vme_bus_error_check(1))
119 printk(KERN_ERR PFX
"Bus error Writing Command\n");
121 /* Wait at least 10 ms after a "reset", for the module to recover */
125 int IntrHandler(void *arg
) {
128 source
= ClearInterrupt();
129 printk(KERN_DEBUG PFX
"Received PPS IRQ source=%08x\n", source
);
134 void show_ctr_info(void)
136 printk(KERN_DEBUG PFX
"CableId: %08x\n",
137 ioread32be(&mmap
->CableId
));
138 printk(KERN_DEBUG PFX
"VhdlVersion: %08x\n",
139 ioread32be(&mmap
->VhdlVersion
));
140 printk(KERN_DEBUG PFX
"InterruptEnable: %08x\n",
141 ioread32be(&mmap
->InterruptEnable
));
142 printk(KERN_DEBUG PFX
"Status: %08x\n",
143 ioread32be(&mmap
->Status
));
144 printk(KERN_DEBUG PFX
"Command: %08x\n",
145 ioread32be(&mmap
->Command
));
146 printk(KERN_DEBUG PFX
"Setup: %08x\n",
147 ioread32be(&mmap
->Setup
));
148 printk(KERN_DEBUG PFX
"PartityErrs: %08x\n",
149 ioread32be(&mmap
->PartityErrs
));
150 printk(KERN_DEBUG PFX
"SyncErrs: %08x\n",
151 ioread32be(&mmap
->SyncErrs
));
152 printk(KERN_DEBUG PFX
"TotalErrs: %08x\n",
153 ioread32be(&mmap
->TotalErrs
));
154 printk(KERN_DEBUG PFX
"CodeViolErrs: %08x\n",
155 ioread32be(&mmap
->CodeViolErrs
));
156 printk(KERN_DEBUG PFX
"QueueErrs: %08x\n",
157 ioread32be(&mmap
->QueueErrs
));
160 int ctrirq_init(void)
164 if ((rc
= vme_find_mapping(&ctr_desc
, 1)) != 0) {
165 printk(KERN_ERR PFX
"Failed to map CTR_n");
169 vmeaddr
= ctr_desc
.kernel_va
;
170 mmap
= (CtrDrvrMemoryMap
*) vmeaddr
;
176 if ((rc
= vme_request_irq(CTR_IRQ_VECTOR
, IntrHandler
, &ctr_desc
,
178 printk(KERN_ERR PFX
"Failed to register interrupt handler\n");
182 EnableCtrInterrupt();
191 if (vme_release_mapping(&ctr_desc
, 1) != 0)
192 printk(KERN_WARNING PFX
"Failed to release mapping on error\n");
197 void ctrirq_exit(void)
199 DisableCtrInterrupt();
203 if (vme_free_irq(CTR_IRQ_VECTOR
))
204 printk(KERN_WARNING PFX
"Failed to free irq\n");
206 if (vme_release_mapping(&ctr_desc
, 1) != 0)
207 printk(KERN_WARNING PFX
"Failed to release mapping\n");
211 static int __init
ctrirq_init_module(void)
213 return ctrirq_init();
216 static void __exit
ctrirq_exit_module(void)
221 module_init(ctrirq_init_module
);
222 module_exit(ctrirq_exit_module
);
224 MODULE_AUTHOR("Sebastien Dugue");
225 MODULE_LICENSE("GPL");
226 MODULE_DESCRIPTION("CTR PPS IRQ test module");
227 MODULE_VERSION(DRV_MODULE_VERSION
);