22
22
* Naturally it's not a 1:1 relation, but there are similarities.
24
24
#include <linux/kernel_stat.h>
25
#include <linux/module.h>
26
25
#include <linux/signal.h>
27
26
#include <linux/ioport.h>
28
27
#include <linux/interrupt.h>
60
59
show_ipi_list(p, prec);
62
#ifdef CONFIG_LOCAL_TIMERS
63
show_local_irqs(p, prec);
65
61
seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
70
* do_IRQ handles all hardware IRQ's. Decoded IRQs should not
71
* come via this function. Instead, they should provide their
66
* handle_IRQ handles all hardware IRQ's. Decoded IRQs should
67
* not come via this function. Instead, they should provide their
68
* own 'handler'. Used by platform code implementing C-based 1st
74
asmlinkage void __exception_irq_entry
75
asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
71
void handle_IRQ(unsigned int irq, struct pt_regs *regs)
77
73
struct pt_regs *old_regs = set_irq_regs(regs);
97
93
set_irq_regs(old_regs);
97
* asm_do_IRQ is the interface to be used from assembly code.
99
asmlinkage void __exception_irq_entry
100
asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
102
handle_IRQ(irq, regs);
100
105
void set_irq_flags(unsigned int irq, unsigned int iflags)
102
107
unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
132
137
#ifdef CONFIG_HOTPLUG_CPU
134
static bool migrate_one_irq(struct irq_data *d)
139
static bool migrate_one_irq(struct irq_desc *desc)
136
unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask);
141
struct irq_data *d = irq_desc_get_irq_data(desc);
142
const struct cpumask *affinity = d->affinity;
137
144
bool ret = false;
139
if (cpu >= nr_cpu_ids) {
140
cpu = cpumask_any(cpu_online_mask);
147
* If this is a per-CPU interrupt, or the affinity does not
148
* include this CPU, then we have nothing to do.
150
if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
153
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
154
affinity = cpu_online_mask;
144
pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu);
146
d->chip->irq_set_affinity(d, cpumask_of(cpu), true);
158
c = irq_data_get_irq_chip(d);
159
if (c->irq_set_affinity)
160
c->irq_set_affinity(d, affinity, true);
162
pr_debug("IRQ%u: unable to set affinity\n", d->irq);
152
* The CPU has been marked offline. Migrate IRQs off this CPU. If
153
* the affinity settings do not allow other CPUs, force them onto any
168
* The current CPU has been marked offline. Migrate IRQs off this CPU.
169
* If the affinity settings do not allow other CPUs, force them onto any
172
* Note: we must iterate over all IRQs, whether they have an attached
173
* action structure or not, as we need to get chained interrupts too.
156
175
void migrate_irqs(void)
158
unsigned int i, cpu = smp_processor_id();
159
178
struct irq_desc *desc;
160
179
unsigned long flags;
162
181
local_irq_save(flags);
164
183
for_each_irq_desc(i, desc) {
165
struct irq_data *d = &desc->irq_data;
166
184
bool affinity_broken = false;
168
189
raw_spin_lock(&desc->lock);
170
if (desc->action == NULL)
176
affinity_broken = migrate_one_irq(d);
190
affinity_broken = migrate_one_irq(desc);
178
191
raw_spin_unlock(&desc->lock);
180
193
if (affinity_broken && printk_ratelimit())
181
pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu);
194
pr_warning("IRQ%u no longer affine to CPU%u\n", i,
184
198
local_irq_restore(flags);