~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/galileo-boards/ev64120/irq-handler.c

Version: ~ [ linux-5.18-rc6 ] ~ [ linux-5.17.6 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.38 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.114 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.192 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.241 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.277 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.312 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Galileo Technology chip interrupt handler
  3  *
  4  *  Modified by RidgeRun, Inc.
  5  */
  6 #include <linux/module.h>
  7 #include <linux/interrupt.h>
  8 #include <linux/kernel.h>
  9 #include <asm/ptrace.h>
 10 #include <linux/config.h>
 11 #include <linux/sched.h>
 12 #include <linux/kernel_stat.h>
 13 #include <asm/io.h>
 14 #include <asm/gt64120.h>
 15 #include <asm/galileo-boards/ev64120.h>
 16 #include <asm/galileo-boards/ev64120int.h>
 17 
 18 /*
 19  * These are interrupt handlers for the GT on-chip interrupts.  They all come
 20  * in to the MIPS on a single interrupt line, and have to be handled and ack'ed
 21  * differently than other MIPS interrupts.
 22  */
 23 
 24 #if CURRENTLY_UNUSED
 25 
 26 struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
 27 void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
 28 
 29 /*
 30  * hook_irq_handler
 31  *
 32  * Hooks IRQ handler to the system. When the system is interrupted
 33  * the interrupt service routine is called.
 34  *
 35  * Inputs :
 36  * int_cause - The interrupt cause number. In EVB64120 two parameters
 37  *             are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
 38  * bit_num   - Indicates which bit number in the cause register
 39  * isr_ptr   - Pointer to the interrupt service routine
 40  *
 41  * Outputs :
 42  */
 43 void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
 44 {
 45         irq_handlers[int_cause][bit_num].routine = isr_ptr;
 46 }
 47 
 48 
 49 /*
 50  * enable_galileo_irq
 51  *
 52  * Enables the IRQ on Galileo Chip
 53  *
 54  * Inputs :
 55  * int_cause -  The interrupt cause number. In EVB64120 two parameters
 56  *            are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
 57  * bit_num   - Indicates which bit number in the cause register
 58  *
 59  * Outputs :
 60  * 1 if succesful, 0 if failure
 61  */
 62 int enable_galileo_irq(int int_cause, int bit_num)
 63 {
 64         if (int_cause == INT_CAUSE_MAIN)
 65                 SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
 66         else if (int_cause == INT_CAUSE_HIGH)
 67                 SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
 68                              (1 << bit_num));
 69         else
 70                 return 0;
 71         return 1;
 72 }
 73 
 74 /*
 75  * disable_galileo_irq
 76  *
 77  * Disables the IRQ on Galileo Chip
 78  *
 79  * Inputs :
 80  * int_cause -  The interrupt cause number. In EVB64120 two parameters
 81  *            are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
 82  * bit_num   - Indicates which bit number in the cause register
 83  *
 84  * Outputs :
 85  * 1 if succesful, 0 if failure
 86  */
 87 int disable_galileo_irq(int int_cause, int bit_num)
 88 {
 89         if (int_cause == INT_CAUSE_MAIN)
 90                 RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
 91                                (1 << bit_num));
 92         else if (int_cause == INT_CAUSE_HIGH)
 93                 RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
 94                                (1 << bit_num));
 95         else
 96                 return 0;
 97         return 1;
 98 }
 99 
