1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/ptrace.h>
18#include <linux/errno.h>
19#include <linux/interrupt.h>
20#include <linux/init.h>
21#include <linux/of.h>
22#include <linux/ftrace.h>
23#include <linux/irq.h>
24#include <linux/seq_file.h>
25#include <linux/kernel_stat.h>
26#include <linux/export.h>
27
28#include <linux/irqflags.h>
29
30
31unsigned long arch_local_save_flags(void)
32{
33 return mfspr(SPR_SR) & (SPR_SR_IEE|SPR_SR_TEE);
34}
35EXPORT_SYMBOL(arch_local_save_flags);
36
37
38void arch_local_irq_restore(unsigned long flags)
39{
40 mtspr(SPR_SR, ((mfspr(SPR_SR) & ~(SPR_SR_IEE|SPR_SR_TEE)) | flags));
41}
42EXPORT_SYMBOL(arch_local_irq_restore);
43
44
45
46
47
48
49
50
51static void or1k_pic_mask(struct irq_data *data)
52{
53 mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->irq));
54}
55
56static void or1k_pic_unmask(struct irq_data *data)
57{
58 mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->irq));
59}
60
61static void or1k_pic_ack(struct irq_data *data)
62{
63
64
65
66
67
68
69
70
71
72
73
74
75#ifdef CONFIG_OR1K_1200
76
77
78
79
80
81
82 mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->irq));
83#else
84 WARN(1, "Interrupt handling possibily broken\n");
85 mtspr(SPR_PICSR, (1UL << irq));
86#endif
87}
88
89static void or1k_pic_mask_ack(struct irq_data *data)
90{
91
92
93#ifdef CONFIG_OR1K_1200
94 mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->irq));
95#else
96 WARN(1, "Interrupt handling possibily broken\n");
97 mtspr(SPR_PICSR, (1UL << irq));
98#endif
99}
100
101static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type)
102{
103
104
105
106
107
108 return irq_setup_alt_chip(data, flow_type);
109}
110
111static inline int pic_get_irq(int first)
112{
113 int irq;
114
115 irq = ffs(mfspr(SPR_PICSR) >> first);
116
117 return irq ? irq + first - 1 : NO_IRQ;
118}
119
120static void __init or1k_irq_init(void)
121{
122 struct irq_chip_generic *gc;
123 struct irq_chip_type *ct;
124
125
126 mtspr(SPR_PICMR, (0UL));
127
128 gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq);
129 ct = gc->chip_types;
130
131 ct->chip.irq_unmask = or1k_pic_unmask;
132 ct->chip.irq_mask = or1k_pic_mask;
133 ct->chip.irq_ack = or1k_pic_ack;
134 ct->chip.irq_mask_ack = or1k_pic_mask_ack;
135 ct->chip.irq_set_type = or1k_pic_set_type;
136
137
138
139
140#if 0
141
142 ct->chip.type = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_MASK;
143#endif
144
145 irq_setup_generic_chip(gc, IRQ_MSK(NR_IRQS), 0,
146 IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
147}
148
149void __init init_IRQ(void)
150{
151 or1k_irq_init();
152}
153
154void __irq_entry do_IRQ(struct pt_regs *regs)
155{
156 int irq = -1;
157 struct pt_regs *old_regs = set_irq_regs(regs);
158
159 irq_enter();
160
161 while ((irq = pic_get_irq(irq + 1)) != NO_IRQ)
162 generic_handle_irq(irq);
163
164 irq_exit();
165 set_irq_regs(old_regs);
166}
167
168unsigned int irq_create_of_mapping(struct device_node *controller,
169 const u32 *intspec, unsigned int intsize)
170{
171 return intspec[0];
172}
173EXPORT_SYMBOL_GPL(irq_create_of_mapping);
174