diff options
Diffstat (limited to 'arch/arm/include')
31 files changed, 744 insertions, 327 deletions
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 29035e86a59d..b6e65dedfd71 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -187,6 +187,17 @@ | |||
187 | #endif | 187 | #endif |
188 | 188 | ||
189 | /* | 189 | /* |
190 | * Instruction barrier | ||
191 | */ | ||
192 | .macro instr_sync | ||
193 | #if __LINUX_ARM_ARCH__ >= 7 | ||
194 | isb | ||
195 | #elif __LINUX_ARM_ARCH__ == 6 | ||
196 | mcr p15, 0, r0, c7, c5, 4 | ||
197 | #endif | ||
198 | .endm | ||
199 | |||
200 | /* | ||
190 | * SMP data memory barrier | 201 | * SMP data memory barrier |
191 | */ | 202 | */ |
192 | .macro smp_dmb mode | 203 | .macro smp_dmb mode |
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h index 9abe7a07d5ac..fac79dceb736 100644 --- a/arch/arm/include/asm/bug.h +++ b/arch/arm/include/asm/bug.h | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #define __BUG(__file, __line, __value) \ | 33 | #define __BUG(__file, __line, __value) \ |
34 | do { \ | 34 | do { \ |
35 | BUILD_BUG_ON(sizeof(struct bug_entry) != 12); \ | ||
36 | asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ | 35 | asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ |
37 | ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ | 36 | ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ |
38 | "2:\t.asciz " #__file "\n" \ | 37 | "2:\t.asciz " #__file "\n" \ |
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h new file mode 100644 index 000000000000..a0ada3ea4358 --- /dev/null +++ b/arch/arm/include/asm/cti.h | |||
@@ -0,0 +1,179 @@ | |||
1 | #ifndef __ASMARM_CTI_H | ||
2 | #define __ASMARM_CTI_H | ||
3 | |||
4 | #include <asm/io.h> | ||
5 | |||
6 | /* The registers' definition is from section 3.2 of | ||
7 | * Embedded Cross Trigger Revision: r0p0 | ||
8 | */ | ||
9 | #define CTICONTROL 0x000 | ||
10 | #define CTISTATUS 0x004 | ||
11 | #define CTILOCK 0x008 | ||
12 | #define CTIPROTECTION 0x00C | ||
13 | #define CTIINTACK 0x010 | ||
14 | #define CTIAPPSET 0x014 | ||
15 | #define CTIAPPCLEAR 0x018 | ||
16 | #define CTIAPPPULSE 0x01c | ||
17 | #define CTIINEN 0x020 | ||
18 | #define CTIOUTEN 0x0A0 | ||
19 | #define CTITRIGINSTATUS 0x130 | ||
20 | #define CTITRIGOUTSTATUS 0x134 | ||
21 | #define CTICHINSTATUS 0x138 | ||
22 | #define CTICHOUTSTATUS 0x13c | ||
23 | #define CTIPERIPHID0 0xFE0 | ||
24 | #define CTIPERIPHID1 0xFE4 | ||
25 | #define CTIPERIPHID2 0xFE8 | ||
26 | #define CTIPERIPHID3 0xFEC | ||
27 | #define CTIPCELLID0 0xFF0 | ||
28 | #define CTIPCELLID1 0xFF4 | ||
29 | #define CTIPCELLID2 0xFF8 | ||
30 | #define CTIPCELLID3 0xFFC | ||
31 | |||
32 | /* The below are from section 3.6.4 of | ||
33 | * CoreSight v1.0 Architecture Specification | ||
34 | */ | ||
35 | #define LOCKACCESS 0xFB0 | ||
36 | #define LOCKSTATUS 0xFB4 | ||
37 | |||
38 | /* write this value to LOCKACCESS will unlock the module, and | ||
39 | * other value will lock the module | ||
40 | */ | ||
41 | #define LOCKCODE 0xC5ACCE55 | ||
42 | |||
43 | /** | ||
44 | * struct cti - cross trigger interface struct | ||
45 | * @base: mapped virtual address for the cti base | ||
46 | * @irq: irq number for the cti | ||
47 | * @trig_out_for_irq: triger out number which will cause | ||
48 | * the @irq happen | ||
49 | * | ||
50 | * cti struct used to operate cti registers. | ||
51 | */ | ||
52 | struct cti { | ||
53 | void __iomem *base; | ||
54 | int irq; | ||
55 | int trig_out_for_irq; | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * cti_init - initialize the cti instance | ||
60 | * @cti: cti instance | ||
61 | * @base: mapped virtual address for the cti base | ||
62 | * @irq: irq number for the cti | ||
63 | * @trig_out: triger out number which will cause | ||
64 | * the @irq happen | ||
65 | * | ||
66 | * called by machine code to pass the board dependent | ||
67 | * @base, @irq and @trig_out to cti. | ||
68 | */ | ||
69 | static inline void cti_init(struct cti *cti, | ||
70 | void __iomem *base, int irq, int trig_out) | ||
71 | { | ||
72 | cti->base = base; | ||
73 | cti->irq = irq; | ||
74 | cti->trig_out_for_irq = trig_out; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * cti_map_trigger - use the @chan to map @trig_in to @trig_out | ||
79 | * @cti: cti instance | ||
80 | * @trig_in: trigger in number | ||
81 | * @trig_out: trigger out number | ||
82 | * @channel: channel number | ||
83 | * | ||
84 | * This function maps one trigger in of @trig_in to one trigger | ||
85 | * out of @trig_out using the channel @chan. | ||
86 | */ | ||
87 | static inline void cti_map_trigger(struct cti *cti, | ||
88 | int trig_in, int trig_out, int chan) | ||
89 | { | ||
90 | void __iomem *base = cti->base; | ||
91 | unsigned long val; | ||
92 | |||
93 | val = __raw_readl(base + CTIINEN + trig_in * 4); | ||
94 | val |= BIT(chan); | ||
95 | __raw_writel(val, base + CTIINEN + trig_in * 4); | ||
96 | |||
97 | val = __raw_readl(base + CTIOUTEN + trig_out * 4); | ||
98 | val |= BIT(chan); | ||
99 | __raw_writel(val, base + CTIOUTEN + trig_out * 4); | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * cti_enable - enable the cti module | ||
104 | * @cti: cti instance | ||
105 | * | ||
106 | * enable the cti module | ||
107 | */ | ||
108 | static inline void cti_enable(struct cti *cti) | ||
109 | { | ||
110 | __raw_writel(0x1, cti->base + CTICONTROL); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * cti_disable - disable the cti module | ||
115 | * @cti: cti instance | ||
116 | * | ||
117 | * enable the cti module | ||
118 | */ | ||
119 | static inline void cti_disable(struct cti *cti) | ||
120 | { | ||
121 | __raw_writel(0, cti->base + CTICONTROL); | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * cti_irq_ack - clear the cti irq | ||
126 | * @cti: cti instance | ||
127 | * | ||
128 | * clear the cti irq | ||
129 | */ | ||
130 | static inline void cti_irq_ack(struct cti *cti) | ||
131 | { | ||
132 | void __iomem *base = cti->base; | ||
133 | unsigned long val; | ||
134 | |||
135 | val = __raw_readl(base + CTIINTACK); | ||
136 | val |= BIT(cti->trig_out_for_irq); | ||
137 | __raw_writel(val, base + CTIINTACK); | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * cti_unlock - unlock cti module | ||
142 | * @cti: cti instance | ||
143 | * | ||
144 | * unlock the cti module, or else any writes to the cti | ||
145 | * module is not allowed. | ||
146 | */ | ||
147 | static inline void cti_unlock(struct cti *cti) | ||
148 | { | ||
149 | void __iomem *base = cti->base; | ||
150 | unsigned long val; | ||
151 | |||
152 | val = __raw_readl(base + LOCKSTATUS); | ||
153 | |||
154 | if (val & 1) { | ||
155 | val = LOCKCODE; | ||
156 | __raw_writel(val, base + LOCKACCESS); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * cti_lock - lock cti module | ||
162 | * @cti: cti instance | ||
163 | * | ||
164 | * lock the cti module, so any writes to the cti | ||
165 | * module will be not allowed. | ||
166 | */ | ||
167 | static inline void cti_lock(struct cti *cti) | ||
168 | { | ||
169 | void __iomem *base = cti->base; | ||
170 | unsigned long val; | ||
171 | |||
172 | val = __raw_readl(base + LOCKSTATUS); | ||
173 | |||
174 | if (!(val & 1)) { | ||
175 | val = ~LOCKCODE; | ||
176 | __raw_writel(val, base + LOCKACCESS); | ||
177 | } | ||
178 | } | ||
179 | #endif | ||
diff --git a/arch/arm/include/asm/edac.h b/arch/arm/include/asm/edac.h new file mode 100644 index 000000000000..0df7a2c1fc3d --- /dev/null +++ b/arch/arm/include/asm/edac.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Calxeda, Inc. | ||
3 | * Based on PPC version Copyright 2007 MontaVista Software, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #ifndef ASM_EDAC_H | ||
18 | #define ASM_EDAC_H | ||
19 | /* | ||
20 | * ECC atomic, DMA, SMP and interrupt safe scrub function. | ||
21 | * Implements the per arch atomic_scrub() that EDAC use for software | ||
22 | * ECC scrubbing. It reads memory and then writes back the original | ||
23 | * value, allowing the hardware to detect and correct memory errors. | ||
24 | */ | ||
25 | static inline void atomic_scrub(void *va, u32 size) | ||
26 | { | ||
27 | #if __LINUX_ARM_ARCH__ >= 6 | ||
28 | unsigned int *virt_addr = va; | ||
29 | unsigned int temp, temp2; | ||
30 | unsigned int i; | ||
31 | |||
32 | for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) { | ||
33 | /* Very carefully read and write to memory atomically | ||
34 | * so we are interrupt, DMA and SMP safe. | ||
35 | */ | ||
36 | __asm__ __volatile__("\n" | ||
37 | "1: ldrex %0, [%2]\n" | ||
38 | " strex %1, %0, [%2]\n" | ||
39 | " teq %1, #0\n" | ||
40 | " bne 1b\n" | ||
41 | : "=&r"(temp), "=&r"(temp2) | ||
42 | : "r"(virt_addr) | ||
43 | : "cc"); | ||
44 | } | ||
45 | #endif | ||
46 | } | ||
47 | |||
48 | #endif | ||
diff --git a/arch/arm/include/asm/entry-macro-vic2.S b/arch/arm/include/asm/entry-macro-vic2.S deleted file mode 100644 index 3ceb85e43850..000000000000 --- a/arch/arm/include/asm/entry-macro-vic2.S +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* arch/arm/include/asm/entry-macro-vic2.S | ||
2 | * | ||
3 | * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S | ||
4 | * | ||
5 | * Copyright 2008 Openmoko, Inc. | ||
6 | * Copyright 2008 Simtec Electronics | ||
7 | * http://armlinux.simtec.co.uk/ | ||
8 | * Ben Dooks <ben@simtec.co.uk> | ||
9 | * | ||
10 | * Low-level IRQ helper macros for a device with two VICs | ||
11 | * | ||
12 | * This file is licensed under the terms of the GNU General Public | ||
13 | * License version 2. This program is licensed "as is" without any | ||
14 | * warranty of any kind, whether express or implied. | ||
15 | */ | ||
16 | |||
17 | /* This should be included from <mach/entry-macro.S> with the necessary | ||
18 | * defines for virtual addresses and IRQ bases for the two vics. | ||
19 | * | ||
20 | * The code needs the following defined: | ||
21 | * IRQ_VIC0_BASE IRQ number of VIC0's first IRQ | ||
22 | * IRQ_VIC1_BASE IRQ number of VIC1's first IRQ | ||
23 | * VA_VIC0 Virtual address of VIC0 | ||
24 | * VA_VIC1 Virtual address of VIC1 | ||
25 | * | ||
26 | * Note, code assumes VIC0's virtual address is an ARM immediate constant | ||
27 | * away from VIC1. | ||
28 | */ | ||
29 | |||
30 | #include <asm/hardware/vic.h> | ||
31 | |||
32 | .macro disable_fiq | ||
33 | .endm | ||
34 | |||
35 | .macro get_irqnr_preamble, base, tmp | ||
36 | ldr \base, =VA_VIC0 | ||
37 | .endm | ||
38 | |||
39 | .macro arch_ret_to_user, tmp1, tmp2 | ||
40 | .endm | ||
41 | |||
42 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
43 | |||
44 | @ check the vic0 | ||
45 | mov \irqnr, #IRQ_VIC0_BASE + 31 | ||
46 | ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] | ||
47 | teq \irqstat, #0 | ||
48 | |||
49 | @ otherwise try vic1 | ||
50 | addeq \tmp, \base, #(VA_VIC1 - VA_VIC0) | ||
51 | addeq \irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE) | ||
52 | ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] | ||
53 | teqeq \irqstat, #0 | ||
54 | |||
55 | clzne \irqstat, \irqstat | ||
56 | subne \irqnr, \irqnr, \irqstat | ||
57 | .endm | ||
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index 11ad0bfbb0ad..7151753b0989 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h | |||
@@ -1,6 +1,10 @@ | |||
1 | #ifndef _ARCH_ARM_GPIO_H | 1 | #ifndef _ARCH_ARM_GPIO_H |
2 | #define _ARCH_ARM_GPIO_H | 2 | #define _ARCH_ARM_GPIO_H |
3 | 3 | ||
4 | #if CONFIG_ARCH_NR_GPIO > 0 | ||
5 | #define ARCH_NR_GPIO CONFIG_ARCH_NR_GPIO | ||
6 | #endif | ||
7 | |||
4 | /* not all ARM platforms necessarily support this API ... */ | 8 | /* not all ARM platforms necessarily support this API ... */ |
5 | #include <mach/gpio.h> | 9 | #include <mach/gpio.h> |
6 | 10 | ||
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index ddf07a92a6c8..436e60b2cf7a 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h | |||
@@ -27,23 +27,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu); | |||
27 | 27 | ||
28 | #define arch_irq_stat_cpu smp_irq_stat_cpu | 28 | #define arch_irq_stat_cpu smp_irq_stat_cpu |
29 | 29 | ||
30 | #if NR_IRQS > 512 | ||
31 | #define HARDIRQ_BITS 10 | ||
32 | #elif NR_IRQS > 256 | ||
33 | #define HARDIRQ_BITS 9 | ||
34 | #else | ||
35 | #define HARDIRQ_BITS 8 | ||
36 | #endif | ||
37 | |||
38 | /* | ||
39 | * The hardirq mask has to be large enough to have space | ||
40 | * for potentially all IRQ sources in the system nesting | ||
41 | * on a single CPU: | ||
42 | */ | ||
43 | #if (1 << HARDIRQ_BITS) < NR_IRQS | ||
44 | # error HARDIRQ_BITS is too low! | ||
45 | #endif | ||
46 | |||
47 | #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 | 30 | #define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 |
48 | 31 | ||
49 | #endif /* __ASM_HARDIRQ_H */ | 32 | #endif /* __ASM_HARDIRQ_H */ |
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S deleted file mode 100644 index 74ebc803904d..000000000000 --- a/arch/arm/include/asm/hardware/entry-macro-gic.S +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/hardware/entry-macro-gic.S | ||
3 | * | ||
4 | * Low-level IRQ helper macros for GIC | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <asm/hardware/gic.h> | ||
12 | |||
13 | #ifndef HAVE_GET_IRQNR_PREAMBLE | ||
14 | .macro get_irqnr_preamble, base, tmp | ||
15 | ldr \base, =gic_cpu_base_addr | ||
16 | ldr \base, [\base] | ||
17 | .endm | ||
18 | #endif | ||
19 | |||
20 | /* | ||
21 | * The interrupt numbering scheme is defined in the | ||
22 | * interrupt controller spec. To wit: | ||
23 | * | ||
24 | * Interrupts 0-15 are IPI | ||
25 | * 16-31 are local. We allow 30 to be used for the watchdog. | ||
26 | * 32-1020 are global | ||
27 | * 1021-1022 are reserved | ||
28 | * 1023 is "spurious" (no interrupt) | ||
29 | * | ||
30 | * A simple read from the controller will tell us the number of the highest | ||
31 | * priority enabled interrupt. We then just need to check whether it is in the | ||
32 | * valid range for an IRQ (30-1020 inclusive). | ||
33 | */ | ||
34 | |||
35 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
36 | |||
37 | ldr \irqstat, [\base, #GIC_CPU_INTACK] | ||
38 | /* bits 12-10 = src CPU, 9-0 = int # */ | ||
39 | |||
40 | ldr \tmp, =1021 | ||
41 | bic \irqnr, \irqstat, #0x1c00 | ||
42 | cmp \irqnr, #15 | ||
43 | cmpcc \irqnr, \irqnr | ||
44 | cmpne \irqnr, \tmp | ||
45 | cmpcs \irqnr, \irqnr | ||
46 | .endm | ||
47 | |||
48 | /* We assume that irqstat (the raw value of the IRQ acknowledge | ||
49 | * register) is preserved from the macro above. | ||
50 | * If there is an IPI, we immediately signal end of interrupt on the | ||
51 | * controller, since this requires the original irqstat value which | ||
52 | * we won't easily be able to recreate later. | ||
53 | */ | ||
54 | |||
55 | .macro test_for_ipi, irqnr, irqstat, base, tmp | ||
56 | bic \irqnr, \irqstat, #0x1c00 | ||
57 | cmp \irqnr, #16 | ||
58 | strcc \irqstat, [\base, #GIC_CPU_EOI] | ||
59 | cmpcs \irqnr, \irqnr | ||
60 | .endm | ||
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 3e91f22046f5..4bdfe0018696 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h | |||
@@ -36,30 +36,22 @@ | |||
36 | #include <linux/irqdomain.h> | 36 | #include <linux/irqdomain.h> |
37 | struct device_node; | 37 | struct device_node; |
38 | 38 | ||
39 | extern void __iomem *gic_cpu_base_addr; | ||
40 | extern struct irq_chip gic_arch_extn; | 39 | extern struct irq_chip gic_arch_extn; |
41 | 40 | ||
42 | void gic_init(unsigned int, int, void __iomem *, void __iomem *); | 41 | void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, |
42 | u32 offset); | ||
43 | int gic_of_init(struct device_node *node, struct device_node *parent); | 43 | int gic_of_init(struct device_node *node, struct device_node *parent); |
44 | void gic_secondary_init(unsigned int); | 44 | void gic_secondary_init(unsigned int); |
45 | void gic_handle_irq(struct pt_regs *regs); | ||
45 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); | 46 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); |
46 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); | 47 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); |
47 | 48 | ||
48 | struct gic_chip_data { | 49 | static inline void gic_init(unsigned int nr, int start, |
49 | void __iomem *dist_base; | 50 | void __iomem *dist , void __iomem *cpu) |
50 | void __iomem *cpu_base; | 51 | { |
51 | #ifdef CONFIG_CPU_PM | 52 | gic_init_bases(nr, start, dist, cpu, 0); |
52 | u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; | 53 | } |
53 | u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; | 54 | |
54 | u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; | ||
55 | u32 __percpu *saved_ppi_enable; | ||
56 | u32 __percpu *saved_ppi_conf; | ||
57 | #endif | ||
58 | #ifdef CONFIG_IRQ_DOMAIN | ||
59 | struct irq_domain domain; | ||
60 | #endif | ||
61 | unsigned int gic_irqs; | ||
62 | }; | ||
63 | #endif | 55 | #endif |
64 | 56 | ||
65 | #endif | 57 | #endif |
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 5daea2961d48..077c32326c63 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h | |||
@@ -234,6 +234,7 @@ extern int iop3xx_get_init_atu(void); | |||
234 | void iop3xx_map_io(void); | 234 | void iop3xx_map_io(void); |
235 | void iop_init_cp6_handler(void); | 235 | void iop_init_cp6_handler(void); |
236 | void iop_init_time(unsigned long tickrate); | 236 | void iop_init_time(unsigned long tickrate); |
237 | void iop3xx_restart(char, const char *); | ||
237 | 238 | ||
238 | static inline u32 read_tmr0(void) | 239 | static inline u32 read_tmr0(void) |
239 | { | 240 | { |
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h index 5d72550a8097..f42ebd619590 100644 --- a/arch/arm/include/asm/hardware/vic.h +++ b/arch/arm/include/asm/hardware/vic.h | |||
@@ -41,7 +41,15 @@ | |||
41 | #define VIC_PL192_VECT_ADDR 0xF00 | 41 | #define VIC_PL192_VECT_ADDR 0xF00 |
42 | 42 | ||
43 | #ifndef __ASSEMBLY__ | 43 | #ifndef __ASSEMBLY__ |
44 | #include <linux/compiler.h> | ||
45 | #include <linux/types.h> | ||
46 | |||
47 | struct device_node; | ||
48 | struct pt_regs; | ||
49 | |||
44 | void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); | 50 | void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); |
45 | #endif | 51 | int vic_of_init(struct device_node *node, struct device_node *parent); |
52 | void vic_handle_irq(struct pt_regs *regs); | ||
46 | 53 | ||
54 | #endif /* __ASSEMBLY__ */ | ||
47 | #endif | 55 | #endif |
diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h new file mode 100644 index 000000000000..bf863edb517d --- /dev/null +++ b/arch/arm/include/asm/idmap.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef __ASM_IDMAP_H | ||
2 | #define __ASM_IDMAP_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <asm/pgtable.h> | ||
6 | |||
7 | /* Tag a function as requiring to be executed via an identity mapping. */ | ||
8 | #define __idmap __section(.idmap.text) noinline notrace | ||
9 | |||
10 | extern pgd_t *idmap_pgd; | ||
11 | |||
12 | void setup_mm_for_reboot(void); | ||
13 | |||
14 | #endif /* __ASM_IDMAP_H */ | ||
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 2b0efc3104ac..bcb0c883e21e 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h | |||
@@ -31,10 +31,10 @@ struct machine_desc { | |||
31 | unsigned int video_start; /* start of video RAM */ | 31 | unsigned int video_start; /* start of video RAM */ |
32 | unsigned int video_end; /* end of video RAM */ | 32 | unsigned int video_end; /* end of video RAM */ |
33 | 33 | ||
34 | unsigned int reserve_lp0 :1; /* never has lp0 */ | 34 | unsigned char reserve_lp0 :1; /* never has lp0 */ |
35 | unsigned int reserve_lp1 :1; /* never has lp1 */ | 35 | unsigned char reserve_lp1 :1; /* never has lp1 */ |
36 | unsigned int reserve_lp2 :1; /* never has lp2 */ | 36 | unsigned char reserve_lp2 :1; /* never has lp2 */ |
37 | unsigned int soft_reboot :1; /* soft reboot */ | 37 | char restart_mode; /* default restart mode */ |
38 | void (*fixup)(struct tag *, char **, | 38 | void (*fixup)(struct tag *, char **, |
39 | struct meminfo *); | 39 | struct meminfo *); |
40 | void (*reserve)(void);/* reserve mem blocks */ | 40 | void (*reserve)(void);/* reserve mem blocks */ |
@@ -46,6 +46,7 @@ struct machine_desc { | |||
46 | #ifdef CONFIG_MULTI_IRQ_HANDLER | 46 | #ifdef CONFIG_MULTI_IRQ_HANDLER |
47 | void (*handle_irq)(struct pt_regs *); | 47 | void (*handle_irq)(struct pt_regs *); |
48 | #endif | 48 | #endif |
49 | void (*restart)(char, const char *); | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /* | 52 | /* |
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h new file mode 100644 index 000000000000..c0efdd60966f --- /dev/null +++ b/arch/arm/include/asm/opcodes.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/opcodes.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_ARM_OPCODES_H | ||
10 | #define __ASM_ARM_OPCODES_H | ||
11 | |||
12 | #ifndef __ASSEMBLY__ | ||
13 | extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); | ||
14 | #endif | ||
15 | |||
16 | #define ARM_OPCODE_CONDTEST_FAIL 0 | ||
17 | #define ARM_OPCODE_CONDTEST_PASS 1 | ||
18 | #define ARM_OPCODE_CONDTEST_UNCOND 2 | ||
19 | |||
20 | #endif /* __ASM_ARM_OPCODES_H */ | ||
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index ca94653f1ecb..97b440c25c58 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h | |||
@@ -151,7 +151,11 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from, | |||
151 | #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) | 151 | #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) |
152 | extern void copy_page(void *to, const void *from); | 152 | extern void copy_page(void *to, const void *from); |
153 | 153 | ||
154 | #ifdef CONFIG_ARM_LPAE | ||
155 | #include <asm/pgtable-3level-types.h> | ||
156 | #else | ||
154 | #include <asm/pgtable-2level-types.h> | 157 | #include <asm/pgtable-2level-types.h> |
158 | #endif | ||
155 | 159 | ||
156 | #endif /* CONFIG_MMU */ | 160 | #endif /* CONFIG_MMU */ |
157 | 161 | ||
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 0f8e3827a89b..99cfe3607989 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h | |||
@@ -32,7 +32,4 @@ enum arm_perf_pmu_ids { | |||
32 | extern enum arm_perf_pmu_ids | 32 | extern enum arm_perf_pmu_ids |
33 | armpmu_get_pmu_id(void); | 33 | armpmu_get_pmu_id(void); |
34 | 34 | ||
35 | extern int | ||
36 | armpmu_get_max_events(void); | ||
37 | |||
38 | #endif /* __ARM_PERF_EVENT_H__ */ | 35 | #endif /* __ARM_PERF_EVENT_H__ */ |
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 3e08fd3fbb6b..943504f53f57 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h | |||
@@ -25,12 +25,34 @@ | |||
25 | #define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) | 25 | #define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) |
26 | #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) | 26 | #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) |
27 | 27 | ||
28 | #ifdef CONFIG_ARM_LPAE | ||
29 | |||
30 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
31 | { | ||
32 | return (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT); | ||
33 | } | ||
34 | |||
35 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | ||
36 | { | ||
37 | BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); | ||
38 | free_page((unsigned long)pmd); | ||
39 | } | ||
40 | |||
41 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | ||
42 | { | ||
43 | set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE)); | ||
44 | } | ||
45 | |||
46 | #else /* !CONFIG_ARM_LPAE */ | ||
47 | |||
28 | /* | 48 | /* |
29 | * Since we have only two-level page tables, these are trivial | 49 | * Since we have only two-level page tables, these are trivial |
30 | */ | 50 | */ |
31 | #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) | 51 | #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) |
32 | #define pmd_free(mm, pmd) do { } while (0) | 52 | #define pmd_free(mm, pmd) do { } while (0) |
33 | #define pgd_populate(mm,pmd,pte) BUG() | 53 | #define pud_populate(mm,pmd,pte) BUG() |
54 | |||
55 | #endif /* CONFIG_ARM_LPAE */ | ||
34 | 56 | ||
35 | extern pgd_t *pgd_alloc(struct mm_struct *mm); | 57 | extern pgd_t *pgd_alloc(struct mm_struct *mm); |
36 | extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); | 58 | extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); |
@@ -109,7 +131,9 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte, | |||
109 | { | 131 | { |
110 | pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot; | 132 | pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot; |
111 | pmdp[0] = __pmd(pmdval); | 133 | pmdp[0] = __pmd(pmdval); |
134 | #ifndef CONFIG_ARM_LPAE | ||
112 | pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); | 135 | pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); |
136 | #endif | ||
113 | flush_pmd_entry(pmdp); | 137 | flush_pmd_entry(pmdp); |
114 | } | 138 | } |
115 | 139 | ||
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index 470457e1cfc5..2317a71c8f8e 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h | |||
@@ -140,4 +140,45 @@ | |||
140 | #define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ | 140 | #define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ |
141 | #define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) | 141 | #define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) |
142 | 142 | ||
143 | #ifndef __ASSEMBLY__ | ||
144 | |||
145 | /* | ||
146 | * The "pud_xxx()" functions here are trivial when the pmd is folded into | ||
147 | * the pud: the pud entry is never bad, always exists, and can't be set or | ||
148 | * cleared. | ||
149 | */ | ||
150 | #define pud_none(pud) (0) | ||
151 | #define pud_bad(pud) (0) | ||
152 | #define pud_present(pud) (1) | ||
153 | #define pud_clear(pudp) do { } while (0) | ||
154 | #define set_pud(pud,pudp) do { } while (0) | ||
155 | |||
156 | static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | ||
157 | { | ||
158 | return (pmd_t *)pud; | ||
159 | } | ||
160 | |||
161 | #define pmd_bad(pmd) (pmd_val(pmd) & 2) | ||
162 | |||
163 | #define copy_pmd(pmdpd,pmdps) \ | ||
164 | do { \ | ||
165 | pmdpd[0] = pmdps[0]; \ | ||
166 | pmdpd[1] = pmdps[1]; \ | ||
167 | flush_pmd_entry(pmdpd); \ | ||
168 | } while (0) | ||
169 | |||
170 | #define pmd_clear(pmdp) \ | ||
171 | do { \ | ||
172 | pmdp[0] = __pmd(0); \ | ||
173 | pmdp[1] = __pmd(0); \ | ||
174 | clean_pmd_entry(pmdp); \ | ||
175 | } while (0) | ||
176 | |||
177 | /* we don't need complex calculations here as the pmd is folded into the pgd */ | ||
178 | #define pmd_addr_end(addr,end) (end) | ||
179 | |||
180 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) | ||
181 | |||
182 | #endif /* __ASSEMBLY__ */ | ||
183 | |||
143 | #endif /* _ASM_PGTABLE_2LEVEL_H */ | 184 | #endif /* _ASM_PGTABLE_2LEVEL_H */ |
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h new file mode 100644 index 000000000000..d7952824c5c4 --- /dev/null +++ b/arch/arm/include/asm/pgtable-3level-hwdef.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/pgtable-3level-hwdef.h | ||
3 | * | ||
4 | * Copyright (C) 2011 ARM Ltd. | ||
5 | * Author: Catalin Marinas <catalin.marinas@arm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | #ifndef _ASM_PGTABLE_3LEVEL_HWDEF_H | ||
21 | #define _ASM_PGTABLE_3LEVEL_HWDEF_H | ||
22 | |||
23 | /* | ||
24 | * Hardware page table definitions. | ||
25 | * | ||
26 | * + Level 1/2 descriptor | ||
27 | * - common | ||
28 | */ | ||
29 | #define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0) | ||
30 | #define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) | ||
31 | #define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0) | ||
32 | #define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0) | ||
33 | #define PMD_BIT4 (_AT(pmdval_t, 0)) | ||
34 | #define PMD_DOMAIN(x) (_AT(pmdval_t, 0)) | ||
35 | |||
36 | /* | ||
37 | * - section | ||
38 | */ | ||
39 | #define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) | ||
40 | #define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) | ||
41 | #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) | ||
42 | #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) | ||
43 | #define PMD_SECT_nG (_AT(pmdval_t, 1) << 11) | ||
44 | #define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) | ||
45 | #define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0)) | ||
46 | #define PMD_SECT_AP_READ (_AT(pmdval_t, 0)) | ||
47 | #define PMD_SECT_TEX(x) (_AT(pmdval_t, 0)) | ||
48 | |||
49 | /* | ||
50 | * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). | ||
51 | */ | ||
52 | #define PMD_SECT_UNCACHED (_AT(pmdval_t, 0) << 2) /* strongly ordered */ | ||
53 | #define PMD_SECT_BUFFERED (_AT(pmdval_t, 1) << 2) /* normal non-cacheable */ | ||
54 | #define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */ | ||
55 | #define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */ | ||
56 | #define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */ | ||
57 | |||
58 | /* | ||
59 | * + Level 3 descriptor (PTE) | ||
60 | */ | ||
61 | #define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0) | ||
62 | #define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0) | ||
63 | #define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0) | ||
64 | #define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ | ||
65 | #define PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ | ||
66 | #define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ | ||
67 | #define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ | ||
68 | #define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ | ||
69 | #define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ | ||
70 | |||
71 | /* | ||
72 | * 40-bit physical address supported. | ||
73 | */ | ||
74 | #define PHYS_MASK_SHIFT (40) | ||
75 | #define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1) | ||
76 | |||
77 | #endif | ||
diff --git a/arch/arm/include/asm/pgtable-3level-types.h b/arch/arm/include/asm/pgtable-3level-types.h new file mode 100644 index 000000000000..921aa30259c4 --- /dev/null +++ b/arch/arm/include/asm/pgtable-3level-types.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/pgtable-3level-types.h | ||
3 | * | ||
4 | * Copyright (C) 2011 ARM Ltd. | ||
5 | * Author: Catalin Marinas <catalin.marinas@arm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | #ifndef _ASM_PGTABLE_3LEVEL_TYPES_H | ||
21 | #define _ASM_PGTABLE_3LEVEL_TYPES_H | ||
22 | |||
23 | #include <asm/types.h> | ||
24 | |||
25 | typedef u64 pteval_t; | ||
26 | typedef u64 pmdval_t; | ||
27 | typedef u64 pgdval_t; | ||
28 | |||
29 | #undef STRICT_MM_TYPECHECKS | ||
30 | |||
31 | #ifdef STRICT_MM_TYPECHECKS | ||
32 | |||
33 | /* | ||
34 | * These are used to make use of C type-checking.. | ||
35 | */ | ||
36 | typedef struct { pteval_t pte; } pte_t; | ||
37 | typedef struct { pmdval_t pmd; } pmd_t; | ||
38 | typedef struct { pgdval_t pgd; } pgd_t; | ||
39 | typedef struct { pteval_t pgprot; } pgprot_t; | ||
40 | |||
41 | #define pte_val(x) ((x).pte) | ||
42 | #define pmd_val(x) ((x).pmd) | ||
43 | #define pgd_val(x) ((x).pgd) | ||
44 | #define pgprot_val(x) ((x).pgprot) | ||
45 | |||
46 | #define __pte(x) ((pte_t) { (x) } ) | ||
47 | #define __pmd(x) ((pmd_t) { (x) } ) | ||
48 | #define __pgd(x) ((pgd_t) { (x) } ) | ||
49 | #define __pgprot(x) ((pgprot_t) { (x) } ) | ||
50 | |||
51 | #else /* !STRICT_MM_TYPECHECKS */ | ||
52 | |||
53 | typedef pteval_t pte_t; | ||
54 | typedef pmdval_t pmd_t; | ||
55 | typedef pgdval_t pgd_t; | ||
56 | typedef pteval_t pgprot_t; | ||
57 | |||
58 | #define pte_val(x) (x) | ||
59 | #define pmd_val(x) (x) | ||
60 | #define pgd_val(x) (x) | ||
61 | #define pgprot_val(x) (x) | ||
62 | |||
63 | #define __pte(x) (x) | ||
64 | #define __pmd(x) (x) | ||
65 | #define __pgd(x) (x) | ||
66 | #define __pgprot(x) (x) | ||
67 | |||
68 | #endif /* STRICT_MM_TYPECHECKS */ | ||
69 | |||
70 | #endif /* _ASM_PGTABLE_3LEVEL_TYPES_H */ | ||
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h new file mode 100644 index 000000000000..759af70f9a0a --- /dev/null +++ b/arch/arm/include/asm/pgtable-3level.h | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * arch/arm/include/asm/pgtable-3level.h | ||
3 | * | ||
4 | * Copyright (C) 2011 ARM Ltd. | ||
5 | * Author: Catalin Marinas <catalin.marinas@arm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | #ifndef _ASM_PGTABLE_3LEVEL_H | ||
21 | #define _ASM_PGTABLE_3LEVEL_H | ||
22 | |||
23 | /* | ||
24 | * With LPAE, there are 3 levels of page tables. Each level has 512 entries of | ||
25 | * 8 bytes each, occupying a 4K page. The first level table covers a range of | ||
26 | * 512GB, each entry representing 1GB. Since we are limited to 4GB input | ||
27 | * address range, only 4 entries in the PGD are used. | ||
28 | * | ||
29 | * There are enough spare bits in a page table entry for the kernel specific | ||
30 | * state. | ||
31 | */ | ||
32 | #define PTRS_PER_PTE 512 | ||
33 | #define PTRS_PER_PMD 512 | ||
34 | #define PTRS_PER_PGD 4 | ||
35 | |||
36 | #define PTE_HWTABLE_PTRS (PTRS_PER_PTE) | ||
37 | #define PTE_HWTABLE_OFF (0) | ||
38 | #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) | ||
39 | |||
40 | /* | ||
41 | * PGDIR_SHIFT determines the size a top-level page table entry can map. | ||
42 | */ | ||
43 | #define PGDIR_SHIFT 30 | ||
44 | |||
45 | /* | ||
46 | * PMD_SHIFT determines the size a middle-level page table entry can map. | ||
47 | */ | ||
48 | #define PMD_SHIFT 21 | ||
49 | |||
50 | #define PMD_SIZE (1UL << PMD_SHIFT) | ||
51 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
52 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | ||
53 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
54 | |||
55 | /* | ||
56 | * section address mask and size definitions. | ||
57 | */ | ||
58 | #define SECTION_SHIFT 21 | ||
59 | #define SECTION_SIZE (1UL << SECTION_SHIFT) | ||
60 | #define SECTION_MASK (~(SECTION_SIZE-1)) | ||
61 | |||
62 | #define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE) | ||
63 | |||
64 | /* | ||
65 | * "Linux" PTE definitions for LPAE. | ||
66 | * | ||
67 | * These bits overlap with the hardware bits but the naming is preserved for | ||
68 | * consistency with the classic page table format. | ||
69 | */ | ||
70 | #define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */ | ||
71 | #define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ | ||
72 | #define L_PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ | ||
73 | #define L_PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ | ||
74 | #define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */ | ||
75 | #define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */ | ||
76 | #define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ | ||
77 | #define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */ | ||
78 | #define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ | ||
79 | #define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */ | ||
80 | #define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */ | ||
81 | |||
82 | /* | ||
83 | * To be used in assembly code with the upper page attributes. | ||
84 | */ | ||
85 | #define L_PTE_XN_HIGH (1 << (54 - 32)) | ||
86 | #define L_PTE_DIRTY_HIGH (1 << (55 - 32)) | ||
87 | |||
88 | /* | ||
89 | * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). | ||
90 | */ | ||
91 | #define L_PTE_MT_UNCACHED (_AT(pteval_t, 0) << 2) /* strongly ordered */ | ||
92 | #define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 1) << 2) /* normal non-cacheable */ | ||
93 | #define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 2) << 2) /* normal inner write-through */ | ||
94 | #define L_PTE_MT_WRITEBACK (_AT(pteval_t, 3) << 2) /* normal inner write-back */ | ||
95 | #define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 7) << 2) /* normal inner write-alloc */ | ||
96 | #define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 4) << 2) /* device */ | ||
97 | #define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 4) << 2) /* device */ | ||
98 | #define L_PTE_MT_DEV_WC (_AT(pteval_t, 1) << 2) /* normal non-cacheable */ | ||
99 | #define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 3) << 2) /* normal inner write-back */ | ||
100 | #define L_PTE_MT_MASK (_AT(pteval_t, 7) << 2) | ||
101 | |||
102 | /* | ||
103 | * Software PGD flags. | ||
104 | */ | ||
105 | #define L_PGD_SWAPPER (_AT(pgdval_t, 1) << 55) /* swapper_pg_dir entry */ | ||
106 | |||
107 | #ifndef __ASSEMBLY__ | ||
108 | |||
109 | #define pud_none(pud) (!pud_val(pud)) | ||
110 | #define pud_bad(pud) (!(pud_val(pud) & 2)) | ||
111 | #define pud_present(pud) (pud_val(pud)) | ||
112 | |||
113 | #define pud_clear(pudp) \ | ||
114 | do { \ | ||
115 | *pudp = __pud(0); \ | ||
116 | clean_pmd_entry(pudp); \ | ||
117 | } while (0) | ||
118 | |||
119 | #define set_pud(pudp, pud) \ | ||
120 | do { \ | ||
121 | *pudp = pud; \ | ||
122 | flush_pmd_entry(pudp); \ | ||
123 | } while (0) | ||
124 | |||
125 | static inline pmd_t *pud_page_vaddr(pud_t pud) | ||
126 | { | ||
127 | return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK); | ||
128 | } | ||
129 | |||
130 | /* Find an entry in the second-level page table.. */ | ||
131 | #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) | ||
132 | static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) | ||
133 | { | ||
134 | return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr); | ||
135 | } | ||
136 | |||
137 | #define pmd_bad(pmd) (!(pmd_val(pmd) & 2)) | ||
138 | |||
139 | #define copy_pmd(pmdpd,pmdps) \ | ||
140 | do { \ | ||
141 | *pmdpd = *pmdps; \ | ||
142 | flush_pmd_entry(pmdpd); \ | ||
143 | } while (0) | ||
144 | |||
145 | #define pmd_clear(pmdp) \ | ||
146 | do { \ | ||
147 | *pmdp = __pmd(0); \ | ||
148 | clean_pmd_entry(pmdp); \ | ||
149 | } while (0) | ||
150 | |||
151 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext))) | ||
152 | |||
153 | #endif /* __ASSEMBLY__ */ | ||
154 | |||
155 | #endif /* _ASM_PGTABLE_3LEVEL_H */ | ||
diff --git a/arch/arm/include/asm/pgtable-hwdef.h b/arch/arm/include/asm/pgtable-hwdef.h index 183111164ce9..8426229ba292 100644 --- a/arch/arm/include/asm/pgtable-hwdef.h +++ b/arch/arm/include/asm/pgtable-hwdef.h | |||
@@ -10,6 +10,10 @@ | |||
10 | #ifndef _ASMARM_PGTABLE_HWDEF_H | 10 | #ifndef _ASMARM_PGTABLE_HWDEF_H |
11 | #define _ASMARM_PGTABLE_HWDEF_H | 11 | #define _ASMARM_PGTABLE_HWDEF_H |
12 | 12 | ||
13 | #ifdef CONFIG_ARM_LPAE | ||
14 | #include <asm/pgtable-3level-hwdef.h> | ||
15 | #else | ||
13 | #include <asm/pgtable-2level-hwdef.h> | 16 | #include <asm/pgtable-2level-hwdef.h> |
17 | #endif | ||
14 | 18 | ||
15 | #endif | 19 | #endif |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 9451dce3a553..f66626d71e7d 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -11,20 +11,24 @@ | |||
11 | #define _ASMARM_PGTABLE_H | 11 | #define _ASMARM_PGTABLE_H |
12 | 12 | ||
13 | #include <linux/const.h> | 13 | #include <linux/const.h> |
14 | #include <asm-generic/4level-fixup.h> | ||
15 | #include <asm/proc-fns.h> | 14 | #include <asm/proc-fns.h> |
16 | 15 | ||
17 | #ifndef CONFIG_MMU | 16 | #ifndef CONFIG_MMU |
18 | 17 | ||
18 | #include <asm-generic/4level-fixup.h> | ||
19 | #include "pgtable-nommu.h" | 19 | #include "pgtable-nommu.h" |
20 | 20 | ||
21 | #else | 21 | #else |
22 | 22 | ||
23 | #include <asm-generic/pgtable-nopud.h> | ||
23 | #include <asm/memory.h> | 24 | #include <asm/memory.h> |
24 | #include <mach/vmalloc.h> | ||
25 | #include <asm/pgtable-hwdef.h> | 25 | #include <asm/pgtable-hwdef.h> |
26 | 26 | ||
27 | #ifdef CONFIG_ARM_LPAE | ||
28 | #include <asm/pgtable-3level.h> | ||
29 | #else | ||
27 | #include <asm/pgtable-2level.h> | 30 | #include <asm/pgtable-2level.h> |
31 | #endif | ||
28 | 32 | ||
29 | /* | 33 | /* |
30 | * Just any arbitrary offset to the start of the vmalloc VM area: the | 34 | * Just any arbitrary offset to the start of the vmalloc VM area: the |
@@ -33,15 +37,10 @@ | |||
33 | * any out-of-bounds memory accesses will hopefully be caught. | 37 | * any out-of-bounds memory accesses will hopefully be caught. |
34 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | 38 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced |
35 | * area for the same reason. ;) | 39 | * area for the same reason. ;) |
36 | * | ||
37 | * Note that platforms may override VMALLOC_START, but they must provide | ||
38 | * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space, | ||
39 | * which may not overlap IO space. | ||
40 | */ | 40 | */ |
41 | #ifndef VMALLOC_START | ||
42 | #define VMALLOC_OFFSET (8*1024*1024) | 41 | #define VMALLOC_OFFSET (8*1024*1024) |
43 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) | 42 | #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) |
44 | #endif | 43 | #define VMALLOC_END 0xff000000UL |
45 | 44 | ||
46 | #define LIBRARY_TEXT_START 0x0c000000 | 45 | #define LIBRARY_TEXT_START 0x0c000000 |
47 | 46 | ||
@@ -163,39 +162,8 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; | |||
163 | /* to find an entry in a kernel page-table-directory */ | 162 | /* to find an entry in a kernel page-table-directory */ |
164 | #define pgd_offset_k(addr) pgd_offset(&init_mm, addr) | 163 | #define pgd_offset_k(addr) pgd_offset(&init_mm, addr) |
165 | 164 | ||
166 | /* | ||
167 | * The "pgd_xxx()" functions here are trivial for a folded two-level | ||
168 | * setup: the pgd is never bad, and a pmd always exists (as it's folded | ||
169 | * into the pgd entry) | ||
170 | */ | ||
171 | #define pgd_none(pgd) (0) | ||
172 | #define pgd_bad(pgd) (0) | ||
173 | #define pgd_present(pgd) (1) | ||
174 | #define pgd_clear(pgdp) do { } while (0) | ||
175 | #define set_pgd(pgd,pgdp) do { } while (0) | ||
176 | #define set_pud(pud,pudp) do { } while (0) | ||
177 | |||
178 | |||
179 | /* Find an entry in the second-level page table.. */ | ||
180 | #define pmd_offset(dir, addr) ((pmd_t *)(dir)) | ||
181 | |||
182 | #define pmd_none(pmd) (!pmd_val(pmd)) | 165 | #define pmd_none(pmd) (!pmd_val(pmd)) |
183 | #define pmd_present(pmd) (pmd_val(pmd)) | 166 | #define pmd_present(pmd) (pmd_val(pmd)) |
184 | #define pmd_bad(pmd) (pmd_val(pmd) & 2) | ||
185 | |||
186 | #define copy_pmd(pmdpd,pmdps) \ | ||
187 | do { \ | ||
188 | pmdpd[0] = pmdps[0]; \ | ||
189 | pmdpd[1] = pmdps[1]; \ | ||
190 | flush_pmd_entry(pmdpd); \ | ||
191 | } while (0) | ||
192 | |||
193 | #define pmd_clear(pmdp) \ | ||
194 | do { \ | ||
195 | pmdp[0] = __pmd(0); \ | ||
196 | pmdp[1] = __pmd(0); \ | ||
197 | clean_pmd_entry(pmdp); \ | ||
198 | } while (0) | ||
199 | 167 | ||
200 | static inline pte_t *pmd_page_vaddr(pmd_t pmd) | 168 | static inline pte_t *pmd_page_vaddr(pmd_t pmd) |
201 | { | 169 | { |
@@ -204,10 +172,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
204 | 172 | ||
205 | #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) | 173 | #define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK)) |
206 | 174 | ||
207 | /* we don't need complex calculations here as the pmd is folded into the pgd */ | ||
208 | #define pmd_addr_end(addr,end) (end) | ||
209 | |||
210 | |||
211 | #ifndef CONFIG_HIGHPTE | 175 | #ifndef CONFIG_HIGHPTE |
212 | #define __pte_map(pmd) pmd_page_vaddr(*(pmd)) | 176 | #define __pte_map(pmd) pmd_page_vaddr(*(pmd)) |
213 | #define __pte_unmap(pte) do { } while (0) | 177 | #define __pte_unmap(pte) do { } while (0) |
@@ -229,7 +193,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
229 | #define pte_page(pte) pfn_to_page(pte_pfn(pte)) | 193 | #define pte_page(pte) pfn_to_page(pte_pfn(pte)) |
230 | #define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot) | 194 | #define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot) |
231 | 195 | ||
232 | #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) | ||
233 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) | 196 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) |
234 | 197 | ||
235 | #if __LINUX_ARM_ARCH__ < 6 | 198 | #if __LINUX_ARM_ARCH__ < 6 |
@@ -336,6 +299,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
336 | * We provide our own arch_get_unmapped_area to cope with VIPT caches. | 299 | * We provide our own arch_get_unmapped_area to cope with VIPT caches. |
337 | */ | 300 | */ |
338 | #define HAVE_ARCH_UNMAPPED_AREA | 301 | #define HAVE_ARCH_UNMAPPED_AREA |
302 | #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN | ||
339 | 303 | ||
340 | /* | 304 | /* |
341 | * remap a physical page `pfn' of size `size' with page protection `prot' | 305 | * remap a physical page `pfn' of size `size' with page protection `prot' |
@@ -346,9 +310,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
346 | 310 | ||
347 | #define pgtable_cache_init() do { } while (0) | 311 | #define pgtable_cache_init() do { } while (0) |
348 | 312 | ||
349 | void identity_mapping_add(pgd_t *, unsigned long, unsigned long); | ||
350 | void identity_mapping_del(pgd_t *, unsigned long, unsigned long); | ||
351 | |||
352 | #endif /* !__ASSEMBLY__ */ | 313 | #endif /* !__ASSEMBLY__ */ |
353 | 314 | ||
354 | #endif /* CONFIG_MMU */ | 315 | #endif /* CONFIG_MMU */ |
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 0bda22c094a6..b5a5be2536c1 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h | |||
@@ -27,13 +27,22 @@ enum arm_pmu_type { | |||
27 | /* | 27 | /* |
28 | * struct arm_pmu_platdata - ARM PMU platform data | 28 | * struct arm_pmu_platdata - ARM PMU platform data |
29 | * | 29 | * |
30 | * @handle_irq: an optional handler which will be called from the interrupt and | 30 | * @handle_irq: an optional handler which will be called from the |
31 | * passed the address of the low level handler, and can be used to implement | 31 | * interrupt and passed the address of the low level handler, |
32 | * any platform specific handling before or after calling it. | 32 | * and can be used to implement any platform specific handling |
33 | * before or after calling it. | ||
34 | * @enable_irq: an optional handler which will be called after | ||
35 | * request_irq and be used to handle some platform specific | ||
36 | * irq enablement | ||
37 | * @disable_irq: an optional handler which will be called before | ||
38 | * free_irq and be used to handle some platform specific | ||
39 | * irq disablement | ||
33 | */ | 40 | */ |
34 | struct arm_pmu_platdata { | 41 | struct arm_pmu_platdata { |
35 | irqreturn_t (*handle_irq)(int irq, void *dev, | 42 | irqreturn_t (*handle_irq)(int irq, void *dev, |
36 | irq_handler_t pmu_handler); | 43 | irq_handler_t pmu_handler); |
44 | void (*enable_irq)(int irq); | ||
45 | void (*disable_irq)(int irq); | ||
37 | }; | 46 | }; |
38 | 47 | ||
39 | #ifdef CONFIG_CPU_HAS_PMU | 48 | #ifdef CONFIG_CPU_HAS_PMU |
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index 9e92cb205e65..f3628fb3d2b3 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h | |||
@@ -65,7 +65,11 @@ extern struct processor { | |||
65 | * Set a possibly extended PTE. Non-extended PTEs should | 65 | * Set a possibly extended PTE. Non-extended PTEs should |
66 | * ignore 'ext'. | 66 | * ignore 'ext'. |
67 | */ | 67 | */ |
68 | #ifdef CONFIG_ARM_LPAE | ||
69 | void (*set_pte_ext)(pte_t *ptep, pte_t pte); | ||
70 | #else | ||
68 | void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); | 71 | void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); |
72 | #endif | ||
69 | 73 | ||
70 | /* Suspend/resume */ | 74 | /* Suspend/resume */ |
71 | unsigned int suspend_size; | 75 | unsigned int suspend_size; |
@@ -79,7 +83,11 @@ extern void cpu_proc_fin(void); | |||
79 | extern int cpu_do_idle(void); | 83 | extern int cpu_do_idle(void); |
80 | extern void cpu_dcache_clean_area(void *, int); | 84 | extern void cpu_dcache_clean_area(void *, int); |
81 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | 85 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); |
86 | #ifdef CONFIG_ARM_LPAE | ||
87 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte); | ||
88 | #else | ||
82 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); | 89 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); |
90 | #endif | ||
83 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); | 91 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); |
84 | 92 | ||
85 | /* These three are private to arch/arm/kernel/suspend.c */ | 93 | /* These three are private to arch/arm/kernel/suspend.c */ |
@@ -107,6 +115,18 @@ extern void cpu_resume(void); | |||
107 | 115 | ||
108 | #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) | 116 | #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) |
109 | 117 | ||
118 | #ifdef CONFIG_ARM_LPAE | ||
119 | #define cpu_get_pgd() \ | ||
120 | ({ \ | ||
121 | unsigned long pg, pg2; \ | ||
122 | __asm__("mrrc p15, 0, %0, %1, c2" \ | ||
123 | : "=r" (pg), "=r" (pg2) \ | ||
124 | : \ | ||
125 | : "cc"); \ | ||
126 | pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \ | ||
127 | (pgd_t *)phys_to_virt(pg); \ | ||
128 | }) | ||
129 | #else | ||
110 | #define cpu_get_pgd() \ | 130 | #define cpu_get_pgd() \ |
111 | ({ \ | 131 | ({ \ |
112 | unsigned long pg; \ | 132 | unsigned long pg; \ |
@@ -115,6 +135,7 @@ extern void cpu_resume(void); | |||
115 | pg &= ~0x3fff; \ | 135 | pg &= ~0x3fff; \ |
116 | (pgd_t *)phys_to_virt(pg); \ | 136 | (pgd_t *)phys_to_virt(pg); \ |
117 | }) | 137 | }) |
138 | #endif | ||
118 | 139 | ||
119 | #endif | 140 | #endif |
120 | 141 | ||
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index b2d9df5667af..ce280b8d613c 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h | |||
@@ -123,6 +123,8 @@ static inline void prefetch(const void *ptr) | |||
123 | 123 | ||
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | #define HAVE_ARCH_PICK_MMAP_LAYOUT | ||
127 | |||
126 | #endif | 128 | #endif |
127 | 129 | ||
128 | #endif /* __ASM_ARM_PROCESSOR_H */ | 130 | #endif /* __ASM_ARM_PROCESSOR_H */ |
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h index c8e6ddf3e860..e3f757263438 100644 --- a/arch/arm/include/asm/sched_clock.h +++ b/arch/arm/include/asm/sched_clock.h | |||
@@ -8,113 +8,7 @@ | |||
8 | #ifndef ASM_SCHED_CLOCK | 8 | #ifndef ASM_SCHED_CLOCK |
9 | #define ASM_SCHED_CLOCK | 9 | #define ASM_SCHED_CLOCK |
10 | 10 | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/types.h> | ||
13 | |||
14 | struct clock_data { | ||
15 | u64 epoch_ns; | ||
16 | u32 epoch_cyc; | ||
17 | u32 epoch_cyc_copy; | ||
18 | u32 mult; | ||
19 | u32 shift; | ||
20 | }; | ||
21 | |||
22 | #define DEFINE_CLOCK_DATA(name) struct clock_data name | ||
23 | |||
24 | static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) | ||
25 | { | ||
26 | return (cyc * mult) >> shift; | ||
27 | } | ||
28 | |||
29 | /* | ||
30 | * Atomically update the sched_clock epoch. Your update callback will | ||
31 | * be called from a timer before the counter wraps - read the current | ||
32 | * counter value, and call this function to safely move the epochs | ||
33 | * forward. Only use this from the update callback. | ||
34 | */ | ||
35 | static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask) | ||
36 | { | ||
37 | unsigned long flags; | ||
38 | u64 ns = cd->epoch_ns + | ||
39 | cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift); | ||
40 | |||
41 | /* | ||
42 | * Write epoch_cyc and epoch_ns in a way that the update is | ||
43 | * detectable in cyc_to_fixed_sched_clock(). | ||
44 | */ | ||
45 | raw_local_irq_save(flags); | ||
46 | cd->epoch_cyc = cyc; | ||
47 | smp_wmb(); | ||
48 | cd->epoch_ns = ns; | ||
49 | smp_wmb(); | ||
50 | cd->epoch_cyc_copy = cyc; | ||
51 | raw_local_irq_restore(flags); | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * If your clock rate is known at compile time, using this will allow | ||
56 | * you to optimize the mult/shift loads away. This is paired with | ||
57 | * init_fixed_sched_clock() to ensure that your mult/shift are correct. | ||
58 | */ | ||
59 | static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd, | ||
60 | u32 cyc, u32 mask, u32 mult, u32 shift) | ||
61 | { | ||
62 | u64 epoch_ns; | ||
63 | u32 epoch_cyc; | ||
64 | |||
65 | /* | ||
66 | * Load the epoch_cyc and epoch_ns atomically. We do this by | ||
67 | * ensuring that we always write epoch_cyc, epoch_ns and | ||
68 | * epoch_cyc_copy in strict order, and read them in strict order. | ||
69 | * If epoch_cyc and epoch_cyc_copy are not equal, then we're in | ||
70 | * the middle of an update, and we should repeat the load. | ||
71 | */ | ||
72 | do { | ||
73 | epoch_cyc = cd->epoch_cyc; | ||
74 | smp_rmb(); | ||
75 | epoch_ns = cd->epoch_ns; | ||
76 | smp_rmb(); | ||
77 | } while (epoch_cyc != cd->epoch_cyc_copy); | ||
78 | |||
79 | return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Otherwise, you need to use this, which will obtain the mult/shift | ||
84 | * from the clock_data structure. Use init_sched_clock() with this. | ||
85 | */ | ||
86 | static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd, | ||
87 | u32 cyc, u32 mask) | ||
88 | { | ||
89 | return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Initialize the clock data - calculate the appropriate multiplier | ||
94 | * and shift. Also setup a timer to ensure that the epoch is refreshed | ||
95 | * at the appropriate time interval, which will call your update | ||
96 | * handler. | ||
97 | */ | ||
98 | void init_sched_clock(struct clock_data *, void (*)(void), | ||
99 | unsigned int, unsigned long); | ||
100 | |||
101 | /* | ||
102 | * Use this initialization function rather than init_sched_clock() if | ||
103 | * you're using cyc_to_fixed_sched_clock, which will warn if your | ||
104 | * constants are incorrect. | ||
105 | */ | ||
106 | static inline void init_fixed_sched_clock(struct clock_data *cd, | ||
107 | void (*update)(void), unsigned int bits, unsigned long rate, | ||
108 | u32 mult, u32 shift) | ||
109 | { | ||
110 | init_sched_clock(cd, update, bits, rate); | ||
111 | if (cd->mult != mult || cd->shift != shift) { | ||
112 | pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n" | ||
113 | "sched_clock: fix multiply/shift to avoid scheduler hiccups\n", | ||
114 | mult, shift, cd->mult, cd->shift); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | extern void sched_clock_postinit(void); | 11 | extern void sched_clock_postinit(void); |
12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); | ||
119 | 13 | ||
120 | #endif | 14 | #endif |
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 915696dd9c7c..23ebc0c82a39 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h | |||
@@ -192,11 +192,7 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn } | |||
192 | /* | 192 | /* |
193 | * Memory map description | 193 | * Memory map description |
194 | */ | 194 | */ |
195 | #ifdef CONFIG_ARCH_EP93XX | 195 | #define NR_BANKS CONFIG_ARM_NR_BANKS |
196 | # define NR_BANKS 16 | ||
197 | #else | ||
198 | # define NR_BANKS 8 | ||
199 | #endif | ||
200 | 196 | ||
201 | struct membank { | 197 | struct membank { |
202 | phys_addr_t start; | 198 | phys_addr_t start; |
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h index 9997ad20eff1..32ee164a2f6b 100644 --- a/arch/arm/include/asm/swab.h +++ b/arch/arm/include/asm/swab.h | |||
@@ -24,12 +24,13 @@ | |||
24 | 24 | ||
25 | #if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6 | 25 | #if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6 |
26 | 26 | ||
27 | static inline __attribute_const__ __u16 __arch_swab16(__u16 x) | 27 | static inline __attribute_const__ __u32 __arch_swahb32(__u32 x) |
28 | { | 28 | { |
29 | __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); | 29 | __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); |
30 | return x; | 30 | return x; |
31 | } | 31 | } |
32 | #define __arch_swab16 __arch_swab16 | 32 | #define __arch_swahb32 __arch_swahb32 |
33 | #define __arch_swab16(x) ((__u16)__arch_swahb32(x)) | ||
33 | 34 | ||
34 | static inline __attribute_const__ __u32 __arch_swab32(__u32 x) | 35 | static inline __attribute_const__ __u32 __arch_swab32(__u32 x) |
35 | { | 36 | { |
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 984014b92647..e4c96cc6ec0c 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
@@ -80,6 +80,14 @@ struct siginfo; | |||
80 | void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, | 80 | void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, |
81 | unsigned long err, unsigned long trap); | 81 | unsigned long err, unsigned long trap); |
82 | 82 | ||
83 | #ifdef CONFIG_ARM_LPAE | ||
84 | #define FAULT_CODE_ALIGNMENT 33 | ||
85 | #define FAULT_CODE_DEBUG 34 | ||
86 | #else | ||
87 | #define FAULT_CODE_ALIGNMENT 1 | ||
88 | #define FAULT_CODE_DEBUG 2 | ||
89 | #endif | ||
90 | |||
83 | void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, | 91 | void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, |
84 | struct pt_regs *), | 92 | struct pt_regs *), |
85 | int sig, int code, const char *name); | 93 | int sig, int code, const char *name); |
@@ -100,7 +108,7 @@ extern void __show_regs(struct pt_regs *); | |||
100 | extern int __pure cpu_architecture(void); | 108 | extern int __pure cpu_architecture(void); |
101 | extern void cpu_init(void); | 109 | extern void cpu_init(void); |
102 | 110 | ||
103 | void arm_machine_restart(char mode, const char *cmd); | 111 | void soft_restart(unsigned long); |
104 | extern void (*arm_pm_restart)(char str, const char *cmd); | 112 | extern void (*arm_pm_restart)(char str, const char *cmd); |
105 | 113 | ||
106 | #define UDBG_UNDEFINED (1 << 0) | 114 | #define UDBG_UNDEFINED (1 << 0) |
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 265f908c4a6e..5d3ed7e38561 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h | |||
@@ -202,8 +202,18 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | |||
202 | tlb_remove_page(tlb, pte); | 202 | tlb_remove_page(tlb, pte); |
203 | } | 203 | } |
204 | 204 | ||
205 | static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, | ||
206 | unsigned long addr) | ||
207 | { | ||
208 | #ifdef CONFIG_ARM_LPAE | ||
209 | tlb_add_flush(tlb, addr); | ||
210 | tlb_remove_page(tlb, virt_to_page(pmdp)); | ||
211 | #endif | ||
212 | } | ||
213 | |||
205 | #define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) | 214 | #define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) |
206 | #define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp) | 215 | #define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr) |
216 | #define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp) | ||
207 | 217 | ||
208 | #define tlb_migrate_finish(mm) do { } while (0) | 218 | #define tlb_migrate_finish(mm) do { } while (0) |
209 | 219 | ||