~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to arch/arm/kernel/irq.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 *  Naturally it's not a 1:1 relation, but there are similarities.
23
23
 */
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>
35
34
#include <linux/list.h>
36
35
#include <linux/kallsyms.h>
37
36
#include <linux/proc_fs.h>
38
 
#include <linux/ftrace.h>
39
37
 
 
38
#include <asm/exception.h>
40
39
#include <asm/system.h>
41
40
#include <asm/mach/arch.h>
42
41
#include <asm/mach/irq.h>
59
58
#ifdef CONFIG_SMP
60
59
        show_ipi_list(p, prec);
61
60
#endif
62
 
#ifdef CONFIG_LOCAL_TIMERS
63
 
        show_local_irqs(p, prec);
64
 
#endif
65
61
        seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
66
62
        return 0;
67
63
}
68
64
 
69
65
/*
70
 
 * do_IRQ handles all hardware IRQ's.  Decoded IRQs should not
71
 
 * come via this function.  Instead, they should provide their
72
 
 * own 'handler'
 
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
 
69
 * level decoding.
73
70
 */
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)
76
72
{
77
73
        struct pt_regs *old_regs = set_irq_regs(regs);
78
74
 
97
93
        set_irq_regs(old_regs);
98
94
}
99
95
 
 
96
/*
 
97
 * asm_do_IRQ is the interface to be used from assembly code.
 
98
 */
 
99
asmlinkage void __exception_irq_entry
 
100
asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 
101
{
 
102
        handle_IRQ(irq, regs);
 
103
}
 
104
 
100
105
void set_irq_flags(unsigned int irq, unsigned int iflags)
101
106
{
102
107
        unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
131
136
 
132
137
#ifdef CONFIG_HOTPLUG_CPU
133
138
 
134
 
static bool migrate_one_irq(struct irq_data *d)
 
139
static bool migrate_one_irq(struct irq_desc *desc)
135
140
{
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;
 
143
        struct irq_chip *c;
137
144
        bool ret = false;
138
145
 
139
 
        if (cpu >= nr_cpu_ids) {
140
 
                cpu = cpumask_any(cpu_online_mask);
 
146
        /*
 
147
         * If this is a per-CPU interrupt, or the affinity does not
 
148
         * include this CPU, then we have nothing to do.
 
149
         */
 
150
        if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
 
151
                return false;
 
152
 
 
153
        if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
 
154
                affinity = cpu_online_mask;
141
155
                ret = true;
142
156
        }
143
157
 
144
 
        pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu);
145
 
 
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);
 
161
        else
 
162
                pr_debug("IRQ%u: unable to set affinity\n", d->irq);
147
163
 
148
164
        return ret;
149
165
}
150
166
 
151
167
/*
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
154
170
 * available CPU.
 
171
 *
 
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.
155
174
 */
156
175
void migrate_irqs(void)
157
176
{
158
 
        unsigned int i, cpu = smp_processor_id();
 
177
        unsigned int i;
159
178
        struct irq_desc *desc;
160
179
        unsigned long flags;
161
180
 
162
181
        local_irq_save(flags);
163
182
 
164
183
        for_each_irq_desc(i, desc) {
165
 
                struct irq_data *d = &desc->irq_data;
166
184
                bool affinity_broken = false;
167
185
 
 
186
                if (!desc)
 
187
                        continue;
 
188
 
168
189
                raw_spin_lock(&desc->lock);
169
 
                do {
170
 
                        if (desc->action == NULL)
171
 
                                break;
172
 
 
173
 
                        if (d->node != cpu)
174
 
                                break;
175
 
 
176
 
                        affinity_broken = migrate_one_irq(d);
177
 
                } while (0);
 
190
                affinity_broken = migrate_one_irq(desc);
178
191
                raw_spin_unlock(&desc->lock);
179
192
 
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,
 
195
                                smp_processor_id());
182
196
        }
183
197
 
184
198
        local_irq_restore(flags);