Skip to content

Commit 34471a9

Browse files
author
Russell King
committed
Merge branch 'ppi-irq-core-for-rmk' of git://github.com/mzyngier/arm-platforms into devel-stable
2 parents cefd3e7 + 28af690 commit 34471a9

File tree

46 files changed

+829
-307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+829
-307
lines changed

arch/arm/Kconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,31 @@ config SMP_ON_UP
14201420

14211421
If you don't know what to do here, say Y.
14221422

1423+
config ARM_CPU_TOPOLOGY
1424+
bool "Support cpu topology definition"
1425+
depends on SMP && CPU_V7
1426+
default y
1427+
help
1428+
Support ARM cpu topology definition. The MPIDR register defines
1429+
affinity between processors which is then used to describe the cpu
1430+
topology of an ARM System.
1431+
1432+
config SCHED_MC
1433+
bool "Multi-core scheduler support"
1434+
depends on ARM_CPU_TOPOLOGY
1435+
help
1436+
Multi-core scheduler support improves the CPU scheduler's decision
1437+
making when dealing with multi-core CPU chips at a cost of slightly
1438+
increased overhead in some places. If unsure say N here.
1439+
1440+
config SCHED_SMT
1441+
bool "SMT scheduler support"
1442+
depends on ARM_CPU_TOPOLOGY
1443+
help
1444+
Improves the CPU scheduler's decision making when dealing with
1445+
MultiThreading at a cost of slightly increased overhead in some
1446+
places. If unsure say N here.
1447+
14231448
config HAVE_ARM_SCU
14241449
bool
14251450
help

arch/arm/common/gic.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#include <linux/cpu_pm.h>
3030
#include <linux/cpumask.h>
3131
#include <linux/io.h>
32+
#include <linux/interrupt.h>
33+
#include <linux/percpu.h>
34+
#include <linux/slab.h>
3235

3336
#include <asm/irq.h>
3437
#include <asm/mach/irq.h>
@@ -181,7 +184,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
181184
return -EINVAL;
182185

183186
mask = 0xff << shift;
184-
bit = 1 << (cpu + shift);
187+
bit = 1 << (cpu_logical_map(cpu) + shift);
185188