100 #endif                          /*  UNUSED  */
101 
102 /*
103  * galileo_irq -
104  *
105  * Interrupt handler for interrupts coming from the Galileo chip.
106  * It could be timer interrupt, built in ethernet ports etc...
107  *
108  * Inputs :
109  *
110  * Outputs :
111  *
112  */
113 static void galileo_irq(int irq, void *dev_id, struct pt_regs *regs)
114 {
115         unsigned int irq_src, int_high_src, irq_src_mask,
116             int_high_src_mask;
117         int handled;
118         unsigned int count;
119         static int counter = 0;
120 
121         GT_READ(GT_INTRCAUSE_OFS, &irq_src);
122         GT_READ(GT_INTRMASK_OFS, &irq_src_mask);
123         GT_READ(GT_HINTRCAUSE_OFS, &int_high_src);
124         GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask);
125         irq_src = irq_src & irq_src_mask;
126         int_high_src = int_high_src & int_high_src_mask;
127 
128         handled = 0;
129 
130         /* Execute all interrupt handlers */
131         /* Check for timer interrupt */
132         if (irq_src & 0x00000800) {
133                 handled = 1;
134                 irq_src &= ~0x00000800;
135                 //    RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8);
136                 do_timer(regs);
137         }
138 
139         if (irq_src) {
140                 printk(KERN_INFO
141                        "Other Galileo interrupt received irq_src %x\n",
142                        irq_src);
143 #if CURRENTLY_UNUSED
144                 for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) {
145                         if (irq_src & (1 << count)) {
146                                 if (irq_handlers[INT_CAUSE_MAIN][count].
147                                     routine) {
148                                         queue_task(&irq_handlers
149                                                    [INT_CAUSE_MAIN][count],
150                                                    &tq_immediate);
151                                         mark_bh(IMMEDIATE_BH);
152                                         handled = 1;
153                                 }
154                         }
155                 }
156 #endif                          /*  UNUSED  */
157         }
158         GT_WRITE(GT_INTRCAUSE_OFS, 0);
159         GT_WRITE(GT_HINTRCAUSE_OFS, 0);
160 
161 #undef GALILEO_I2O
162 #ifdef GALILEO_I2O
163         /*
164            Future I2O support.  We currently attach I2O interrupt handlers to the
165            Galileo interrupt (int 4) and handle them in do_IRQ.
166          */
167         if (isInBoundDoorBellInterruptSet()) {
168                 printk(KERN_INFO "I2O doorbell interrupt received.\n");
169                 handled = 1;
170         }
171 
172         if (isInBoundPostQueueInterruptSet()) {
173                 printk(KERN_INFO "I2O Queue interrupt received.\n");
174                 handled = 1;
175         }
176 
177         /*
178            This normally would be outside of the ifdef, but since
179            we're handling I2O outside of this handler, this
180            printk shows up every time we get a valid I2O
181            interrupt.  So turn this off for now.
182          */
183         if (handled == 0) {
184                 if (counter < 50) {
185                         printk("Spurious Galileo interrupt...\n");
186                         counter++;
187                 }
188         }
189 #endif
190 }
191 
192 /*
193  * galileo_time_init -
194  *
195  * Initializes timer using galileo's built in timer.
196  *
197  *
198  * Inputs :
199  * irq - number of irq to be used by the timer
200  *
201  * Outpus :
202  *
203  */
204 #ifdef CONFIG_SYSCLK_100
205 #define Sys_clock (100 * 1000000)       // 100 MHz
206 #endif
207 #ifdef CONFIG_SYSCLK_83
208 #define Sys_clock (83.333 * 1000000)    // 83.333 MHz
209 #endif
210 #ifdef CONFIG_SYSCLK_75
211 #define Sys_clock (75 * 1000000)        // 75 MHz
212 #endif
213 
214 /*
215  * This will ignore the standard MIPS timer interrupt handler that is passed
216  * in as *irq (=irq0 in ../kernel/time.c).  We will do our own timer interrupt
217  * handling.
218  */
219 void galileo_time_init(struct irqaction *irq)
220 {
221         extern irq_desc_t irq_desc[NR_IRQS];
222         static struct irqaction timer;
223 
224         /* Disable timer first */
225         GT_WRITE(GT_TC_CONTROL_OFS, 0);
226         /* Load timer value for 100 Hz */
227         GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
228 
229         /*
230          * Create the IRQ structure entry for the timer.  Since we're too early
231          * in the boot process to use the "request_irq()" call, we'll hard-code
232          * the values to the correct interrupt line.
233          */
234         timer.handler = &galileo_irq;
235         timer.flags = SA_SHIRQ;
236         timer.name = "timer";
237         timer.dev_id = NULL;
238         timer.next = NULL;
239         timer.mask = 0;
240         irq_desc[TIMER].action = &timer;
241 
242         /* Enable timer ints */
243         GT_WRITE(GT_TC_CONTROL_OFS, 0xc0);
244         /* clear Cause register first */
245         GT_WRITE(GT_INTRCAUSE_OFS, 0x0);
246         /* Unmask timer int */
247         GT_WRITE(GT_INTRMASK_OFS, 0x800);
248         /* Clear High int register */
249         GT_WRITE(GT_HINTRCAUSE_OFS, 0x0);
250         /* Mask All interrupts at High cause interrupt */
251         GT_WRITE(GT_HINTRMASK_OFS, 0x0);
252 
253 }
254 
255 void galileo_irq_init(void)
256 {
257 #if CURRENTLY_UNUSED
258         int i, j;
259 
260         /* Reset irq handlers pointers to NULL */
261         for (i = 0; i < MAX_CAUSE_REGS; i++) {
262                 for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
263                         irq_handlers[i][j].next = NULL;
264                         irq_handlers[i][j].sync = 0;
265                         irq_handlers[i][j].routine = NULL;
266                         irq_handlers[i][j].data = NULL;
267                 }
268         }
269 #endif
270 }
271 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp