Commit 31edf274f9aff1ccd39934a0b2fce38f4405c656
9 parents
3c0eee3fe6
ed60453fa8
ac61d143ff
28257f7fde
b230653132
50005a8deb
cf562b4a55
3d09fbcd26
8a9618f5df
Exists in
master
and in
4 other branches
Merge branches 'ftrace', 'gic', 'io', 'kexec', 'mod', 'sa11x0', 'sh' and 'versatile' into devel
Showing 86 changed files Side-by-side Diff
- arch/arm/Kconfig
- arch/arm/boot/compressed/Makefile
- arch/arm/boot/compressed/head-shmobile.S
- arch/arm/common/Makefile
- arch/arm/common/gic.c
- arch/arm/common/timer-sp.c
- arch/arm/include/asm/elf.h
- arch/arm/include/asm/hardware/entry-macro-gic.S
- arch/arm/include/asm/hardware/gic.h
- arch/arm/include/asm/hardware/timer-sp.h
- arch/arm/include/asm/io.h
- arch/arm/include/asm/kexec.h
- arch/arm/include/asm/module.h
- arch/arm/kernel/machine_kexec.c
- arch/arm/kernel/module.c
- arch/arm/kernel/smp_twd.c
- arch/arm/mach-cns3xxx/core.c
- arch/arm/mach-cns3xxx/core.h
- arch/arm/mach-cns3xxx/include/mach/entry-macro.S
- arch/arm/mach-davinci/include/mach/io.h
- arch/arm/mach-integrator/integrator_cp.c
- arch/arm/mach-iop13xx/include/mach/io.h
- arch/arm/mach-iop32x/include/mach/io.h
- arch/arm/mach-iop33x/include/mach/io.h
- arch/arm/mach-ixp23xx/include/mach/io.h
- arch/arm/mach-ixp4xx/include/mach/io.h
- arch/arm/mach-kirkwood/include/mach/io.h
- arch/arm/mach-msm/board-msm8x60.c
- arch/arm/mach-omap2/include/mach/entry-macro.S
- arch/arm/mach-omap2/include/mach/omap4-common.h
- arch/arm/mach-omap2/omap-smp.c
- arch/arm/mach-omap2/omap4-common.c
- arch/arm/mach-orion5x/include/mach/io.h
- arch/arm/mach-realview/core.c
- arch/arm/mach-realview/core.h
- arch/arm/mach-realview/include/mach/entry-macro.S
- arch/arm/mach-realview/platsmp.c
- arch/arm/mach-realview/realview_eb.c
- arch/arm/mach-realview/realview_pb1176.c
- arch/arm/mach-realview/realview_pb11mp.c
- arch/arm/mach-realview/realview_pba8.c
- arch/arm/mach-realview/realview_pbx.c
- arch/arm/mach-s5pv310/cpu.c
- arch/arm/mach-s5pv310/include/mach/smp.h
- arch/arm/mach-s5pv310/platsmp.c
- arch/arm/mach-sa1100/Kconfig
- arch/arm/mach-sa1100/Makefile
- arch/arm/mach-sa1100/cpu-sa1100.c
- arch/arm/mach-sa1100/cpu-sa1110.c
- arch/arm/mach-sa1100/generic.c
- arch/arm/mach-sa1100/include/mach/hardware.h
- arch/arm/mach-sa1100/include/mach/nanoengine.h
- arch/arm/mach-sa1100/nanoengine.c
- arch/arm/mach-sa1100/pci-nanoengine.c
- arch/arm/mach-sa1100/simpad.c
- arch/arm/mach-shmobile/board-ap4evb.c
- arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
- arch/arm/mach-shmobile/include/mach/zboot.h
- arch/arm/mach-shmobile/include/mach/zboot_macros.h
- arch/arm/mach-tegra/include/mach/entry-macro.S
- arch/arm/mach-tegra/include/mach/io.h
- arch/arm/mach-tegra/irq.c
- arch/arm/mach-tegra/platsmp.c
- arch/arm/mach-ux500/cpu.c
- arch/arm/mach-ux500/include/mach/entry-macro.S
- arch/arm/mach-ux500/platsmp.c
- arch/arm/mach-versatile/core.c
- arch/arm/mach-vexpress/core.h
- arch/arm/mach-vexpress/ct-ca9x4.c
- arch/arm/mach-vexpress/include/mach/entry-macro.S
- arch/arm/mach-vexpress/platsmp.c
- arch/arm/mach-vexpress/v2m.c
- arch/arm/plat-omap/include/plat/io.h
- arch/arm/plat-versatile/Makefile
- arch/arm/plat-versatile/include/plat/timer-sp.h
- arch/arm/plat-versatile/timer-sp.c
- drivers/pcmcia/Makefile
- drivers/pcmcia/sa1100_generic.c
- drivers/pcmcia/sa1100_generic.h
- drivers/pcmcia/sa1100_nanoengine.c
- drivers/pcmcia/soc_common.c
- drivers/rtc/rtc-sa1100.c
- fs/proc/vmcore.c
- include/linux/crash_dump.h
- scripts/recordmcount.c
- scripts/recordmcount.h
arch/arm/Kconfig
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | select PERF_USE_VMALLOC |
24 | 24 | select HAVE_REGS_AND_STACK_ACCESS_API |
25 | 25 | select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7)) |
26 | + select HAVE_C_RECORDMCOUNT | |
26 | 27 | help |
27 | 28 | The ARM series is a line of low-power-consumption RISC chip designs |
28 | 29 | licensed by ARM Ltd and targeted at embedded applications and |
... | ... | @@ -1164,7 +1165,7 @@ |
1164 | 1165 | bool |
1165 | 1166 | |
1166 | 1167 | config PCI |
1167 | - bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX | |
1168 | + bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX || SA1100_NANOENGINE | |
1168 | 1169 | help |
1169 | 1170 | Find out whether you have a PCI motherboard. PCI is the name of a |
1170 | 1171 | bus system, i.e. the way the CPU talks to the other stuff inside |
... | ... | @@ -1175,6 +1176,12 @@ |
1175 | 1176 | bool |
1176 | 1177 | depends on PCI |
1177 | 1178 | |
1179 | +config PCI_NANOENGINE | |
1180 | + bool "BSE nanoEngine PCI support" | |
1181 | + depends on SA1100_NANOENGINE | |
1182 | + help | |
1183 | + Enable PCI on the BSE nanoEngine board. | |
1184 | + | |
1178 | 1185 | config PCI_SYSCALL |
1179 | 1186 | def_bool PCI |
1180 | 1187 | |
... | ... | @@ -1649,6 +1656,19 @@ |
1649 | 1656 | help |
1650 | 1657 | Should the atags used to boot the kernel be exported in an "atags" |
1651 | 1658 | file in procfs. Useful with kexec. |
1659 | + | |
1660 | +config CRASH_DUMP | |
1661 | + bool "Build kdump crash kernel (EXPERIMENTAL)" | |
1662 | + depends on EXPERIMENTAL | |
1663 | + help | |
1664 | + Generate crash dump after being started by kexec. This should | |
1665 | + be normally only set in special crash dump kernels which are | |
1666 | + loaded in the main kernel with kexec-tools into a specially | |
1667 | + reserved region and then later executed after a crash by | |
1668 | + kdump/kexec. The crash dump kernel must be compiled to a | |
1669 | + memory address not used by the main kernel | |
1670 | + | |
1671 | + For more details see Documentation/kdump/kdump.txt | |
1652 | 1672 | |
1653 | 1673 | config AUTO_ZRELADDR |
1654 | 1674 | bool "Auto calculation of the decompressed kernel image address" |
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head-shmobile.S
1 | +/* | |
2 | + * The head-file for SH-Mobile ARM platforms | |
3 | + * | |
4 | + * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
5 | + * Simon Horman <horms@verge.net.au> | |
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 as published by | |
9 | + * the Free Software Foundation; version 2 of the License. | |
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | + */ | |
20 | + | |
21 | +#ifdef CONFIG_ZBOOT_ROM | |
22 | + | |
23 | + .section ".start", "ax" | |
24 | + | |
25 | + /* load board-specific initialization code */ | |
26 | +#include <mach/zboot.h> | |
27 | + | |
28 | + b 1f | |
29 | +__atags:@ tag #1 | |
30 | + .long 12 @ tag->hdr.size = tag_size(tag_core); | |
31 | + .long 0x54410001 @ tag->hdr.tag = ATAG_CORE; | |
32 | + .long 0 @ tag->u.core.flags = 0; | |
33 | + .long 0 @ tag->u.core.pagesize = 0; | |
34 | + .long 0 @ tag->u.core.rootdev = 0; | |
35 | + @ tag #2 | |
36 | + .long 8 @ tag->hdr.size = tag_size(tag_mem32); | |
37 | + .long 0x54410002 @ tag->hdr.tag = ATAG_MEM; | |
38 | + .long CONFIG_MEMORY_SIZE @ tag->u.mem.size = CONFIG_MEMORY_SIZE; | |
39 | + .long CONFIG_MEMORY_START @ @ tag->u.mem.start = CONFIG_MEMORY_START; | |
40 | + @ tag #3 | |
41 | + .long 0 @ tag->hdr.size = 0 | |
42 | + .long 0 @ tag->hdr.tag = ATAG_NONE; | |
43 | +1: | |
44 | + | |
45 | + /* Set board ID necessary for boot */ | |
46 | + ldr r7, 1f @ Set machine type register | |
47 | + adr r8, __atags @ Set atag register | |
48 | + b 2f | |
49 | + | |
50 | +1 : .long MACH_TYPE | |
51 | +2 : | |
52 | + | |
53 | +#endif /* CONFIG_ZBOOT_ROM */ |
arch/arm/common/Makefile
arch/arm/common/gic.c
... | ... | @@ -35,6 +35,9 @@ |
35 | 35 | |
36 | 36 | static DEFINE_SPINLOCK(irq_controller_lock); |
37 | 37 | |
38 | +/* Address of GIC 0 CPU interface */ | |
39 | +void __iomem *gic_cpu_base_addr __read_mostly; | |
40 | + | |
38 | 41 | struct gic_chip_data { |
39 | 42 | unsigned int irq_offset; |
40 | 43 | void __iomem *dist_base; |
... | ... | @@ -45,7 +48,7 @@ |
45 | 48 | #define MAX_GIC_NR 1 |
46 | 49 | #endif |
47 | 50 | |
48 | -static struct gic_chip_data gic_data[MAX_GIC_NR]; | |
51 | +static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly; | |
49 | 52 | |
50 | 53 | static inline void __iomem *gic_dist_base(unsigned int irq) |
51 | 54 | { |
52 | 55 | |
53 | 56 | |
54 | 57 | |
... | ... | @@ -213,21 +216,16 @@ |
213 | 216 | set_irq_chained_handler(irq, gic_handle_cascade_irq); |
214 | 217 | } |
215 | 218 | |
216 | -void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, | |
217 | - unsigned int irq_start) | |
219 | +static void __init gic_dist_init(struct gic_chip_data *gic, | |
220 | + unsigned int irq_start) | |
218 | 221 | { |
219 | 222 | unsigned int gic_irqs, irq_limit, i; |
223 | + void __iomem *base = gic->dist_base; | |
220 | 224 | u32 cpumask = 1 << smp_processor_id(); |
221 | 225 | |
222 | - if (gic_nr >= MAX_GIC_NR) | |
223 | - BUG(); | |
224 | - | |
225 | 226 | cpumask |= cpumask << 8; |
226 | 227 | cpumask |= cpumask << 16; |
227 | 228 | |
228 | - gic_data[gic_nr].dist_base = base; | |
229 | - gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; | |
230 | - | |
231 | 229 | writel(0, base + GIC_DIST_CTRL); |
232 | 230 | |
233 | 231 | /* |
... | ... | @@ -267,7 +265,7 @@ |
267 | 265 | /* |
268 | 266 | * Limit number of interrupts registered to the platform maximum |
269 | 267 | */ |
270 | - irq_limit = gic_data[gic_nr].irq_offset + gic_irqs; | |
268 | + irq_limit = gic->irq_offset + gic_irqs; | |
271 | 269 | if (WARN_ON(irq_limit > NR_IRQS)) |
272 | 270 | irq_limit = NR_IRQS; |
273 | 271 | |
... | ... | @@ -276,7 +274,7 @@ |
276 | 274 | */ |
277 | 275 | for (i = irq_start; i < irq_limit; i++) { |
278 | 276 | set_irq_chip(i, &gic_chip); |
279 | - set_irq_chip_data(i, &gic_data[gic_nr]); | |
277 | + set_irq_chip_data(i, gic); | |
280 | 278 | set_irq_handler(i, handle_level_irq); |
281 | 279 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); |
282 | 280 | } |
283 | 281 | |
284 | 282 | |
... | ... | @@ -284,19 +282,12 @@ |
284 | 282 | writel(1, base + GIC_DIST_CTRL); |
285 | 283 | } |
286 | 284 | |
287 | -void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) | |
285 | +static void __cpuinit gic_cpu_init(struct gic_chip_data *gic) | |
288 | 286 | { |
289 | - void __iomem *dist_base; | |
287 | + void __iomem *dist_base = gic->dist_base; | |
288 | + void __iomem *base = gic->cpu_base; | |
290 | 289 | int i; |
291 | 290 | |
292 | - if (gic_nr >= MAX_GIC_NR) | |
293 | - BUG(); | |
294 | - | |
295 | - dist_base = gic_data[gic_nr].dist_base; | |
296 | - BUG_ON(!dist_base); | |
297 | - | |
298 | - gic_data[gic_nr].cpu_base = base; | |
299 | - | |
300 | 291 | /* |
301 | 292 | * Deal with the banked PPI and SGI interrupts - disable all |
302 | 293 | * PPI interrupts, ensure all SGI interrupts are enabled. |
... | ... | @@ -312,6 +303,42 @@ |
312 | 303 | |
313 | 304 | writel(0xf0, base + GIC_CPU_PRIMASK); |
314 | 305 | writel(1, base + GIC_CPU_CTRL); |
306 | +} | |
307 | + | |
308 | +void __init gic_init(unsigned int gic_nr, unsigned int irq_start, | |
309 | + void __iomem *dist_base, void __iomem *cpu_base) | |
310 | +{ | |
311 | + struct gic_chip_data *gic; | |
312 | + | |
313 | + BUG_ON(gic_nr >= MAX_GIC_NR); | |
314 | + | |
315 | + gic = &gic_data[gic_nr]; | |
316 | + gic->dist_base = dist_base; | |
317 | + gic->cpu_base = cpu_base; | |
318 | + gic->irq_offset = (irq_start - 1) & ~31; | |
319 | + | |
320 | + if (gic_nr == 0) | |
321 | + gic_cpu_base_addr = cpu_base; | |
322 | + | |
323 | + gic_dist_init(gic, irq_start); | |
324 | + gic_cpu_init(gic); | |
325 | +} | |
326 | + | |
327 | +void __cpuinit gic_secondary_init(unsigned int gic_nr) | |
328 | +{ | |
329 | + BUG_ON(gic_nr >= MAX_GIC_NR); | |
330 | + | |
331 | + gic_cpu_init(&gic_data[gic_nr]); | |
332 | +} | |
333 | + | |
334 | +void __cpuinit gic_enable_ppi(unsigned int irq) | |
335 | +{ | |
336 | + unsigned long flags; | |
337 | + | |
338 | + local_irq_save(flags); | |
339 | + irq_to_desc(irq)->status |= IRQ_NOPROBE; | |
340 | + gic_unmask_irq(irq); | |
341 | + local_irq_restore(flags); | |
315 | 342 | } |
316 | 343 | |
317 | 344 | #ifdef CONFIG_SMP |
arch/arm/common/timer-sp.c
1 | +/* | |
2 | + * linux/arch/arm/common/timer-sp.c | |
3 | + * | |
4 | + * Copyright (C) 1999 - 2003 ARM Limited | |
5 | + * Copyright (C) 2000 Deep Blue Solutions Ltd | |
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 as published by | |
9 | + * the Free Software Foundation; either version 2 of the License, or | |
10 | + * (at your option) any later version. | |
11 | + * | |
12 | + * This program is distributed in the hope that it will be useful, | |
13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | + * GNU General Public License for more details. | |
16 | + * | |
17 | + * You should have received a copy of the GNU General Public License | |
18 | + * along with this program; if not, write to the Free Software | |
19 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | + */ | |
21 | +#include <linux/clocksource.h> | |
22 | +#include <linux/clockchips.h> | |
23 | +#include <linux/interrupt.h> | |
24 | +#include <linux/irq.h> | |
25 | +#include <linux/io.h> | |
26 | + | |
27 | +#include <asm/hardware/arm_timer.h> | |
28 | + | |
29 | +/* | |
30 | + * These timers are currently always setup to be clocked at 1MHz. | |
31 | + */ | |
32 | +#define TIMER_FREQ_KHZ (1000) | |
33 | +#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) | |
34 | + | |
35 | +static void __iomem *clksrc_base; | |
36 | + | |
37 | +static cycle_t sp804_read(struct clocksource *cs) | |
38 | +{ | |
39 | + return ~readl(clksrc_base + TIMER_VALUE); | |
40 | +} | |
41 | + | |
42 | +static struct clocksource clocksource_sp804 = { | |
43 | + .name = "timer3", | |
44 | + .rating = 200, | |
45 | + .read = sp804_read, | |
46 | + .mask = CLOCKSOURCE_MASK(32), | |
47 | + .shift = 20, | |
48 | + .flags = CLOCK_SOURCE_IS_CONTINUOUS, | |
49 | +}; | |
50 | + | |
51 | +void __init sp804_clocksource_init(void __iomem *base) | |
52 | +{ | |
53 | + struct clocksource *cs = &clocksource_sp804; | |
54 | + | |
55 | + clksrc_base = base; | |
56 | + | |
57 | + /* setup timer 0 as free-running clocksource */ | |
58 | + writel(0, clksrc_base + TIMER_CTRL); | |
59 | + writel(0xffffffff, clksrc_base + TIMER_LOAD); | |
60 | + writel(0xffffffff, clksrc_base + TIMER_VALUE); | |
61 | + writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, | |
62 | + clksrc_base + TIMER_CTRL); | |
63 | + | |
64 | + cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift); | |
65 | + clocksource_register(cs); | |
66 | +} | |
67 | + | |
68 | + | |
69 | +static void __iomem *clkevt_base; | |
70 | + | |
71 | +/* | |
72 | + * IRQ handler for the timer | |
73 | + */ | |
74 | +static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) | |
75 | +{ | |
76 | + struct clock_event_device *evt = dev_id; | |
77 | + | |
78 | + /* clear the interrupt */ | |
79 | + writel(1, clkevt_base + TIMER_INTCLR); | |
80 | + | |
81 | + evt->event_handler(evt); | |
82 | + | |
83 | + return IRQ_HANDLED; | |
84 | +} | |
85 | + | |
86 | +static void sp804_set_mode(enum clock_event_mode mode, | |
87 | + struct clock_event_device *evt) | |
88 | +{ | |
89 | + unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE; | |
90 | + | |
91 | + writel(ctrl, clkevt_base + TIMER_CTRL); | |
92 | + | |
93 | + switch (mode) { | |
94 | + case CLOCK_EVT_MODE_PERIODIC: | |
95 | + writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD); | |
96 | + ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; | |
97 | + break; | |
98 | + | |
99 | + case CLOCK_EVT_MODE_ONESHOT: | |
100 | + /* period set, and timer enabled in 'next_event' hook */ | |
101 | + ctrl |= TIMER_CTRL_ONESHOT; | |
102 | + break; | |
103 | + | |
104 | + case CLOCK_EVT_MODE_UNUSED: | |
105 | + case CLOCK_EVT_MODE_SHUTDOWN: | |
106 | + default: | |
107 | + break; | |
108 | + } | |
109 | + | |
110 | + writel(ctrl, clkevt_base + TIMER_CTRL); | |
111 | +} | |
112 | + | |
113 | +static int sp804_set_next_event(unsigned long next, | |
114 | + struct clock_event_device *evt) | |
115 | +{ | |
116 | + unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); | |
117 | + | |
118 | + writel(next, clkevt_base + TIMER_LOAD); | |
119 | + writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | |
120 | + | |
121 | + return 0; | |
122 | +} | |
123 | + | |
124 | +static struct clock_event_device sp804_clockevent = { | |
125 | + .name = "timer0", | |
126 | + .shift = 32, | |
127 | + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | |
128 | + .set_mode = sp804_set_mode, | |
129 | + .set_next_event = sp804_set_next_event, | |
130 | + .rating = 300, | |
131 | + .cpumask = cpu_all_mask, | |
132 | +}; | |
133 | + | |
134 | +static struct irqaction sp804_timer_irq = { | |
135 | + .name = "timer", | |
136 | + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | |
137 | + .handler = sp804_timer_interrupt, | |
138 | + .dev_id = &sp804_clockevent, | |
139 | +}; | |
140 | + | |
141 | +void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq) | |
142 | +{ | |
143 | + struct clock_event_device *evt = &sp804_clockevent; | |
144 | + | |
145 | + clkevt_base = base; | |
146 | + | |
147 | + evt->irq = timer_irq; | |
148 | + evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift); | |
149 | + evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); | |
150 | + evt->min_delta_ns = clockevent_delta2ns(0xf, evt); | |
151 | + | |
152 | + setup_irq(timer_irq, &sp804_timer_irq); | |
153 | + clockevents_register_device(evt); | |
154 | +} |
arch/arm/include/asm/elf.h
... | ... | @@ -99,6 +99,8 @@ |
99 | 99 | extern int elf_check_arch(const struct elf32_hdr *); |
100 | 100 | #define elf_check_arch elf_check_arch |
101 | 101 | |
102 | +#define vmcore_elf64_check_arch(x) (0) | |
103 | + | |
102 | 104 | extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int); |
103 | 105 | #define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk) |
104 | 106 |
arch/arm/include/asm/hardware/entry-macro-gic.S
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-28 are reserved | |
26 | + * 29-31 are local. We allow 30 to be used for the watchdog. | |
27 | + * 32-1020 are global | |
28 | + * 1021-1022 are reserved | |
29 | + * 1023 is "spurious" (no interrupt) | |
30 | + * | |
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 | + * | |
34 | + * A simple read from the controller will tell us the number of the highest | |
35 | + * priority enabled interrupt. We then just need to check whether it is in the | |
36 | + * valid range for an IRQ (30-1020 inclusive). | |
37 | + */ | |
38 | + | |
39 | + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
40 | + | |
41 | + ldr \irqstat, [\base, #GIC_CPU_INTACK] | |
42 | + /* bits 12-10 = src CPU, 9-0 = int # */ | |
43 | + | |
44 | + ldr \tmp, =1021 | |
45 | + bic \irqnr, \irqstat, #0x1c00 | |
46 | + cmp \irqnr, #29 | |
47 | + cmpcc \irqnr, \irqnr | |
48 | + cmpne \irqnr, \tmp | |
49 | + cmpcs \irqnr, \irqnr | |
50 | + .endm | |
51 | + | |
52 | +/* We assume that irqstat (the raw value of the IRQ acknowledge | |
53 | + * register) is preserved from the macro above. | |
54 | + * If there is an IPI, we immediately signal end of interrupt on the | |
55 | + * controller, since this requires the original irqstat value which | |
56 | + * we won't easily be able to recreate later. | |
57 | + */ | |
58 | + | |
59 | + .macro test_for_ipi, irqnr, irqstat, base, tmp | |
60 | + bic \irqnr, \irqstat, #0x1c00 | |
61 | + cmp \irqnr, #16 | |
62 | + strcc \irqstat, [\base, #GIC_CPU_EOI] | |
63 | + cmpcs \irqnr, \irqnr | |
64 | + .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
... | ... | @@ -33,10 +33,13 @@ |
33 | 33 | #define GIC_DIST_SOFTINT 0xf00 |
34 | 34 | |
35 | 35 | #ifndef __ASSEMBLY__ |
36 | -void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); | |
37 | -void gic_cpu_init(unsigned int gic_nr, void __iomem *base); | |
36 | +extern void __iomem *gic_cpu_base_addr; | |
37 | + | |
38 | +void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); | |
39 | +void gic_secondary_init(unsigned int); | |
38 | 40 | void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); |
39 | 41 | void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); |
42 | +void gic_enable_ppi(unsigned int); | |
40 | 43 | #endif |
41 | 44 | |
42 | 45 | #endif |
arch/arm/include/asm/hardware/timer-sp.h
arch/arm/include/asm/io.h
... | ... | @@ -241,18 +241,15 @@ |
241 | 241 | * |
242 | 242 | */ |
243 | 243 | #ifndef __arch_ioremap |
244 | -#define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) | |
245 | -#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) | |
246 | -#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED) | |
247 | -#define ioremap_wc(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_WC) | |
248 | -#define iounmap(cookie) __iounmap(cookie) | |
249 | -#else | |
244 | +#define __arch_ioremap __arm_ioremap | |
245 | +#define __arch_iounmap __iounmap | |
246 | +#endif | |
247 | + | |
250 | 248 | #define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) |
251 | 249 | #define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) |
252 | 250 | #define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED) |
253 | 251 | #define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC) |
254 | -#define iounmap(cookie) __arch_iounmap(cookie) | |
255 | -#endif | |
252 | +#define iounmap __arch_iounmap | |
256 | 253 | |
257 | 254 | /* |
258 | 255 | * io{read,write}{8,16,32} macros |
arch/arm/include/asm/kexec.h
... | ... | @@ -33,10 +33,20 @@ |
33 | 33 | if (oldregs) { |
34 | 34 | memcpy(newregs, oldregs, sizeof(*newregs)); |
35 | 35 | } else { |
36 | - __asm__ __volatile__ ("stmia %0, {r0 - r15}" | |
37 | - : : "r" (&newregs->ARM_r0)); | |
38 | - __asm__ __volatile__ ("mrs %0, cpsr" | |
39 | - : "=r" (newregs->ARM_cpsr)); | |
36 | + __asm__ __volatile__ ( | |
37 | + "stmia %[regs_base], {r0-r12}\n\t" | |
38 | + "mov %[_ARM_sp], sp\n\t" | |
39 | + "str lr, %[_ARM_lr]\n\t" | |
40 | + "adr %[_ARM_pc], 1f\n\t" | |
41 | + "mrs %[_ARM_cpsr], cpsr\n\t" | |
42 | + "1:" | |
43 | + : [_ARM_pc] "=r" (newregs->ARM_pc), | |
44 | + [_ARM_cpsr] "=r" (newregs->ARM_cpsr), | |
45 | + [_ARM_sp] "=r" (newregs->ARM_sp), | |
46 | + [_ARM_lr] "=o" (newregs->ARM_lr) | |
47 | + : [regs_base] "r" (&newregs->ARM_r0) | |
48 | + : "memory" | |
49 | + ); | |
40 | 50 | } |
41 | 51 | } |
42 | 52 |
arch/arm/include/asm/module.h
... | ... | @@ -8,11 +8,6 @@ |
8 | 8 | struct unwind_table; |
9 | 9 | |
10 | 10 | #ifdef CONFIG_ARM_UNWIND |
11 | -struct arm_unwind_mapping { | |
12 | - Elf_Shdr *unw_sec; | |
13 | - Elf_Shdr *sec_text; | |
14 | - struct unwind_table *unwind; | |
15 | -}; | |
16 | 11 | enum { |
17 | 12 | ARM_SEC_INIT, |
18 | 13 | ARM_SEC_DEVINIT, |
19 | 14 | |
20 | 15 | |
... | ... | @@ -21,13 +16,13 @@ |
21 | 16 | ARM_SEC_DEVEXIT, |
22 | 17 | ARM_SEC_MAX, |
23 | 18 | }; |
19 | +#endif | |
20 | + | |
24 | 21 | struct mod_arch_specific { |
25 | - struct arm_unwind_mapping map[ARM_SEC_MAX]; | |
26 | -}; | |
27 | -#else | |
28 | -struct mod_arch_specific { | |
29 | -}; | |
22 | +#ifdef CONFIG_ARM_UNWIND | |
23 | + struct unwind_table *unwind[ARM_SEC_MAX]; | |
30 | 24 | #endif |
25 | +}; | |
31 | 26 | |
32 | 27 | /* |
33 | 28 | * Include the ARM architecture version. |
arch/arm/kernel/machine_kexec.c
... | ... | @@ -23,6 +23,8 @@ |
23 | 23 | extern unsigned long kexec_mach_type; |
24 | 24 | extern unsigned long kexec_boot_atags; |
25 | 25 | |
26 | +static atomic_t waiting_for_crash_ipi; | |
27 | + | |
26 | 28 | /* |
27 | 29 | * Provide a dummy crash_notes definition while crash dump arrives to arm. |
28 | 30 | * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. |
29 | 31 | |
30 | 32 | |
... | ... | @@ -37,9 +39,37 @@ |
37 | 39 | { |
38 | 40 | } |
39 | 41 | |
42 | +void machine_crash_nonpanic_core(void *unused) | |
43 | +{ | |
44 | + struct pt_regs regs; | |
45 | + | |
46 | + crash_setup_regs(®s, NULL); | |
47 | + printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n", | |
48 | + smp_processor_id()); | |
49 | + crash_save_cpu(®s, smp_processor_id()); | |
50 | + flush_cache_all(); | |
51 | + | |
52 | + atomic_dec(&waiting_for_crash_ipi); | |
53 | + while (1) | |
54 | + cpu_relax(); | |
55 | +} | |
56 | + | |
40 | 57 | void machine_crash_shutdown(struct pt_regs *regs) |
41 | 58 | { |
59 | + unsigned long msecs; | |
60 | + | |
42 | 61 | local_irq_disable(); |
62 | + | |
63 | + atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | |
64 | + smp_call_function(machine_crash_nonpanic_core, NULL, false); | |
65 | + msecs = 1000; /* Wait at most a second for the other cpus to stop */ | |
66 | + while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { | |
67 | + mdelay(1); | |
68 | + msecs--; | |
69 | + } | |
70 | + if (atomic_read(&waiting_for_crash_ipi) > 0) | |
71 | + printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); | |
72 | + | |
43 | 73 | crash_save_cpu(regs, smp_processor_id()); |
44 | 74 | |
45 | 75 | printk(KERN_INFO "Loading crashdump kernel...\n"); |
arch/arm/kernel/module.c
... | ... | @@ -67,35 +67,6 @@ |
67 | 67 | char *secstrings, |
68 | 68 | struct module *mod) |
69 | 69 | { |
70 | -#ifdef CONFIG_ARM_UNWIND | |
71 | - Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; | |
72 | - struct arm_unwind_mapping *maps = mod->arch.map; | |
73 | - | |
74 | - for (s = sechdrs; s < sechdrs_end; s++) { | |
75 | - char const *secname = secstrings + s->sh_name; | |
76 | - | |
77 | - if (strcmp(".ARM.exidx.init.text", secname) == 0) | |
78 | - maps[ARM_SEC_INIT].unw_sec = s; | |
79 | - else if (strcmp(".ARM.exidx.devinit.text", secname) == 0) | |
80 | - maps[ARM_SEC_DEVINIT].unw_sec = s; | |
81 | - else if (strcmp(".ARM.exidx", secname) == 0) | |
82 | - maps[ARM_SEC_CORE].unw_sec = s; | |
83 | - else if (strcmp(".ARM.exidx.exit.text", secname) == 0) | |
84 | - maps[ARM_SEC_EXIT].unw_sec = s; | |
85 | - else if (strcmp(".ARM.exidx.devexit.text", secname) == 0) | |
86 | - maps[ARM_SEC_DEVEXIT].unw_sec = s; | |
87 | - else if (strcmp(".init.text", secname) == 0) | |
88 | - maps[ARM_SEC_INIT].sec_text = s; | |
89 | - else if (strcmp(".devinit.text", secname) == 0) | |
90 | - maps[ARM_SEC_DEVINIT].sec_text = s; | |
91 | - else if (strcmp(".text", secname) == 0) | |
92 | - maps[ARM_SEC_CORE].sec_text = s; | |
93 | - else if (strcmp(".exit.text", secname) == 0) | |
94 | - maps[ARM_SEC_EXIT].sec_text = s; | |
95 | - else if (strcmp(".devexit.text", secname) == 0) | |
96 | - maps[ARM_SEC_DEVEXIT].sec_text = s; | |
97 | - } | |
98 | -#endif | |
99 | 70 | return 0; |
100 | 71 | } |
101 | 72 | |
102 | 73 | |
103 | 74 | |
104 | 75 | |
105 | 76 | |
106 | 77 | |
107 | 78 | |
... | ... | @@ -300,42 +271,70 @@ |
300 | 271 | return -ENOEXEC; |
301 | 272 | } |
302 | 273 | |
303 | -#ifdef CONFIG_ARM_UNWIND | |
304 | -static void register_unwind_tables(struct module *mod) | |
274 | +struct mod_unwind_map { | |
275 | + const Elf_Shdr *unw_sec; | |
276 | + const Elf_Shdr *txt_sec; | |
277 | +}; | |
278 | + | |
279 | +int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |
280 | + struct module *mod) | |
305 | 281 | { |
282 | +#ifdef CONFIG_ARM_UNWIND | |
283 | + const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | |
284 | + const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; | |
285 | + struct mod_unwind_map maps[ARM_SEC_MAX]; | |
306 | 286 | int i; |
307 | - for (i = 0; i < ARM_SEC_MAX; ++i) { | |
308 | - struct arm_unwind_mapping *map = &mod->arch.map[i]; | |
309 | - if (map->unw_sec && map->sec_text) | |
310 | - map->unwind = unwind_table_add(map->unw_sec->sh_addr, | |
311 | - map->unw_sec->sh_size, | |
312 | - map->sec_text->sh_addr, | |
313 | - map->sec_text->sh_size); | |
287 | + | |
288 | + memset(maps, 0, sizeof(maps)); | |
289 | + | |
290 | + for (s = sechdrs; s < sechdrs_end; s++) { | |
291 | + const char *secname = secstrs + s->sh_name; | |
292 | + | |
293 | + if (!(s->sh_flags & SHF_ALLOC)) | |
294 | + continue; | |
295 | + | |
296 | + if (strcmp(".ARM.exidx.init.text", secname) == 0) | |
297 | + maps[ARM_SEC_INIT].unw_sec = s; | |
298 | + else if (strcmp(".ARM.exidx.devinit.text", secname) == 0) | |
299 | + maps[ARM_SEC_DEVINIT].unw_sec = s; | |
300 | + else if (strcmp(".ARM.exidx", secname) == 0) | |
301 | + maps[ARM_SEC_CORE].unw_sec = s; | |
302 | + else if (strcmp(".ARM.exidx.exit.text", secname) == 0) | |
303 | + maps[ARM_SEC_EXIT].unw_sec = s; | |
304 | + else if (strcmp(".ARM.exidx.devexit.text", secname) == 0) | |
305 | + maps[ARM_SEC_DEVEXIT].unw_sec = s; | |
306 | + else if (strcmp(".init.text", secname) == 0) | |
307 | + maps[ARM_SEC_INIT].txt_sec = s; | |
308 | + else if (strcmp(".devinit.text", secname) == 0) | |
309 | + maps[ARM_SEC_DEVINIT].txt_sec = s; | |
310 | + else if (strcmp(".text", secname) == 0) | |
311 | + maps[ARM_SEC_CORE].txt_sec = s; | |
312 | + else if (strcmp(".exit.text", secname) == 0) | |
313 | + maps[ARM_SEC_EXIT].txt_sec = s; | |
314 | + else if (strcmp(".devexit.text", secname) == 0) | |
315 | + maps[ARM_SEC_DEVEXIT].txt_sec = s; | |
314 | 316 | } |
315 | -} | |
316 | 317 | |
317 | -static void unregister_unwind_tables(struct module *mod) | |
318 | -{ | |
319 | - int i = ARM_SEC_MAX; | |
320 | - while (--i >= 0) | |
321 | - unwind_table_del(mod->arch.map[i].unwind); | |
322 | -} | |
323 | -#else | |
324 | -static inline void register_unwind_tables(struct module *mod) { } | |
325 | -static inline void unregister_unwind_tables(struct module *mod) { } | |
318 | + for (i = 0; i < ARM_SEC_MAX; i++) | |
319 | + if (maps[i].unw_sec && maps[i].txt_sec) | |
320 | + mod->arch.unwind[i] = | |
321 | + unwind_table_add(maps[i].unw_sec->sh_addr, | |
322 | + maps[i].unw_sec->sh_size, | |
323 | + maps[i].txt_sec->sh_addr, | |
324 | + maps[i].txt_sec->sh_size); | |
326 | 325 | #endif |
327 | - | |
328 | -int | |
329 | -module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | |
330 | - struct module *module) | |
331 | -{ | |
332 | - register_unwind_tables(module); | |
333 | 326 | return 0; |
334 | 327 | } |
335 | 328 | |
336 | 329 | void |
337 | 330 | module_arch_cleanup(struct module *mod) |
338 | 331 | { |
339 | - unregister_unwind_tables(mod); | |
332 | +#ifdef CONFIG_ARM_UNWIND | |
333 | + int i; | |
334 | + | |
335 | + for (i = 0; i < ARM_SEC_MAX; i++) | |
336 | + if (mod->arch.unwind[i]) | |
337 | + unwind_table_del(mod->arch.unwind[i]); | |
338 | +#endif | |
340 | 339 | } |
arch/arm/kernel/smp_twd.c
... | ... | @@ -127,8 +127,6 @@ |
127 | 127 | */ |
128 | 128 | void __cpuinit twd_timer_setup(struct clock_event_device *clk) |
129 | 129 | { |
130 | - unsigned long flags; | |
131 | - | |
132 | 130 | twd_calibrate_rate(); |
133 | 131 | |
134 | 132 | clk->name = "local_timer"; |
... | ... | @@ -143,10 +141,7 @@ |
143 | 141 | clk->min_delta_ns = clockevent_delta2ns(0xf, clk); |
144 | 142 | |
145 | 143 | /* Make sure our local interrupt controller has this enabled */ |
146 | - local_irq_save(flags); | |
147 | - irq_to_desc(clk->irq)->status |= IRQ_NOPROBE; | |
148 | - get_irq_chip(clk->irq)->unmask(clk->irq); | |
149 | - local_irq_restore(flags); | |
144 | + gic_enable_ppi(clk->irq); | |
150 | 145 | |
151 | 146 | clockevents_register_device(clk); |
152 | 147 | } |
arch/arm/mach-cns3xxx/core.c
... | ... | @@ -69,13 +69,10 @@ |
69 | 69 | } |
70 | 70 | |
71 | 71 | /* used by entry-macro.S */ |
72 | -void __iomem *gic_cpu_base_addr; | |
73 | - | |
74 | 72 | void __init cns3xxx_init_irq(void) |
75 | 73 | { |
76 | - gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT); | |
77 | - gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29); | |
78 | - gic_cpu_init(0, gic_cpu_base_addr); | |
74 | + gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), | |
75 | + __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT)); | |
79 | 76 | } |
80 | 77 | |
81 | 78 | void cns3xxx_power_off(void) |
arch/arm/mach-cns3xxx/core.h
arch/arm/mach-cns3xxx/include/mach/entry-macro.S
... | ... | @@ -9,75 +9,11 @@ |
9 | 9 | */ |
10 | 10 | |
11 | 11 | #include <mach/hardware.h> |
12 | -#include <asm/hardware/gic.h> | |
12 | +#include <asm/hardware/entry-macro-gic.S> | |
13 | 13 | |
14 | 14 | .macro disable_fiq |
15 | 15 | .endm |
16 | 16 | |
17 | - .macro get_irqnr_preamble, base, tmp | |
18 | - ldr \base, =gic_cpu_base_addr | |
19 | - ldr \base, [\base] | |
20 | - .endm | |
21 | - | |
22 | 17 | .macro arch_ret_to_user, tmp1, tmp2 |
23 | - .endm | |
24 | - | |
25 | - /* | |
26 | - * The interrupt numbering scheme is defined in the | |
27 | - * interrupt controller spec. To wit: | |
28 | - * | |
29 | - * Interrupts 0-15 are IPI | |
30 | - * 16-28 are reserved | |
31 | - * 29-31 are local. We allow 30 to be used for the watchdog. | |
32 | - * 32-1020 are global | |
33 | - * 1021-1022 are reserved | |
34 | - * 1023 is "spurious" (no interrupt) | |
35 | - * | |
36 | - * For now, we ignore all local interrupts so only return an interrupt if it's | |
37 | - * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. | |
38 | - * | |
39 | - * A simple read from the controller will tell us the number of the highest | |
40 | - * priority enabled interrupt. We then just need to check whether it is in the | |
41 | - * valid range for an IRQ (30-1020 inclusive). | |
42 | - */ | |
43 | - | |
44 | - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
45 | - | |
46 | - ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ | |
47 | - | |
48 | - ldr \tmp, =1021 | |
49 | - | |
50 | - bic \irqnr, \irqstat, #0x1c00 | |
51 | - | |
52 | - cmp \irqnr, #29 | |
53 | - cmpcc \irqnr, \irqnr | |
54 | - cmpne \irqnr, \tmp | |
55 | - cmpcs \irqnr, \irqnr | |
56 | - | |
57 | - .endm | |
58 | - | |
59 | - /* We assume that irqstat (the raw value of the IRQ acknowledge | |
60 | - * register) is preserved from the macro above. | |
61 | - * If there is an IPI, we immediately signal end of interrupt on the | |
62 | - * controller, since this requires the original irqstat value which | |
63 | - * we won't easily be able to recreate later. | |
64 | - */ | |
65 | - | |
66 | - .macro test_for_ipi, irqnr, irqstat, base, tmp | |
67 | - bic \irqnr, \irqstat, #0x1c00 | |
68 | - cmp \irqnr, #16 | |
69 | - strcc \irqstat, [\base, #GIC_CPU_EOI] | |
70 | - cmpcs \irqnr, \irqnr | |
71 | - .endm | |
72 | - | |
73 | - /* As above, this assumes that irqstat and base are preserved.. */ | |
74 | - | |
75 | - .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
76 | - bic \irqnr, \irqstat, #0x1c00 | |
77 | - mov \tmp, #0 | |
78 | - cmp \irqnr, #29 | |
79 | - moveq \tmp, #1 | |
80 | - streq \irqstat, [\base, #GIC_CPU_EOI] | |
81 | - cmp \tmp, #0 | |
82 | 18 | .endm |
arch/arm/mach-davinci/include/mach/io.h
... | ... | @@ -22,8 +22,8 @@ |
22 | 22 | #define __mem_isa(a) (a) |
23 | 23 | |
24 | 24 | #ifndef __ASSEMBLER__ |
25 | -#define __arch_ioremap(p, s, t) davinci_ioremap(p, s, t) | |
26 | -#define __arch_iounmap(v) davinci_iounmap(v) | |
25 | +#define __arch_ioremap davinci_ioremap | |
26 | +#define __arch_iounmap davinci_iounmap | |
27 | 27 | |
28 | 28 | void __iomem *davinci_ioremap(unsigned long phys, size_t size, |
29 | 29 | unsigned int type); |
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-iop13xx/include/mach/io.h
... | ... | @@ -35,8 +35,8 @@ |
35 | 35 | extern size_t iop13xx_atue_mem_size; |
36 | 36 | extern size_t iop13xx_atux_mem_size; |
37 | 37 | |
38 | -#define __arch_ioremap(a, s, f) __iop13xx_ioremap(a, s, f) | |
39 | -#define __arch_iounmap(a) __iop13xx_iounmap(a) | |
38 | +#define __arch_ioremap __iop13xx_ioremap | |
39 | +#define __arch_iounmap __iop13xx_iounmap | |
40 | 40 | |
41 | 41 | #endif |
arch/arm/mach-iop32x/include/mach/io.h
... | ... | @@ -21,8 +21,8 @@ |
21 | 21 | #define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p)) |
22 | 22 | #define __mem_pci(a) (a) |
23 | 23 | |
24 | -#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f) | |
25 | -#define __arch_iounmap(a) __iop3xx_iounmap(a) | |
24 | +#define __arch_ioremap __iop3xx_ioremap | |
25 | +#define __arch_iounmap __iop3xx_iounmap | |
26 | 26 | |
27 | 27 | #endif |
arch/arm/mach-iop33x/include/mach/io.h
... | ... | @@ -21,8 +21,8 @@ |
21 | 21 | #define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p)) |
22 | 22 | #define __mem_pci(a) (a) |
23 | 23 | |
24 | -#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f) | |
25 | -#define __arch_iounmap(a) __iop3xx_iounmap(a) | |
24 | +#define __arch_ioremap __iop3xx_ioremap | |
25 | +#define __arch_iounmap __iop3xx_iounmap | |
26 | 26 | |
27 | 27 | #endif |
arch/arm/mach-ixp23xx/include/mach/io.h
arch/arm/mach-ixp4xx/include/mach/io.h
... | ... | @@ -74,8 +74,8 @@ |
74 | 74 | __iounmap(addr); |
75 | 75 | } |
76 | 76 | |
77 | -#define __arch_ioremap(a, s, f) __indirect_ioremap(a, s, f) | |
78 | -#define __arch_iounmap(a) __indirect_iounmap(a) | |
77 | +#define __arch_ioremap __indirect_ioremap | |
78 | +#define __arch_iounmap __indirect_iounmap | |
79 | 79 | |
80 | 80 | #define writeb(v, p) __indirect_writeb(v, p) |
81 | 81 | #define writew(v, p) __indirect_writew(v, p) |
arch/arm/mach-kirkwood/include/mach/io.h
... | ... | @@ -42,8 +42,8 @@ |
42 | 42 | __iounmap(addr); |
43 | 43 | } |
44 | 44 | |
45 | -#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m) | |
46 | -#define __arch_iounmap(a) __arch_iounmap(a) | |
45 | +#define __arch_ioremap __arch_ioremap | |
46 | +#define __arch_iounmap __arch_iounmap | |
47 | 47 | #define __io(a) __io(a) |
48 | 48 | #define __mem_pci(a) (a) |
49 | 49 |
arch/arm/mach-msm/board-msm8x60.c
... | ... | @@ -28,8 +28,6 @@ |
28 | 28 | #include <mach/board.h> |
29 | 29 | #include <mach/msm_iomap.h> |
30 | 30 | |
31 | -void __iomem *gic_cpu_base_addr; | |
32 | - | |
33 | 31 | unsigned long clk_get_max_axi_khz(void) |
34 | 32 | { |
35 | 33 | return 0; |
... | ... | @@ -44,9 +42,8 @@ |
44 | 42 | { |
45 | 43 | unsigned int i; |
46 | 44 | |
47 | - gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START); | |
48 | - gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE; | |
49 | - gic_cpu_init(0, MSM_QGIC_CPU_BASE); | |
45 | + gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, | |
46 | + (void *)MSM_QGIC_CPU_BASE); | |
50 | 47 | |
51 | 48 | /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ |
52 | 49 | writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); |
arch/arm/mach-omap2/include/mach/entry-macro.S
... | ... | @@ -105,7 +105,36 @@ |
105 | 105 | 9999: |
106 | 106 | .endm |
107 | 107 | |
108 | +#ifdef CONFIG_SMP | |
109 | + /* We assume that irqstat (the raw value of the IRQ acknowledge | |
110 | + * register) is preserved from the macro above. | |
111 | + * If there is an IPI, we immediately signal end of interrupt | |
112 | + * on the controller, since this requires the original irqstat | |
113 | + * value which we won't easily be able to recreate later. | |
114 | + */ | |
108 | 115 | |
116 | + .macro test_for_ipi, irqnr, irqstat, base, tmp | |
117 | + bic \irqnr, \irqstat, #0x1c00 | |
118 | + cmp \irqnr, #16 | |
119 | + it cc | |
120 | + strcc \irqstat, [\base, #GIC_CPU_EOI] | |
121 | + it cs | |
122 | + cmpcs \irqnr, \irqnr | |
123 | + .endm | |
124 | + | |
125 | + /* As above, this assumes that irqstat and base are preserved */ | |
126 | + | |
127 | + .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
128 | + bic \irqnr, \irqstat, #0x1c00 | |
129 | + mov \tmp, #0 | |
130 | + cmp \irqnr, #29 | |
131 | + itt eq | |
132 | + moveq \tmp, #1 | |
133 | + streq \irqstat, [\base, #GIC_CPU_EOI] | |
134 | + cmp \tmp, #0 | |
135 | + .endm | |
136 | +#endif /* CONFIG_SMP */ | |
137 | + | |
109 | 138 | #else /* MULTI_OMAP2 */ |
110 | 139 | |
111 | 140 | |
112 | 141 | |
113 | 142 | |
114 | 143 | |
... | ... | @@ -141,74 +170,16 @@ |
141 | 170 | |
142 | 171 | |
143 | 172 | #ifdef CONFIG_ARCH_OMAP4 |
173 | +#define HAVE_GET_IRQNR_PREAMBLE | |
174 | +#include <asm/hardware/entry-macro-gic.S> | |
144 | 175 | |
145 | 176 | .macro get_irqnr_preamble, base, tmp |
146 | 177 | ldr \base, =OMAP4_IRQ_BASE |
147 | 178 | .endm |
148 | 179 | |
149 | - /* | |
150 | - * The interrupt numbering scheme is defined in the | |
151 | - * interrupt controller spec. To wit: | |
152 | - * | |
153 | - * Interrupts 0-15 are IPI | |
154 | - * 16-28 are reserved | |
155 | - * 29-31 are local. We allow 30 to be used for the watchdog. | |
156 | - * 32-1020 are global | |
157 | - * 1021-1022 are reserved | |
158 | - * 1023 is "spurious" (no interrupt) | |
159 | - * | |
160 | - * For now, we ignore all local interrupts so only return an | |
161 | - * interrupt if it's between 30 and 1020. The test_for_ipi | |
162 | - * routine below will pick up on IPIs. | |
163 | - * A simple read from the controller will tell us the number | |
164 | - * of the highest priority enabled interrupt. | |
165 | - * We then just need to check whether it is in the | |
166 | - * valid range for an IRQ (30-1020 inclusive). | |
167 | - */ | |
168 | - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
169 | - ldr \irqstat, [\base, #GIC_CPU_INTACK] | |
170 | - | |
171 | - ldr \tmp, =1021 | |
172 | - | |
173 | - bic \irqnr, \irqstat, #0x1c00 | |
174 | - | |
175 | - cmp \irqnr, #29 | |
176 | - cmpcc \irqnr, \irqnr | |
177 | - cmpne \irqnr, \tmp | |
178 | - cmpcs \irqnr, \irqnr | |
179 | - .endm | |
180 | 180 | #endif |
181 | -#endif /* MULTI_OMAP2 */ | |
182 | 181 | |
183 | -#ifdef CONFIG_SMP | |
184 | - /* We assume that irqstat (the raw value of the IRQ acknowledge | |
185 | - * register) is preserved from the macro above. | |
186 | - * If there is an IPI, we immediately signal end of interrupt | |
187 | - * on the controller, since this requires the original irqstat | |
188 | - * value which we won't easily be able to recreate later. | |
189 | - */ | |
190 | - | |
191 | - .macro test_for_ipi, irqnr, irqstat, base, tmp | |
192 | - bic \irqnr, \irqstat, #0x1c00 | |
193 | - cmp \irqnr, #16 | |
194 | - it cc | |
195 | - strcc \irqstat, [\base, #GIC_CPU_EOI] | |
196 | - it cs | |
197 | - cmpcs \irqnr, \irqnr | |
198 | - .endm | |
199 | - | |
200 | - /* As above, this assumes that irqstat and base are preserved */ | |
201 | - | |
202 | - .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
203 | - bic \irqnr, \irqstat, #0x1c00 | |
204 | - mov \tmp, #0 | |
205 | - cmp \irqnr, #29 | |
206 | - itt eq | |
207 | - moveq \tmp, #1 | |
208 | - streq \irqstat, [\base, #GIC_CPU_EOI] | |
209 | - cmp \tmp, #0 | |
210 | - .endm | |
211 | -#endif /* CONFIG_SMP */ | |
182 | +#endif /* MULTI_OMAP2 */ | |
212 | 183 | |
213 | 184 | .macro irq_prio_table |
214 | 185 | .endm |
arch/arm/mach-omap2/include/mach/omap4-common.h
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/omap4-common.c
... | ... | @@ -26,21 +26,22 @@ |
26 | 26 | void __iomem *l2cache_base; |
27 | 27 | #endif |
28 | 28 | |
29 | -void __iomem *gic_cpu_base_addr; | |
30 | 29 | void __iomem *gic_dist_base_addr; |
31 | 30 | |
32 | 31 | |
33 | 32 | void __init gic_init_irq(void) |
34 | 33 | { |
34 | + void __iomem *gic_cpu_base; | |
35 | + | |
35 | 36 | /* Static mapping, never released */ |
36 | 37 | gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); |
37 | 38 | BUG_ON(!gic_dist_base_addr); |
38 | - gic_dist_init(0, gic_dist_base_addr, 29); | |
39 | 39 | |
40 | 40 | /* Static mapping, never released */ |
41 | - gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); | |
42 | - BUG_ON(!gic_cpu_base_addr); | |
43 | - gic_cpu_init(0, gic_cpu_base_addr); | |
41 | + gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); | |
42 | + BUG_ON(!gic_cpu_base); | |
43 | + | |
44 | + gic_init(0, 29, gic_dist_base_addr, gic_cpu_base); | |
44 | 45 | } |
45 | 46 | |
46 | 47 | #ifdef CONFIG_CACHE_L2X0 |
arch/arm/mach-orion5x/include/mach/io.h
... | ... | @@ -38,8 +38,8 @@ |
38 | 38 | __iounmap(addr); |
39 | 39 | } |
40 | 40 | |
41 | -#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m) | |
42 | -#define __arch_iounmap(a) __arch_iounmap(a) | |
41 | +#define __arch_ioremap __arch_ioremap | |
42 | +#define __arch_iounmap __arch_iounmap | |
43 | 43 | #define __io(a) __typesafe_io(a) |
44 | 44 | #define __mem_pci(a) (a) |
45 | 45 |
arch/arm/mach-realview/core.c
... | ... | @@ -50,12 +50,9 @@ |
50 | 50 | #include <mach/clkdev.h> |
51 | 51 | #include <mach/platform.h> |
52 | 52 | #include <mach/irqs.h> |
53 | -#include <plat/timer-sp.h> | |
53 | +#include <asm/hardware/timer-sp.h> | |
54 | 54 | |
55 | 55 | #include "core.h" |
56 | - | |
57 | -/* used by entry-macro.S and platsmp.c */ | |
58 | -void __iomem *gic_cpu_base_addr; | |
59 | 56 | |
60 | 57 | #ifdef CONFIG_ZONE_DMA |
61 | 58 | /* |
arch/arm/mach-realview/core.h
... | ... | @@ -53,7 +53,6 @@ |
53 | 53 | extern struct mmci_platform_data realview_mmc0_plat_data; |
54 | 54 | extern struct mmci_platform_data realview_mmc1_plat_data; |
55 | 55 | extern struct clcd_board clcd_plat_data; |
56 | -extern void __iomem *gic_cpu_base_addr; | |
57 | 56 | extern void __iomem *timer0_va_base; |
58 | 57 | extern void __iomem *timer1_va_base; |
59 | 58 | extern void __iomem *timer2_va_base; |
arch/arm/mach-realview/include/mach/entry-macro.S
... | ... | @@ -8,75 +8,11 @@ |
8 | 8 | * warranty of any kind, whether express or implied. |
9 | 9 | */ |
10 | 10 | #include <mach/hardware.h> |
11 | -#include <asm/hardware/gic.h> | |
11 | +#include <asm/hardware/entry-macro-gic.S> | |
12 | 12 | |
13 | 13 | .macro disable_fiq |
14 | 14 | .endm |
15 | 15 | |
16 | - .macro get_irqnr_preamble, base, tmp | |
17 | - ldr \base, =gic_cpu_base_addr | |
18 | - ldr \base, [\base] | |
19 | - .endm | |
20 | - | |
21 | 16 | .macro arch_ret_to_user, tmp1, tmp2 |
22 | - .endm | |
23 | - | |
24 | - /* | |
25 | - * The interrupt numbering scheme is defined in the | |
26 | - * interrupt controller spec. To wit: | |
27 | - * | |
28 | - * Interrupts 0-15 are IPI | |
29 | - * 16-28 are reserved | |
30 | - * 29-31 are local. We allow 30 to be used for the watchdog. | |
31 | - * 32-1020 are global | |
32 | - * 1021-1022 are reserved | |
33 | - * 1023 is "spurious" (no interrupt) | |
34 | - * | |
35 | - * For now, we ignore all local interrupts so only return an interrupt if it's | |
36 | - * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. | |
37 | - * | |
38 | - * A simple read from the controller will tell us the number of the highest | |
39 | - * priority enabled interrupt. We then just need to check whether it is in the | |
40 | - * valid range for an IRQ (30-1020 inclusive). | |
41 | - */ | |
42 | - | |
43 | - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
44 | - | |
45 | - ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ | |
46 | - | |
47 | - ldr \tmp, =1021 | |
48 | - | |
49 | - bic \irqnr, \irqstat, #0x1c00 | |
50 | - | |
51 | - cmp \irqnr, #29 | |
52 | - cmpcc \irqnr, \irqnr | |
53 | - cmpne \irqnr, \tmp | |
54 | - cmpcs \irqnr, \irqnr | |
55 | - | |
56 | - .endm | |
57 | - | |
58 | - /* We assume that irqstat (the raw value of the IRQ acknowledge | |
59 | - * register) is preserved from the macro above. | |
60 | - * If there is an IPI, we immediately signal end of interrupt on the | |
61 | - * controller, since this requires the original irqstat value which | |
62 | - * we won't easily be able to recreate later. | |
63 | - */ | |
64 | - | |
65 | - .macro test_for_ipi, irqnr, irqstat, base, tmp | |
66 | - bic \irqnr, \irqstat, #0x1c00 | |
67 | - cmp \irqnr, #16 | |
68 | - strcc \irqstat, [\base, #GIC_CPU_EOI] | |
69 | - cmpcs \irqnr, \irqnr | |
70 | - .endm | |
71 | - | |
72 | - /* As above, this assumes that irqstat and base are preserved.. */ | |
73 | - | |
74 | - .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
75 | - bic \irqnr, \irqstat, #0x1c00 | |
76 | - mov \tmp, #0 | |
77 | - cmp \irqnr, #29 | |
78 | - moveq \tmp, #1 | |
79 | - streq \irqstat, [\base, #GIC_CPU_EOI] | |
80 | - cmp \tmp, #0 | |
81 | 17 | .endm |
arch/arm/mach-realview/platsmp.c
arch/arm/mach-realview/realview_eb.c
... | ... | @@ -364,21 +364,19 @@ |
364 | 364 | writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); |
365 | 365 | |
366 | 366 | /* core tile GIC, primary */ |
367 | - gic_cpu_base_addr = __io_address(REALVIEW_EB11MP_GIC_CPU_BASE); | |
368 | - gic_dist_init(0, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE), 29); | |
369 | - gic_cpu_init(0, gic_cpu_base_addr); | |
367 | + gic_init(0, 29, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE), | |
368 | + __io_address(REALVIEW_EB11MP_GIC_CPU_BASE)); | |
370 | 369 | |
371 | 370 | #ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB |
372 | 371 | /* board GIC, secondary */ |
373 | - gic_dist_init(1, __io_address(REALVIEW_EB_GIC_DIST_BASE), 64); | |
374 | - gic_cpu_init(1, __io_address(REALVIEW_EB_GIC_CPU_BASE)); | |
372 | + gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE), | |
373 | + __io_address(REALVIEW_EB_GIC_CPU_BASE)); | |
375 | 374 | gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1); |
376 | 375 | #endif |
377 | 376 | } else { |
378 | 377 | /* board GIC, primary */ |
379 | - gic_cpu_base_addr = __io_address(REALVIEW_EB_GIC_CPU_BASE); | |
380 | - gic_dist_init(0, __io_address(REALVIEW_EB_GIC_DIST_BASE), 29); | |
381 | - gic_cpu_init(0, gic_cpu_base_addr); | |
378 | + gic_init(0, 29, __io_address(REALVIEW_EB_GIC_DIST_BASE), | |
379 | + __io_address(REALVIEW_EB_GIC_CPU_BASE)); | |
382 | 380 | } |
383 | 381 | } |
384 | 382 |
arch/arm/mach-realview/realview_pb1176.c
... | ... | @@ -304,13 +304,14 @@ |
304 | 304 | static void __init gic_init_irq(void) |
305 | 305 | { |
306 | 306 | /* ARM1176 DevChip GIC, primary */ |
307 | - gic_cpu_base_addr = __io_address(REALVIEW_DC1176_GIC_CPU_BASE); | |
308 | - gic_dist_init(0, __io_address(REALVIEW_DC1176_GIC_DIST_BASE), IRQ_DC1176_GIC_START); | |
309 | - gic_cpu_init(0, gic_cpu_base_addr); | |
307 | + gic_init(0, IRQ_DC1176_GIC_START, | |
308 | + __io_address(REALVIEW_DC1176_GIC_DIST_BASE), | |
309 | + __io_address(REALVIEW_DC1176_GIC_CPU_BASE)); | |
310 | 310 | |
311 | 311 | /* board GIC, secondary */ |
312 | - gic_dist_init(1, __io_address(REALVIEW_PB1176_GIC_DIST_BASE), IRQ_PB1176_GIC_START); | |
313 | - gic_cpu_init(1, __io_address(REALVIEW_PB1176_GIC_CPU_BASE)); | |
312 | + gic_init(1, IRQ_PB1176_GIC_START, | |
313 | + __io_address(REALVIEW_PB1176_GIC_DIST_BASE), | |
314 | + __io_address(REALVIEW_PB1176_GIC_CPU_BASE)); | |
314 | 315 | gic_cascade_irq(1, IRQ_DC1176_PB_IRQ1); |
315 | 316 | } |
316 | 317 |
arch/arm/mach-realview/realview_pb11mp.c
... | ... | @@ -309,13 +309,13 @@ |
309 | 309 | writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); |
310 | 310 | |
311 | 311 | /* ARM11MPCore test chip GIC, primary */ |
312 | - gic_cpu_base_addr = __io_address(REALVIEW_TC11MP_GIC_CPU_BASE); | |
313 | - gic_dist_init(0, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE), 29); | |
314 | - gic_cpu_init(0, gic_cpu_base_addr); | |
312 | + gic_init(0, 29, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE), | |
313 | + __io_address(REALVIEW_TC11MP_GIC_CPU_BASE)); | |
315 | 314 | |
316 | 315 | /* board GIC, secondary */ |
317 | - gic_dist_init(1, __io_address(REALVIEW_PB11MP_GIC_DIST_BASE), IRQ_PB11MP_GIC_START); | |
318 | - gic_cpu_init(1, __io_address(REALVIEW_PB11MP_GIC_CPU_BASE)); | |
316 | + gic_init(1, IRQ_PB11MP_GIC_START, | |
317 | + __io_address(REALVIEW_PB11MP_GIC_DIST_BASE), | |
318 | + __io_address(REALVIEW_PB11MP_GIC_CPU_BASE)); | |
319 | 319 | gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1); |
320 | 320 | } |
321 | 321 |
arch/arm/mach-realview/realview_pba8.c
... | ... | @@ -273,9 +273,9 @@ |
273 | 273 | static void __init gic_init_irq(void) |
274 | 274 | { |
275 | 275 | /* ARM PB-A8 on-board GIC */ |
276 | - gic_cpu_base_addr = __io_address(REALVIEW_PBA8_GIC_CPU_BASE); | |
277 | - gic_dist_init(0, __io_address(REALVIEW_PBA8_GIC_DIST_BASE), IRQ_PBA8_GIC_START); | |
278 | - gic_cpu_init(0, __io_address(REALVIEW_PBA8_GIC_CPU_BASE)); | |
276 | + gic_init(0, IRQ_PBA8_GIC_START, | |
277 | + __io_address(REALVIEW_PBA8_GIC_DIST_BASE), | |
278 | + __io_address(REALVIEW_PBA8_GIC_CPU_BASE)); | |
279 | 279 | } |
280 | 280 | |
281 | 281 | static void __init realview_pba8_timer_init(void) |
arch/arm/mach-realview/realview_pbx.c
... | ... | @@ -313,15 +313,12 @@ |
313 | 313 | { |
314 | 314 | /* ARM PBX on-board GIC */ |
315 | 315 | if (core_tile_pbx11mp() || core_tile_pbxa9mp()) { |
316 | - gic_cpu_base_addr = __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE); | |
317 | - gic_dist_init(0, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE), | |
318 | - 29); | |
319 | - gic_cpu_init(0, __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE)); | |
316 | + gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE), | |
317 | + __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE)); | |
320 | 318 | } else { |
321 | - gic_cpu_base_addr = __io_address(REALVIEW_PBX_GIC_CPU_BASE); | |
322 | - gic_dist_init(0, __io_address(REALVIEW_PBX_GIC_DIST_BASE), | |
323 | - IRQ_PBX_GIC_START); | |
324 | - gic_cpu_init(0, __io_address(REALVIEW_PBX_GIC_CPU_BASE)); | |
319 | + gic_init(0, IRQ_PBX_GIC_START, | |
320 | + __io_address(REALVIEW_PBX_GIC_DIST_BASE), | |
321 | + __io_address(REALVIEW_PBX_GIC_CPU_BASE)); | |
325 | 322 | } |
326 | 323 | } |
327 | 324 |
arch/arm/mach-s5pv310/cpu.c
... | ... | @@ -24,8 +24,6 @@ |
24 | 24 | |
25 | 25 | #include <mach/regs-irq.h> |
26 | 26 | |
27 | -void __iomem *gic_cpu_base_addr; | |
28 | - | |
29 | 27 | extern int combiner_init(unsigned int combiner_nr, void __iomem *base, |
30 | 28 | unsigned int irq_start); |
31 | 29 | extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); |
... | ... | @@ -122,9 +120,7 @@ |
122 | 120 | { |
123 | 121 | int irq; |
124 | 122 | |
125 | - gic_cpu_base_addr = S5P_VA_GIC_CPU; | |
126 | - gic_dist_init(0, S5P_VA_GIC_DIST, IRQ_LOCALTIMER); | |
127 | - gic_cpu_init(0, S5P_VA_GIC_CPU); | |
123 | + gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); | |
128 | 124 | |
129 | 125 | for (irq = 0; irq < MAX_COMBINER_NR; irq++) { |
130 | 126 | combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), |
arch/arm/mach-s5pv310/include/mach/smp.h
arch/arm/mach-s5pv310/platsmp.c
arch/arm/mach-sa1100/Kconfig
... | ... | @@ -118,6 +118,16 @@ |
118 | 118 | (also known as the LART). See <http://www.lartmaker.nl/> for |
119 | 119 | information on the LART. |
120 | 120 | |
121 | +config SA1100_NANOENGINE | |
122 | + bool "nanoEngine" | |
123 | + select CPU_FREQ_SA1110 | |
124 | + select PCI | |
125 | + select PCI_NANOENGINE | |
126 | + help | |
127 | + Say Y here if you are using the Bright Star Engineering nanoEngine. | |
128 | + See <http://www.brightstareng.com/arm/nanoeng.htm> for information | |
129 | + on the BSE nanoEngine. | |
130 | + | |
121 | 131 | config SA1100_PLEB |
122 | 132 | bool "PLEB" |
123 | 133 | select CPU_FREQ_SA1100 |
arch/arm/mach-sa1100/Makefile
... | ... | @@ -37,6 +37,9 @@ |
37 | 37 | obj-$(CONFIG_SA1100_LART) += lart.o |
38 | 38 | led-$(CONFIG_SA1100_LART) += leds-lart.o |
39 | 39 | |
40 | +obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o | |
41 | +obj-$(CONFIG_PCI_NANOENGINE) += pci-nanoengine.o | |
42 | + | |
40 | 43 | obj-$(CONFIG_SA1100_PLEB) += pleb.o |
41 | 44 | |
42 | 45 | obj-$(CONFIG_SA1100_SHANNON) += shannon.o |
arch/arm/mach-sa1100/cpu-sa1100.c
... | ... | @@ -94,48 +94,47 @@ |
94 | 94 | |
95 | 95 | #include "generic.h" |
96 | 96 | |
97 | -typedef struct { | |
97 | +struct sa1100_dram_regs { | |
98 | 98 | int speed; |
99 | 99 | u32 mdcnfg; |
100 | 100 | u32 mdcas0; |
101 | 101 | u32 mdcas1; |
102 | 102 | u32 mdcas2; |
103 | -} sa1100_dram_regs_t; | |
103 | +}; | |
104 | 104 | |
105 | 105 | |
106 | 106 | static struct cpufreq_driver sa1100_driver; |
107 | 107 | |
108 | -static sa1100_dram_regs_t sa1100_dram_settings[] = | |
109 | -{ | |
110 | - /* speed, mdcnfg, mdcas0, mdcas1, mdcas2 clock frequency */ | |
111 | - { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */ | |
112 | - { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */ | |
113 | - { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */ | |
114 | - { 103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 103.2 MHz */ | |
115 | - { 118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 118.0 MHz */ | |
116 | - { 132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 132.7 MHz */ | |
117 | - { 147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff }, /* 147.5 MHz */ | |
118 | - { 162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff }, /* 162.2 MHz */ | |
119 | - { 176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff }, /* 176.9 MHz */ | |
120 | - { 191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff }, /* 191.7 MHz */ | |
121 | - { 206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 206.4 MHz */ | |
122 | - { 221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 221.2 MHz */ | |
123 | - { 235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1 }, /* 235.9 MHz */ | |
124 | - { 250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 250.7 MHz */ | |
125 | - { 265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 265.4 MHz */ | |
126 | - { 280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87 }, /* 280.2 MHz */ | |
108 | +static struct sa1100_dram_regs sa1100_dram_settings[] = { | |
109 | + /*speed, mdcnfg, mdcas0, mdcas1, mdcas2, clock freq */ | |
110 | + { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 59.0 MHz */ | |
111 | + { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 73.7 MHz */ | |
112 | + { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 88.5 MHz */ | |
113 | + {103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 103.2 MHz */ | |
114 | + {118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff},/* 118.0 MHz */ | |
115 | + {132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff},/* 132.7 MHz */ | |
116 | + {147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff},/* 147.5 MHz */ | |
117 | + {162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff},/* 162.2 MHz */ | |
118 | + {176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff},/* 176.9 MHz */ | |
119 | + {191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff},/* 191.7 MHz */ | |
120 | + {206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 206.4 MHz */ | |
121 | + {221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 221.2 MHz */ | |
122 | + {235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1},/* 235.9 MHz */ | |
123 | + {250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 250.7 MHz */ | |
124 | + {265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 265.4 MHz */ | |
125 | + {280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87},/* 280.2 MHz */ | |
127 | 126 | { 0, 0, 0, 0, 0 } /* last entry */ |
128 | 127 | }; |
129 | 128 | |
130 | 129 | static void sa1100_update_dram_timings(int current_speed, int new_speed) |
131 | 130 | { |
132 | - sa1100_dram_regs_t *settings = sa1100_dram_settings; | |
131 | + struct sa1100_dram_regs *settings = sa1100_dram_settings; | |
133 | 132 | |
134 | 133 | /* find speed */ |
135 | 134 | while (settings->speed != 0) { |
136 | - if(new_speed == settings->speed) | |
135 | + if (new_speed == settings->speed) | |
137 | 136 | break; |
138 | - | |
137 | + | |
139 | 138 | settings++; |
140 | 139 | } |
141 | 140 | |
... | ... | @@ -149,7 +148,7 @@ |
149 | 148 | /* We're going FASTER, so first relax the memory |
150 | 149 | * timings before changing the core frequency |
151 | 150 | */ |
152 | - | |
151 | + | |
153 | 152 | /* Half the memory access clock */ |
154 | 153 | MDCNFG |= MDCNFG_CDB2; |
155 | 154 | |
... | ... | @@ -187,7 +186,7 @@ |
187 | 186 | struct cpufreq_freqs freqs; |
188 | 187 | |
189 | 188 | new_ppcr = sa11x0_freq_to_ppcr(target_freq); |
190 | - switch(relation){ | |
189 | + switch (relation) { | |
191 | 190 | case CPUFREQ_RELATION_L: |
192 | 191 | if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) |
193 | 192 | new_ppcr--; |
arch/arm/mach-sa1100/cpu-sa1110.c
... | ... | @@ -16,28 +16,24 @@ |
16 | 16 | * |
17 | 17 | * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type |
18 | 18 | */ |
19 | -#include <linux/moduleparam.h> | |
20 | -#include <linux/types.h> | |
21 | -#include <linux/kernel.h> | |
22 | -#include <linux/sched.h> | |
23 | 19 | #include <linux/cpufreq.h> |
24 | 20 | #include <linux/delay.h> |
25 | 21 | #include <linux/init.h> |
26 | -#include <linux/io.h> | |
22 | +#include <linux/kernel.h> | |
23 | +#include <linux/moduleparam.h> | |
24 | +#include <linux/types.h> | |
27 | 25 | |
28 | -#include <mach/hardware.h> | |
29 | 26 | #include <asm/cputype.h> |
30 | 27 | #include <asm/mach-types.h> |
31 | -#include <asm/system.h> | |
32 | 28 | |
29 | +#include <mach/hardware.h> | |
30 | + | |
33 | 31 | #include "generic.h" |
34 | 32 | |
35 | 33 | #undef DEBUG |
36 | 34 | |
37 | -static struct cpufreq_driver sa1110_driver; | |
38 | - | |
39 | 35 | struct sdram_params { |
40 | - const char name[16]; | |
36 | + const char name[20]; | |
41 | 37 | u_char rows; /* bits */ |
42 | 38 | u_char cas_latency; /* cycles */ |
43 | 39 | u_char tck; /* clock cycle time (ns) */ |
... | ... | @@ -107,6 +103,15 @@ |
107 | 103 | .twr = 8, |
108 | 104 | .refresh = 64000, |
109 | 105 | .cas_latency = 3, |
106 | + }, { /* Micron MT48LC8M16A2TG-75 */ | |
107 | + .name = "MT48LC8M16A2TG-75", | |
108 | + .rows = 12, | |
109 | + .tck = 8, | |
110 | + .trcd = 20, | |
111 | + .trp = 20, | |
112 | + .twr = 8, | |
113 | + .refresh = 64000, | |
114 | + .cas_latency = 3, | |
110 | 115 | }, |
111 | 116 | }; |
112 | 117 | |
113 | 118 | |
... | ... | @@ -180,11 +185,13 @@ |
180 | 185 | sd->mdrefr |= MDREFR_K1DB2; |
181 | 186 | |
182 | 187 | /* initial number of '1's in MDCAS + 1 */ |
183 | - set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz)); | |
188 | + set_mdcas(sd->mdcas, sd_khz >= 62000, | |
189 | + ns_to_cycles(sdram->trcd, mem_khz)); | |
184 | 190 | |
185 | 191 | #ifdef DEBUG |
186 | - printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n", | |
187 | - sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]); | |
192 | + printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n", | |
193 | + sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], | |
194 | + sd->mdcas[2]); | |
188 | 195 | #endif |
189 | 196 | } |
190 | 197 | |
... | ... | @@ -213,7 +220,7 @@ |
213 | 220 | |
214 | 221 | #ifdef DEBUG |
215 | 222 | mdelay(250); |
216 | - printk("new dri value = %d\n", dri); | |
223 | + printk(KERN_DEBUG "new dri value = %d\n", dri); | |
217 | 224 | #endif |
218 | 225 | |
219 | 226 | sdram_set_refresh(dri); |
... | ... | @@ -232,7 +239,7 @@ |
232 | 239 | unsigned long flags; |
233 | 240 | unsigned int ppcr, unused; |
234 | 241 | |
235 | - switch(relation){ | |
242 | + switch (relation) { | |
236 | 243 | case CPUFREQ_RELATION_L: |
237 | 244 | ppcr = sa11x0_freq_to_ppcr(target_freq); |
238 | 245 | if (sa11x0_ppcr_to_freq(ppcr) > policy->max) |
239 | 246 | |
240 | 247 | |
... | ... | @@ -280,11 +287,10 @@ |
280 | 287 | * We wait 20ms to be safe. |
281 | 288 | */ |
282 | 289 | sdram_set_refresh(2); |
283 | - if (!irqs_disabled()) { | |
290 | + if (!irqs_disabled()) | |
284 | 291 | msleep(20); |
285 | - } else { | |
292 | + else | |
286 | 293 | mdelay(20); |
287 | - } | |
288 | 294 | |
289 | 295 | /* |
290 | 296 | * Reprogram the DRAM timings with interrupts disabled, and |
... | ... | @@ -295,7 +301,7 @@ |
295 | 301 | local_irq_save(flags); |
296 | 302 | asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); |
297 | 303 | udelay(10); |
298 | - __asm__ __volatile__(" \n\ | |
304 | + __asm__ __volatile__("\n\ | |
299 | 305 | b 2f \n\ |
300 | 306 | .align 5 \n\ |
301 | 307 | 1: str %3, [%1, #0] @ MDCNFG \n\ |
... | ... | @@ -336,7 +342,9 @@ |
336 | 342 | return 0; |
337 | 343 | } |
338 | 344 | |
339 | -static struct cpufreq_driver sa1110_driver = { | |
345 | +/* sa1110_driver needs __refdata because it must remain after init registers | |
346 | + * it with cpufreq_register_driver() */ | |
347 | +static struct cpufreq_driver sa1110_driver __refdata = { | |
340 | 348 | .flags = CPUFREQ_STICKY, |
341 | 349 | .verify = sa11x0_verify_speed, |
342 | 350 | .target = sa1110_target, |
... | ... | @@ -349,7 +357,8 @@ |
349 | 357 | { |
350 | 358 | struct sdram_params *sdram; |
351 | 359 | |
352 | - for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl); sdram++) | |
360 | + for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl); | |
361 | + sdram++) | |
353 | 362 | if (strcmp(name, sdram->name) == 0) |
354 | 363 | return sdram; |
355 | 364 | |
356 | 365 | |
357 | 366 | |
... | ... | @@ -369,14 +378,14 @@ |
369 | 378 | if (!name[0]) { |
370 | 379 | if (machine_is_assabet()) |
371 | 380 | name = "TC59SM716-CL3"; |
372 | - | |
373 | 381 | if (machine_is_pt_system3()) |
374 | 382 | name = "K4S641632D"; |
375 | - | |
376 | 383 | if (machine_is_h3100()) |
377 | 384 | name = "KM416S4030CT"; |
378 | 385 | if (machine_is_jornada720()) |
379 | - name = "K4S281632B-1H"; | |
386 | + name = "K4S281632B-1H"; | |
387 | + if (machine_is_nanoengine()) | |
388 | + name = "MT48LC8M16A2TG-75"; | |
380 | 389 | } |
381 | 390 | |
382 | 391 | sdram = sa1110_find_sdram(name); |
arch/arm/mach-sa1100/generic.c
... | ... | @@ -163,10 +163,15 @@ |
163 | 163 | |
164 | 164 | static struct resource sa11x0udc_resources[] = { |
165 | 165 | [0] = { |
166 | - .start = 0x80000000, | |
167 | - .end = 0x8000ffff, | |
166 | + .start = __PREG(Ser0UDCCR), | |
167 | + .end = __PREG(Ser0UDCCR) + 0xffff, | |
168 | 168 | .flags = IORESOURCE_MEM, |
169 | 169 | }, |
170 | + [1] = { | |
171 | + .start = IRQ_Ser0UDC, | |
172 | + .end = IRQ_Ser0UDC, | |
173 | + .flags = IORESOURCE_IRQ, | |
174 | + }, | |
170 | 175 | }; |
171 | 176 | |
172 | 177 | static u64 sa11x0udc_dma_mask = 0xffffffffUL; |
173 | 178 | |
... | ... | @@ -184,10 +189,15 @@ |
184 | 189 | |
185 | 190 | static struct resource sa11x0uart1_resources[] = { |
186 | 191 | [0] = { |
187 | - .start = 0x80010000, | |
188 | - .end = 0x8001ffff, | |
192 | + .start = __PREG(Ser1UTCR0), | |
193 | + .end = __PREG(Ser1UTCR0) + 0xffff, | |
189 | 194 | .flags = IORESOURCE_MEM, |
190 | 195 | }, |
196 | + [1] = { | |
197 | + .start = IRQ_Ser1UART, | |
198 | + .end = IRQ_Ser1UART, | |
199 | + .flags = IORESOURCE_IRQ, | |
200 | + }, | |
191 | 201 | }; |
192 | 202 | |
193 | 203 | static struct platform_device sa11x0uart1_device = { |
194 | 204 | |
... | ... | @@ -199,10 +209,15 @@ |
199 | 209 | |
200 | 210 | static struct resource sa11x0uart3_resources[] = { |
201 | 211 | [0] = { |
202 | - .start = 0x80050000, | |
203 | - .end = 0x8005ffff, | |
212 | + .start = __PREG(Ser3UTCR0), | |
213 | + .end = __PREG(Ser3UTCR0) + 0xffff, | |
204 | 214 | .flags = IORESOURCE_MEM, |
205 | 215 | }, |
216 | + [1] = { | |
217 | + .start = IRQ_Ser3UART, | |
218 | + .end = IRQ_Ser3UART, | |
219 | + .flags = IORESOURCE_IRQ, | |
220 | + }, | |
206 | 221 | }; |
207 | 222 | |
208 | 223 | static struct platform_device sa11x0uart3_device = { |
209 | 224 | |
... | ... | @@ -214,10 +229,15 @@ |
214 | 229 | |
215 | 230 | static struct resource sa11x0mcp_resources[] = { |
216 | 231 | [0] = { |
217 | - .start = 0x80060000, | |
218 | - .end = 0x8006ffff, | |
232 | + .start = __PREG(Ser4MCCR0), | |
233 | + .end = __PREG(Ser4MCCR0) + 0xffff, | |
219 | 234 | .flags = IORESOURCE_MEM, |
220 | 235 | }, |
236 | + [1] = { | |
237 | + .start = IRQ_Ser4MCP, | |
238 | + .end = IRQ_Ser4MCP, | |
239 | + .flags = IORESOURCE_IRQ, | |
240 | + }, | |
221 | 241 | }; |
222 | 242 | |
223 | 243 | static u64 sa11x0mcp_dma_mask = 0xffffffffUL; |
... | ... | @@ -243,6 +263,11 @@ |
243 | 263 | .start = 0x80070000, |
244 | 264 | .end = 0x8007ffff, |
245 | 265 | .flags = IORESOURCE_MEM, |
266 | + }, | |
267 | + [1] = { | |
268 | + .start = IRQ_Ser4SSP, | |
269 | + .end = IRQ_Ser4SSP, | |
270 | + .flags = IORESOURCE_IRQ, | |
246 | 271 | }, |
247 | 272 | }; |
248 | 273 |
arch/arm/mach-sa1100/include/mach/hardware.h
... | ... | @@ -76,5 +76,13 @@ |
76 | 76 | #include "SA-1101.h" |
77 | 77 | #endif |
78 | 78 | |
79 | +#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI) | |
80 | +#define PCIBIOS_MIN_IO 0 | |
81 | +#define PCIBIOS_MIN_MEM 0 | |
82 | +#define pcibios_assign_all_busses() 1 | |
83 | +#define HAVE_ARCH_PCI_SET_DMA_MASK 1 | |
84 | +#endif | |
85 | + | |
86 | + | |
79 | 87 | #endif /* _ASM_ARCH_HARDWARE_H */ |
arch/arm/mach-sa1100/include/mach/nanoengine.h
1 | +/* | |
2 | + * arch/arm/mach-sa1100/include/mach/nanoengine.h | |
3 | + * | |
4 | + * This file contains the hardware specific definitions for nanoEngine. | |
5 | + * Only include this file from SA1100-specific files. | |
6 | + * | |
7 | + * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> | |
8 | + * | |
9 | + * This program is free software; you can redistribute it and/or modify | |
10 | + * it under the terms of the GNU General Public License version 2 as | |
11 | + * published by the Free Software Foundation. | |
12 | + * | |
13 | + */ | |
14 | +#ifndef __ASM_ARCH_NANOENGINE_H | |
15 | +#define __ASM_ARCH_NANOENGINE_H | |
16 | + | |
17 | +#include <mach/irqs.h> | |
18 | + | |
19 | +#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/ | |
20 | +#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */ | |
21 | +#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */ | |
22 | +#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */ | |
23 | +#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ | |
24 | +#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ | |
25 | + | |
26 | +#define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0 | |
27 | +#define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11 | |
28 | +#define NANOENGINE_IRQ_GPIO_PC_READY1 IRQ_GPIO12 | |
29 | +#define NANOENGINE_IRQ_GPIO_PC_CD0 IRQ_GPIO13 | |
30 | +#define NANOENGINE_IRQ_GPIO_PC_CD1 IRQ_GPIO14 | |
31 | + | |
32 | +/* | |
33 | + * nanoEngine Memory Map: | |
34 | + * | |
35 | + * 0000.0000 - 003F.0000 - 4 MB Flash | |
36 | + * C000.0000 - C1FF.FFFF - 32 MB SDRAM | |
37 | + * 1860.0000 - 186F.FFFF - 1 MB Internal PCI Memory Read/Write | |
38 | + * 18A1.0000 - 18A1.FFFF - 64 KB Internal PCI Config Space | |
39 | + * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode | |
40 | + * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode | |
41 | + * | |
42 | + */ | |
43 | + | |
44 | +#define NANO_PCI_MEM_RW_PHYS 0x18600000 | |
45 | +#define NANO_PCI_MEM_RW_VIRT 0xf1000000 | |
46 | +#define NANO_PCI_MEM_RW_SIZE SZ_1M | |
47 | +#define NANO_PCI_CONFIG_SPACE_PHYS 0x18A10000 | |
48 | +#define NANO_PCI_CONFIG_SPACE_VIRT 0xf2000000 | |
49 | +#define NANO_PCI_CONFIG_SPACE_SIZE SZ_64K | |
50 | + | |
51 | +#endif |
arch/arm/mach-sa1100/nanoengine.c
1 | +/* | |
2 | + * linux/arch/arm/mach-sa1100/nanoengine.c | |
3 | + * | |
4 | + * Bright Star Engineering's nanoEngine board init code. | |
5 | + * | |
6 | + * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + * | |
12 | + */ | |
13 | + | |
14 | +#include <linux/init.h> | |
15 | +#include <linux/kernel.h> | |
16 | +#include <linux/mtd/mtd.h> | |
17 | +#include <linux/mtd/partitions.h> | |
18 | +#include <linux/root_dev.h> | |
19 | + | |
20 | +#include <asm/mach-types.h> | |
21 | +#include <asm/setup.h> | |
22 | + | |
23 | +#include <asm/mach/arch.h> | |
24 | +#include <asm/mach/flash.h> | |
25 | +#include <asm/mach/map.h> | |
26 | +#include <asm/mach/serial_sa1100.h> | |
27 | + | |
28 | +#include <mach/hardware.h> | |
29 | +#include <mach/nanoengine.h> | |
30 | + | |
31 | +#include "generic.h" | |
32 | + | |
33 | +/* Flash bank 0 */ | |
34 | +static struct mtd_partition nanoengine_partitions[] = { | |
35 | + { | |
36 | + .name = "nanoEngine boot firmware and parameter table", | |
37 | + .size = 0x00010000, /* 32K */ | |
38 | + .offset = 0, | |
39 | + .mask_flags = MTD_WRITEABLE, | |
40 | + }, { | |
41 | + .name = "kernel/initrd reserved", | |
42 | + .size = 0x002f0000, | |
43 | + .offset = 0x00010000, | |
44 | + .mask_flags = MTD_WRITEABLE, | |
45 | + }, { | |
46 | + .name = "experimental filesystem allocation", | |
47 | + .size = 0x00100000, | |
48 | + .offset = 0x00300000, | |
49 | + .mask_flags = MTD_WRITEABLE, | |
50 | + } | |
51 | +}; | |
52 | + | |
53 | +static struct flash_platform_data nanoengine_flash_data = { | |
54 | + .map_name = "jedec_probe", | |
55 | + .parts = nanoengine_partitions, | |
56 | + .nr_parts = ARRAY_SIZE(nanoengine_partitions), | |
57 | +}; | |
58 | + | |
59 | +static struct resource nanoengine_flash_resources[] = { | |
60 | + { | |
61 | + .start = SA1100_CS0_PHYS, | |
62 | + .end = SA1100_CS0_PHYS + SZ_32M - 1, | |
63 | + .flags = IORESOURCE_MEM, | |
64 | + }, { | |
65 | + .start = SA1100_CS1_PHYS, | |
66 | + .end = SA1100_CS1_PHYS + SZ_32M - 1, | |
67 | + .flags = IORESOURCE_MEM, | |
68 | + } | |
69 | +}; | |
70 | + | |
71 | +static struct map_desc nanoengine_io_desc[] __initdata = { | |
72 | + { | |
73 | + /* System Registers */ | |
74 | + .virtual = 0xf0000000, | |
75 | + .pfn = __phys_to_pfn(0x10000000), | |
76 | + .length = 0x00100000, | |
77 | + .type = MT_DEVICE | |
78 | + }, { | |
79 | + /* Internal PCI Memory Read/Write */ | |
80 | + .virtual = NANO_PCI_MEM_RW_VIRT, | |
81 | + .pfn = __phys_to_pfn(NANO_PCI_MEM_RW_PHYS), | |
82 | + .length = NANO_PCI_MEM_RW_SIZE, | |
83 | + .type = MT_DEVICE | |
84 | + }, { | |
85 | + /* Internal PCI Config Space */ | |
86 | + .virtual = NANO_PCI_CONFIG_SPACE_VIRT, | |
87 | + .pfn = __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS), | |
88 | + .length = NANO_PCI_CONFIG_SPACE_SIZE, | |
89 | + .type = MT_DEVICE | |
90 | + } | |
91 | +}; | |
92 | + | |
93 | +static void __init nanoengine_map_io(void) | |
94 | +{ | |
95 | + sa1100_map_io(); | |
96 | + iotable_init(nanoengine_io_desc, ARRAY_SIZE(nanoengine_io_desc)); | |
97 | + | |
98 | + sa1100_register_uart(0, 1); | |
99 | + sa1100_register_uart(1, 2); | |
100 | + sa1100_register_uart(2, 3); | |
101 | + Ser1SDCR0 |= SDCR0_UART; | |
102 | + /* disable IRDA -- UART2 is used as a normal serial port */ | |
103 | + Ser2UTCR4 = 0; | |
104 | + Ser2HSCR0 = 0; | |
105 | +} | |
106 | + | |
107 | +static void __init nanoengine_init(void) | |
108 | +{ | |
109 | + sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources, | |
110 | + ARRAY_SIZE(nanoengine_flash_resources)); | |
111 | +} | |
112 | + | |
113 | +MACHINE_START(NANOENGINE, "BSE nanoEngine") | |
114 | + .boot_params = 0xc0000000, | |
115 | + .map_io = nanoengine_map_io, | |
116 | + .init_irq = sa1100_init_irq, | |
117 | + .timer = &sa1100_timer, | |
118 | + .init_machine = nanoengine_init, | |
119 | +MACHINE_END |
arch/arm/mach-sa1100/pci-nanoengine.c
1 | +/* | |
2 | + * linux/arch/arm/mach-sa1100/pci-nanoengine.c | |
3 | + * | |
4 | + * PCI functions for BSE nanoEngine PCI | |
5 | + * | |
6 | + * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License as published by | |
10 | + * the Free Software Foundation; either version 2 of the License, or | |
11 | + * (at your option) any later version. | |
12 | + * | |
13 | + * This program is distributed in the hope that it will be useful, | |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | + * GNU General Public License for more details. | |
17 | + * | |
18 | + * You should have received a copy of the GNU General Public License | |
19 | + * along with this program; if not, write to the Free Software | |
20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | + */ | |
22 | +#include <linux/kernel.h> | |
23 | +#include <linux/irq.h> | |
24 | +#include <linux/pci.h> | |
25 | +#include <linux/spinlock.h> | |
26 | + | |
27 | +#include <asm/mach/pci.h> | |
28 | +#include <asm/mach-types.h> | |
29 | + | |
30 | +#include <mach/nanoengine.h> | |
31 | + | |
32 | +static DEFINE_SPINLOCK(nano_lock); | |
33 | + | |
34 | +static int nanoengine_get_pci_address(struct pci_bus *bus, | |
35 | + unsigned int devfn, int where, unsigned long *address) | |
36 | +{ | |
37 | + int ret = PCIBIOS_DEVICE_NOT_FOUND; | |
38 | + unsigned int busnr = bus->number; | |
39 | + | |
40 | + *address = NANO_PCI_CONFIG_SPACE_VIRT + | |
41 | + ((bus->number << 16) | (devfn << 8) | (where & ~3)); | |
42 | + | |
43 | + ret = (busnr > 255 || devfn > 255 || where > 255) ? | |
44 | + PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | |
45 | + | |
46 | + return ret; | |
47 | +} | |
48 | + | |
49 | +static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where, | |
50 | + int size, u32 *val) | |
51 | +{ | |
52 | + int ret; | |
53 | + unsigned long address; | |
54 | + unsigned long flags; | |
55 | + u32 v; | |
56 | + | |
57 | + /* nanoEngine PCI bridge does not return -1 for a non-existing | |
58 | + * device. We must fake the answer. We know that the only valid | |
59 | + * device is device zero at bus 0, which is the network chip. */ | |
60 | + if (bus->number != 0 || (devfn >> 3) != 0) { | |
61 | + v = -1; | |
62 | + nanoengine_get_pci_address(bus, devfn, where, &address); | |
63 | + goto exit_function; | |
64 | + } | |
65 | + | |
66 | + spin_lock_irqsave(&nano_lock, flags); | |
67 | + | |
68 | + ret = nanoengine_get_pci_address(bus, devfn, where, &address); | |
69 | + if (ret != PCIBIOS_SUCCESSFUL) | |
70 | + return ret; | |
71 | + v = __raw_readl(address); | |
72 | + | |
73 | + spin_unlock_irqrestore(&nano_lock, flags); | |
74 | + | |
75 | + v >>= ((where & 3) * 8); | |
76 | + v &= (unsigned long)(-1) >> ((4 - size) * 8); | |
77 | + | |
78 | +exit_function: | |
79 | + *val = v; | |
80 | + return PCIBIOS_SUCCESSFUL; | |
81 | +} | |
82 | + | |
83 | +static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where, | |
84 | + int size, u32 val) | |
85 | +{ | |
86 | + int ret; | |
87 | + unsigned long address; | |
88 | + unsigned long flags; | |
89 | + unsigned shift; | |
90 | + u32 v; | |
91 | + | |
92 | + shift = (where & 3) * 8; | |
93 | + | |
94 | + spin_lock_irqsave(&nano_lock, flags); | |
95 | + | |
96 | + ret = nanoengine_get_pci_address(bus, devfn, where, &address); | |
97 | + if (ret != PCIBIOS_SUCCESSFUL) | |
98 | + return ret; | |
99 | + v = __raw_readl(address); | |
100 | + switch (size) { | |
101 | + case 1: | |
102 | + v &= ~(0xFF << shift); | |
103 | + v |= val << shift; | |
104 | + break; | |
105 | + case 2: | |
106 | + v &= ~(0xFFFF << shift); | |
107 | + v |= val << shift; | |
108 | + break; | |
109 | + case 4: | |
110 | + v = val; | |
111 | + break; | |
112 | + } | |
113 | + __raw_writel(v, address); | |
114 | + | |
115 | + spin_unlock_irqrestore(&nano_lock, flags); | |
116 | + | |
117 | + return PCIBIOS_SUCCESSFUL; | |
118 | +} | |
119 | + | |
120 | +static struct pci_ops pci_nano_ops = { | |
121 | + .read = nanoengine_read_config, | |
122 | + .write = nanoengine_write_config, | |
123 | +}; | |
124 | + | |
125 | +static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |
126 | +{ | |
127 | + return NANOENGINE_IRQ_GPIO_PCI; | |
128 | +} | |
129 | + | |
130 | +struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys) | |
131 | +{ | |
132 | + return pci_scan_bus(sys->busnr, &pci_nano_ops, sys); | |
133 | +} | |
134 | + | |
135 | +static struct resource pci_io_ports = { | |
136 | + .name = "PCI IO", | |
137 | + .start = 0x400, | |
138 | + .end = 0x7FF, | |
139 | + .flags = IORESOURCE_IO, | |
140 | +}; | |
141 | + | |
142 | +static struct resource pci_non_prefetchable_memory = { | |
143 | + .name = "PCI non-prefetchable", | |
144 | + .start = NANO_PCI_MEM_RW_PHYS, | |
145 | + /* nanoEngine documentation says there is a 1 Megabyte window here, | |
146 | + * but PCI reports just 128 + 8 kbytes. */ | |
147 | + .end = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1, | |
148 | +/* .end = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/ | |
149 | + .flags = IORESOURCE_MEM, | |
150 | +}; | |
151 | + | |
152 | +/* | |
153 | + * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it | |
154 | + * overlaps with previously defined memory. | |
155 | + * | |
156 | + * Here is what happens: | |
157 | + * | |
158 | +# dmesg | |
159 | +... | |
160 | +pci 0000:00:00.0: [8086:1209] type 0 class 0x000200 | |
161 | +pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff] | |
162 | +pci 0000:00:00.0: reg 14: [io 0x0000-0x003f] | |
163 | +pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff] | |
164 | +pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref] | |
165 | +pci 0000:00:00.0: supports D1 D2 | |
166 | +pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot | |
167 | +pci 0000:00:00.0: PME# disabled | |
168 | +PCI: bus0: Fast back to back transfers enabled | |
169 | +pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000) | |
170 | +pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff] | |
171 | +pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff]) | |
172 | +pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff] | |
173 | +pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff]) | |
174 | +pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f] | |
175 | +pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f]) | |
176 | + * | |
177 | + * On the other hand, if we do not request the prefetchable memory resource, | |
178 | + * linux will alloc it first and the two non-prefetchable memory areas that | |
179 | + * are our real interest will not be mapped. So we choose to map it to an | |
180 | + * unused area. It gets recognized as expansion ROM, but becomes disabled. | |
181 | + * | |
182 | + * Here is what happens then: | |
183 | + * | |
184 | +# dmesg | |
185 | +... | |
186 | +pci 0000:00:00.0: [8086:1209] type 0 class 0x000200 | |
187 | +pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff] | |
188 | +pci 0000:00:00.0: reg 14: [io 0x0000-0x003f] | |
189 | +pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff] | |
190 | +pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref] | |
191 | +pci 0000:00:00.0: supports D1 D2 | |
192 | +pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot | |
193 | +pci 0000:00:00.0: PME# disabled | |
194 | +PCI: bus0: Fast back to back transfers enabled | |
195 | +pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref] | |
196 | +pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff] | |
197 | +pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff]) | |
198 | +pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff] | |
199 | +pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff]) | |
200 | +pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f] | |
201 | +pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f]) | |
202 | + | |
203 | +# lspci -vv -s 0000:00:00.0 | |
204 | +00:00.0 Class 0200: Device 8086:1209 (rev 09) | |
205 | + Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx- | |
206 | + Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx- | |
207 | + Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes | |
208 | + Interrupt: pin A routed to IRQ 0 | |
209 | + Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K] | |
210 | + Region 1: I/O ports at 0400 [size=64] | |
211 | + Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K] | |
212 | + [virtual] Expansion ROM at 78000000 [disabled] [size=1M] | |
213 | + Capabilities: [dc] Power Management version 2 | |
214 | + Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-) | |
215 | + Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME- | |
216 | + Kernel driver in use: e100 | |
217 | + Kernel modules: e100 | |
218 | + * | |
219 | + */ | |
220 | +static struct resource pci_prefetchable_memory = { | |
221 | + .name = "PCI prefetchable", | |
222 | + .start = 0x78000000, | |
223 | + .end = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1, | |
224 | + .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH, | |
225 | +}; | |
226 | + | |
227 | +static int __init pci_nanoengine_setup_resources(struct resource **resource) | |
228 | +{ | |
229 | + if (request_resource(&ioport_resource, &pci_io_ports)) { | |
230 | + printk(KERN_ERR "PCI: unable to allocate io port region\n"); | |
231 | + return -EBUSY; | |
232 | + } | |
233 | + if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) { | |
234 | + release_resource(&pci_io_ports); | |
235 | + printk(KERN_ERR "PCI: unable to allocate non prefetchable\n"); | |
236 | + return -EBUSY; | |
237 | + } | |
238 | + if (request_resource(&iomem_resource, &pci_prefetchable_memory)) { | |
239 | + release_resource(&pci_io_ports); | |
240 | + release_resource(&pci_non_prefetchable_memory); | |
241 | + printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); | |
242 | + return -EBUSY; | |
243 | + } | |
244 | + resource[0] = &pci_io_ports; | |
245 | + resource[1] = &pci_non_prefetchable_memory; | |
246 | + resource[2] = &pci_prefetchable_memory; | |
247 | + | |
248 | + return 1; | |
249 | +} | |
250 | + | |
251 | +int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys) | |
252 | +{ | |
253 | + int ret = 0; | |
254 | + | |
255 | + if (nr == 0) { | |
256 | + sys->mem_offset = NANO_PCI_MEM_RW_PHYS; | |
257 | + sys->io_offset = 0x400; | |
258 | + ret = pci_nanoengine_setup_resources(sys->resource); | |
259 | + /* Enable alternate memory bus master mode, see | |
260 | + * "Intel StrongARM SA1110 Developer's Manual", | |
261 | + * section 10.8, "Alternate Memory Bus Master Mode". */ | |
262 | + GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; | |
263 | + GAFR |= GPIO_MBGNT | GPIO_MBREQ; | |
264 | + TUCR |= TUCR_MBGPIO; | |
265 | + } | |
266 | + | |
267 | + return ret; | |
268 | +} | |
269 | + | |
270 | +static struct hw_pci nanoengine_pci __initdata = { | |
271 | + .map_irq = pci_nanoengine_map_irq, | |
272 | + .nr_controllers = 1, | |
273 | + .scan = pci_nanoengine_scan_bus, | |
274 | + .setup = pci_nanoengine_setup, | |
275 | +}; | |
276 | + | |
277 | +static int __init nanoengine_pci_init(void) | |
278 | +{ | |
279 | + if (machine_is_nanoengine()) | |
280 | + pci_common_init(&nanoengine_pci); | |
281 | + return 0; | |
282 | +} | |
283 | + | |
284 | +subsys_initcall(nanoengine_pci_init); |
arch/arm/mach-sa1100/simpad.c
... | ... | @@ -166,9 +166,6 @@ |
166 | 166 | PCFR = 0; |
167 | 167 | PSDR = 0; |
168 | 168 | |
169 | - sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, | |
170 | - ARRAY_SIZE(simpad_flash_resources)); | |
171 | - sa11x0_register_mcp(&simpad_mcp_data); | |
172 | 169 | } |
173 | 170 | |
174 | 171 | static void simpad_power_off(void) |
... | ... | @@ -215,6 +212,10 @@ |
215 | 212 | int ret; |
216 | 213 | |
217 | 214 | pm_power_off = simpad_power_off; |
215 | + | |
216 | + sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, | |
217 | + ARRAY_SIZE(simpad_flash_resources)); | |
218 | + sa11x0_register_mcp(&simpad_mcp_data); | |
218 | 219 | |
219 | 220 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
220 | 221 | if(ret) |
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
1 | +LIST "partner-jet-setup.txt" | |
2 | +LIST "(C) Copyright 2010 Renesas Solutions Corp" | |
3 | +LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>" | |
4 | + | |
5 | +LIST "RWT Setting" | |
6 | +EW 0xE6020004, 0xA500 | |
7 | +EW 0xE6030004, 0xA500 | |
8 | + | |
9 | +DD 0x01001000, 0x01001000 | |
10 | + | |
11 | +LIST "GPIO Setting" | |
12 | +EB 0xE6051013, 0xA2 | |
13 | + | |
14 | +LIST "CPG" | |
15 | +ED 0xE6150080, 0x00000180 | |
16 | +ED 0xE61500C0, 0x00000002 | |
17 | + | |
18 | +WAIT 1, 0xFE40009C | |
19 | + | |
20 | +LIST "FRQCR" | |
21 | +ED 0xE6150000, 0x2D1305C3 | |
22 | +ED 0xE61500E0, 0x9E40358E | |
23 | +ED 0xE6150004, 0x80331050 | |
24 | + | |
25 | +WAIT 1, 0xFE40009C | |
26 | + | |
27 | +ED 0xE61500E4, 0x00002000 | |
28 | + | |
29 | +WAIT 1, 0xFE40009C | |
30 | + | |
31 | +LIST "PLL" | |
32 | +ED 0xE6150028, 0x00004000 | |
33 | + | |
34 | +WAIT 1, 0xFE40009C | |
35 | + | |
36 | +ED 0xE615002C, 0x93000040 | |
37 | + | |
38 | +WAIT 1, 0xFE40009C | |
39 | + | |
40 | +LIST "BSC" | |
41 | +ED 0xFEC10000, 0x00E0001B | |
42 | + | |
43 | +LIST "SBSC1" | |
44 | +ED 0xFE400354, 0x01AD8000 | |
45 | +ED 0xFE400354, 0x01AD8001 | |
46 | + | |
47 | +WAIT 5, 0xFE40009C | |
48 | + | |
49 | +ED 0xFE400008, 0xBCC90151 | |
50 | +ED 0xFE400040, 0x41774113 | |
51 | +ED 0xFE400044, 0x2712E229 | |
52 | +ED 0xFE400048, 0x20C18505 | |
53 | +ED 0xFE40004C, 0x00110209 | |
54 | +ED 0xFE400010, 0x00000087 | |
55 | + | |
56 | +WAIT 10, 0xFE40009C | |
57 | + | |
58 | +ED 0xFE400084, 0x0000003F | |
59 | +EB 0xFE500000, 0x00 | |
60 | + | |
61 | +WAIT 5, 0xFE40009C | |
62 | + | |
63 | +ED 0xFE400084, 0x0000FF0A | |
64 | +EB 0xFE500000, 0x00 | |
65 | + | |
66 | +WAIT 1, 0xFE40009C | |
67 | + | |
68 | +ED 0xFE400084, 0x00002201 | |
69 | +EB 0xFE500000, 0x00 | |
70 | +ED 0xFE400084, 0x00000302 | |
71 | +EB 0xFE500000, 0x00 | |
72 | +EB 0xFE5C0000, 0x00 | |
73 | +ED 0xFE400008, 0xBCC90159 | |
74 | +ED 0xFE40008C, 0x88800004 | |
75 | +ED 0xFE400094, 0x00000004 | |
76 | +ED 0xFE400028, 0xA55A0032 | |
77 | +ED 0xFE40002C, 0xA55A000C | |
78 | +ED 0xFE400020, 0xA55A2048 | |
79 | +ED 0xFE400008, 0xBCC90959 | |
80 | + | |
81 | +LIST "Change CPGA setting" | |
82 | +ED 0xE61500E0, 0x9E40352E | |
83 | +ED 0xE6150004, 0x80331050 | |
84 | + | |
85 | +WAIT 1, 0xFE40009C | |
86 | + | |
87 | +ED 0xE6150354, 0x00000002 |
arch/arm/mach-shmobile/include/mach/zboot.h
1 | +#ifndef ZBOOT_H | |
2 | +#define ZBOOT_H | |
3 | + | |
4 | +#include <asm/mach-types.h> | |
5 | +#include <mach/zboot_macros.h> | |
6 | + | |
7 | +/************************************************** | |
8 | + * | |
9 | + * board specific settings | |
10 | + * | |
11 | + **************************************************/ | |
12 | + | |
13 | +#ifdef CONFIG_MACH_AP4EVB | |
14 | +#define MACH_TYPE MACH_TYPE_AP4EVB | |
15 | +#include "mach/head-ap4evb.txt" | |
16 | +#else | |
17 | +#error "unsupported board." | |
18 | +#endif | |
19 | + | |
20 | +#endif /* ZBOOT_H */ |
arch/arm/mach-shmobile/include/mach/zboot_macros.h
1 | +#ifndef __ZBOOT_MACRO_H | |
2 | +#define __ZBOOT_MACRO_H | |
3 | + | |
4 | +/* The LIST command is used to include comments in the script */ | |
5 | +.macro LIST comment | |
6 | +.endm | |
7 | + | |
8 | +/* The ED command is used to write a 32-bit word */ | |
9 | +.macro ED, addr, data | |
10 | + LDR r0, 1f | |
11 | + LDR r1, 2f | |
12 | + STR r1, [r0] | |
13 | + B 3f | |
14 | +1 : .long \addr | |
15 | +2 : .long \data | |
16 | +3 : | |
17 | +.endm | |
18 | + | |
19 | +/* The EW command is used to write a 16-bit word */ | |
20 | +.macro EW, addr, data | |
21 | + LDR r0, 1f | |
22 | + LDR r1, 2f | |
23 | + STRH r1, [r0] | |
24 | + B 3f | |
25 | +1 : .long \addr | |
26 | +2 : .long \data | |
27 | +3 : | |
28 | +.endm | |
29 | + | |
30 | +/* The EB command is used to write an 8-bit word */ | |
31 | +.macro EB, addr, data | |
32 | + LDR r0, 1f | |
33 | + LDR r1, 2f | |
34 | + STRB r1, [r0] | |
35 | + B 3f | |
36 | +1 : .long \addr | |
37 | +2 : .long \data | |
38 | +3 : | |
39 | +.endm | |
40 | + | |
41 | +/* The WAIT command is used to delay the execution */ | |
42 | +.macro WAIT, time, reg | |
43 | + LDR r1, 1f | |
44 | + LDR r0, 2f | |
45 | + STR r0, [r1] | |
46 | +10 : | |
47 | + LDR r0, [r1] | |
48 | + CMP r0, #0x00000000 | |
49 | + BNE 10b | |
50 | + NOP | |
51 | + B 3f | |
52 | +1 : .long \reg | |
53 | +2 : .long \time * 100 | |
54 | +3 : | |
55 | +.endm | |
56 | + | |
57 | +/* The DD command is used to read a 32-bit word */ | |
58 | +.macro DD, start, end | |
59 | + LDR r1, 1f | |
60 | + B 2f | |
61 | +1 : .long \start | |
62 | +2 : | |
63 | +.endm | |
64 | + | |
65 | +#endif /* __ZBOOT_MACRO_H */ |
arch/arm/mach-tegra/include/mach/entry-macro.S
... | ... | @@ -16,9 +16,9 @@ |
16 | 16 | #include <mach/io.h> |
17 | 17 | |
18 | 18 | #if defined(CONFIG_ARM_GIC) |
19 | +#define HAVE_GET_IRQNR_PREAMBLE | |
20 | +#include <asm/hardware/entry-macro-gic.S> | |
19 | 21 | |
20 | -#include <asm/hardware/gic.h> | |
21 | - | |
22 | 22 | /* Uses the GIC interrupt controller built into the cpu */ |
23 | 23 | #define ICTRL_BASE (IO_CPU_VIRT + 0x100) |
24 | 24 | |
... | ... | @@ -32,68 +32,6 @@ |
32 | 32 | |
33 | 33 | .macro arch_ret_to_user, tmp1, tmp2 |
34 | 34 | .endm |
35 | - | |
36 | - /* | |
37 | - * The interrupt numbering scheme is defined in the | |
38 | - * interrupt controller spec. To wit: | |
39 | - * | |
40 | - * Interrupts 0-15 are IPI | |
41 | - * 16-28 are reserved | |
42 | - * 29-31 are local. We allow 30 to be used for the watchdog. | |
43 | - * 32-1020 are global | |
44 | - * 1021-1022 are reserved | |
45 | - * 1023 is "spurious" (no interrupt) | |
46 | - * | |
47 | - * For now, we ignore all local interrupts so only return an interrupt | |
48 | - * if it's between 30 and 1020. The test_for_ipi routine below will | |
49 | - * pick up on IPIs. | |
50 | - * | |
51 | - * A simple read from the controller will tell us the number of the | |
52 | - * highest priority enabled interrupt. We then just need to check | |
53 | - * whether it is in the valid range for an IRQ (30-1020 inclusive). | |
54 | - */ | |
55 | - | |
56 | - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
57 | - | |
58 | - /* bits 12-10 = src CPU, 9-0 = int # */ | |
59 | - ldr \irqstat, [\base, #GIC_CPU_INTACK] | |
60 | - | |
61 | - ldr \tmp, =1021 | |
62 | - | |
63 | - bic \irqnr, \irqstat, #0x1c00 | |
64 | - | |
65 | - cmp \irqnr, #29 | |
66 | - cmpcc \irqnr, \irqnr | |
67 | - cmpne \irqnr, \tmp | |
68 | - cmpcs \irqnr, \irqnr | |
69 | - | |
70 | - .endm | |
71 | - | |
72 | - /* We assume that irqstat (the raw value of the IRQ acknowledge | |
73 | - * register) is preserved from the macro above. | |
74 | - * If there is an IPI, we immediately signal end of interrupt on the | |
75 | - * controller, since this requires the original irqstat value which | |
76 | - * we won't easily be able to recreate later. | |
77 | - */ | |
78 | - | |
79 | - .macro test_for_ipi, irqnr, irqstat, base, tmp | |
80 | - bic \irqnr, \irqstat, #0x1c00 | |
81 | - cmp \irqnr, #16 | |
82 | - strcc \irqstat, [\base, #GIC_CPU_EOI] | |
83 | - cmpcs \irqnr, \irqnr | |
84 | - .endm | |
85 | - | |
86 | - /* As above, this assumes that irqstat and base are preserved.. */ | |
87 | - | |
88 | - .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
89 | - bic \irqnr, \irqstat, #0x1c00 | |
90 | - mov \tmp, #0 | |
91 | - cmp \irqnr, #29 | |
92 | - moveq \tmp, #1 | |
93 | - streq \irqstat, [\base, #GIC_CPU_EOI] | |
94 | - cmp \tmp, #0 | |
95 | - .endm | |
96 | - | |
97 | 35 | #else |
98 | 36 | /* legacy interrupt controller for AP16 */ |
99 | 37 | .macro disable_fiq |
arch/arm/mach-tegra/include/mach/io.h
... | ... | @@ -65,8 +65,8 @@ |
65 | 65 | |
66 | 66 | #ifndef __ASSEMBLER__ |
67 | 67 | |
68 | -#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t) | |
69 | -#define __arch_iounmap(v) tegra_iounmap(v) | |
68 | +#define __arch_ioremap tegra_ioremap | |
69 | +#define __arch_iounmap tegra_iounmap | |
70 | 70 | |
71 | 71 | void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type); |
72 | 72 | void tegra_iounmap(volatile void __iomem *addr); |
arch/arm/mach-tegra/irq.c
... | ... | @@ -94,8 +94,8 @@ |
94 | 94 | writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS); |
95 | 95 | } |
96 | 96 | |
97 | - gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29); | |
98 | - gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); | |
97 | + gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), | |
98 | + IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); | |
99 | 99 | |
100 | 100 | gic = get_irq_chip(29); |
101 | 101 | gic_unmask_irq = gic->unmask; |
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-ux500/cpu.c
... | ... | @@ -61,8 +61,8 @@ |
61 | 61 | |
62 | 62 | void __init ux500_init_irq(void) |
63 | 63 | { |
64 | - gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); | |
65 | - gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); | |
64 | + gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE), | |
65 | + __io_address(UX500_GIC_CPU_BASE)); | |
66 | 66 | |
67 | 67 | /* |
68 | 68 | * Init clocks here so that they are available for system timer |
arch/arm/mach-ux500/include/mach/entry-macro.S
... | ... | @@ -11,7 +11,8 @@ |
11 | 11 | * warranty of any kind, whether express or implied. |
12 | 12 | */ |
13 | 13 | #include <mach/hardware.h> |
14 | -#include <asm/hardware/gic.h> | |
14 | +#define HAVE_GET_IRQNR_PREAMBLE | |
15 | +#include <asm/hardware/entry-macro-gic.S> | |
15 | 16 | |
16 | 17 | .macro disable_fiq |
17 | 18 | .endm |
... | ... | @@ -21,70 +22,5 @@ |
21 | 22 | .endm |
22 | 23 | |
23 | 24 | .macro arch_ret_to_user, tmp1, tmp2 |
24 | - .endm | |
25 | - | |
26 | - /* | |
27 | - * The interrupt numbering scheme is defined in the | |
28 | - * interrupt controller spec. To wit: | |
29 | - * | |
30 | - * Interrupts 0-15 are IPI | |
31 | - * 16-28 are reserved | |
32 | - * 29-31 are local. We allow 30 to be used for the watchdog. | |
33 | - * 32-1020 are global | |
34 | - * 1021-1022 are reserved | |
35 | - * 1023 is "spurious" (no interrupt) | |
36 | - * | |
37 | - * For now, we ignore all local interrupts so only return an | |
38 | - * interrupt if it's between 30 and 1020. The test_for_ipi | |
39 | - * routine below will pick up on IPIs. | |
40 | - * | |
41 | - * A simple read from the controller will tell us the number | |
42 | - * of the highest priority enabled interrupt. We then just | |
43 | - * need to check whether it is in the valid range for an | |
44 | - * IRQ (30-1020 inclusive). | |
45 | - */ | |
46 | - | |
47 | - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
48 | - | |
49 | - /* bits 12-10 = src CPU, 9-0 = int # */ | |
50 | - ldr \irqstat, [\base, #GIC_CPU_INTACK] | |
51 | - | |
52 | - ldr \tmp, =1021 | |
53 | - | |
54 | - bic \irqnr, \irqstat, #0x1c00 | |
55 | - | |
56 | - cmp \irqnr, #29 | |
57 | - cmpcc \irqnr, \irqnr | |
58 | - cmpne \irqnr, \tmp | |
59 | - cmpcs \irqnr, \irqnr | |
60 | - | |
61 | - .endm | |
62 | - | |
63 | - /* We assume that irqstat (the raw value of the IRQ | |
64 | - * acknowledge register) is preserved from the macro above. | |
65 | - * If there is an IPI, we immediately signal end of | |
66 | - * interrupt on the controller, since this requires the | |
67 | - * original irqstat value which we won't easily be able | |
68 | - * to recreate later. | |
69 | - */ | |
70 | - | |
71 | - .macro test_for_ipi, irqnr, irqstat, base, tmp | |
72 | - bic \irqnr, \irqstat, #0x1c00 | |
73 | - cmp \irqnr, #16 | |
74 | - strcc \irqstat, [\base, #GIC_CPU_EOI] | |
75 | - cmpcs \irqnr, \irqnr | |
76 | - .endm | |
77 | - | |
78 | - /* As above, this assumes that irqstat and base | |
79 | - * are preserved.. | |
80 | - */ | |
81 | - | |
82 | - .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
83 | - bic \irqnr, \irqstat, #0x1c00 | |
84 | - mov \tmp, #0 | |
85 | - cmp \irqnr, #29 | |
86 | - moveq \tmp, #1 | |
87 | - streq \irqstat, [\base, #GIC_CPU_EOI] | |
88 | - cmp \tmp, #0 | |
89 | 25 | .endm |
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-versatile/core.c
arch/arm/mach-vexpress/core.h
arch/arm/mach-vexpress/ct-ca9x4.c
... | ... | @@ -21,7 +21,7 @@ |
21 | 21 | #include <mach/clkdev.h> |
22 | 22 | #include <mach/ct-ca9x4.h> |
23 | 23 | |
24 | -#include <plat/timer-sp.h> | |
24 | +#include <asm/hardware/timer-sp.h> | |
25 | 25 | |
26 | 26 | #include <asm/mach/arch.h> |
27 | 27 | #include <asm/mach/map.h> |
28 | 28 | |
... | ... | @@ -60,13 +60,10 @@ |
60 | 60 | v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); |
61 | 61 | } |
62 | 62 | |
63 | -void __iomem *gic_cpu_base_addr; | |
64 | - | |
65 | 63 | static void __init ct_ca9x4_init_irq(void) |
66 | 64 | { |
67 | - gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU); | |
68 | - gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29); | |
69 | - gic_cpu_init(0, gic_cpu_base_addr); | |
65 | + gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST), | |
66 | + MMIO_P2V(A9_MPCORE_GIC_CPU)); | |
70 | 67 | } |
71 | 68 | |
72 | 69 | #if 0 |
arch/arm/mach-vexpress/include/mach/entry-macro.S
1 | -#include <asm/hardware/gic.h> | |
1 | +#include <asm/hardware/entry-macro-gic.S> | |
2 | 2 | |
3 | 3 | .macro disable_fiq |
4 | 4 | .endm |
5 | 5 | |
6 | - .macro get_irqnr_preamble, base, tmp | |
7 | - ldr \base, =gic_cpu_base_addr | |
8 | - ldr \base, [\base] | |
9 | - .endm | |
10 | - | |
11 | 6 | .macro arch_ret_to_user, tmp1, tmp2 |
12 | - .endm | |
13 | - | |
14 | - /* | |
15 | - * The interrupt numbering scheme is defined in the | |
16 | - * interrupt controller spec. To wit: | |
17 | - * | |
18 | - * Interrupts 0-15 are IPI | |
19 | - * 16-28 are reserved | |
20 | - * 29-31 are local. We allow 30 to be used for the watchdog. | |
21 | - * 32-1020 are global | |
22 | - * 1021-1022 are reserved | |
23 | - * 1023 is "spurious" (no interrupt) | |
24 | - * | |
25 | - * For now, we ignore all local interrupts so only return an interrupt if it's | |
26 | - * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. | |
27 | - * | |
28 | - * A simple read from the controller will tell us the number of the highest | |
29 | - * priority enabled interrupt. We then just need to check whether it is in the | |
30 | - * valid range for an IRQ (30-1020 inclusive). | |
31 | - */ | |
32 | - | |
33 | - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | |
34 | - ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */ | |
35 | - ldr \tmp, =1021 | |
36 | - bic \irqnr, \irqstat, #0x1c00 | |
37 | - cmp \irqnr, #29 | |
38 | - cmpcc \irqnr, \irqnr | |
39 | - cmpne \irqnr, \tmp | |
40 | - cmpcs \irqnr, \irqnr | |
41 | - .endm | |
42 | - | |
43 | - /* We assume that irqstat (the raw value of the IRQ acknowledge | |
44 | - * register) is preserved from the macro above. | |
45 | - * If there is an IPI, we immediately signal end of interrupt on the | |
46 | - * controller, since this requires the original irqstat value which | |
47 | - * we won't easily be able to recreate later. | |
48 | - */ | |
49 | - | |
50 | - .macro test_for_ipi, irqnr, irqstat, base, tmp | |
51 | - bic \irqnr, \irqstat, #0x1c00 | |
52 | - cmp \irqnr, #16 | |
53 | - strcc \irqstat, [\base, #GIC_CPU_EOI] | |
54 | - cmpcs \irqnr, \irqnr | |
55 | - .endm | |
56 | - | |
57 | - /* As above, this assumes that irqstat and base are preserved.. */ | |
58 | - | |
59 | - .macro test_for_ltirq, irqnr, irqstat, base, tmp | |
60 | - bic \irqnr, \irqstat, #0x1c00 | |
61 | - mov \tmp, #0 | |
62 | - cmp \irqnr, #29 | |
63 | - moveq \tmp, #1 | |
64 | - streq \irqstat, [\base, #GIC_CPU_EOI] | |
65 | - cmp \tmp, #0 | |
66 | 7 | .endm |
arch/arm/mach-vexpress/platsmp.c
arch/arm/mach-vexpress/v2m.c
arch/arm/plat-omap/include/plat/io.h
... | ... | @@ -294,8 +294,8 @@ |
294 | 294 | extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, |
295 | 295 | struct omap_sdrc_params *sdrc_cs1); |
296 | 296 | |
297 | -#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t) | |
298 | -#define __arch_iounmap(v) omap_iounmap(v) | |
297 | +#define __arch_ioremap omap_ioremap | |
298 | +#define __arch_iounmap omap_iounmap | |
299 | 299 | |
300 | 300 | void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type); |
301 | 301 | void omap_iounmap(volatile void __iomem *addr); |
arch/arm/plat-versatile/Makefile
arch/arm/plat-versatile/include/plat/timer-sp.h
arch/arm/plat-versatile/timer-sp.c
1 | -/* | |
2 | - * linux/arch/arm/plat-versatile/timer-sp.c | |
3 | - * | |
4 | - * Copyright (C) 1999 - 2003 ARM Limited | |
5 | - * Copyright (C) 2000 Deep Blue Solutions Ltd | |
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 as published by | |
9 | - * the Free Software Foundation; either version 2 of the License, or | |
10 | - * (at your option) any later version. | |
11 | - * | |
12 | - * This program is distributed in the hope that it will be useful, | |
13 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | - * GNU General Public License for more details. | |
16 | - * | |
17 | - * You should have received a copy of the GNU General Public License | |
18 | - * along with this program; if not, write to the Free Software | |
19 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | - */ | |
21 | -#include <linux/clocksource.h> | |
22 | -#include <linux/clockchips.h> | |
23 | -#include <linux/interrupt.h> | |
24 | -#include <linux/irq.h> | |
25 | -#include <linux/io.h> | |
26 | - | |
27 | -#include <asm/hardware/arm_timer.h> | |
28 | - | |
29 | -#include <plat/timer-sp.h> | |
30 | - | |
31 | -/* | |
32 | - * These timers are currently always setup to be clocked at 1MHz. | |
33 | - */ | |
34 | -#define TIMER_FREQ_KHZ (1000) | |
35 | -#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) | |
36 | - | |
37 | -static void __iomem *clksrc_base; | |
38 | - | |
39 | -static cycle_t sp804_read(struct clocksource *cs) | |
40 | -{ | |
41 | - return ~readl(clksrc_base + TIMER_VALUE); | |
42 | -} | |
43 | - | |
44 | -static struct clocksource clocksource_sp804 = { | |
45 | - .name = "timer3", | |
46 | - .rating = 200, | |
47 | - .read = sp804_read, | |
48 | - .mask = CLOCKSOURCE_MASK(32), | |
49 | - .shift = 20, | |
50 | - .flags = CLOCK_SOURCE_IS_CONTINUOUS, | |
51 | -}; | |
52 | - | |
53 | -void __init sp804_clocksource_init(void __iomem *base) | |
54 | -{ | |
55 | - struct clocksource *cs = &clocksource_sp804; | |
56 | - | |
57 | - clksrc_base = base; | |
58 | - | |
59 | - /* setup timer 0 as free-running clocksource */ | |
60 | - writel(0, clksrc_base + TIMER_CTRL); | |
61 | - writel(0xffffffff, clksrc_base + TIMER_LOAD); | |
62 | - writel(0xffffffff, clksrc_base + TIMER_VALUE); | |
63 | - writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, | |
64 | - clksrc_base + TIMER_CTRL); | |
65 | - | |
66 | - cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift); | |
67 | - clocksource_register(cs); | |
68 | -} | |
69 | - | |
70 | - | |
71 | -static void __iomem *clkevt_base; | |
72 | - | |
73 | -/* | |
74 | - * IRQ handler for the timer | |
75 | - */ | |
76 | -static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) | |
77 | -{ | |
78 | - struct clock_event_device *evt = dev_id; | |
79 | - | |
80 | - /* clear the interrupt */ | |
81 | - writel(1, clkevt_base + TIMER_INTCLR); | |
82 | - | |
83 | - evt->event_handler(evt); | |
84 | - | |
85 | - return IRQ_HANDLED; | |
86 | -} | |
87 | - | |
88 | -static void sp804_set_mode(enum clock_event_mode mode, | |
89 | - struct clock_event_device *evt) | |
90 | -{ | |
91 | - unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE; | |
92 | - | |
93 | - writel(ctrl, clkevt_base + TIMER_CTRL); | |
94 | - | |
95 | - switch (mode) { | |
96 | - case CLOCK_EVT_MODE_PERIODIC: | |
97 | - writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD); | |
98 | - ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; | |
99 | - break; | |
100 | - | |
101 | - case CLOCK_EVT_MODE_ONESHOT: | |
102 | - /* period set, and timer enabled in 'next_event' hook */ | |
103 | - ctrl |= TIMER_CTRL_ONESHOT; | |
104 | - break; | |
105 | - | |
106 | - case CLOCK_EVT_MODE_UNUSED: | |
107 | - case CLOCK_EVT_MODE_SHUTDOWN: | |
108 | - default: | |
109 | - break; | |
110 | - } | |
111 | - | |
112 | - writel(ctrl, clkevt_base + TIMER_CTRL); | |
113 | -} | |
114 | - | |
115 | -static int sp804_set_next_event(unsigned long next, | |
116 | - struct clock_event_device *evt) | |
117 | -{ | |
118 | - unsigned long ctrl = readl(clkevt_base + TIMER_CTRL); | |
119 | - | |
120 | - writel(next, clkevt_base + TIMER_LOAD); | |
121 | - writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL); | |
122 | - | |
123 | - return 0; | |
124 | -} | |
125 | - | |
126 | -static struct clock_event_device sp804_clockevent = { | |
127 | - .name = "timer0", | |
128 | - .shift = 32, | |
129 | - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | |
130 | - .set_mode = sp804_set_mode, | |
131 | - .set_next_event = sp804_set_next_event, | |
132 | - .rating = 300, | |
133 | - .cpumask = cpu_all_mask, | |
134 | -}; | |
135 | - | |
136 | -static struct irqaction sp804_timer_irq = { | |
137 | - .name = "timer", | |
138 | - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | |
139 | - .handler = sp804_timer_interrupt, | |
140 | - .dev_id = &sp804_clockevent, | |
141 | -}; | |
142 | - | |
143 | -void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq) | |
144 | -{ | |
145 | - struct clock_event_device *evt = &sp804_clockevent; | |
146 | - | |
147 | - clkevt_base = base; | |
148 | - | |
149 | - evt->irq = timer_irq; | |
150 | - evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift); | |
151 | - evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); | |
152 | - evt->min_delta_ns = clockevent_delta2ns(0xf, evt); | |
153 | - | |
154 | - setup_irq(timer_irq, &sp804_timer_irq); | |
155 | - clockevents_register_device(evt); | |
156 | -} |
drivers/pcmcia/Makefile
... | ... | @@ -50,8 +50,9 @@ |
50 | 50 | sa1100_cs-y += sa1100_generic.o |
51 | 51 | sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o |
52 | 52 | sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o |
53 | -sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o | |
53 | +sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o | |
54 | 54 | sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o |
55 | +sa1100_cs-$(CONFIG_SA1100_NANOENGINE) += sa1100_nanoengine.o | |
55 | 56 | sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o |
56 | 57 | sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o |
57 | 58 |
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1100_generic.h
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | extern int pcmcia_gcplus_init(struct device *); |
14 | 14 | extern int pcmcia_graphicsmaster_init(struct device *); |
15 | 15 | extern int pcmcia_h3600_init(struct device *); |
16 | +extern int pcmcia_nanoengine_init(struct device *); | |
16 | 17 | extern int pcmcia_pangolin_init(struct device *); |
17 | 18 | extern int pcmcia_pfs168_init(struct device *); |
18 | 19 | extern int pcmcia_shannon_init(struct device *); |
drivers/pcmcia/sa1100_nanoengine.c
1 | +/* | |
2 | + * drivers/pcmcia/sa1100_nanoengine.c | |
3 | + * | |
4 | + * PCMCIA implementation routines for BSI nanoEngine. | |
5 | + * | |
6 | + * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine | |
7 | + * board you should carefully read this: | |
8 | + * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/ | |
9 | + * | |
10 | + * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> | |
11 | + * | |
12 | + * Based on original work for kernel 2.4 by | |
13 | + * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br> | |
14 | + * | |
15 | + * This program is free software; you can redistribute it and/or modify | |
16 | + * it under the terms of the GNU General Public License version 2 as | |
17 | + * published by the Free Software Foundation. | |
18 | + * | |
19 | + */ | |
20 | +#include <linux/device.h> | |
21 | +#include <linux/errno.h> | |
22 | +#include <linux/interrupt.h> | |
23 | +#include <linux/irq.h> | |
24 | +#include <linux/init.h> | |
25 | +#include <linux/kernel.h> | |
26 | +#include <linux/module.h> | |
27 | +#include <linux/signal.h> | |
28 | + | |
29 | +#include <asm/mach-types.h> | |
30 | +#include <asm/irq.h> | |
31 | + | |
32 | +#include <mach/hardware.h> | |
33 | +#include <mach/nanoengine.h> | |
34 | + | |
35 | +#include "sa1100_generic.h" | |
36 | + | |
37 | +static struct pcmcia_irqs irqs_skt0[] = { | |
38 | + /* socket, IRQ, name */ | |
39 | + { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" }, | |
40 | +}; | |
41 | + | |
42 | +static struct pcmcia_irqs irqs_skt1[] = { | |
43 | + /* socket, IRQ, name */ | |
44 | + { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" }, | |
45 | +}; | |
46 | + | |
47 | +struct nanoengine_pins { | |
48 | + unsigned input_pins; | |
49 | + unsigned output_pins; | |
50 | + unsigned clear_outputs; | |
51 | + unsigned transition_pins; | |
52 | + unsigned pci_irq; | |
53 | + struct pcmcia_irqs *pcmcia_irqs; | |
54 | + unsigned pcmcia_irqs_size; | |
55 | +}; | |
56 | + | |
57 | +static struct nanoengine_pins nano_skts[] = { | |
58 | + { | |
59 | + .input_pins = GPIO_PC_READY0 | GPIO_PC_CD0, | |
60 | + .output_pins = GPIO_PC_RESET0, | |
61 | + .clear_outputs = GPIO_PC_RESET0, | |
62 | + .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD0, | |
63 | + .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY0, | |
64 | + .pcmcia_irqs = irqs_skt0, | |
65 | + .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt0) | |
66 | + }, { | |
67 | + .input_pins = GPIO_PC_READY1 | GPIO_PC_CD1, | |
68 | + .output_pins = GPIO_PC_RESET1, | |
69 | + .clear_outputs = GPIO_PC_RESET1, | |
70 | + .transition_pins = NANOENGINE_IRQ_GPIO_PC_CD1, | |
71 | + .pci_irq = NANOENGINE_IRQ_GPIO_PC_READY1, | |
72 | + .pcmcia_irqs = irqs_skt1, | |
73 | + .pcmcia_irqs_size = ARRAY_SIZE(irqs_skt1) | |
74 | + } | |
75 | +}; | |
76 | + | |
77 | +unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts); | |
78 | + | |
79 | +static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |
80 | +{ | |
81 | + unsigned i = skt->nr; | |
82 | + | |
83 | + if (i >= num_nano_pcmcia_sockets) | |
84 | + return -ENXIO; | |
85 | + | |
86 | + GPDR &= ~nano_skts[i].input_pins; | |
87 | + GPDR |= nano_skts[i].output_pins; | |
88 | + GPCR = nano_skts[i].clear_outputs; | |
89 | + set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH); | |
90 | + skt->socket.pci_irq = nano_skts[i].pci_irq; | |
91 | + | |
92 | + return soc_pcmcia_request_irqs(skt, | |
93 | + nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | |
94 | +} | |
95 | + | |
96 | +/* | |
97 | + * Release all resources. | |
98 | + */ | |
99 | +static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |
100 | +{ | |
101 | + unsigned i = skt->nr; | |
102 | + | |
103 | + if (i >= num_nano_pcmcia_sockets) | |
104 | + return; | |
105 | + | |
106 | + soc_pcmcia_free_irqs(skt, | |
107 | + nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | |
108 | +} | |
109 | + | |
110 | +static int nanoengine_pcmcia_configure_socket( | |
111 | + struct soc_pcmcia_socket *skt, const socket_state_t *state) | |
112 | +{ | |
113 | + unsigned reset; | |
114 | + unsigned i = skt->nr; | |
115 | + | |
116 | + if (i >= num_nano_pcmcia_sockets) | |
117 | + return -ENXIO; | |
118 | + | |
119 | + switch (i) { | |
120 | + case 0: | |
121 | + reset = GPIO_PC_RESET0; | |
122 | + break; | |
123 | + case 1: | |
124 | + reset = GPIO_PC_RESET1; | |
125 | + break; | |
126 | + default: | |
127 | + return -ENXIO; | |
128 | + } | |
129 | + | |
130 | + if (state->flags & SS_RESET) | |
131 | + GPSR = reset; | |
132 | + else | |
133 | + GPCR = reset; | |
134 | + | |
135 | + return 0; | |
136 | +} | |
137 | + | |
138 | +static void nanoengine_pcmcia_socket_state( | |
139 | + struct soc_pcmcia_socket *skt, struct pcmcia_state *state) | |
140 | +{ | |
141 | + unsigned long levels = GPLR; | |
142 | + unsigned i = skt->nr; | |
143 | + | |
144 | + if (i >= num_nano_pcmcia_sockets) | |
145 | + return; | |
146 | + | |
147 | + memset(state, 0, sizeof(struct pcmcia_state)); | |
148 | + switch (i) { | |
149 | + case 0: | |
150 | + state->ready = (levels & GPIO_PC_READY0) ? 1 : 0; | |
151 | + state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0; | |
152 | + break; | |
153 | + case 1: | |
154 | + state->ready = (levels & GPIO_PC_READY1) ? 1 : 0; | |
155 | + state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0; | |
156 | + break; | |
157 | + default: | |
158 | + return; | |
159 | + } | |
160 | + state->bvd1 = 1; | |
161 | + state->bvd2 = 1; | |
162 | + state->wrprot = 0; /* Not available */ | |
163 | + state->vs_3v = 1; /* Can only apply 3.3V */ | |
164 | + state->vs_Xv = 0; | |
165 | +} | |
166 | + | |
167 | +/* | |
168 | + * Enable card status IRQs on (re-)initialisation. This can | |
169 | + * be called at initialisation, power management event, or | |
170 | + * pcmcia event. | |
171 | + */ | |
172 | +static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt) | |
173 | +{ | |
174 | + unsigned i = skt->nr; | |
175 | + | |
176 | + if (i >= num_nano_pcmcia_sockets) | |
177 | + return; | |
178 | + | |
179 | + soc_pcmcia_enable_irqs(skt, | |
180 | + nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | |
181 | +} | |
182 | + | |
183 | +/* | |
184 | + * Disable card status IRQs on suspend. | |
185 | + */ | |
186 | +static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) | |
187 | +{ | |
188 | + unsigned i = skt->nr; | |
189 | + | |
190 | + if (i >= num_nano_pcmcia_sockets) | |
191 | + return; | |
192 | + | |
193 | + soc_pcmcia_disable_irqs(skt, | |
194 | + nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size); | |
195 | +} | |
196 | + | |
197 | +static struct pcmcia_low_level nanoengine_pcmcia_ops = { | |
198 | + .owner = THIS_MODULE, | |
199 | + | |
200 | + .hw_init = nanoengine_pcmcia_hw_init, | |
201 | + .hw_shutdown = nanoengine_pcmcia_hw_shutdown, | |
202 | + | |
203 | + .configure_socket = nanoengine_pcmcia_configure_socket, | |
204 | + .socket_state = nanoengine_pcmcia_socket_state, | |
205 | + .socket_init = nanoengine_pcmcia_socket_init, | |
206 | + .socket_suspend = nanoengine_pcmcia_socket_suspend, | |
207 | +}; | |
208 | + | |
209 | +int pcmcia_nanoengine_init(struct device *dev) | |
210 | +{ | |
211 | + int ret = -ENODEV; | |
212 | + | |
213 | + if (machine_is_nanoengine()) | |
214 | + ret = sa11xx_drv_pcmcia_probe( | |
215 | + dev, &nanoengine_pcmcia_ops, 0, 2); | |
216 | + | |
217 | + return ret; | |
218 | +} |
drivers/pcmcia/soc_common.c
... | ... | @@ -31,20 +31,20 @@ |
31 | 31 | ======================================================================*/ |
32 | 32 | |
33 | 33 | |
34 | -#include <linux/module.h> | |
35 | -#include <linux/moduleparam.h> | |
34 | +#include <linux/cpufreq.h> | |
36 | 35 | #include <linux/init.h> |
36 | +#include <linux/interrupt.h> | |
37 | +#include <linux/io.h> | |
38 | +#include <linux/irq.h> | |
37 | 39 | #include <linux/kernel.h> |
38 | -#include <linux/timer.h> | |
39 | 40 | #include <linux/mm.h> |
41 | +#include <linux/module.h> | |
42 | +#include <linux/moduleparam.h> | |
40 | 43 | #include <linux/mutex.h> |
41 | -#include <linux/interrupt.h> | |
42 | -#include <linux/irq.h> | |
43 | 44 | #include <linux/spinlock.h> |
44 | -#include <linux/cpufreq.h> | |
45 | +#include <linux/timer.h> | |
45 | 46 | |
46 | 47 | #include <mach/hardware.h> |
47 | -#include <asm/io.h> | |
48 | 48 | #include <asm/system.h> |
49 | 49 | |
50 | 50 | #include "soc_common.h" |
... | ... | @@ -74,7 +74,8 @@ |
74 | 74 | |
75 | 75 | #endif |
76 | 76 | |
77 | -#define to_soc_pcmcia_socket(x) container_of(x, struct soc_pcmcia_socket, socket) | |
77 | +#define to_soc_pcmcia_socket(x) \ | |
78 | + container_of(x, struct soc_pcmcia_socket, socket) | |
78 | 79 | |
79 | 80 | static unsigned short |
80 | 81 | calc_speed(unsigned short *spds, int num, unsigned short dflt) |
81 | 82 | |
... | ... | @@ -91,11 +92,15 @@ |
91 | 92 | return speed; |
92 | 93 | } |
93 | 94 | |
94 | -void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, struct soc_pcmcia_timing *timing) | |
95 | +void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, | |
96 | + struct soc_pcmcia_timing *timing) | |
95 | 97 | { |
96 | - timing->io = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS); | |
97 | - timing->mem = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | |
98 | - timing->attr = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | |
98 | + timing->io = | |
99 | + calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS); | |
100 | + timing->mem = | |
101 | + calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | |
102 | + timing->attr = | |
103 | + calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS); | |
99 | 104 | } |
100 | 105 | EXPORT_SYMBOL(soc_common_pcmcia_get_timing); |
101 | 106 | |
... | ... | @@ -137,8 +142,8 @@ |
137 | 142 | * |
138 | 143 | * Convert PCMCIA socket state to our socket configure structure. |
139 | 144 | */ |
140 | -static int | |
141 | -soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *state) | |
145 | +static int soc_common_pcmcia_config_skt( | |
146 | + struct soc_pcmcia_socket *skt, socket_state_t *state) | |
142 | 147 | { |
143 | 148 | int ret; |
144 | 149 | |
... | ... | @@ -150,7 +155,8 @@ |
150 | 155 | */ |
151 | 156 | if (skt->irq_state != 1 && state->io_irq) { |
152 | 157 | skt->irq_state = 1; |
153 | - set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING); | |
158 | + set_irq_type(skt->socket.pci_irq, | |
159 | + IRQ_TYPE_EDGE_FALLING); | |
154 | 160 | } else if (skt->irq_state == 1 && state->io_irq == 0) { |
155 | 161 | skt->irq_state = 0; |
156 | 162 | set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE); |
157 | 163 | |
... | ... | @@ -304,24 +310,24 @@ |
304 | 310 | * of power configuration, reset, &c. We also record the value of |
305 | 311 | * `state' in order to regurgitate it to the PCMCIA core later. |
306 | 312 | */ |
307 | -static int | |
308 | -soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |
313 | +static int soc_common_pcmcia_set_socket( | |
314 | + struct pcmcia_socket *sock, socket_state_t *state) | |
309 | 315 | { |
310 | 316 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); |
311 | 317 | |
312 | - debug(skt, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n", | |
313 | - (state->csc_mask==0)?"<NONE> ":"", | |
314 | - (state->csc_mask&SS_DETECT)?"DETECT ":"", | |
315 | - (state->csc_mask&SS_READY)?"READY ":"", | |
316 | - (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", | |
317 | - (state->csc_mask&SS_BATWARN)?"BATWARN ":"", | |
318 | - (state->csc_mask&SS_STSCHG)?"STSCHG ":"", | |
319 | - (state->flags==0)?"<NONE> ":"", | |
320 | - (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", | |
321 | - (state->flags&SS_IOCARD)?"IOCARD ":"", | |
322 | - (state->flags&SS_RESET)?"RESET ":"", | |
323 | - (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", | |
324 | - (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"", | |
318 | + debug(skt, 2, "mask: %s%s%s%s%s%s flags: %s%s%s%s%s%s Vcc %d Vpp %d irq %d\n", | |
319 | + (state->csc_mask == 0) ? "<NONE> " : "", | |
320 | + (state->csc_mask & SS_DETECT) ? "DETECT " : "", | |
321 | + (state->csc_mask & SS_READY) ? "READY " : "", | |
322 | + (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "", | |
323 | + (state->csc_mask & SS_BATWARN) ? "BATWARN " : "", | |
324 | + (state->csc_mask & SS_STSCHG) ? "STSCHG " : "", | |
325 | + (state->flags == 0) ? "<NONE> " : "", | |
326 | + (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "", | |
327 | + (state->flags & SS_IOCARD) ? "IOCARD " : "", | |
328 | + (state->flags & SS_RESET) ? "RESET " : "", | |
329 | + (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "", | |
330 | + (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "", | |
325 | 331 | state->Vcc, state->Vpp, state->io_irq); |
326 | 332 | |
327 | 333 | return soc_common_pcmcia_config_skt(skt, state); |
... | ... | @@ -336,8 +342,8 @@ |
336 | 342 | * |
337 | 343 | * Returns: 0 on success, -1 on error |
338 | 344 | */ |
339 | -static int | |
340 | -soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) | |
345 | +static int soc_common_pcmcia_set_io_map( | |
346 | + struct pcmcia_socket *sock, struct pccard_io_map *map) | |
341 | 347 | { |
342 | 348 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); |
343 | 349 | unsigned short speed = map->speed; |
... | ... | @@ -346,14 +352,14 @@ |
346 | 352 | map->map, map->speed, (unsigned long long)map->start, |
347 | 353 | (unsigned long long)map->stop); |
348 | 354 | debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", |
349 | - (map->flags==0)?"<NONE>":"", | |
350 | - (map->flags&MAP_ACTIVE)?"ACTIVE ":"", | |
351 | - (map->flags&MAP_16BIT)?"16BIT ":"", | |
352 | - (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", | |
353 | - (map->flags&MAP_0WS)?"0WS ":"", | |
354 | - (map->flags&MAP_WRPROT)?"WRPROT ":"", | |
355 | - (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"", | |
356 | - (map->flags&MAP_PREFETCH)?"PREFETCH ":""); | |
355 | + (map->flags == 0) ? "<NONE>" : "", | |
356 | + (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", | |
357 | + (map->flags & MAP_16BIT) ? "16BIT " : "", | |
358 | + (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", | |
359 | + (map->flags & MAP_0WS) ? "0WS " : "", | |
360 | + (map->flags & MAP_WRPROT) ? "WRPROT " : "", | |
361 | + (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "", | |
362 | + (map->flags & MAP_PREFETCH) ? "PREFETCH " : ""); | |
357 | 363 | |
358 | 364 | if (map->map >= MAX_IO_WIN) { |
359 | 365 | printk(KERN_ERR "%s(): map (%d) out of range\n", __func__, |
... | ... | @@ -390,8 +396,8 @@ |
390 | 396 | * |
391 | 397 | * Returns: 0 on success, -ERRNO on error |
392 | 398 | */ |
393 | -static int | |
394 | -soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) | |
399 | +static int soc_common_pcmcia_set_mem_map( | |
400 | + struct pcmcia_socket *sock, struct pccard_mem_map *map) | |
395 | 401 | { |
396 | 402 | struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); |
397 | 403 | struct resource *res; |
... | ... | @@ -400,14 +406,14 @@ |
400 | 406 | debug(skt, 2, "map %u speed %u card_start %08x\n", |
401 | 407 | map->map, map->speed, map->card_start); |
402 | 408 | debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n", |
403 | - (map->flags==0)?"<NONE>":"", | |
404 | - (map->flags&MAP_ACTIVE)?"ACTIVE ":"", | |
405 | - (map->flags&MAP_16BIT)?"16BIT ":"", | |
406 | - (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", | |
407 | - (map->flags&MAP_0WS)?"0WS ":"", | |
408 | - (map->flags&MAP_WRPROT)?"WRPROT ":"", | |
409 | - (map->flags&MAP_ATTRIB)?"ATTRIB ":"", | |
410 | - (map->flags&MAP_USE_WAIT)?"USE_WAIT ":""); | |
409 | + (map->flags == 0) ? "<NONE>" : "", | |
410 | + (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", | |
411 | + (map->flags & MAP_16BIT) ? "16BIT " : "", | |
412 | + (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", | |
413 | + (map->flags & MAP_0WS) ? "0WS " : "", | |
414 | + (map->flags & MAP_WRPROT) ? "WRPROT " : "", | |
415 | + (map->flags & MAP_ATTRIB) ? "ATTRIB " : "", | |
416 | + (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : ""); | |
411 | 417 | |
412 | 418 | if (map->map >= MAX_WIN) |
413 | 419 | return -EINVAL; |
... | ... | @@ -462,8 +468,8 @@ |
462 | 468 | { SS_OUTPUT_ENA, "SS_OUTPUT_ENA" }, |
463 | 469 | }; |
464 | 470 | |
465 | -static void | |
466 | -dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, int sz) | |
471 | +static void dump_bits(char **p, const char *prefix, | |
472 | + unsigned int val, struct bittbl *bits, int sz) | |
467 | 473 | { |
468 | 474 | char *b = *p; |
469 | 475 | int i; |
470 | 476 | |
... | ... | @@ -481,13 +487,14 @@ |
481 | 487 | * |
482 | 488 | * Returns: the number of characters added to the buffer |
483 | 489 | */ |
484 | -static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf) | |
490 | +static ssize_t show_status( | |
491 | + struct device *dev, struct device_attribute *attr, char *buf) | |
485 | 492 | { |
486 | 493 | struct soc_pcmcia_socket *skt = |
487 | 494 | container_of(dev, struct soc_pcmcia_socket, socket.dev); |
488 | 495 | char *p = buf; |
489 | 496 | |
490 | - p+=sprintf(p, "slot : %d\n", skt->nr); | |
497 | + p += sprintf(p, "slot : %d\n", skt->nr); | |
491 | 498 | |
492 | 499 | dump_bits(&p, "status", skt->status, |
493 | 500 | status_bits, ARRAY_SIZE(status_bits)); |
494 | 501 | |
... | ... | @@ -496,12 +503,12 @@ |
496 | 503 | dump_bits(&p, "cs_flags", skt->cs_state.flags, |
497 | 504 | conf_bits, ARRAY_SIZE(conf_bits)); |
498 | 505 | |
499 | - p+=sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc); | |
500 | - p+=sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp); | |
501 | - p+=sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, | |
506 | + p += sprintf(p, "Vcc : %d\n", skt->cs_state.Vcc); | |
507 | + p += sprintf(p, "Vpp : %d\n", skt->cs_state.Vpp); | |
508 | + p += sprintf(p, "IRQ : %d (%d)\n", skt->cs_state.io_irq, | |
502 | 509 | skt->socket.pci_irq); |
503 | 510 | if (skt->ops->show_timing) |
504 | - p+=skt->ops->show_timing(skt, p); | |
511 | + p += skt->ops->show_timing(skt, p); | |
505 | 512 | |
506 | 513 | return p-buf; |
507 | 514 | } |
... | ... | @@ -594,7 +601,7 @@ |
594 | 601 | |
595 | 602 | mutex_lock(&soc_pcmcia_sockets_lock); |
596 | 603 | list_for_each_entry(skt, &soc_pcmcia_sockets, node) |
597 | - if ( skt->ops->frequency_change ) | |
604 | + if (skt->ops->frequency_change) | |
598 | 605 | ret += skt->ops->frequency_change(skt, val, freqs); |
599 | 606 | mutex_unlock(&soc_pcmcia_sockets_lock); |
600 | 607 | |
... | ... | @@ -620,7 +627,8 @@ |
620 | 627 | |
621 | 628 | static void soc_pcmcia_cpufreq_unregister(void) |
622 | 629 | { |
623 | - cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); | |
630 | + cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, | |
631 | + CPUFREQ_TRANSITION_NOTIFIER); | |
624 | 632 | } |
625 | 633 | module_exit(soc_pcmcia_cpufreq_unregister); |
626 | 634 |
drivers/rtc/rtc-sa1100.c
... | ... | @@ -39,10 +39,10 @@ |
39 | 39 | #include <mach/regs-ost.h> |
40 | 40 | #endif |
41 | 41 | |
42 | -#define RTC_DEF_DIVIDER 32768 - 1 | |
42 | +#define RTC_DEF_DIVIDER (32768 - 1) | |
43 | 43 | #define RTC_DEF_TRIM 0 |
44 | 44 | |
45 | -static unsigned long rtc_freq = 1024; | |
45 | +static const unsigned long RTC_FREQ = 1024; | |
46 | 46 | static unsigned long timer_freq; |
47 | 47 | static struct rtc_time rtc_alarm; |
48 | 48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
... | ... | @@ -61,7 +61,8 @@ |
61 | 61 | * Calculate the next alarm time given the requested alarm time mask |
62 | 62 | * and the current time. |
63 | 63 | */ |
64 | -static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) | |
64 | +static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, | |
65 | + struct rtc_time *alrm) | |
65 | 66 | { |
66 | 67 | unsigned long next_time; |
67 | 68 | unsigned long now_time; |
... | ... | @@ -116,7 +117,23 @@ |
116 | 117 | rtsr = RTSR; |
117 | 118 | /* clear interrupt sources */ |
118 | 119 | RTSR = 0; |
119 | - RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | |
120 | + /* Fix for a nasty initialization problem the in SA11xx RTSR register. | |
121 | + * See also the comments in sa1100_rtc_probe(). */ | |
122 | + if (rtsr & (RTSR_ALE | RTSR_HZE)) { | |
123 | + /* This is the original code, before there was the if test | |
124 | + * above. This code does not clear interrupts that were not | |
125 | + * enabled. */ | |
126 | + RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | |
127 | + } else { | |
128 | + /* For some reason, it is possible to enter this routine | |
129 | + * without interruptions enabled, it has been tested with | |
130 | + * several units (Bug in SA11xx chip?). | |
131 | + * | |
132 | + * This situation leads to an infinite "loop" of interrupt | |
133 | + * routine calling and as a result the processor seems to | |
134 | + * lock on its first call to open(). */ | |
135 | + RTSR = RTSR_AL | RTSR_HZ; | |
136 | + } | |
120 | 137 | |
121 | 138 | /* clear alarm interrupt if it has occurred */ |
122 | 139 | if (rtsr & RTSR_AL) |
123 | 140 | |
... | ... | @@ -139,8 +156,58 @@ |
139 | 156 | return IRQ_HANDLED; |
140 | 157 | } |
141 | 158 | |
159 | +static int sa1100_irq_set_freq(struct device *dev, int freq) | |
160 | +{ | |
161 | + if (freq < 1 || freq > timer_freq) { | |
162 | + return -EINVAL; | |
163 | + } else { | |
164 | + struct rtc_device *rtc = (struct rtc_device *)dev; | |
165 | + | |
166 | + rtc->irq_freq = freq; | |
167 | + | |
168 | + return 0; | |
169 | + } | |
170 | +} | |
171 | + | |
142 | 172 | static int rtc_timer1_count; |
143 | 173 | |
174 | +static int sa1100_irq_set_state(struct device *dev, int enabled) | |
175 | +{ | |
176 | + spin_lock_irq(&sa1100_rtc_lock); | |
177 | + if (enabled) { | |
178 | + struct rtc_device *rtc = (struct rtc_device *)dev; | |
179 | + | |
180 | + OSMR1 = timer_freq / rtc->irq_freq + OSCR; | |
181 | + OIER |= OIER_E1; | |
182 | + rtc_timer1_count = 1; | |
183 | + } else { | |
184 | + OIER &= ~OIER_E1; | |
185 | + } | |
186 | + spin_unlock_irq(&sa1100_rtc_lock); | |
187 | + | |
188 | + return 0; | |
189 | +} | |
190 | + | |
191 | +static inline int sa1100_timer1_retrigger(struct rtc_device *rtc) | |
192 | +{ | |
193 | + unsigned long diff; | |
194 | + unsigned long period = timer_freq / rtc->irq_freq; | |
195 | + | |
196 | + spin_lock_irq(&sa1100_rtc_lock); | |
197 | + | |
198 | + do { | |
199 | + OSMR1 += period; | |
200 | + diff = OSMR1 - OSCR; | |
201 | + /* If OSCR > OSMR1, diff is a very large number (unsigned | |
202 | + * math). This means we have a lost interrupt. */ | |
203 | + } while (diff > period); | |
204 | + OIER |= OIER_E1; | |
205 | + | |
206 | + spin_unlock_irq(&sa1100_rtc_lock); | |
207 | + | |
208 | + return 0; | |
209 | +} | |
210 | + | |
144 | 211 | static irqreturn_t timer1_interrupt(int irq, void *dev_id) |
145 | 212 | { |
146 | 213 | struct platform_device *pdev = to_platform_device(dev_id); |
147 | 214 | |
148 | 215 | |
149 | 216 | |
... | ... | @@ -158,16 +225,22 @@ |
158 | 225 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); |
159 | 226 | |
160 | 227 | if (rtc_timer1_count == 1) |
161 | - rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); | |
228 | + rtc_timer1_count = | |
229 | + (rtc->irq_freq * ((1 << 30) / (timer_freq >> 2))); | |
162 | 230 | |
231 | + /* retrigger. */ | |
232 | + sa1100_timer1_retrigger(rtc); | |
233 | + | |
163 | 234 | return IRQ_HANDLED; |
164 | 235 | } |
165 | 236 | |
166 | 237 | static int sa1100_rtc_read_callback(struct device *dev, int data) |
167 | 238 | { |
168 | 239 | if (data & RTC_PF) { |
240 | + struct rtc_device *rtc = (struct rtc_device *)dev; | |
241 | + | |
169 | 242 | /* interpolate missed periods and set match for the next */ |
170 | - unsigned long period = timer_freq / rtc_freq; | |
243 | + unsigned long period = timer_freq / rtc->irq_freq; | |
171 | 244 | unsigned long oscr = OSCR; |
172 | 245 | unsigned long osmr1 = OSMR1; |
173 | 246 | unsigned long missed = (oscr - osmr1)/period; |
... | ... | @@ -178,7 +251,7 @@ |
178 | 251 | * Here we compare (match - OSCR) 8 instead of 0 -- |
179 | 252 | * see comment in pxa_timer_interrupt() for explanation. |
180 | 253 | */ |
181 | - while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { | |
254 | + while ((signed long)((osmr1 = OSMR1) - OSCR) <= 8) { | |
182 | 255 | data += 0x100; |
183 | 256 | OSSR = OSSR_M1; /* clear match on timer 1 */ |
184 | 257 | OSMR1 = osmr1 + period; |
185 | 258 | |
186 | 259 | |
187 | 260 | |
188 | 261 | |
... | ... | @@ -190,25 +263,29 @@ |
190 | 263 | static int sa1100_rtc_open(struct device *dev) |
191 | 264 | { |
192 | 265 | int ret; |
266 | + struct rtc_device *rtc = (struct rtc_device *)dev; | |
193 | 267 | |
194 | 268 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, |
195 | - "rtc 1Hz", dev); | |
269 | + "rtc 1Hz", dev); | |
196 | 270 | if (ret) { |
197 | 271 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
198 | 272 | goto fail_ui; |
199 | 273 | } |
200 | 274 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, |
201 | - "rtc Alrm", dev); | |
275 | + "rtc Alrm", dev); | |
202 | 276 | if (ret) { |
203 | 277 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
204 | 278 | goto fail_ai; |
205 | 279 | } |
206 | 280 | ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED, |
207 | - "rtc timer", dev); | |
281 | + "rtc timer", dev); | |
208 | 282 | if (ret) { |
209 | 283 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); |
210 | 284 | goto fail_pi; |
211 | 285 | } |
286 | + rtc->max_user_freq = RTC_FREQ; | |
287 | + sa1100_irq_set_freq(dev, RTC_FREQ); | |
288 | + | |
212 | 289 | return 0; |
213 | 290 | |
214 | 291 | fail_pi: |
... | ... | @@ -236,7 +313,7 @@ |
236 | 313 | static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, |
237 | 314 | unsigned long arg) |
238 | 315 | { |
239 | - switch(cmd) { | |
316 | + switch (cmd) { | |
240 | 317 | case RTC_AIE_OFF: |
241 | 318 | spin_lock_irq(&sa1100_rtc_lock); |
242 | 319 | RTSR &= ~RTSR_ALE; |
... | ... | @@ -257,25 +334,6 @@ |
257 | 334 | RTSR |= RTSR_HZE; |
258 | 335 | spin_unlock_irq(&sa1100_rtc_lock); |
259 | 336 | return 0; |
260 | - case RTC_PIE_OFF: | |
261 | - spin_lock_irq(&sa1100_rtc_lock); | |
262 | - OIER &= ~OIER_E1; | |
263 | - spin_unlock_irq(&sa1100_rtc_lock); | |
264 | - return 0; | |
265 | - case RTC_PIE_ON: | |
266 | - spin_lock_irq(&sa1100_rtc_lock); | |
267 | - OSMR1 = timer_freq / rtc_freq + OSCR; | |
268 | - OIER |= OIER_E1; | |
269 | - rtc_timer1_count = 1; | |
270 | - spin_unlock_irq(&sa1100_rtc_lock); | |
271 | - return 0; | |
272 | - case RTC_IRQP_READ: | |
273 | - return put_user(rtc_freq, (unsigned long *)arg); | |
274 | - case RTC_IRQP_SET: | |
275 | - if (arg < 1 || arg > timer_freq) | |
276 | - return -EINVAL; | |
277 | - rtc_freq = arg; | |
278 | - return 0; | |
279 | 337 | } |
280 | 338 | return -ENOIOCTLCMD; |
281 | 339 | } |
282 | 340 | |
... | ... | @@ -327,12 +385,15 @@ |
327 | 385 | |
328 | 386 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
329 | 387 | { |
388 | + struct rtc_device *rtc = (struct rtc_device *)dev; | |
389 | + | |
330 | 390 | seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR); |
331 | 391 | seq_printf(seq, "update_IRQ\t: %s\n", |
332 | 392 | (RTSR & RTSR_HZE) ? "yes" : "no"); |
333 | 393 | seq_printf(seq, "periodic_IRQ\t: %s\n", |
334 | 394 | (OIER & OIER_E1) ? "yes" : "no"); |
335 | - seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); | |
395 | + seq_printf(seq, "periodic_freq\t: %d\n", rtc->irq_freq); | |
396 | + seq_printf(seq, "RTSR\t\t: 0x%08x\n", (u32)RTSR); | |
336 | 397 | |
337 | 398 | return 0; |
338 | 399 | } |
... | ... | @@ -347,6 +408,8 @@ |
347 | 408 | .read_alarm = sa1100_rtc_read_alarm, |
348 | 409 | .set_alarm = sa1100_rtc_set_alarm, |
349 | 410 | .proc = sa1100_rtc_proc, |
411 | + .irq_set_freq = sa1100_irq_set_freq, | |
412 | + .irq_set_state = sa1100_irq_set_state, | |
350 | 413 | }; |
351 | 414 | |
352 | 415 | static int sa1100_rtc_probe(struct platform_device *pdev) |
... | ... | @@ -364,7 +427,8 @@ |
364 | 427 | */ |
365 | 428 | if (RTTR == 0) { |
366 | 429 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
367 | - dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); | |
430 | + dev_warn(&pdev->dev, "warning: " | |
431 | + "initializing default clock divider/trim value\n"); | |
368 | 432 | /* The current RTC value probably doesn't make sense either */ |
369 | 433 | RCNR = 0; |
370 | 434 | } |
371 | 435 | |
... | ... | @@ -372,13 +436,42 @@ |
372 | 436 | device_init_wakeup(&pdev->dev, 1); |
373 | 437 | |
374 | 438 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
375 | - THIS_MODULE); | |
439 | + THIS_MODULE); | |
376 | 440 | |
377 | 441 | if (IS_ERR(rtc)) |
378 | 442 | return PTR_ERR(rtc); |
379 | 443 | |
380 | 444 | platform_set_drvdata(pdev, rtc); |
381 | 445 | |
446 | + /* Set the irq_freq */ | |
447 | + /*TODO: Find out who is messing with this value after we initialize | |
448 | + * it here.*/ | |
449 | + rtc->irq_freq = RTC_FREQ; | |
450 | + | |
451 | + /* Fix for a nasty initialization problem the in SA11xx RTSR register. | |
452 | + * See also the comments in sa1100_rtc_interrupt(). | |
453 | + * | |
454 | + * Sometimes bit 1 of the RTSR (RTSR_HZ) will wake up 1, which means an | |
455 | + * interrupt pending, even though interrupts were never enabled. | |
456 | + * In this case, this bit it must be reset before enabling | |
457 | + * interruptions to avoid a nonexistent interrupt to occur. | |
458 | + * | |
459 | + * In principle, the same problem would apply to bit 0, although it has | |
460 | + * never been observed to happen. | |
461 | + * | |
462 | + * This issue is addressed both here and in sa1100_rtc_interrupt(). | |
463 | + * If the issue is not addressed here, in the times when the processor | |
464 | + * wakes up with the bit set there will be one spurious interrupt. | |
465 | + * | |
466 | + * The issue is also dealt with in sa1100_rtc_interrupt() to be on the | |
467 | + * safe side, once the condition that lead to this strange | |
468 | + * initialization is unknown and could in principle happen during | |
469 | + * normal processing. | |
470 | + * | |
471 | + * Notice that clearing bit 1 and 0 is accomplished by writting ONES to | |
472 | + * the corresponding bits in RTSR. */ | |
473 | + RTSR = RTSR_AL | RTSR_HZ; | |
474 | + | |
382 | 475 | return 0; |
383 | 476 | } |
384 | 477 | |
... | ... | @@ -386,7 +479,7 @@ |
386 | 479 | { |
387 | 480 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
388 | 481 | |
389 | - if (rtc) | |
482 | + if (rtc) | |
390 | 483 | rtc_device_unregister(rtc); |
391 | 484 | |
392 | 485 | return 0; |
fs/proc/vmcore.c
... | ... | @@ -499,7 +499,7 @@ |
499 | 499 | /* Do some basic Verification. */ |
500 | 500 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || |
501 | 501 | (ehdr.e_type != ET_CORE) || |
502 | - !vmcore_elf_check_arch(&ehdr) || | |
502 | + !vmcore_elf64_check_arch(&ehdr) || | |
503 | 503 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || |
504 | 504 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || |
505 | 505 | ehdr.e_version != EV_CURRENT || |
include/linux/crash_dump.h
... | ... | @@ -20,7 +20,14 @@ |
20 | 20 | #define vmcore_elf_check_arch_cross(x) 0 |
21 | 21 | #endif |
22 | 22 | |
23 | -#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x)) | |
23 | +/* | |
24 | + * Architecture code can redefine this if there are any special checks | |
25 | + * needed for 64-bit ELF vmcores. In case of 32-bit only architecture, | |
26 | + * this can be set to zero. | |
27 | + */ | |
28 | +#ifndef vmcore_elf64_check_arch | |
29 | +#define vmcore_elf64_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x)) | |
30 | +#endif | |
24 | 31 | |
25 | 32 | /* |
26 | 33 | * is_kdump_kernel() checks whether this kernel is booting after a panic of |
scripts/recordmcount.c
... | ... | @@ -38,6 +38,7 @@ |
38 | 38 | static char gpfx; /* prefix for global symbol name (sometimes '_') */ |
39 | 39 | static struct stat sb; /* Remember .st_size, etc. */ |
40 | 40 | static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ |
41 | +static const char *altmcount; /* alternate mcount symbol name */ | |
41 | 42 | |
42 | 43 | /* setjmp() return values */ |
43 | 44 | enum { |
... | ... | @@ -299,7 +300,9 @@ |
299 | 300 | fail_file(); |
300 | 301 | } break; |
301 | 302 | case EM_386: reltype = R_386_32; break; |
302 | - case EM_ARM: reltype = R_ARM_ABS32; break; | |
303 | + case EM_ARM: reltype = R_ARM_ABS32; | |
304 | + altmcount = "__gnu_mcount_nc"; | |
305 | + break; | |
303 | 306 | case EM_IA_64: reltype = R_IA64_IMM64; gpfx = '_'; break; |
304 | 307 | case EM_MIPS: /* reltype: e_class */ gpfx = '_'; break; |
305 | 308 | case EM_PPC: reltype = R_PPC_ADDR32; gpfx = '_'; break; |
... | ... | @@ -357,7 +360,7 @@ |
357 | 360 | int |
358 | 361 | main(int argc, char const *argv[]) |
359 | 362 | { |
360 | - const char ftrace[] = "kernel/trace/ftrace.o"; | |
363 | + const char ftrace[] = "/ftrace.o"; | |
361 | 364 | int ftrace_size = sizeof(ftrace) - 1; |
362 | 365 | int n_error = 0; /* gcc-4.3.0 false positive complaint */ |
363 | 366 |
scripts/recordmcount.h
... | ... | @@ -275,11 +275,12 @@ |
275 | 275 | Elf_Sym const *const symp = |
276 | 276 | &sym0[Elf_r_sym(relp)]; |
277 | 277 | char const *symname = &str0[w(symp->st_name)]; |
278 | + char const *mcount = '_' == gpfx ? "_mcount" : "mcount"; | |
278 | 279 | |
279 | 280 | if ('.' == symname[0]) |
280 | 281 | ++symname; /* ppc64 hack */ |
281 | - if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"), | |
282 | - symname)) | |
282 | + if (0 == strcmp(mcount, symname) || | |
283 | + (altmcount && 0 == strcmp(altmcount, symname))) | |
283 | 284 | mcountsym = Elf_r_sym(relp); |
284 | 285 | } |
285 | 286 |