186189
spin_lock(&irq_controller_lock);
187190
val = readl_relaxed(reg) & ~mask;
@@ -260,9 +263,16 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
260263
unsigned int irq_start)
261264
{
262265
unsigned int gic_irqs, irq_limit, i;
266+
u32 cpumask;
263267
void __iomem *base = gic->dist_base;
264-
u32 cpumask = 1 << smp_processor_id();
268+
u32 cpu = 0;
269+
u32 nrppis = 0, ppi_base = 0;
265270

271+
#ifdef CONFIG_SMP
272+
cpu = cpu_logical_map(smp_processor_id());
273+
#endif
274+
275+
cpumask = 1 << cpu;
266276
cpumask |= cpumask << 8;
267277
cpumask |= cpumask << 16;
268278

@@ -279,6 +289,23 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
279289

280290
gic->gic_irqs = gic_irqs;
281291

292+
/*
293+
* Nobody would be insane enough to use PPIs on a secondary
294+
* GIC, right?
295+
*/
296+
if (gic == &gic_data[0]) {
297+
nrppis = (32 - irq_start) & 31;
298+
299+
/* The GIC only supports up to 16 PPIs. */
300+
if (nrppis > 16)
301+
BUG();
302+
303+
ppi_base = gic->irq_offset + 32 - nrppis;
304+
}
305+
306+
pr_info("Configuring GIC with %d sources (%d PPIs)\n",
307+
gic_irqs, (gic == &gic_data[0]) ? nrppis : 0);
308+
282309
/*
283310
* Set all global interrupts to be level triggered, active low.
284311
*/
@@ -314,7 +341,17 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
314341
/*
315342
* Setup the Linux IRQ subsystem.
316343
*/
317-
for (i = irq_start; i < irq_limit; i++) {
344+
for (i = 0; i < nrppis; i++) {
345+
int ppi = i + ppi_base;
346+
347+
irq_set_percpu_devid(ppi);
348+
irq_set_chip_and_handler(ppi, &gic_chip,
349+
handle_percpu_devid_irq);
350+
irq_set_chip_data(ppi, gic);
351+
set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
352+
}
353+
354+
for (i = irq_start + nrppis; i < irq_limit; i++) {
318355
irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
319356
irq_set_chip_data(i, gic);
320357
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
@@ -557,20 +594,15 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)
557594
gic_cpu_init(&gic_data[gic_nr]);
558595
}
559596

560-
void __cpuinit gic_enable_ppi(unsigned int irq)
561-
{
562-
unsigned long flags;
563-
564-
local_irq_save(flags);
565-
irq_set_status_flags(irq, IRQ_NOPROBE);
566-
gic_unmask_irq(irq_get_irq_data(irq));
567-
local_irq_restore(flags);
568-
}
569-
570597
#ifdef CONFIG_SMP
571598
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
572599
{
573-
unsigned long map = *cpus_addr(*mask);
600+
int cpu;
601+
unsigned long map = 0;
602+
603+
/* Convert our logical CPU mask into a physical one. */
604+
for_each_cpu(cpu, mask)
605+
map |= 1 << cpu_logical_map(cpu);
574606

575607
/*
576608
* Ensure that stores to Normal memory are visible to the

arch/arm/include/asm/cputype.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define CPUID_CACHETYPE 1
99
#define CPUID_TCM 2
1010
#define CPUID_TLBTYPE 3
11+
#define CPUID_MPIDR 5
1112

1213
#define CPUID_EXT_PFR0 "c1, 0"
1314
#define CPUID_EXT_PFR1 "c1, 1"
@@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)
7071
return read_cpuid(CPUID_TCM);
7172
}
7273

74+
static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
75+
{
76+
return read_cpuid(CPUID_MPIDR);
77+
}
78+
7379
/*
7480
* Intel's XScale3 core supports some v6 features (supersections, L2)
7581
* but advertises itself as v5 as it does not support the v6 ISA. For

arch/arm/include/asm/entry-macro-multi.S

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@
2525
movne r1, sp
2626
adrne lr, BSYM(1b)
2727
bne do_IPI
28-
29-
#ifdef CONFIG_LOCAL_TIMERS
30-
test_for_ltirq r0, r2, r6, lr
31-
movne r0, sp
32-
adrne lr, BSYM(1b)
33-
bne do_local_timer
34-
#endif
3528
#endif
3629
9997:
3730
.endm

arch/arm/include/asm/exception.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Annotations for marking C functions as exception handlers.
3+
*
4+
* These should only be used for C functions that are called from the low
5+
* level exception entry code and not any intervening C code.
6+
*/
7+
#ifndef __ASM_ARM_EXCEPTION_H
8+
#define __ASM_ARM_EXCEPTION_H
9+
10+
#include <linux/ftrace.h>
11+
12+
#define __exception __attribute__((section(".exception.text")))
13+
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
14+
#define __exception_irq_entry __irq_entry
15+
#else
16+
#define __exception_irq_entry __exception
17+
#endif
18+
19+
#endif /* __ASM_ARM_EXCEPTION_H */

arch/arm/include/asm/hardirq.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99

1010
typedef struct {
1111
unsigned int __softirq_pending;
12-
#ifdef CONFIG_LOCAL_TIMERS
13-
unsigned int local_timer_irqs;
14-
#endif
1512
#ifdef CONFIG_SMP
1613
unsigned int ipi_irqs[NR_IPI];
1714
#endif

arch/arm/include/asm/hardware/entry-macro-gic.S

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,11 @@
2222
* interrupt controller spec. To wit:
2323
*
2424
* Interrupts 0-15 are IPI
25-
* 16-28 are reserved
26-
* 29-31 are local. We allow 30 to be used for the watchdog.
25+
* 16-31 are local. We allow 30 to be used for the watchdog.
2726
* 32-1020 are global
2827
* 1021-1022 are reserved
2928
* 1023 is "spurious" (no interrupt)
3029
*
31-
* For now, we ignore all local interrupts so only return an interrupt if it's
32-
* between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
33-
*
3430
* A simple read from the controller will tell us the number of the highest
3531
* priority enabled interrupt. We then just need to check whether it is in the
3632
* valid range for an IRQ (30-1020 inclusive).
@@ -43,7 +39,7 @@
4339

4440
ldr \tmp, =1021
4541
bic \irqnr, \irqstat, #0x1c00
46-
cmp \irqnr, #29
42+
cmp \irqnr, #15
4743
cmpcc \irqnr, \irqnr
4844
cmpne \irqnr, \tmp
4945
cmpcs \irqnr, \irqnr
@@ -62,14 +58,3 @@
6258
strcc \irqstat, [\base, #GIC_CPU_EOI]
6359
cmpcs \irqnr, \irqnr
6460
.endm
65-
66-
/* As above, this assumes that irqstat and base are preserved.. */
67-
68-
.macro test_for_ltirq, irqnr, irqstat, base, tmp
69-
bic \irqnr, \irqstat, #0x1c00
70-
mov \tmp, #0
71-
cmp \irqnr, #29
72-
moveq \tmp, #1
73-
streq \irqstat, [\base, #GIC_CPU_EOI]
74-
cmp \tmp, #0
75-
.endm

arch/arm/include/asm/hardware/gic.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
4040
void gic_secondary_init(unsigned int);
4141
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
4242
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
43-
void gic_enable_ppi(unsigned int);
4443

4544
struct gic_chip_data {
4645
unsigned int irq_offset;

arch/arm/include/asm/localtimer.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,29 @@
1010
#ifndef __ASM_ARM_LOCALTIMER_H
1111
#define __ASM_ARM_LOCALTIMER_H
1212

13+
#include <linux/interrupt.h>
14+
1315
struct clock_event_device;
1416

1517
/*
1618
* Setup a per-cpu timer, whether it be a local timer or dummy broadcast
1719
*/
1820
void percpu_timer_setup(void);
1921

20-
/*
21-
* Called from assembly, this is the local timer IRQ handler
22-
*/
23-
asmlinkage void do_local_timer(struct pt_regs *);
24-
25-
2622
#ifdef CONFIG_LOCAL_TIMERS
2723

2824
#ifdef CONFIG_HAVE_ARM_TWD
2925

3026
#include "smp_twd.h"
3127

32-
#define local_timer_ack() twd_timer_ack()
28+
#define local_timer_stop(c) twd_timer_stop((c))
3329

3430
#else
3531

3632
/*
37-
* Platform provides this to acknowledge a local timer IRQ.
38-
* Returns true if the local timer IRQ is to be processed.
33+
* Stop the local timer
3934
*/
40-
int local_timer_ack(void);
35+
void local_timer_stop(struct clock_event_device *);
4136

4237
#endif
4338

@@ -52,6 +47,10 @@ static inline int local_timer_setup(struct clock_event_device *evt)
5247
{
5348
return -ENXIO;
5449
}
50+
51+
static inline void local_timer_stop(struct clock_event_device *evt)
52+
{
53+
}
5554
#endif
5655

5756
#endif

arch/arm/include/asm/smp.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ extern void show_ipi_list(struct seq_file *, int);
3232
*/
3333
asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
3434

35+
/*
36+
* Called from C code, this handles an IPI.
37+
*/
38+
void handle_IPI(int ipinr, struct pt_regs *regs);
39+
3540
/*
3641
* Setup the set of possible CPUs (via set_cpu_possible)
3742
*/
@@ -65,6 +70,12 @@ extern void platform_secondary_init(unsigned int cpu);
6570
*/
6671
extern void platform_smp_prepare_cpus(unsigned int);
6772

73+
/*
74+
* Logical CPU mapping.
75+
*/
76+
extern int __cpu_logical_map[NR_CPUS];
77+
#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
78+
6879
/*
6980
* Initial data for bringing up a secondary CPU.
7081
*/
@@ -88,9 +99,4 @@ extern void platform_cpu_enable(unsigned int cpu);
8899
extern void arch_send_call_function_single_ipi(int cpu);
89100
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
90101

91-
/*
92-
* show local interrupt info
93-
*/
94-
extern void show_local_irqs(struct seq_file *, int);
95-
96102
#endif /* ifndef __ASM_ARM_SMP_H */

arch/arm/include/asm/smp_twd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct clock_event_device;
2222

2323
extern void __iomem *twd_base;
2424

25-
int twd_timer_ack(void);
2625
void twd_timer_setup(struct clock_event_device *);
26+
void twd_timer_stop(struct clock_event_device *);
2727

2828
#endif

arch/arm/include/asm/system.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@
6262

6363
#include <asm/outercache.h>
6464

65-
#define __exception __attribute__((section(".exception.text")))
66-
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
67-
#define __exception_irq_entry __irq_entry
68-
#else
69-
#define __exception_irq_entry __exception
70-
#endif
71-
7265
struct thread_info;
7366
struct task_struct;
7467

0 commit comments

Comments
 (0)