Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
irq_asic.c
Go to the documentation of this file.
1 /*
2  * Portions copyright (C) 2005-2009 Scientific Atlanta
3  * Portions copyright (C) 2009 Cisco Systems, Inc.
4  *
5  * Modified from arch/mips/kernel/irq-rm7000.c:
6  * Copyright (C) 2003 Ralf Baechle
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  */
13 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/irq.h>
17 
18 #include <asm/irq_cpu.h>
19 #include <asm/mipsregs.h>
20 
22 
23 static inline void unmask_asic_irq(struct irq_data *d)
24 {
25  unsigned long enable_bit;
26  unsigned int irq = d->irq;
27 
28  enable_bit = (1 << (irq & 0x1f));
29 
30  switch (irq >> 5) {
31  case 0:
32  asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
33  break;
34  case 1:
35  asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
36  break;
37  case 2:
38  asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
39  break;
40  case 3:
41  asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
42  break;
43  default:
44  BUG();
45  }
46 }
47 
48 static inline void mask_asic_irq(struct irq_data *d)
49 {
50  unsigned long disable_mask;
51  unsigned int irq = d->irq;
52 
53  disable_mask = ~(1 << (irq & 0x1f));
54 
55  switch (irq >> 5) {
56  case 0:
57  asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
58  break;
59  case 1:
60  asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
61  break;
62  case 2:
63  asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
64  break;
65  case 3:
66  asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
67  break;
68  default:
69  BUG();
70  }
71 }
72 
73 static struct irq_chip asic_irq_chip = {
74  .name = "ASIC Level",
75  .irq_mask = mask_asic_irq,
76  .irq_unmask = unmask_asic_irq,
77 };
78 
80 {
81  int i;
82 
83  /* set priority to 0 */
84  write_c0_status(read_c0_status() & ~(0x0000fc00));
85 
86  asic_write(0, ien_int_0);
87  asic_write(0, ien_int_1);
88  asic_write(0, ien_int_2);
89  asic_write(0, ien_int_3);
90 
91  asic_write(0x0fffffff, int_level_3_3);
92  asic_write(0xffffffff, int_level_3_2);
93  asic_write(0xffffffff, int_level_3_1);
94  asic_write(0xffffffff, int_level_3_0);
95  asic_write(0xffffffff, int_level_2_3);
96  asic_write(0xffffffff, int_level_2_2);
97  asic_write(0xffffffff, int_level_2_1);
98  asic_write(0xffffffff, int_level_2_0);
99  asic_write(0xffffffff, int_level_1_3);
100  asic_write(0xffffffff, int_level_1_2);
101  asic_write(0xffffffff, int_level_1_1);
102  asic_write(0xffffffff, int_level_1_0);
103  asic_write(0xffffffff, int_level_0_3);
104  asic_write(0xffffffff, int_level_0_2);
105  asic_write(0xffffffff, int_level_0_1);
106  asic_write(0xffffffff, int_level_0_0);
107 
108  asic_write(0xf, int_int_scan);
109 
110  /*
111  * Initialize interrupt handlers.
112  */
113  for (i = 0; i < NR_IRQS; i++)
114  irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
115 }