76
76
* internal IRQs operations: only mask/unmask on PERF irq mask
79
static inline void bcm63xx_internal_irq_mask(unsigned int irq)
79
static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
81
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
83
irq -= IRQ_INTERNAL_BASE;
84
84
mask = bcm_perf_readl(PERF_IRQMASK_REG);
85
85
mask &= ~(1 << irq);
86
86
bcm_perf_writel(mask, PERF_IRQMASK_REG);
89
static void bcm63xx_internal_irq_unmask(unsigned int irq)
89
static void bcm63xx_internal_irq_unmask(struct irq_data *d)
91
unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
93
irq -= IRQ_INTERNAL_BASE;
94
94
mask = bcm_perf_readl(PERF_IRQMASK_REG);
95
95
mask |= (1 << irq);
96
96
bcm_perf_writel(mask, PERF_IRQMASK_REG);
99
static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
101
bcm63xx_internal_irq_unmask(irq);
106
100
* external IRQs operations: mask/unmask and clear on PERF external
107
101
* irq control register.
109
static void bcm63xx_external_irq_mask(unsigned int irq)
103
static void bcm63xx_external_irq_mask(struct irq_data *d)
105
unsigned int irq = d->irq - IRQ_EXT_BASE;
114
108
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
115
109
reg &= ~EXTIRQ_CFG_MASK(irq);
116
110
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
119
static void bcm63xx_external_irq_unmask(unsigned int irq)
113
static void bcm63xx_external_irq_unmask(struct irq_data *d)
115
unsigned int irq = d->irq - IRQ_EXT_BASE;
124
118
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
125
119
reg |= EXTIRQ_CFG_MASK(irq);
126
120
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
129
static void bcm63xx_external_irq_clear(unsigned int irq)
123
static void bcm63xx_external_irq_clear(struct irq_data *d)
125
unsigned int irq = d->irq - IRQ_EXT_BASE;
134
128
reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
135
129
reg |= EXTIRQ_CFG_CLEAR(irq);
136
130
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
139
static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
133
static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
141
set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
135
set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
142
136
irq_enable_hazard();
143
bcm63xx_external_irq_unmask(irq);
137
bcm63xx_external_irq_unmask(d);
147
static void bcm63xx_external_irq_shutdown(unsigned int irq)
141
static void bcm63xx_external_irq_shutdown(struct irq_data *d)
149
bcm63xx_external_irq_mask(irq);
150
clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
143
bcm63xx_external_irq_mask(d);
144
clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
151
145
irq_disable_hazard();
154
static int bcm63xx_external_irq_set_type(unsigned int irq,
148
static int bcm63xx_external_irq_set_type(struct irq_data *d,
155
149
unsigned int flow_type)
151
unsigned int irq = d->irq - IRQ_EXT_BASE;
158
struct irq_desc *desc = irq_desc + irq;
162
154
flow_type &= IRQ_TYPE_SENSE_MASK;
200
192
bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
202
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
203
desc->status |= IRQ_LEVEL;
204
desc->handle_irq = handle_level_irq;
206
desc->handle_irq = handle_edge_irq;
194
irqd_set_trigger_type(d, flow_type);
195
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
196
__irq_set_handler_locked(d->irq, handle_level_irq);
198
__irq_set_handler_locked(d->irq, handle_edge_irq);
200
return IRQ_SET_MASK_OK_NOCOPY;
212
203
static struct irq_chip bcm63xx_internal_irq_chip = {
213
204
.name = "bcm63xx_ipic",
214
.startup = bcm63xx_internal_irq_startup,
215
.shutdown = bcm63xx_internal_irq_mask,
217
.mask = bcm63xx_internal_irq_mask,
218
.mask_ack = bcm63xx_internal_irq_mask,
219
.unmask = bcm63xx_internal_irq_unmask,
205
.irq_mask = bcm63xx_internal_irq_mask,
206
.irq_unmask = bcm63xx_internal_irq_unmask,
222
209
static struct irq_chip bcm63xx_external_irq_chip = {
223
210
.name = "bcm63xx_epic",
224
.startup = bcm63xx_external_irq_startup,
225
.shutdown = bcm63xx_external_irq_shutdown,
227
.ack = bcm63xx_external_irq_clear,
229
.mask = bcm63xx_external_irq_mask,
230
.unmask = bcm63xx_external_irq_unmask,
232
.set_type = bcm63xx_external_irq_set_type,
211
.irq_startup = bcm63xx_external_irq_startup,
212
.irq_shutdown = bcm63xx_external_irq_shutdown,
214
.irq_ack = bcm63xx_external_irq_clear,
216
.irq_mask = bcm63xx_external_irq_mask,
217
.irq_unmask = bcm63xx_external_irq_unmask,
219
.irq_set_type = bcm63xx_external_irq_set_type,
235
222
static struct irqaction cpu_ip2_cascade_action = {
244
231
mips_cpu_irq_init();
245
232
for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
246
set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip,
233
irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
247
234
handle_level_irq);
249
236
for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
250
set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip,
237
irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
251
238
handle_edge_irq);
253
240
setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);