summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 14:23:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-01-05 14:23:17 -0500
commit1205b62390eed4e747232d183fbf412a5aecacd9 (patch)
tree7fde1a5aaee01a23e6ea4137329f332d5e179adf
parent9ee3b3f4a5eb523ef27675ac2fcd2269b9d68767 (diff)
parent6de92920a717ea2b7b45bb3d651b8bb951eab185 (diff)
Merge tag 'for-4.21' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King: "Included in this update: - Florian Fainelli noticed that userspace segfaults caused by the lack of kernel-userspace helpers was hard to diagnose; we now issue a warning when userspace tries to use the helpers but the kernel has them disabled. - Ben Dooks wants compatibility for the old ATAG serial number with DT systems. - Some cleanup of assembly by Nicolas Pitre. - User accessors optimisation from Vincent Whitchurch. - More robust kdump on SMP systems from Yufen Wang. - Sebastian Andrzej Siewior noticed problems with the SMP "boot_lock" on RT kernels, and so we convert the Versatile series of platforms to use a raw spinlock instead, consolidating the Versatile implementation. We entirely remove the boot_lock on OMAP systems, where it's unnecessary. Further patches for other systems will be submitted for the following merge window. - Start switching old StrongARM-11x0 systems to use gpiolib rather than their private GPIO implementation - mostly PCMCIA bits. - ARM Kconfig cleanups. - Cleanup a mostly harmless mistake in the recent Spectre patch in 4.20 (which had the effect that data that can be placed into the init sections was incorrectly always placed in the rodata section)" * tag 'for-4.21' of git://git.armlinux.org.uk/~rmk/linux-arm: (25 commits) ARM: omap2: remove unnecessary boot_lock ARM: versatile: rename and comment SMP implementation ARM: versatile: convert boot_lock to raw ARM: vexpress/realview: consolidate immitation CPU hotplug ARM: fix the cockup in the previous patch ARM: sa1100/cerf: switch to using gpio_led_register_device() ARM: sa1100/assabet: switch to using gpio leds ARM: sa1100/assabet: add gpio keys support for right-hand two buttons ARM: sa1111: remove legacy GPIO interfaces pcmcia: sa1100*: remove redundant bvd1/bvd2 setting ARM: pxa/lubbock: switch PCMCIA to MAX1600 library ARM: pxa/mainstone: switch PCMCIA to MAX1600 library and gpiod APIs ARM: sa1100/neponset: switch PCMCIA to MAX1600 library and gpiod APIs ARM: sa1100/jornada720: switch PCMCIA to gpiod APIs pcmcia: add MAX1600 library ARM: sa1100: explicitly register sa11x0-pcmcia devices ARM: 8813/1: Make aligned 2-byte getuser()/putuser() atomic on ARMv6+ ARM: 8812/1: Optimise copy_{from/to}_user for !CPU_USE_DOMAINS ARM: 8811/1: always list both ldrd/strd registers explicitly ARM: 8808/1: kexec:offline panic_smp_self_stop CPU ...
-rw-r--r--arch/arm/Kconfig25
-rw-r--r--arch/arm/boot/compressed/atags_to_fdt.c23
-rw-r--r--arch/arm/common/sa1111.c59
-rw-r--r--arch/arm/include/asm/assembler.h6
-rw-r--r--arch/arm/include/asm/hardware/sa1111.h4
-rw-r--r--arch/arm/include/asm/uaccess.h18
-rw-r--r--arch/arm/kernel/head.S2
-rw-r--r--arch/arm/kernel/smp.c15
-rw-r--r--arch/arm/lib/copy_from_user.S23
-rw-r--r--arch/arm/lib/copy_to_user.S27
-rw-r--r--arch/arm/lib/getuser.S11
-rw-r--r--arch/arm/lib/putuser.S20
-rw-r--r--arch/arm/mach-omap2/Kconfig1
-rw-r--r--arch/arm/mach-omap2/omap-smp.c20
-rw-r--r--arch/arm/mach-pxa/Kconfig2
-rw-r--r--arch/arm/mach-pxa/include/mach/mainstone.h4
-rw-r--r--arch/arm/mach-pxa/lubbock.c16
-rw-r--r--arch/arm/mach-pxa/mainstone.c53
-rw-r--r--arch/arm/mach-realview/Makefile1
-rw-r--r--arch/arm/mach-realview/hotplug.c111
-rw-r--r--arch/arm/mach-realview/hotplug.h1
-rw-r--r--arch/arm/mach-realview/platsmp-dt.c8
-rw-r--r--arch/arm/mach-sa1100/Kconfig2
-rw-r--r--arch/arm/mach-sa1100/assabet.c143
-rw-r--r--arch/arm/mach-sa1100/cerf.c11
-rw-r--r--arch/arm/mach-sa1100/generic.c10
-rw-r--r--arch/arm/mach-sa1100/h3100.c1
-rw-r--r--arch/arm/mach-sa1100/jornada720.c12
-rw-r--r--arch/arm/mach-sa1100/neponset.c19
-rw-r--r--arch/arm/mach-vexpress/Makefile1
-rw-r--r--arch/arm/mach-vexpress/core.h2
-rw-r--r--arch/arm/mach-vexpress/platsmp.c7
-rw-r--r--arch/arm/mm/copypage-fa.c35
-rw-r--r--arch/arm/mm/copypage-feroceon.c98
-rw-r--r--arch/arm/mm/copypage-v4mc.c19
-rw-r--r--arch/arm/mm/copypage-v4wb.c41
-rw-r--r--arch/arm/mm/copypage-v4wt.c37
-rw-r--r--arch/arm/mm/copypage-xsc3.c79
-rw-r--r--arch/arm/mm/copypage-xscale.c79
-rw-r--r--arch/arm/mm/fault.c6
-rw-r--r--arch/arm/mm/proc-macros.S4
-rw-r--r--arch/arm/mm/pv-fixup-asm.S16
-rw-r--r--arch/arm/plat-omap/Kconfig1
-rw-r--r--arch/arm/plat-versatile/Makefile1
-rw-r--r--arch/arm/plat-versatile/headsmp.S2
-rw-r--r--arch/arm/plat-versatile/hotplug.c (renamed from arch/arm/mach-vexpress/hotplug.c)47
-rw-r--r--arch/arm/plat-versatile/include/plat/platsmp.h2
-rw-r--r--arch/arm/plat-versatile/platsmp.c47
-rw-r--r--drivers/pcmcia/Kconfig6
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/max1600.c122
-rw-r--r--drivers/pcmcia/max1600.h32
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c113
-rw-r--r--drivers/pcmcia/sa1100_simpad.c4
-rw-r--r--drivers/pcmcia/sa1111_jornada720.c83
-rw-r--r--drivers/pcmcia/sa1111_lubbock.c110
-rw-r--r--drivers/pcmcia/sa1111_neponset.c79
57 files changed, 869 insertions, 853 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a3f436ba554d..c1227757817b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -28,14 +28,14 @@ config ARM
28 select ARCH_WANT_IPC_PARSE_VERSION 28 select ARCH_WANT_IPC_PARSE_VERSION
29 select BUILDTIME_EXTABLE_SORT if MMU 29 select BUILDTIME_EXTABLE_SORT if MMU
30 select CLONE_BACKWARDS 30 select CLONE_BACKWARDS
31 select CPU_PM if (SUSPEND || CPU_IDLE) 31 select CPU_PM if SUSPEND || CPU_IDLE
32 select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS 32 select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS
33 select DMA_REMAP if MMU 33 select DMA_REMAP if MMU
34 select EDAC_SUPPORT 34 select EDAC_SUPPORT
35 select EDAC_ATOMIC_SCRUB 35 select EDAC_ATOMIC_SCRUB
36 select GENERIC_ALLOCATOR 36 select GENERIC_ALLOCATOR
37 select GENERIC_ARCH_TOPOLOGY if ARM_CPU_TOPOLOGY 37 select GENERIC_ARCH_TOPOLOGY if ARM_CPU_TOPOLOGY
38 select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) 38 select GENERIC_ATOMIC64 if CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI
39 select GENERIC_CLOCKEVENTS_BROADCAST if SMP 39 select GENERIC_CLOCKEVENTS_BROADCAST if SMP
40 select GENERIC_CPU_AUTOPROBE 40 select GENERIC_CPU_AUTOPROBE
41 select GENERIC_EARLY_IOREMAP 41 select GENERIC_EARLY_IOREMAP
@@ -50,12 +50,12 @@ config ARM
50 select GENERIC_STRNLEN_USER 50 select GENERIC_STRNLEN_USER
51 select HANDLE_DOMAIN_IRQ 51 select HANDLE_DOMAIN_IRQ
52 select HARDIRQS_SW_RESEND 52 select HARDIRQS_SW_RESEND
53 select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) 53 select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
54 select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 54 select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
55 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU 55 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
56 select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU 56 select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
57 select HAVE_ARCH_MMAP_RND_BITS if MMU 57 select HAVE_ARCH_MMAP_RND_BITS if MMU
58 select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) 58 select HAVE_ARCH_SECCOMP_FILTER if AEABI && !OABI_COMPAT
59 select HAVE_ARCH_THREAD_STRUCT_WHITELIST 59 select HAVE_ARCH_THREAD_STRUCT_WHITELIST
60 select HAVE_ARCH_TRACEHOOK 60 select HAVE_ARCH_TRACEHOOK
61 select HAVE_ARM_SMCCC if CPU_V7 61 select HAVE_ARM_SMCCC if CPU_V7
@@ -64,16 +64,16 @@ config ARM
64 select HAVE_C_RECORDMCOUNT 64 select HAVE_C_RECORDMCOUNT
65 select HAVE_DEBUG_KMEMLEAK 65 select HAVE_DEBUG_KMEMLEAK
66 select HAVE_DMA_CONTIGUOUS if MMU 66 select HAVE_DMA_CONTIGUOUS if MMU
67 select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU 67 select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
68 select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE 68 select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
69 select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU 69 select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU
70 select HAVE_EXIT_THREAD 70 select HAVE_EXIT_THREAD
71 select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) 71 select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
72 select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) 72 select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL
73 select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) 73 select HAVE_FUNCTION_TRACER if !XIP_KERNEL
74 select HAVE_GCC_PLUGINS 74 select HAVE_GCC_PLUGINS
75 select HAVE_GENERIC_DMA_COHERENT 75 select HAVE_GENERIC_DMA_COHERENT
76 select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) 76 select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
77 select HAVE_IDE if PCI || ISA || PCMCIA 77 select HAVE_IDE if PCI || ISA || PCMCIA
78 select HAVE_IRQ_TIME_ACCOUNTING 78 select HAVE_IRQ_TIME_ACCOUNTING
79 select HAVE_KERNEL_GZIP 79 select HAVE_KERNEL_GZIP
@@ -82,15 +82,15 @@ config ARM
82 select HAVE_KERNEL_LZO 82 select HAVE_KERNEL_LZO
83 select HAVE_KERNEL_XZ 83 select HAVE_KERNEL_XZ
84 select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M 84 select HAVE_KPROBES if !XIP_KERNEL && !CPU_ENDIAN_BE32 && !CPU_V7M
85 select HAVE_KRETPROBES if (HAVE_KPROBES) 85 select HAVE_KRETPROBES if HAVE_KPROBES
86 select HAVE_MOD_ARCH_SPECIFIC 86 select HAVE_MOD_ARCH_SPECIFIC
87 select HAVE_NMI 87 select HAVE_NMI
88 select HAVE_OPROFILE if (HAVE_PERF_EVENTS) 88 select HAVE_OPROFILE if HAVE_PERF_EVENTS
89 select HAVE_OPTPROBES if !THUMB2_KERNEL 89 select HAVE_OPTPROBES if !THUMB2_KERNEL
90 select HAVE_PERF_EVENTS 90 select HAVE_PERF_EVENTS
91 select HAVE_PERF_REGS 91 select HAVE_PERF_REGS
92 select HAVE_PERF_USER_STACK_DUMP 92 select HAVE_PERF_USER_STACK_DUMP
93 select HAVE_RCU_TABLE_FREE if (SMP && ARM_LPAE) 93 select HAVE_RCU_TABLE_FREE if SMP && ARM_LPAE
94 select HAVE_REGS_AND_STACK_ACCESS_API 94 select HAVE_REGS_AND_STACK_ACCESS_API
95 select HAVE_RSEQ 95 select HAVE_RSEQ
96 select HAVE_STACKPROTECTOR 96 select HAVE_STACKPROTECTOR
@@ -1738,7 +1738,6 @@ config PARAVIRT
1738config PARAVIRT_TIME_ACCOUNTING 1738config PARAVIRT_TIME_ACCOUNTING
1739 bool "Paravirtual steal time accounting" 1739 bool "Paravirtual steal time accounting"
1740 select PARAVIRT 1740 select PARAVIRT
1741 default n
1742 help 1741 help
1743 Select this option to enable fine granularity task steal time 1742 Select this option to enable fine granularity task steal time
1744 accounting. Time spent executing other tasks in parallel with 1743 accounting. Time spent executing other tasks in parallel with
diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c
index 41fa7316c52b..330cd3c2eae5 100644
--- a/arch/arm/boot/compressed/atags_to_fdt.c
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -98,6 +98,24 @@ static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
98 setprop_string(fdt, "/chosen", "bootargs", cmdline); 98 setprop_string(fdt, "/chosen", "bootargs", cmdline);
99} 99}
100 100
101static void hex_str(char *out, uint32_t value)
102{
103 uint32_t digit;
104 int idx;
105
106 for (idx = 7; idx >= 0; idx--) {
107 digit = value >> 28;
108 value <<= 4;
109 digit &= 0xf;
110 if (digit < 10)
111 digit += '0';
112 else
113 digit += 'A'-10;
114 *out++ = digit;
115 }
116 *out = '\0';
117}
118
101/* 119/*
102 * Convert and fold provided ATAGs into the provided FDT. 120 * Convert and fold provided ATAGs into the provided FDT.
103 * 121 *
@@ -180,6 +198,11 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
180 initrd_start); 198 initrd_start);
181 setprop_cell(fdt, "/chosen", "linux,initrd-end", 199 setprop_cell(fdt, "/chosen", "linux,initrd-end",
182 initrd_start + initrd_size); 200 initrd_start + initrd_size);
201 } else if (atag->hdr.tag == ATAG_SERIAL) {
202 char serno[16+2];
203 hex_str(serno, atag->u.serialnr.high);
204 hex_str(serno+8, atag->u.serialnr.low);
205 setprop_string(fdt, "/", "serial-number", serno);
183 } 206 }
184 } 207 }
185 208
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a2c878769eaf..45412d21aa6b 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1282,65 +1282,6 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
1282} 1282}
1283EXPORT_SYMBOL(sa1111_get_audio_rate); 1283EXPORT_SYMBOL(sa1111_get_audio_rate);
1284 1284
1285void sa1111_set_io_dir(struct sa1111_dev *sadev,
1286 unsigned int bits, unsigned int dir,
1287 unsigned int sleep_dir)
1288{
1289 struct sa1111 *sachip = sa1111_chip_driver(sadev);
1290 unsigned long flags;
1291 unsigned int val;
1292 void __iomem *gpio = sachip->base + SA1111_GPIO;
1293
1294#define MODIFY_BITS(port, mask, dir) \
1295 if (mask) { \
1296 val = readl_relaxed(port); \
1297 val &= ~(mask); \
1298 val |= (dir) & (mask); \
1299 writel_relaxed(val, port); \
1300 }
1301
1302 spin_lock_irqsave(&sachip->lock, flags);
1303 MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir);
1304 MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8);
1305 MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16);
1306
1307 MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir);
1308 MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8);
1309 MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
1310 spin_unlock_irqrestore(&sachip->lock, flags);
1311}
1312EXPORT_SYMBOL(sa1111_set_io_dir);
1313
1314void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
1315{
1316 struct sa1111 *sachip = sa1111_chip_driver(sadev);
1317 unsigned long flags;
1318 unsigned int val;
1319 void __iomem *gpio = sachip->base + SA1111_GPIO;
1320
1321 spin_lock_irqsave(&sachip->lock, flags);
1322 MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
1323 MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8);
1324 MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
1325 spin_unlock_irqrestore(&sachip->lock, flags);
1326}
1327EXPORT_SYMBOL(sa1111_set_io);
1328
1329void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
1330{
1331 struct sa1111 *sachip = sa1111_chip_driver(sadev);
1332 unsigned long flags;
1333 unsigned int val;
1334 void __iomem *gpio = sachip->base + SA1111_GPIO;
1335
1336 spin_lock_irqsave(&sachip->lock, flags);
1337 MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
1338 MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8);
1339 MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
1340 spin_unlock_irqrestore(&sachip->lock, flags);
1341}
1342EXPORT_SYMBOL(sa1111_set_sleep_io);
1343
1344/* 1285/*
1345 * Individual device operations. 1286 * Individual device operations.
1346 */ 1287 */
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 88286dd483ff..28a48e0d4cca 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -243,13 +243,15 @@
243 .endm 243 .endm
244#endif 244#endif
245 245
246#define USER(x...) \ 246#define USERL(l, x...) \
2479999: x; \ 2479999: x; \
248 .pushsection __ex_table,"a"; \ 248 .pushsection __ex_table,"a"; \
249 .align 3; \ 249 .align 3; \
250 .long 9999b,9001f; \ 250 .long 9999b,l; \
251 .popsection 251 .popsection
252 252
253#define USER(x...) USERL(9001f, x)
254
253#ifdef CONFIG_SMP 255#ifdef CONFIG_SMP
254#define ALT_SMP(instr...) \ 256#define ALT_SMP(instr...) \
2559998: instr 2579998: instr
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 798e520e8a49..d134b9a5ff94 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -433,10 +433,6 @@ int sa1111_check_dma_bug(dma_addr_t addr);
433int sa1111_driver_register(struct sa1111_driver *); 433int sa1111_driver_register(struct sa1111_driver *);
434void sa1111_driver_unregister(struct sa1111_driver *); 434void sa1111_driver_unregister(struct sa1111_driver *);
435 435
436void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir);
437void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
438void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
439
440struct sa1111_platform_data { 436struct sa1111_platform_data {
441 int irq_base; /* base for cascaded on-chip IRQs */ 437 int irq_base; /* base for cascaded on-chip IRQs */
442 unsigned disable_devs; 438 unsigned disable_devs;
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 27ed17ec45fe..42aa4a22803c 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -349,6 +349,13 @@ do { \
349#define __get_user_asm_byte(x, addr, err) \ 349#define __get_user_asm_byte(x, addr, err) \
350 __get_user_asm(x, addr, err, ldrb) 350 __get_user_asm(x, addr, err, ldrb)
351 351
352#if __LINUX_ARM_ARCH__ >= 6
353
354#define __get_user_asm_half(x, addr, err) \
355 __get_user_asm(x, addr, err, ldrh)
356
357#else
358
352#ifndef __ARMEB__ 359#ifndef __ARMEB__
353#define __get_user_asm_half(x, __gu_addr, err) \ 360#define __get_user_asm_half(x, __gu_addr, err) \
354({ \ 361({ \
@@ -367,6 +374,8 @@ do { \
367}) 374})
368#endif 375#endif
369 376
377#endif /* __LINUX_ARM_ARCH__ >= 6 */
378
370#define __get_user_asm_word(x, addr, err) \ 379#define __get_user_asm_word(x, addr, err) \
371 __get_user_asm(x, addr, err, ldr) 380 __get_user_asm(x, addr, err, ldr)
372#endif 381#endif
@@ -442,6 +451,13 @@ do { \
442#define __put_user_asm_byte(x, __pu_addr, err) \ 451#define __put_user_asm_byte(x, __pu_addr, err) \
443 __put_user_asm(x, __pu_addr, err, strb) 452 __put_user_asm(x, __pu_addr, err, strb)
444 453
454#if __LINUX_ARM_ARCH__ >= 6
455
456#define __put_user_asm_half(x, __pu_addr, err) \
457 __put_user_asm(x, __pu_addr, err, strh)
458
459#else
460
445#ifndef __ARMEB__ 461#ifndef __ARMEB__
446#define __put_user_asm_half(x, __pu_addr, err) \ 462#define __put_user_asm_half(x, __pu_addr, err) \
447({ \ 463({ \
@@ -458,6 +474,8 @@ do { \
458}) 474})
459#endif 475#endif
460 476
477#endif /* __LINUX_ARM_ARCH__ >= 6 */
478
461#define __put_user_asm_word(x, __pu_addr, err) \ 479#define __put_user_asm_word(x, __pu_addr, err) \
462 __put_user_asm(x, __pu_addr, err, str) 480 __put_user_asm(x, __pu_addr, err, str)
463 481
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 6b1148cafffd..4485d0404514 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -398,7 +398,7 @@ ENTRY(secondary_startup)
398 ldmia r4, {r5, r7, r12} @ address to jump to after 398 ldmia r4, {r5, r7, r12} @ address to jump to after
399 sub lr, r4, r5 @ mmu has been enabled 399 sub lr, r4, r5 @ mmu has been enabled
400 add r3, r7, lr 400 add r3, r7, lr
401 ldrd r4, [r3, #0] @ get secondary_data.pgdir 401 ldrd r4, r5, [r3, #0] @ get secondary_data.pgdir
402ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE: 402ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE:
403ARM_BE8(eor r5, r4, r5) @ it can be done in 3 steps 403ARM_BE8(eor r5, r4, r5) @ it can be done in 3 steps
404ARM_BE8(eor r4, r4, r5) @ without using a temp reg. 404ARM_BE8(eor r4, r4, r5) @ without using a temp reg.
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 12a6172263c0..3bf82232b1be 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -724,6 +724,21 @@ void smp_send_stop(void)
724 pr_warn("SMP: failed to stop secondary CPUs\n"); 724 pr_warn("SMP: failed to stop secondary CPUs\n");
725} 725}
726 726
727/* In case panic() and panic() called at the same time on CPU1 and CPU2,
728 * and CPU 1 calls panic_smp_self_stop() before crash_smp_send_stop()
729 * CPU1 can't receive the ipi irqs from CPU2, CPU1 will be always online,
730 * kdump fails. So split out the panic_smp_self_stop() and add
731 * set_cpu_online(smp_processor_id(), false).
732 */
733void panic_smp_self_stop(void)
734{
735 pr_debug("CPU %u will stop doing anything useful since another CPU has paniced\n",
736 smp_processor_id());
737 set_cpu_online(smp_processor_id(), false);
738 while (1)
739 cpu_relax();
740}
741
727/* 742/*
728 * not supported here 743 * not supported here
729 */ 744 */
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 6709a8d33963..0d4c189c7f4f 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -34,12 +34,13 @@
34 * Number of bytes NOT copied. 34 * Number of bytes NOT copied.
35 */ 35 */
36 36
37#ifdef CONFIG_CPU_USE_DOMAINS
38
37#ifndef CONFIG_THUMB2_KERNEL 39#ifndef CONFIG_THUMB2_KERNEL
38#define LDR1W_SHIFT 0 40#define LDR1W_SHIFT 0
39#else 41#else
40#define LDR1W_SHIFT 1 42#define LDR1W_SHIFT 1
41#endif 43#endif
42#define STR1W_SHIFT 0
43 44
44 .macro ldr1w ptr reg abort 45 .macro ldr1w ptr reg abort
45 ldrusr \reg, \ptr, 4, abort=\abort 46 ldrusr \reg, \ptr, 4, abort=\abort
@@ -57,10 +58,30 @@
57 ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort 58 ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
58 .endm 59 .endm
59 60
61#else
62
63#define LDR1W_SHIFT 0
64
65 .macro ldr1w ptr reg abort
66 USERL(\abort, W(ldr) \reg, [\ptr], #4)
67 .endm
68
69 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
70 USERL(\abort, ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4})
71 .endm
72
73 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
74 USERL(\abort, ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
75 .endm
76
77#endif /* CONFIG_CPU_USE_DOMAINS */
78
60 .macro ldr1b ptr reg cond=al abort 79 .macro ldr1b ptr reg cond=al abort
61 ldrusr \reg, \ptr, 1, \cond, abort=\abort 80 ldrusr \reg, \ptr, 1, \cond, abort=\abort
62 .endm 81 .endm
63 82
83#define STR1W_SHIFT 0
84
64 .macro str1w ptr reg abort 85 .macro str1w ptr reg abort
65 W(str) \reg, [\ptr], #4 86 W(str) \reg, [\ptr], #4
66 .endm 87 .endm
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 970abe521197..97a6ff4b7e3c 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -35,11 +35,6 @@
35 */ 35 */
36 36
37#define LDR1W_SHIFT 0 37#define LDR1W_SHIFT 0
38#ifndef CONFIG_THUMB2_KERNEL
39#define STR1W_SHIFT 0
40#else
41#define STR1W_SHIFT 1
42#endif
43 38
44 .macro ldr1w ptr reg abort 39 .macro ldr1w ptr reg abort
45 W(ldr) \reg, [\ptr], #4 40 W(ldr) \reg, [\ptr], #4
@@ -57,6 +52,14 @@
57 ldr\cond\()b \reg, [\ptr], #1 52 ldr\cond\()b \reg, [\ptr], #1
58 .endm 53 .endm
59 54
55#ifdef CONFIG_CPU_USE_DOMAINS
56
57#ifndef CONFIG_THUMB2_KERNEL
58#define STR1W_SHIFT 0
59#else
60#define STR1W_SHIFT 1
61#endif
62
60 .macro str1w ptr reg abort 63 .macro str1w ptr reg abort
61 strusr \reg, \ptr, 4, abort=\abort 64 strusr \reg, \ptr, 4, abort=\abort
62 .endm 65 .endm
@@ -72,6 +75,20 @@
72 str1w \ptr, \reg8, \abort 75 str1w \ptr, \reg8, \abort
73 .endm 76 .endm
74 77
78#else
79
80#define STR1W_SHIFT 0
81
82 .macro str1w ptr reg abort
83 USERL(\abort, W(str) \reg, [\ptr], #4)
84 .endm
85
86 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
87 USERL(\abort, stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
88 .endm
89
90#endif /* CONFIG_CPU_USE_DOMAINS */
91
75 .macro str1b ptr reg cond=al abort 92 .macro str1b ptr reg cond=al abort
76 strusr \reg, \ptr, 1, \cond, abort=\abort 93 strusr \reg, \ptr, 1, \cond, abort=\abort
77 .endm 94 .endm
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 746e7801dcdf..b2e4bc3a635e 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -42,6 +42,12 @@ _ASM_NOKPROBE(__get_user_1)
42 42
43ENTRY(__get_user_2) 43ENTRY(__get_user_2)
44 check_uaccess r0, 2, r1, r2, __get_user_bad 44 check_uaccess r0, 2, r1, r2, __get_user_bad
45#if __LINUX_ARM_ARCH__ >= 6
46
472: TUSER(ldrh) r2, [r0]
48
49#else
50
45#ifdef CONFIG_CPU_USE_DOMAINS 51#ifdef CONFIG_CPU_USE_DOMAINS
46rb .req ip 52rb .req ip
472: ldrbt r2, [r0], #1 532: ldrbt r2, [r0], #1
@@ -56,6 +62,9 @@ rb .req r0
56#else 62#else
57 orr r2, rb, r2, lsl #8 63 orr r2, rb, r2, lsl #8
58#endif 64#endif
65
66#endif /* __LINUX_ARM_ARCH__ >= 6 */
67
59 mov r0, #0 68 mov r0, #0
60 ret lr 69 ret lr
61ENDPROC(__get_user_2) 70ENDPROC(__get_user_2)
@@ -145,7 +154,9 @@ _ASM_NOKPROBE(__get_user_bad8)
145.pushsection __ex_table, "a" 154.pushsection __ex_table, "a"
146 .long 1b, __get_user_bad 155 .long 1b, __get_user_bad
147 .long 2b, __get_user_bad 156 .long 2b, __get_user_bad
157#if __LINUX_ARM_ARCH__ < 6
148 .long 3b, __get_user_bad 158 .long 3b, __get_user_bad
159#endif
149 .long 4b, __get_user_bad 160 .long 4b, __get_user_bad
150 .long 5b, __get_user_bad8 161 .long 5b, __get_user_bad8
151 .long 6b, __get_user_bad8 162 .long 6b, __get_user_bad8
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 38d660d3705f..515eeaa9975c 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -41,16 +41,13 @@ ENDPROC(__put_user_1)
41 41
42ENTRY(__put_user_2) 42ENTRY(__put_user_2)
43 check_uaccess r0, 2, r1, ip, __put_user_bad 43 check_uaccess r0, 2, r1, ip, __put_user_bad
44 mov ip, r2, lsr #8 44#if __LINUX_ARM_ARCH__ >= 6
45#ifdef CONFIG_THUMB2_KERNEL 45
46#ifndef __ARMEB__ 462: TUSER(strh) r2, [r0]
472: TUSER(strb) r2, [r0] 47
483: TUSER(strb) ip, [r0, #1]
49#else 48#else
502: TUSER(strb) ip, [r0] 49
513: TUSER(strb) r2, [r0, #1] 50 mov ip, r2, lsr #8
52#endif
53#else /* !CONFIG_THUMB2_KERNEL */
54#ifndef __ARMEB__ 51#ifndef __ARMEB__
552: TUSER(strb) r2, [r0], #1 522: TUSER(strb) r2, [r0], #1
563: TUSER(strb) ip, [r0] 533: TUSER(strb) ip, [r0]
@@ -58,7 +55,8 @@ ENTRY(__put_user_2)
582: TUSER(strb) ip, [r0], #1 552: TUSER(strb) ip, [r0], #1
593: TUSER(strb) r2, [r0] 563: TUSER(strb) r2, [r0]
60#endif 57#endif
61#endif /* CONFIG_THUMB2_KERNEL */ 58
59#endif /* __LINUX_ARM_ARCH__ >= 6 */
62 mov r0, #0 60 mov r0, #0
63 ret lr 61 ret lr
64ENDPROC(__put_user_2) 62ENDPROC(__put_user_2)
@@ -91,7 +89,9 @@ ENDPROC(__put_user_bad)
91.pushsection __ex_table, "a" 89.pushsection __ex_table, "a"
92 .long 1b, __put_user_bad 90 .long 1b, __put_user_bad
93 .long 2b, __put_user_bad 91 .long 2b, __put_user_bad
92#if __LINUX_ARM_ARCH__ < 6
94 .long 3b, __put_user_bad 93 .long 3b, __put_user_bad
94#endif
95 .long 4b, __put_user_bad 95 .long 4b, __put_user_bad
96 .long 5b, __put_user_bad 96 .long 5b, __put_user_bad
97 .long 6b, __put_user_bad 97 .long 6b, __put_user_bad
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 9f27b486a536..5e33d1a90664 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -223,7 +223,6 @@ config MACH_NOKIA_N8X0
223config OMAP3_SDRC_AC_TIMING 223config OMAP3_SDRC_AC_TIMING
224 bool "Enable SDRC AC timing register changes" 224 bool "Enable SDRC AC timing register changes"
225 depends on ARCH_OMAP3 225 depends on ARCH_OMAP3
226 default n
227 help 226 help
228 If you know that none of your system initiators will attempt to 227 If you know that none of your system initiators will attempt to
229 access SDRAM during CORE DVFS, select Y here. This should boost 228 access SDRAM during CORE DVFS, select Y here. This should boost
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 1c73694c871a..10e070368f64 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -69,8 +69,6 @@ static const struct omap_smp_config omap5_cfg __initconst = {
69 .startup_addr = omap5_secondary_startup, 69 .startup_addr = omap5_secondary_startup,
70}; 70};
71 71
72static DEFINE_SPINLOCK(boot_lock);
73
74void __iomem *omap4_get_scu_base(void) 72void __iomem *omap4_get_scu_base(void)
75{ 73{
76 return cfg.scu_base; 74 return cfg.scu_base;
@@ -173,12 +171,6 @@ static void omap4_secondary_init(unsigned int cpu)
173 /* Enable ACR to allow for ICUALLU workaround */ 171 /* Enable ACR to allow for ICUALLU workaround */
174 omap5_secondary_harden_predictor(); 172 omap5_secondary_harden_predictor();
175 } 173 }
176
177 /*
178 * Synchronise with the boot thread.
179 */
180 spin_lock(&boot_lock);
181 spin_unlock(&boot_lock);
182} 174}
183 175
184static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) 176static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -188,12 +180,6 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
188 static struct powerdomain *cpu1_pwrdm; 180 static struct powerdomain *cpu1_pwrdm;
189 181
190 /* 182 /*
191 * Set synchronisation state between this boot processor
192 * and the secondary one
193 */
194 spin_lock(&boot_lock);
195
196 /*
197 * Update the AuxCoreBoot0 with boot state for secondary core. 183 * Update the AuxCoreBoot0 with boot state for secondary core.
198 * omap4_secondary_startup() routine will hold the secondary core till 184 * omap4_secondary_startup() routine will hold the secondary core till
199 * the AuxCoreBoot1 register is updated with cpu state 185 * the AuxCoreBoot1 register is updated with cpu state
@@ -266,12 +252,6 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
266 252
267 arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 253 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
268 254
269 /*
270 * Now the secondary core is starting up let it run its
271 * calibrations, then wait for it to finish
272 */
273 spin_unlock(&boot_lock);
274
275 return 0; 255 return 0;
276} 256}
277 257
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index b185794549be..dc8e4f4b7ade 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -46,6 +46,7 @@ config ARCH_LUBBOCK
46 46
47config MACH_MAINSTONE 47config MACH_MAINSTONE
48 bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)" 48 bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
49 select GPIO_REG
49 select PXA27x 50 select PXA27x
50 51
51config MACH_ZYLONITE 52config MACH_ZYLONITE
@@ -551,7 +552,6 @@ config TOSA_BT
551config TOSA_USE_EXT_KEYCODES 552config TOSA_USE_EXT_KEYCODES
552 bool "Tosa keyboard: use extended keycodes" 553 bool "Tosa keyboard: use extended keycodes"
553 depends on MACH_TOSA 554 depends on MACH_TOSA
554 default n
555 help 555 help
556 Say Y here to enable the tosa keyboard driver to generate extended 556 Say Y here to enable the tosa keyboard driver to generate extended
557 (>= 127) keycodes. Be aware, that they can't be correctly interpreted 557 (>= 127) keycodes. Be aware, that they can't be correctly interpreted
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h
index e82a7d31104e..474041a83d80 100644
--- a/arch/arm/mach-pxa/include/mach/mainstone.h
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -119,6 +119,10 @@
119#define MST_PCMCIA_PWR_VCC_33 0x8 /* voltage VCC = 3.3V */ 119#define MST_PCMCIA_PWR_VCC_33 0x8 /* voltage VCC = 3.3V */
120#define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */ 120#define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */
121 121
122#define MST_PCMCIA_INPUTS \
123 (MST_PCMCIA_nIRQ | MST_PCMCIA_nSPKR_BVD2 | MST_PCMCIA_nSTSCHG_BVD1 | \
124 MST_PCMCIA_nVS2 | MST_PCMCIA_nVS1 | MST_PCMCIA_nCD)
125
122/* board specific IRQs */ 126/* board specific IRQs */
123#define MAINSTONE_NR_IRQS IRQ_BOARD_START 127#define MAINSTONE_NR_IRQS IRQ_BOARD_START
124 128
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index c576e8462043..a1391e113ef4 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -136,10 +136,26 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
136 // no D+ pullup; lubbock can't connect/disconnect in software 136 // no D+ pullup; lubbock can't connect/disconnect in software
137}; 137};
138 138
139/* GPIOs for SA1111 PCMCIA */
140static struct gpiod_lookup_table sa1111_pcmcia_gpio_table = {
141 .dev_id = "1800",
142 .table = {
143 { "sa1111", 0, "a0vpp", GPIO_ACTIVE_HIGH },
144 { "sa1111", 1, "a1vpp", GPIO_ACTIVE_HIGH },
145 { "sa1111", 2, "a0vcc", GPIO_ACTIVE_HIGH },
146 { "sa1111", 3, "a1vcc", GPIO_ACTIVE_HIGH },
147 { "lubbock", 14, "b0vcc", GPIO_ACTIVE_HIGH },
148 { "lubbock", 15, "b1vcc", GPIO_ACTIVE_HIGH },
149 { },
150 },
151};
152
139static void lubbock_init_pcmcia(void) 153static void lubbock_init_pcmcia(void)
140{ 154{
141 struct clk *clk; 155 struct clk *clk;
142 156
157 gpiod_add_lookup_table(&sa1111_pcmcia_gpio_table);
158
143 /* Add an alias for the SA1111 PCMCIA clock */ 159 /* Add an alias for the SA1111 PCMCIA clock */
144 clk = clk_get_sys("pxa2xx-pcmcia", NULL); 160 clk = clk_get_sys("pxa2xx-pcmcia", NULL);
145 if (!IS_ERR(clk)) { 161 if (!IS_ERR(clk)) {
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 9e39fc2ad2d9..d6e17d407ac0 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -13,6 +13,7 @@
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/gpio/gpio-reg.h>
16#include <linux/gpio/machine.h> 17#include <linux/gpio/machine.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -504,12 +505,64 @@ static void __init mainstone_init_keypad(void)
504static inline void mainstone_init_keypad(void) {} 505static inline void mainstone_init_keypad(void) {}
505#endif 506#endif
506 507
508static int mst_pcmcia0_irqs[11] = {
509 [0 ... 10] = -1,
510 [5] = MAINSTONE_S0_CD_IRQ,
511 [8] = MAINSTONE_S0_STSCHG_IRQ,
512 [10] = MAINSTONE_S0_IRQ,
513};
514
515static int mst_pcmcia1_irqs[11] = {
516 [0 ... 10] = -1,
517 [5] = MAINSTONE_S1_CD_IRQ,
518 [8] = MAINSTONE_S1_STSCHG_IRQ,
519 [10] = MAINSTONE_S1_IRQ,
520};
521
522static struct gpiod_lookup_table mainstone_pcmcia_gpio_table = {
523 .dev_id = "pxa2xx-pcmcia",
524 .table = {
525 GPIO_LOOKUP("mst-pcmcia0", 0, "a0vpp", GPIO_ACTIVE_HIGH),
526 GPIO_LOOKUP("mst-pcmcia0", 1, "a1vpp", GPIO_ACTIVE_HIGH),
527 GPIO_LOOKUP("mst-pcmcia0", 2, "a0vcc", GPIO_ACTIVE_HIGH),
528 GPIO_LOOKUP("mst-pcmcia0", 3, "a1vcc", GPIO_ACTIVE_HIGH),
529 GPIO_LOOKUP("mst-pcmcia0", 4, "areset", GPIO_ACTIVE_HIGH),
530 GPIO_LOOKUP("mst-pcmcia0", 5, "adetect", GPIO_ACTIVE_LOW),
531 GPIO_LOOKUP("mst-pcmcia0", 6, "avs1", GPIO_ACTIVE_LOW),
532 GPIO_LOOKUP("mst-pcmcia0", 7, "avs2", GPIO_ACTIVE_LOW),
533 GPIO_LOOKUP("mst-pcmcia0", 8, "abvd1", GPIO_ACTIVE_HIGH),
534 GPIO_LOOKUP("mst-pcmcia0", 9, "abvd2", GPIO_ACTIVE_HIGH),
535 GPIO_LOOKUP("mst-pcmcia0", 10, "aready", GPIO_ACTIVE_HIGH),
536 GPIO_LOOKUP("mst-pcmcia1", 0, "b0vpp", GPIO_ACTIVE_HIGH),
537 GPIO_LOOKUP("mst-pcmcia1", 1, "b1vpp", GPIO_ACTIVE_HIGH),
538 GPIO_LOOKUP("mst-pcmcia1", 2, "b0vcc", GPIO_ACTIVE_HIGH),
539 GPIO_LOOKUP("mst-pcmcia1", 3, "b1vcc", GPIO_ACTIVE_HIGH),
540 GPIO_LOOKUP("mst-pcmcia1", 4, "breset", GPIO_ACTIVE_HIGH),
541 GPIO_LOOKUP("mst-pcmcia1", 5, "bdetect", GPIO_ACTIVE_LOW),
542 GPIO_LOOKUP("mst-pcmcia1", 6, "bvs1", GPIO_ACTIVE_LOW),
543 GPIO_LOOKUP("mst-pcmcia1", 7, "bvs2", GPIO_ACTIVE_LOW),
544 GPIO_LOOKUP("mst-pcmcia1", 8, "bbvd1", GPIO_ACTIVE_HIGH),
545 GPIO_LOOKUP("mst-pcmcia1", 9, "bbvd2", GPIO_ACTIVE_HIGH),
546 GPIO_LOOKUP("mst-pcmcia1", 10, "bready", GPIO_ACTIVE_HIGH),
547 { },
548 },
549};
550
507static void __init mainstone_init(void) 551static void __init mainstone_init(void)
508{ 552{
509 int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ 553 int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
510 554
511 pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config)); 555 pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
512 556
557 /* Register board control register(s) as GPIOs */
558 gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0, -1, 11,
559 "mst-pcmcia0", MST_PCMCIA_INPUTS, 0, NULL,
560 NULL, mst_pcmcia0_irqs);
561 gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA1, -1, 11,
562 "mst-pcmcia1", MST_PCMCIA_INPUTS, 0, NULL,
563 NULL, mst_pcmcia1_irqs);
564 gpiod_add_lookup_table(&mainstone_pcmcia_gpio_table);
565
513 pxa_set_ffuart_info(NULL); 566 pxa_set_ffuart_info(NULL);
514 pxa_set_btuart_info(NULL); 567 pxa_set_btuart_info(NULL);
515 pxa_set_stuart_info(NULL); 568 pxa_set_stuart_info(NULL);
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index adf39ad71cc3..6ca6400fa51e 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -5,4 +5,3 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-versatile/inc
5 5
6obj-y += realview-dt.o 6obj-y += realview-dt.o
7obj-$(CONFIG_SMP) += platsmp-dt.o 7obj-$(CONFIG_SMP) += platsmp-dt.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
deleted file mode 100644
index 968e2d1964f6..000000000000
--- a/arch/arm/mach-realview/hotplug.c
+++ /dev/null
@@ -1,111 +0,0 @@
1/*
2 * linux/arch/arm/mach-realview/hotplug.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/smp.h>
14
15#include <asm/cp15.h>
16#include <asm/smp_plat.h>
17
18static inline void cpu_enter_lowpower(void)
19{
20 unsigned int v;
21
22 asm volatile(
23 " mcr p15, 0, %1, c7, c5, 0\n"
24 " mcr p15, 0, %1, c7, c10, 4\n"
25 /*
26 * Turn off coherency
27 */
28 " mrc p15, 0, %0, c1, c0, 1\n"
29 " bic %0, %0, #0x20\n"
30 " mcr p15, 0, %0, c1, c0, 1\n"
31 " mrc p15, 0, %0, c1, c0, 0\n"
32 " bic %0, %0, %2\n"
33 " mcr p15, 0, %0, c1, c0, 0\n"
34 : "=&r" (v)
35 : "r" (0), "Ir" (CR_C)
36 : "cc");
37}
38
39static inline void cpu_leave_lowpower(void)
40{
41 unsigned int v;
42
43 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
44 " orr %0, %0, %1\n"
45 " mcr p15, 0, %0, c1, c0, 0\n"
46 " mrc p15, 0, %0, c1, c0, 1\n"
47 " orr %0, %0, #0x20\n"
48 " mcr p15, 0, %0, c1, c0, 1\n"
49 : "=&r" (v)
50 : "Ir" (CR_C)
51 : "cc");
52}
53
54static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
55{
56 /*
57 * there is no power-control hardware on this platform, so all
58 * we can do is put the core into WFI; this is safe as the calling
59 * code will have already disabled interrupts
60 */
61 for (;;) {
62 /*
63 * here's the WFI
64 */
65 asm(".word 0xe320f003\n"
66 :
67 :
68 : "memory", "cc");
69
70 if (pen_release == cpu_logical_map(cpu)) {
71 /*
72 * OK, proper wakeup, we're done
73 */
74 break;
75 }
76
77 /*
78 * Getting here, means that we have come out of WFI without
79 * having been woken up - this shouldn't happen
80 *
81 * Just note it happening - when we're woken, we can report
82 * its occurrence.
83 */
84 (*spurious)++;
85 }
86}
87
88/*
89 * platform-specific code to shutdown a CPU
90 *
91 * Called with IRQs disabled
92 */
93void realview_cpu_die(unsigned int cpu)
94{
95 int spurious = 0;
96
97 /*
98 * we're ready for shutdown now, so do it
99 */
100 cpu_enter_lowpower();
101 platform_do_lowpower(cpu, &spurious);
102
103 /*
104 * bring this CPU back into the world of cache
105 * coherency, and then restore interrupts
106 */
107 cpu_leave_lowpower();
108
109 if (spurious)
110 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
111}
diff --git a/arch/arm/mach-realview/hotplug.h b/arch/arm/mach-realview/hotplug.h
deleted file mode 100644
index eacd7a4dad2f..000000000000
--- a/arch/arm/mach-realview/hotplug.h
+++ /dev/null
@@ -1 +0,0 @@
1void realview_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-realview/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c
index c242423bf8db..ce331b3dbf54 100644
--- a/arch/arm/mach-realview/platsmp-dt.c
+++ b/arch/arm/mach-realview/platsmp-dt.c
@@ -17,7 +17,6 @@
17#include <asm/smp_scu.h> 17#include <asm/smp_scu.h>
18 18
19#include <plat/platsmp.h> 19#include <plat/platsmp.h>
20#include "hotplug.h"
21 20
22#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 21#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30
23 22
@@ -79,6 +78,13 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
79 __pa_symbol(versatile_secondary_startup)); 78 __pa_symbol(versatile_secondary_startup));
80} 79}
81 80
81#ifdef CONFIG_HOTPLUG_CPU
82static void realview_cpu_die(unsigned int cpu)
83{
84 return versatile_immitation_cpu_die(cpu, 0x20);
85}
86#endif
87
82static const struct smp_operations realview_dt_smp_ops __initconst = { 88static const struct smp_operations realview_dt_smp_ops __initconst = {
83 .smp_prepare_cpus = realview_smp_prepare_cpus, 89 .smp_prepare_cpus = realview_smp_prepare_cpus,
84 .smp_secondary_init = versatile_secondary_init, 90 .smp_secondary_init = versatile_secondary_init,
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index acb2c520ae8b..ce41c6708a83 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -6,6 +6,7 @@ config SA1100_ASSABET
6 bool "Assabet" 6 bool "Assabet"
7 select ARM_SA1110_CPUFREQ 7 select ARM_SA1110_CPUFREQ
8 select GPIO_REG 8 select GPIO_REG
9 select LEDS_GPIO_REGISTER
9 select REGULATOR 10 select REGULATOR
10 select REGULATOR_FIXED_VOLTAGE 11 select REGULATOR_FIXED_VOLTAGE
11 help 12 help
@@ -24,6 +25,7 @@ config ASSABET_NEPONSET
24config SA1100_CERF 25config SA1100_CERF
25 bool "CerfBoard" 26 bool "CerfBoard"
26 select ARM_SA1110_CPUFREQ 27 select ARM_SA1110_CPUFREQ
28 select LEDS_GPIO_REGISTER
27 help 29 help
28 The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued). 30 The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
29 More information is available at: 31 More information is available at:
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 3e8c0948abcc..dfa42496ec27 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -15,6 +15,7 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/gpio/gpio-reg.h> 16#include <linux/gpio/gpio-reg.h>
17#include <linux/gpio/machine.h> 17#include <linux/gpio/machine.h>
18#include <linux/gpio_keys.h>
18#include <linux/ioport.h> 19#include <linux/ioport.h>
19#include <linux/platform_data/sa11x0-serial.h> 20#include <linux/platform_data/sa11x0-serial.h>
20#include <linux/regulator/fixed.h> 21#include <linux/regulator/fixed.h>
@@ -101,7 +102,7 @@ static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
101 102
102 assabet_bcr_gc = gc; 103 assabet_bcr_gc = gc;
103 104
104 return 0; 105 return gc->base;
105} 106}
106 107
107/* 108/*
@@ -479,6 +480,49 @@ static struct gpiod_lookup_table assabet_cf_vcc_gpio_table = {
479 }, 480 },
480}; 481};
481 482
483static struct gpio_led assabet_leds[] __initdata = {
484 {
485 .name = "assabet:red",
486 .default_trigger = "cpu0",
487 .active_low = 1,
488 .default_state = LEDS_GPIO_DEFSTATE_KEEP,
489 }, {
490 .name = "assabet:green",
491 .default_trigger = "heartbeat",
492 .active_low = 1,
493 .default_state = LEDS_GPIO_DEFSTATE_KEEP,
494 },
495};
496
497static const struct gpio_led_platform_data assabet_leds_pdata __initconst = {
498 .num_leds = ARRAY_SIZE(assabet_leds),
499 .leds = assabet_leds,
500};
501
502static struct gpio_keys_button assabet_keys_buttons[] = {
503 {
504 .gpio = 0,
505 .irq = IRQ_GPIO0,
506 .desc = "gpio0",
507 .wakeup = 1,
508 .can_disable = 1,
509 .debounce_interval = 5,
510 }, {
511 .gpio = 1,
512 .irq = IRQ_GPIO1,
513 .desc = "gpio1",
514 .wakeup = 1,
515 .can_disable = 1,
516 .debounce_interval = 5,
517 },
518};
519
520static const struct gpio_keys_platform_data assabet_keys_pdata = {
521 .buttons = assabet_keys_buttons,
522 .nbuttons = ARRAY_SIZE(assabet_keys_buttons),
523 .rep = 0,
524};
525
482static void __init assabet_init(void) 526static void __init assabet_init(void)
483{ 527{
484 /* 528 /*
@@ -533,6 +577,13 @@ static void __init assabet_init(void)
533 577
534 } 578 }
535 579
580 platform_device_register_resndata(NULL, "gpio-keys", 0,
581 NULL, 0,
582 &assabet_keys_pdata,
583 sizeof(assabet_keys_pdata));
584
585 gpio_led_register_device(-1, &assabet_leds_pdata);
586
536#ifndef ASSABET_PAL_VIDEO 587#ifndef ASSABET_PAL_VIDEO
537 sa11x0_register_lcd(&lq039q2ds54_info); 588 sa11x0_register_lcd(&lq039q2ds54_info);
538#else 589#else
@@ -726,92 +777,9 @@ static void __init assabet_map_io(void)
726 sa1100_register_uart(2, 3); 777 sa1100_register_uart(2, 3);
727} 778}
728 779
729/* LEDs */
730#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
731struct assabet_led {
732 struct led_classdev cdev;
733 u32 mask;
734};
735
736/*
737 * The triggers lines up below will only be used if the
738 * LED triggers are compiled in.
739 */
740static const struct {
741 const char *name;
742 const char *trigger;
743} assabet_leds[] = {
744 { "assabet:red", "cpu0",},
745 { "assabet:green", "heartbeat", },
746};
747
748/*
749 * The LED control in Assabet is reversed:
750 * - setting bit means turn off LED
751 * - clearing bit means turn on LED
752 */
753static void assabet_led_set(struct led_classdev *cdev,
754 enum led_brightness b)
755{
756 struct assabet_led *led = container_of(cdev,
757 struct assabet_led, cdev);
758
759 if (b != LED_OFF)
760 ASSABET_BCR_clear(led->mask);
761 else
762 ASSABET_BCR_set(led->mask);
763}
764
765static enum led_brightness assabet_led_get(struct led_classdev *cdev)
766{
767 struct assabet_led *led = container_of(cdev,
768 struct assabet_led, cdev);
769
770 return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL;
771}
772
773static int __init assabet_leds_init(void)
774{
775 int i;
776
777 if (!machine_is_assabet())
778 return -ENODEV;
779
780 for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) {
781 struct assabet_led *led;
782
783 led = kzalloc(sizeof(*led), GFP_KERNEL);
784 if (!led)
785 break;
786
787 led->cdev.name = assabet_leds[i].name;
788 led->cdev.brightness_set = assabet_led_set;
789 led->cdev.brightness_get = assabet_led_get;
790 led->cdev.default_trigger = assabet_leds[i].trigger;
791
792 if (!i)
793 led->mask = ASSABET_BCR_LED_RED;
794 else
795 led->mask = ASSABET_BCR_LED_GREEN;
796
797 if (led_classdev_register(NULL, &led->cdev) < 0) {
798 kfree(led);
799 break;
800 }
801 }
802
803 return 0;
804}
805
806/*
807 * Since we may have triggers on any subsystem, defer registration
808 * until after subsystem_init.
809 */
810fs_initcall(assabet_leds_init);
811#endif
812
813void __init assabet_init_irq(void) 780void __init assabet_init_irq(void)
814{ 781{
782 unsigned int assabet_gpio_base;
815 u32 def_val; 783 u32 def_val;
816 784
817 sa1100_init_irq(); 785 sa1100_init_irq();
@@ -826,7 +794,10 @@ void __init assabet_init_irq(void)
826 * 794 *
827 * This must precede any driver calls to BCR_set() or BCR_clear(). 795 * This must precede any driver calls to BCR_set() or BCR_clear().
828 */ 796 */
829 assabet_init_gpio((void *)&ASSABET_BCR, def_val); 797 assabet_gpio_base = assabet_init_gpio((void *)&ASSABET_BCR, def_val);
798
799 assabet_leds[0].gpio = assabet_gpio_base + 13;
800 assabet_leds[1].gpio = assabet_gpio_base + 14;
830} 801}
831 802
832MACHINE_START(ASSABET, "Intel-Assabet") 803MACHINE_START(ASSABET, "Intel-Assabet")
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index b2a4b41626ef..88e526561a24 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -89,18 +89,8 @@ static struct gpio_led_platform_data cerf_gpio_led_info = {
89 .num_leds = ARRAY_SIZE(cerf_gpio_leds), 89 .num_leds = ARRAY_SIZE(cerf_gpio_leds),
90}; 90};
91 91
92static struct platform_device cerf_leds = {
93 .name = "leds-gpio",
94 .id = -1,
95 .dev = {
96 .platform_data = &cerf_gpio_led_info,
97 }
98};
99
100
101static struct platform_device *cerf_devices[] __initdata = { 92static struct platform_device *cerf_devices[] __initdata = {
102 &cerfuart2_device, 93 &cerfuart2_device,
103 &cerf_leds,
104}; 94};
105 95
106#ifdef CONFIG_SA1100_CERF_FLASH_32MB 96#ifdef CONFIG_SA1100_CERF_FLASH_32MB
@@ -176,6 +166,7 @@ static void __init cerf_init(void)
176{ 166{
177 sa11x0_ppc_configure_mcp(); 167 sa11x0_ppc_configure_mcp();
178 platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); 168 platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
169 gpio_led_register_device(-1, &cerf_gpio_led_info);
179 sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); 170 sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
180 sa11x0_register_mcp(&cerf_mcp_data); 171 sa11x0_register_mcp(&cerf_mcp_data);
181 sa11x0_register_pcmcia(1, &cerf_cf_gpio_table); 172 sa11x0_register_pcmcia(1, &cerf_cf_gpio_table);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 800321c6cbd8..755290bf658b 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -235,18 +235,11 @@ void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
235 sa11x0_register_device(&sa11x0fb_device, inf); 235 sa11x0_register_device(&sa11x0fb_device, inf);
236} 236}
237 237
238static bool sa11x0pcmcia_legacy = true;
239static struct platform_device sa11x0pcmcia_device = {
240 .name = "sa11x0-pcmcia",
241 .id = -1,
242};
243
244void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table) 238void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
245{ 239{
246 if (table) 240 if (table)
247 gpiod_add_lookup_table(table); 241 gpiod_add_lookup_table(table);
248 platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0); 242 platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
249 sa11x0pcmcia_legacy = false;
250} 243}
251 244
252static struct platform_device sa11x0mtd_device = { 245static struct platform_device sa11x0mtd_device = {
@@ -331,9 +324,6 @@ static int __init sa1100_init(void)
331{ 324{
332 pm_power_off = sa1100_power_off; 325 pm_power_off = sa1100_power_off;
333 326
334 if (sa11x0pcmcia_legacy)
335 platform_device_register(&sa11x0pcmcia_device);
336
337 regulator_has_full_constraints(); 327 regulator_has_full_constraints();
338 328
339 return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices)); 329 return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index c6b412054a3c..9dc5bcb7326b 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -126,6 +126,7 @@ static void __init h3100_mach_init(void)
126{ 126{
127 h3xxx_mach_init(); 127 h3xxx_mach_init();
128 128
129 sa11x0_register_pcmcia(-1, NULL);
129 sa11x0_register_lcd(&h3100_lcd_info); 130 sa11x0_register_lcd(&h3100_lcd_info);
130 sa11x0_register_irda(&h3100_irda_data); 131 sa11x0_register_irda(&h3100_irda_data);
131} 132}
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 0a2ca9be00e6..6298bad09ef3 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -190,6 +190,17 @@ static struct platform_device s1d13xxxfb_device = {
190 .resource = s1d13xxxfb_resources, 190 .resource = s1d13xxxfb_resources,
191}; 191};
192 192
193static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
194 .dev_id = "1800",
195 .table = {
196 GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
197 GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
198 GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
199 GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
200 { },
201 },
202};
203
193static struct resource sa1111_resources[] = { 204static struct resource sa1111_resources[] = {
194 [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN), 205 [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
195 [1] = DEFINE_RES_IRQ(IRQ_GPIO1), 206 [1] = DEFINE_RES_IRQ(IRQ_GPIO1),
@@ -265,6 +276,7 @@ static int __init jornada720_init(void)
265 udelay(20); /* give it some time to restart */ 276 udelay(20); /* give it some time to restart */
266 277
267 gpiod_add_lookup_table(&jornada_ts_gpiod_table); 278 gpiod_add_lookup_table(&jornada_ts_gpiod_table);
279 gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);
268 280
269 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 281 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
270 } 282 }
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index b1823f445358..eb60a71cf125 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -5,6 +5,7 @@
5#include <linux/err.h> 5#include <linux/err.h>
6#include <linux/gpio/driver.h> 6#include <linux/gpio/driver.h>
7#include <linux/gpio/gpio-reg.h> 7#include <linux/gpio/gpio-reg.h>
8#include <linux/gpio/machine.h>
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/ioport.h> 10#include <linux/ioport.h>
10#include <linux/irq.h> 11#include <linux/irq.h>
@@ -96,6 +97,19 @@ struct neponset_drvdata {
96 struct gpio_chip *gpio[4]; 97 struct gpio_chip *gpio[4];
97}; 98};
98 99
100static struct gpiod_lookup_table neponset_pcmcia_table = {
101 .dev_id = "1800",
102 .table = {
103 GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
104 GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
105 GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
106 GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
107 GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
108 GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
109 { },
110 },
111};
112
99static struct neponset_drvdata *nep; 113static struct neponset_drvdata *nep;
100 114
101void neponset_ncr_frob(unsigned int mask, unsigned int val) 115void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -374,6 +388,8 @@ static int neponset_probe(struct platform_device *dev)
374 d->base + AUD_CTL, AUD_NGPIO, false, 388 d->base + AUD_CTL, AUD_NGPIO, false,
375 neponset_aud_names); 389 neponset_aud_names);
376 390
391 gpiod_add_lookup_table(&neponset_pcmcia_table);
392
377 /* 393 /*
378 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately 394 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
379 * something on the Neponset activates this IRQ on sleep (eth?) 395 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -424,6 +440,9 @@ static int neponset_remove(struct platform_device *dev)
424 platform_device_unregister(d->sa1111); 440 platform_device_unregister(d->sa1111);
425 if (!IS_ERR(d->smc91x)) 441 if (!IS_ERR(d->smc91x))
426 platform_device_unregister(d->smc91x); 442 platform_device_unregister(d->smc91x);
443
444 gpiod_remove_lookup_table(&neponset_pcmcia_table);
445
427 irq_set_chained_handler(irq, NULL); 446 irq_set_chained_handler(irq, NULL);
428 irq_free_descs(d->irq_base, NEP_IRQ_NR); 447 irq_free_descs(d->irq_base, NEP_IRQ_NR);
429 nep = NULL; 448 nep = NULL;
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 51c35e2b737a..3651a1ed0f2b 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -15,6 +15,5 @@ obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM) += tc2_pm.o
15CFLAGS_tc2_pm.o += -march=armv7-a 15CFLAGS_tc2_pm.o += -march=armv7-a
16CFLAGS_REMOVE_tc2_pm.o = -pg 16CFLAGS_REMOVE_tc2_pm.o = -pg
17obj-$(CONFIG_SMP) += platsmp.o 17obj-$(CONFIG_SMP) += platsmp.o
18obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
19 18
20obj-$(CONFIG_ARCH_MPS2) += v2m-mps2.o 19obj-$(CONFIG_ARCH_MPS2) += v2m-mps2.o
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index a162ab46ee02..f4a7519084f1 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -1,5 +1,3 @@
1bool vexpress_smp_init_ops(void); 1bool vexpress_smp_init_ops(void);
2 2
3extern const struct smp_operations vexpress_smp_dt_ops; 3extern const struct smp_operations vexpress_smp_dt_ops;
4
5extern void vexpress_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 742499bac6d0..af0113be5970 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -82,6 +82,13 @@ static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
82 vexpress_flags_set(__pa_symbol(versatile_secondary_startup)); 82 vexpress_flags_set(__pa_symbol(versatile_secondary_startup));
83} 83}
84 84
85#ifdef CONFIG_HOTPLUG_CPU
86static void vexpress_cpu_die(unsigned int cpu)
87{
88 versatile_immitation_cpu_die(cpu, 0x40);
89}
90#endif
91
85const struct smp_operations vexpress_smp_dt_ops __initconst = { 92const struct smp_operations vexpress_smp_dt_ops __initconst = {
86 .smp_prepare_cpus = vexpress_smp_dt_prepare_cpus, 93 .smp_prepare_cpus = vexpress_smp_dt_prepare_cpus,
87 .smp_secondary_init = versatile_secondary_init, 94 .smp_secondary_init = versatile_secondary_init,
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
index d130a5ece5d5..bf24690ec83a 100644
--- a/arch/arm/mm/copypage-fa.c
+++ b/arch/arm/mm/copypage-fa.c
@@ -17,26 +17,25 @@
17/* 17/*
18 * Faraday optimised copy_user_page 18 * Faraday optimised copy_user_page
19 */ 19 */
20static void __naked 20static void fa_copy_user_page(void *kto, const void *kfrom)
21fa_copy_user_page(void *kto, const void *kfrom)
22{ 21{
23 asm("\ 22 int tmp;
24 stmfd sp!, {r4, lr} @ 2\n\ 23
25 mov r2, %0 @ 1\n\ 24 asm volatile ("\
261: ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 251: ldmia %1!, {r3, r4, ip, lr} @ 4\n\
27 stmia r0, {r3, r4, ip, lr} @ 4\n\ 26 stmia %0, {r3, r4, ip, lr} @ 4\n\
28 mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\ 27 mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
29 add r0, r0, #16 @ 1\n\ 28 add %0, %0, #16 @ 1\n\
30 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 29 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
31 stmia r0, {r3, r4, ip, lr} @ 4\n\ 30 stmia %0, {r3, r4, ip, lr} @ 4\n\
32 mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\ 31 mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
33 add r0, r0, #16 @ 1\n\ 32 add %0, %0, #16 @ 1\n\
34 subs r2, r2, #1 @ 1\n\ 33 subs %2, %2, #1 @ 1\n\
35 bne 1b @ 1\n\ 34 bne 1b @ 1\n\
36 mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\ 35 mcr p15, 0, %2, c7, c10, 4 @ 1 drain WB"
37 ldmfd sp!, {r4, pc} @ 3" 36 : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
38 : 37 : "2" (PAGE_SIZE / 32)
39 : "I" (PAGE_SIZE / 32)); 38 : "r3", "r4", "ip", "lr");
40} 39}
41 40
42void fa_copy_user_highpage(struct page *to, struct page *from, 41void fa_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c
index 49ee0c1a7209..cc819732d9b8 100644
--- a/arch/arm/mm/copypage-feroceon.c
+++ b/arch/arm/mm/copypage-feroceon.c
@@ -13,58 +13,56 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/highmem.h> 14#include <linux/highmem.h>
15 15
16static void __naked 16static void feroceon_copy_user_page(void *kto, const void *kfrom)
17feroceon_copy_user_page(void *kto, const void *kfrom)
18{ 17{
19 asm("\ 18 int tmp;
20 stmfd sp!, {r4-r9, lr} \n\ 19
21 mov ip, %2 \n\ 20 asm volatile ("\
221: mov lr, r1 \n\ 211: ldmia %1!, {r2 - r7, ip, lr} \n\
23 ldmia r1!, {r2 - r9} \n\ 22 pld [%1, #0] \n\
24 pld [lr, #32] \n\ 23 pld [%1, #32] \n\
25 pld [lr, #64] \n\ 24 pld [%1, #64] \n\
26 pld [lr, #96] \n\ 25 pld [%1, #96] \n\
27 pld [lr, #128] \n\ 26 pld [%1, #128] \n\
28 pld [lr, #160] \n\ 27 pld [%1, #160] \n\
29 pld [lr, #192] \n\ 28 pld [%1, #192] \n\
30 pld [lr, #224] \n\ 29 stmia %0, {r2 - r7, ip, lr} \n\
31 stmia r0, {r2 - r9} \n\ 30 ldmia %1!, {r2 - r7, ip, lr} \n\
32 ldmia r1!, {r2 - r9} \n\ 31 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
33 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 32 add %0, %0, #32 \n\
34 add r0, r0, #32 \n\ 33 stmia %0, {r2 - r7, ip, lr} \n\
35 stmia r0, {r2 - r9} \n\ 34 ldmia %1!, {r2 - r7, ip, lr} \n\
36 ldmia r1!, {r2 - r9} \n\ 35 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
37 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 36 add %0, %0, #32 \n\
38 add r0, r0, #32 \n\ 37 stmia %0, {r2 - r7, ip, lr} \n\
39 stmia r0, {r2 - r9} \n\ 38 ldmia %1!, {r2 - r7, ip, lr} \n\
40 ldmia r1!, {r2 - r9} \n\ 39 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
41 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 40 add %0, %0, #32 \n\
42 add r0, r0, #32 \n\ 41 stmia %0, {r2 - r7, ip, lr} \n\
43 stmia r0, {r2 - r9} \n\ 42 ldmia %1!, {r2 - r7, ip, lr} \n\
44 ldmia r1!, {r2 - r9} \n\ 43 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
45 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 44 add %0, %0, #32 \n\
46 add r0, r0, #32 \n\ 45 stmia %0, {r2 - r7, ip, lr} \n\
47 stmia r0, {r2 - r9} \n\ 46 ldmia %1!, {r2 - r7, ip, lr} \n\
48 ldmia r1!, {r2 - r9} \n\ 47 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
49 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 48 add %0, %0, #32 \n\
50 add r0, r0, #32 \n\ 49 stmia %0, {r2 - r7, ip, lr} \n\
51 stmia r0, {r2 - r9} \n\ 50 ldmia %1!, {r2 - r7, ip, lr} \n\
52 ldmia r1!, {r2 - r9} \n\ 51 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
53 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 52 add %0, %0, #32 \n\
54 add r0, r0, #32 \n\ 53 stmia %0, {r2 - r7, ip, lr} \n\
55 stmia r0, {r2 - r9} \n\ 54 ldmia %1!, {r2 - r7, ip, lr} \n\
56 ldmia r1!, {r2 - r9} \n\ 55 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
57 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 56 add %0, %0, #32 \n\
58 add r0, r0, #32 \n\ 57 stmia %0, {r2 - r7, ip, lr} \n\
59 stmia r0, {r2 - r9} \n\ 58 subs %2, %2, #(32 * 8) \n\
60 subs ip, ip, #(32 * 8) \n\ 59 mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
61 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\ 60 add %0, %0, #32 \n\
62 add r0, r0, #32 \n\
63 bne 1b \n\ 61 bne 1b \n\
64 mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\ 62 mcr p15, 0, %2, c7, c10, 4 @ drain WB"
65 ldmfd sp!, {r4-r9, pc}" 63 : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
66 : 64 : "2" (PAGE_SIZE)
67 : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE)); 65 : "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
68} 66}
69 67
70void feroceon_copy_user_highpage(struct page *to, struct page *from, 68void feroceon_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index 0224416cba3c..b03202cddddb 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -40,12 +40,11 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
40 * instruction. If your processor does not supply this, you have to write your 40 * instruction. If your processor does not supply this, you have to write your
41 * own copy_user_highpage that does the right thing. 41 * own copy_user_highpage that does the right thing.
42 */ 42 */
43static void __naked 43static void mc_copy_user_page(void *from, void *to)
44mc_copy_user_page(void *from, void *to)
45{ 44{
46 asm volatile( 45 int tmp;
47 "stmfd sp!, {r4, lr} @ 2\n\ 46
48 mov r4, %2 @ 1\n\ 47 asm volatile ("\
49 ldmia %0!, {r2, r3, ip, lr} @ 4\n\ 48 ldmia %0!, {r2, r3, ip, lr} @ 4\n\
501: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\ 491: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
51 stmia %1!, {r2, r3, ip, lr} @ 4\n\ 50 stmia %1!, {r2, r3, ip, lr} @ 4\n\
@@ -55,13 +54,13 @@ mc_copy_user_page(void *from, void *to)
55 mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\ 54 mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
56 stmia %1!, {r2, r3, ip, lr} @ 4\n\ 55 stmia %1!, {r2, r3, ip, lr} @ 4\n\
57 ldmia %0!, {r2, r3, ip, lr} @ 4\n\ 56 ldmia %0!, {r2, r3, ip, lr} @ 4\n\
58 subs r4, r4, #1 @ 1\n\ 57 subs %2, %2, #1 @ 1\n\
59 stmia %1!, {r2, r3, ip, lr} @ 4\n\ 58 stmia %1!, {r2, r3, ip, lr} @ 4\n\
60 ldmneia %0!, {r2, r3, ip, lr} @ 4\n\ 59 ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
61 bne 1b @ 1\n\ 60 bne 1b @ "
62 ldmfd sp!, {r4, pc} @ 3" 61 : "+&r" (from), "+&r" (to), "=&r" (tmp)
63 : 62 : "2" (PAGE_SIZE / 64)
64 : "r" (from), "r" (to), "I" (PAGE_SIZE / 64)); 63 : "r2", "r3", "ip", "lr");
65} 64}
66 65
67void v4_mc_copy_user_highpage(struct page *to, struct page *from, 66void v4_mc_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c
index 067d0fdd630c..cd3e165afeed 100644
--- a/arch/arm/mm/copypage-v4wb.c
+++ b/arch/arm/mm/copypage-v4wb.c
@@ -22,29 +22,28 @@
22 * instruction. If your processor does not supply this, you have to write your 22 * instruction. If your processor does not supply this, you have to write your
23 * own copy_user_highpage that does the right thing. 23 * own copy_user_highpage that does the right thing.
24 */ 24 */
25static void __naked 25static void v4wb_copy_user_page(void *kto, const void *kfrom)
26v4wb_copy_user_page(void *kto, const void *kfrom)
27{ 26{
28 asm("\ 27 int tmp;
29 stmfd sp!, {r4, lr} @ 2\n\ 28
30 mov r2, %2 @ 1\n\ 29 asm volatile ("\
31 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 30 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
321: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ 311: mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
33 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 32 stmia %0!, {r3, r4, ip, lr} @ 4\n\
34 ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\ 33 ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
35 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 34 stmia %0!, {r3, r4, ip, lr} @ 4\n\
36 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 35 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
37 mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ 36 mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
38 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 37 stmia %0!, {r3, r4, ip, lr} @ 4\n\
39 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 38 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
40 subs r2, r2, #1 @ 1\n\ 39 subs %2, %2, #1 @ 1\n\
41 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 40 stmia %0!, {r3, r4, ip, lr} @ 4\n\
42 ldmneia r1!, {r3, r4, ip, lr} @ 4\n\ 41 ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
43 bne 1b @ 1\n\ 42 bne 1b @ 1\n\
44 mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\ 43 mcr p15, 0, %1, c7, c10, 4 @ 1 drain WB"
45 ldmfd sp!, {r4, pc} @ 3" 44 : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
46 : 45 : "2" (PAGE_SIZE / 64)
47 : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); 46 : "r3", "r4", "ip", "lr");
48} 47}
49 48
50void v4wb_copy_user_highpage(struct page *to, struct page *from, 49void v4wb_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c
index b85c5da2e510..8614572e1296 100644
--- a/arch/arm/mm/copypage-v4wt.c
+++ b/arch/arm/mm/copypage-v4wt.c
@@ -20,27 +20,26 @@
20 * dirty data in the cache. However, we do have to ensure that 20 * dirty data in the cache. However, we do have to ensure that
21 * subsequent reads are up to date. 21 * subsequent reads are up to date.
22 */ 22 */
23static void __naked 23static void v4wt_copy_user_page(void *kto, const void *kfrom)
24v4wt_copy_user_page(void *kto, const void *kfrom)
25{ 24{
26 asm("\ 25 int tmp;
27 stmfd sp!, {r4, lr} @ 2\n\ 26
28 mov r2, %2 @ 1\n\ 27 asm volatile ("\
29 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 28 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
301: stmia r0!, {r3, r4, ip, lr} @ 4\n\ 291: stmia %0!, {r3, r4, ip, lr} @ 4\n\
31 ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\ 30 ldmia %1!, {r3, r4, ip, lr} @ 4+1\n\
32 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 31 stmia %0!, {r3, r4, ip, lr} @ 4\n\
33 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 32 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
34 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 33 stmia %0!, {r3, r4, ip, lr} @ 4\n\
35 ldmia r1!, {r3, r4, ip, lr} @ 4\n\ 34 ldmia %1!, {r3, r4, ip, lr} @ 4\n\
36 subs r2, r2, #1 @ 1\n\ 35 subs %2, %2, #1 @ 1\n\
37 stmia r0!, {r3, r4, ip, lr} @ 4\n\ 36 stmia %0!, {r3, r4, ip, lr} @ 4\n\
38 ldmneia r1!, {r3, r4, ip, lr} @ 4\n\ 37 ldmneia %1!, {r3, r4, ip, lr} @ 4\n\
39 bne 1b @ 1\n\ 38 bne 1b @ 1\n\
40 mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\ 39 mcr p15, 0, %2, c7, c7, 0 @ flush ID cache"
41 ldmfd sp!, {r4, pc} @ 3" 40 : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
42 : 41 : "2" (PAGE_SIZE / 64)
43 : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64)); 42 : "r3", "r4", "ip", "lr");
44} 43}
45 44
46void v4wt_copy_user_highpage(struct page *to, struct page *from, 45void v4wt_copy_user_highpage(struct page *to, struct page *from,
diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c
index 03a2042aced5..a08158241ad1 100644
--- a/arch/arm/mm/copypage-xsc3.c
+++ b/arch/arm/mm/copypage-xsc3.c
@@ -21,53 +21,46 @@
21 21
22/* 22/*
23 * XSC3 optimised copy_user_highpage 23 * XSC3 optimised copy_user_highpage
24 * r0 = destination
25 * r1 = source
26 * 24 *
27 * The source page may have some clean entries in the cache already, but we 25 * The source page may have some clean entries in the cache already, but we
28 * can safely ignore them - break_cow() will flush them out of the cache 26 * can safely ignore them - break_cow() will flush them out of the cache
29 * if we eventually end up using our copied page. 27 * if we eventually end up using our copied page.
30 * 28 *
31 */ 29 */
32static void __naked 30static void xsc3_mc_copy_user_page(void *kto, const void *kfrom)
33xsc3_mc_copy_user_page(void *kto, const void *kfrom)
34{ 31{
35 asm("\ 32 int tmp;
36 stmfd sp!, {r4, r5, lr} \n\ 33
37 mov lr, %2 \n\ 34 asm volatile ("\
38 \n\ 35 pld [%1, #0] \n\
39 pld [r1, #0] \n\ 36 pld [%1, #32] \n\
40 pld [r1, #32] \n\ 371: pld [%1, #64] \n\
411: pld [r1, #64] \n\ 38 pld [%1, #96] \n\
42 pld [r1, #96] \n\
43 \n\ 39 \n\
442: ldrd r2, [r1], #8 \n\ 402: ldrd r2, r3, [%1], #8 \n\
45 mov ip, r0 \n\ 41 ldrd r4, r5, [%1], #8 \n\
46 ldrd r4, [r1], #8 \n\ 42 mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
47 mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\ 43 strd r2, r3, [%0], #8 \n\
48 strd r2, [r0], #8 \n\ 44 ldrd r2, r3, [%1], #8 \n\
49 ldrd r2, [r1], #8 \n\ 45 strd r4, r5, [%0], #8 \n\
50 strd r4, [r0], #8 \n\ 46 ldrd r4, r5, [%1], #8 \n\
51 ldrd r4, [r1], #8 \n\ 47 strd r2, r3, [%0], #8 \n\
52 strd r2, [r0], #8 \n\ 48 strd r4, r5, [%0], #8 \n\
53 strd r4, [r0], #8 \n\ 49 ldrd r2, r3, [%1], #8 \n\
54 ldrd r2, [r1], #8 \n\ 50 ldrd r4, r5, [%1], #8 \n\
55 mov ip, r0 \n\ 51 mcr p15, 0, %0, c7, c6, 1 @ invalidate\n\
56 ldrd r4, [r1], #8 \n\ 52 strd r2, r3, [%0], #8 \n\
57 mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\ 53 ldrd r2, r3, [%1], #8 \n\
58 strd r2, [r0], #8 \n\ 54 subs %2, %2, #1 \n\
59 ldrd r2, [r1], #8 \n\ 55 strd r4, r5, [%0], #8 \n\
60 subs lr, lr, #1 \n\ 56 ldrd r4, r5, [%1], #8 \n\
61 strd r4, [r0], #8 \n\ 57 strd r2, r3, [%0], #8 \n\
62 ldrd r4, [r1], #8 \n\ 58 strd r4, r5, [%0], #8 \n\
63 strd r2, [r0], #8 \n\
64 strd r4, [r0], #8 \n\
65 bgt 1b \n\ 59 bgt 1b \n\
66 beq 2b \n\ 60 beq 2b "
67 \n\ 61 : "+&r" (kto), "+&r" (kfrom), "=&r" (tmp)
68 ldmfd sp!, {r4, r5, pc}" 62 : "2" (PAGE_SIZE / 64 - 1)
69 : 63 : "r2", "r3", "r4", "r5");
70 : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
71} 64}
72 65
73void xsc3_mc_copy_user_highpage(struct page *to, struct page *from, 66void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
@@ -85,8 +78,6 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
85 78
86/* 79/*
87 * XScale optimised clear_user_page 80 * XScale optimised clear_user_page
88 * r0 = destination
89 * r1 = virtual user address of ultimate destination page
90 */ 81 */
91void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr) 82void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
92{ 83{
@@ -96,10 +87,10 @@ void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
96 mov r2, #0 \n\ 87 mov r2, #0 \n\
97 mov r3, #0 \n\ 88 mov r3, #0 \n\
981: mcr p15, 0, %0, c7, c6, 1 @ invalidate line\n\ 891: mcr p15, 0, %0, c7, c6, 1 @ invalidate line\n\
99 strd r2, [%0], #8 \n\ 90 strd r2, r3, [%0], #8 \n\
100 strd r2, [%0], #8 \n\ 91 strd r2, r3, [%0], #8 \n\
101 strd r2, [%0], #8 \n\ 92 strd r2, r3, [%0], #8 \n\
102 strd r2, [%0], #8 \n\ 93 strd r2, r3, [%0], #8 \n\
103 subs r1, r1, #1 \n\ 94 subs r1, r1, #1 \n\
104 bne 1b" 95 bne 1b"
105 : "=r" (ptr) 96 : "=r" (ptr)
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 97972379f4d6..63b921936754 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -36,52 +36,51 @@ static DEFINE_RAW_SPINLOCK(minicache_lock);
36 * Dcache aliasing issue. The writes will be forwarded to the write buffer, 36 * Dcache aliasing issue. The writes will be forwarded to the write buffer,
37 * and merged as appropriate. 37 * and merged as appropriate.
38 */ 38 */
39static void __naked 39static void mc_copy_user_page(void *from, void *to)
40mc_copy_user_page(void *from, void *to)
41{ 40{
41 int tmp;
42
42 /* 43 /*
43 * Strangely enough, best performance is achieved 44 * Strangely enough, best performance is achieved
44 * when prefetching destination as well. (NP) 45 * when prefetching destination as well. (NP)
45 */ 46 */
46 asm volatile( 47 asm volatile ("\
47 "stmfd sp!, {r4, r5, lr} \n\ 48 pld [%0, #0] \n\
48 mov lr, %2 \n\ 49 pld [%0, #32] \n\
49 pld [r0, #0] \n\ 50 pld [%1, #0] \n\
50 pld [r0, #32] \n\ 51 pld [%1, #32] \n\
51 pld [r1, #0] \n\ 521: pld [%0, #64] \n\
52 pld [r1, #32] \n\ 53 pld [%0, #96] \n\
531: pld [r0, #64] \n\ 54 pld [%1, #64] \n\
54 pld [r0, #96] \n\ 55 pld [%1, #96] \n\
55 pld [r1, #64] \n\ 562: ldrd r2, r3, [%0], #8 \n\
56 pld [r1, #96] \n\ 57 ldrd r4, r5, [%0], #8 \n\
572: ldrd r2, [r0], #8 \n\ 58 mov ip, %1 \n\
58 ldrd r4, [r0], #8 \n\ 59 strd r2, r3, [%1], #8 \n\
59 mov ip, r1 \n\ 60 ldrd r2, r3, [%0], #8 \n\
60 strd r2, [r1], #8 \n\ 61 strd r4, r5, [%1], #8 \n\
61 ldrd r2, [r0], #8 \n\ 62 ldrd r4, r5, [%0], #8 \n\
62 strd r4, [r1], #8 \n\ 63 strd r2, r3, [%1], #8 \n\
63 ldrd r4, [r0], #8 \n\ 64 strd r4, r5, [%1], #8 \n\
64 strd r2, [r1], #8 \n\
65 strd r4, [r1], #8 \n\
66 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ 65 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
67 ldrd r2, [r0], #8 \n\ 66 ldrd r2, r3, [%0], #8 \n\
68 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ 67 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
69 ldrd r4, [r0], #8 \n\ 68 ldrd r4, r5, [%0], #8 \n\
70 mov ip, r1 \n\ 69 mov ip, %1 \n\
71 strd r2, [r1], #8 \n\ 70 strd r2, r3, [%1], #8 \n\
72 ldrd r2, [r0], #8 \n\ 71 ldrd r2, r3, [%0], #8 \n\
73 strd r4, [r1], #8 \n\ 72 strd r4, r5, [%1], #8 \n\
74 ldrd r4, [r0], #8 \n\ 73 ldrd r4, r5, [%0], #8 \n\
75 strd r2, [r1], #8 \n\ 74 strd r2, r3, [%1], #8 \n\
76 strd r4, [r1], #8 \n\ 75 strd r4, r5, [%1], #8 \n\
77 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ 76 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
78 subs lr, lr, #1 \n\ 77 subs %2, %2, #1 \n\
79 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ 78 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
80 bgt 1b \n\ 79 bgt 1b \n\
81 beq 2b \n\ 80 beq 2b "
82 ldmfd sp!, {r4, r5, pc} " 81 : "+&r" (from), "+&r" (to), "=&r" (tmp)
83 : 82 : "2" (PAGE_SIZE / 64 - 1)
84 : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1)); 83 : "r2", "r3", "r4", "r5", "ip");
85} 84}
86 85
87void xscale_mc_copy_user_highpage(struct page *to, struct page *from, 86void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
@@ -115,10 +114,10 @@ xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
115 mov r2, #0 \n\ 114 mov r2, #0 \n\
116 mov r3, #0 \n\ 115 mov r3, #0 \n\
1171: mov ip, %0 \n\ 1161: mov ip, %0 \n\
118 strd r2, [%0], #8 \n\ 117 strd r2, r3, [%0], #8 \n\
119 strd r2, [%0], #8 \n\ 118 strd r2, r3, [%0], #8 \n\
120 strd r2, [%0], #8 \n\ 119 strd r2, r3, [%0], #8 \n\
121 strd r2, [%0], #8 \n\ 120 strd r2, r3, [%0], #8 \n\
122 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ 121 mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
123 subs r1, r1, #1 \n\ 122 subs r1, r1, #1 \n\
124 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ 123 mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index f4ea4c62c613..58f69fa07df9 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -173,6 +173,12 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
173 show_regs(regs); 173 show_regs(regs);
174 } 174 }
175#endif 175#endif
176#ifndef CONFIG_KUSER_HELPERS
177 if ((sig == SIGSEGV) && ((addr & PAGE_MASK) == 0xffff0000))
178 printk_ratelimited(KERN_DEBUG
179 "%s: CONFIG_KUSER_HELPERS disabled at 0x%08lx\n",
180 tsk->comm, addr);
181#endif
176 182
177 tsk->thread.address = addr; 183 tsk->thread.address = addr;
178 tsk->thread.error_code = fsr; 184 tsk->thread.error_code = fsr;
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 19516fbc2c55..5461d589a1e2 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -278,7 +278,7 @@
278 * If we are building for big.Little with branch predictor hardening, 278 * If we are building for big.Little with branch predictor hardening,
279 * we need the processor function tables to remain available after boot. 279 * we need the processor function tables to remain available after boot.
280 */ 280 */
281#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) 281#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
282 .section ".rodata" 282 .section ".rodata"
283#endif 283#endif
284 .type \name\()_processor_functions, #object 284 .type \name\()_processor_functions, #object
@@ -316,7 +316,7 @@ ENTRY(\name\()_processor_functions)
316 .endif 316 .endif
317 317
318 .size \name\()_processor_functions, . - \name\()_processor_functions 318 .size \name\()_processor_functions, . - \name\()_processor_functions
319#if 1 // defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR) 319#if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
320 .previous 320 .previous
321#endif 321#endif
322.endm 322.endm
diff --git a/arch/arm/mm/pv-fixup-asm.S b/arch/arm/mm/pv-fixup-asm.S
index 1867f3e43016..fd2ff9034d17 100644
--- a/arch/arm/mm/pv-fixup-asm.S
+++ b/arch/arm/mm/pv-fixup-asm.S
@@ -33,10 +33,10 @@ ENTRY(lpae_pgtables_remap_asm)
33 add r7, r2, #0x1000 33 add r7, r2, #0x1000
34 add r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER 34 add r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
35 add r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER) 35 add r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
361: ldrd r4, [r7] 361: ldrd r4, r5, [r7]
37 adds r4, r4, r0 37 adds r4, r4, r0
38 adc r5, r5, r1 38 adc r5, r5, r1
39 strd r4, [r7], #1 << L2_ORDER 39 strd r4, r5, [r7], #1 << L2_ORDER
40 cmp r7, r6 40 cmp r7, r6
41 bls 1b 41 bls 1b
42 42
@@ -44,22 +44,22 @@ ENTRY(lpae_pgtables_remap_asm)
44 add r7, r2, #0x1000 44 add r7, r2, #0x1000
45 add r7, r7, r3, lsr #SECTION_SHIFT - L2_ORDER 45 add r7, r7, r3, lsr #SECTION_SHIFT - L2_ORDER
46 bic r7, r7, #(1 << L2_ORDER) - 1 46 bic r7, r7, #(1 << L2_ORDER) - 1
47 ldrd r4, [r7] 47 ldrd r4, r5, [r7]
48 adds r4, r4, r0 48 adds r4, r4, r0
49 adc r5, r5, r1 49 adc r5, r5, r1
50 strd r4, [r7], #1 << L2_ORDER 50 strd r4, r5, [r7], #1 << L2_ORDER
51 ldrd r4, [r7] 51 ldrd r4, r5, [r7]
52 adds r4, r4, r0 52 adds r4, r4, r0
53 adc r5, r5, r1 53 adc r5, r5, r1
54 strd r4, [r7] 54 strd r4, r5, [r7]
55 55
56 /* Update level 1 entries */ 56 /* Update level 1 entries */
57 mov r6, #4 57 mov r6, #4
58 mov r7, r2 58 mov r7, r2
592: ldrd r4, [r7] 592: ldrd r4, r5, [r7]
60 adds r4, r4, r0 60 adds r4, r4, r0
61 adc r5, r5, r1 61 adc r5, r5, r1
62 strd r4, [r7], #1 << L1_ORDER 62 strd r4, r5, [r7], #1 << L1_ORDER
63 subs r6, r6, #1 63 subs r6, r6, #1
64 bne 2b 64 bne 2b
65 65
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index c0a242cae79a..93fd7fc537cf 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -92,7 +92,6 @@ config OMAP_32K_TIMER
92config OMAP3_L2_AUX_SECURE_SAVE_RESTORE 92config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
93 bool "OMAP3 HS/EMU save and restore for L2 AUX control register" 93 bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
94 depends on ARCH_OMAP3 && PM 94 depends on ARCH_OMAP3 && PM
95 default n
96 help 95 help
97 Without this option, L2 Auxiliary control register contents are 96 Without this option, L2 Auxiliary control register contents are
98 lost during off-mode entry on HS/EMU devices. This feature 97 lost during off-mode entry on HS/EMU devices. This feature
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index bff3ba889882..b2f0ddfdc4cc 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -2,3 +2,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
2 2
3obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o 3obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
4obj-$(CONFIG_SMP) += headsmp.o platsmp.o 4obj-$(CONFIG_SMP) += headsmp.o platsmp.o
5obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/plat-versatile/headsmp.S b/arch/arm/plat-versatile/headsmp.S
index 40f27e52de75..e99396dfa6f3 100644
--- a/arch/arm/plat-versatile/headsmp.S
+++ b/arch/arm/plat-versatile/headsmp.S
@@ -37,5 +37,5 @@ pen: ldr r7, [r6]
37 37
38 .align 38 .align
391: .long . 391: .long .
40 .long pen_release 40 .long versatile_cpu_release
41ENDPROC(versatile_secondary_startup) 41ENDPROC(versatile_secondary_startup)
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/plat-versatile/hotplug.c
index d8f1a05f5e87..c974958417fe 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/plat-versatile/hotplug.c
@@ -1,12 +1,15 @@
1/* 1/*
2 * linux/arch/arm/mach-realview/hotplug.c
3 *
4 * Copyright (C) 2002 ARM Ltd. 2 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved 3 * All Rights Reserved
6 * 4 *
7 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 *
9 * This hotplug implementation is _specific_ to the situation found on
10 * ARM development platforms where there is _no_ possibility of actually
11 * taking a CPU offline, resetting it, or otherwise. Real platforms must
12 * NOT copy this code.
10 */ 13 */
11#include <linux/kernel.h> 14#include <linux/kernel.h>
12#include <linux/errno.h> 15#include <linux/errno.h>
@@ -15,9 +18,9 @@
15#include <asm/smp_plat.h> 18#include <asm/smp_plat.h>
16#include <asm/cp15.h> 19#include <asm/cp15.h>
17 20
18#include "core.h" 21#include <plat/platsmp.h>
19 22
20static inline void cpu_enter_lowpower(void) 23static inline void versatile_immitation_enter_lowpower(unsigned int actrl_mask)
21{ 24{
22 unsigned int v; 25 unsigned int v;
23 26
@@ -34,11 +37,11 @@ static inline void cpu_enter_lowpower(void)
34 " bic %0, %0, %2\n" 37 " bic %0, %0, %2\n"
35 " mcr p15, 0, %0, c1, c0, 0\n" 38 " mcr p15, 0, %0, c1, c0, 0\n"
36 : "=&r" (v) 39 : "=&r" (v)
37 : "r" (0), "Ir" (CR_C), "Ir" (0x40) 40 : "r" (0), "Ir" (CR_C), "Ir" (actrl_mask)
38 : "cc"); 41 : "cc");
39} 42}
40 43
41static inline void cpu_leave_lowpower(void) 44static inline void versatile_immitation_leave_lowpower(unsigned int actrl_mask)
42{ 45{
43 unsigned int v; 46 unsigned int v;
44 47
@@ -50,21 +53,23 @@ static inline void cpu_leave_lowpower(void)
50 " orr %0, %0, %2\n" 53 " orr %0, %0, %2\n"
51 " mcr p15, 0, %0, c1, c0, 1\n" 54 " mcr p15, 0, %0, c1, c0, 1\n"
52 : "=&r" (v) 55 : "=&r" (v)
53 : "Ir" (CR_C), "Ir" (0x40) 56 : "Ir" (CR_C), "Ir" (actrl_mask)
54 : "cc"); 57 : "cc");
55} 58}
56 59
57static inline void platform_do_lowpower(unsigned int cpu, int *spurious) 60static inline void versatile_immitation_do_lowpower(unsigned int cpu, int *spurious)
58{ 61{
59 /* 62 /*
60 * there is no power-control hardware on this platform, so all 63 * there is no power-control hardware on this platform, so all
61 * we can do is put the core into WFI; this is safe as the calling 64 * we can do is put the core into WFI; this is safe as the calling
62 * code will have already disabled interrupts 65 * code will have already disabled interrupts.
66 *
67 * This code should not be used outside Versatile platforms.
63 */ 68 */
64 for (;;) { 69 for (;;) {
65 wfi(); 70 wfi();
66 71
67 if (pen_release == cpu_logical_map(cpu)) { 72 if (versatile_cpu_release == cpu_logical_map(cpu)) {
68 /* 73 /*
69 * OK, proper wakeup, we're done 74 * OK, proper wakeup, we're done
70 */ 75 */
@@ -83,25 +88,17 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
83} 88}
84 89
85/* 90/*
86 * platform-specific code to shutdown a CPU 91 * platform-specific code to shutdown a CPU.
87 * 92 * This code supports immitation-style CPU hotplug for Versatile/Realview/
88 * Called with IRQs disabled 93 * Versatile Express platforms that are unable to do real CPU hotplug.
89 */ 94 */
90void vexpress_cpu_die(unsigned int cpu) 95void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask)
91{ 96{
92 int spurious = 0; 97 int spurious = 0;
93 98
94 /* 99 versatile_immitation_enter_lowpower(actrl_mask);
95 * we're ready for shutdown now, so do it 100 versatile_immitation_do_lowpower(cpu, &spurious);
96 */ 101 versatile_immitation_leave_lowpower(actrl_mask);
97 cpu_enter_lowpower();
98 platform_do_lowpower(cpu, &spurious);
99
100 /*
101 * bring this CPU back into the world of cache
102 * coherency, and then restore interrupts
103 */
104 cpu_leave_lowpower();
105 102
106 if (spurious) 103 if (spurious)
107 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious); 104 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
diff --git a/arch/arm/plat-versatile/include/plat/platsmp.h b/arch/arm/plat-versatile/include/plat/platsmp.h
index 50fb830192e0..1b087fbbc700 100644
--- a/arch/arm/plat-versatile/include/plat/platsmp.h
+++ b/arch/arm/plat-versatile/include/plat/platsmp.h
@@ -8,7 +8,9 @@
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11extern volatile int versatile_cpu_release;
11 12
12extern void versatile_secondary_startup(void); 13extern void versatile_secondary_startup(void);
13extern void versatile_secondary_init(unsigned int cpu); 14extern void versatile_secondary_init(unsigned int cpu);
14extern int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle); 15extern int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle);
16void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask);
diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c
index c2366510187a..6e2836243187 100644
--- a/arch/arm/plat-versatile/platsmp.c
+++ b/arch/arm/plat-versatile/platsmp.c
@@ -7,6 +7,11 @@
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 *
11 * This code is specific to the hardware found on ARM Realview and
12 * Versatile Express platforms where the CPUs are unable to be individually
13 * woken, and where there is no way to hot-unplug CPUs. Real platforms
14 * should not copy this code.
10 */ 15 */
11#include <linux/init.h> 16#include <linux/init.h>
12#include <linux/errno.h> 17#include <linux/errno.h>
@@ -21,18 +26,32 @@
21#include <plat/platsmp.h> 26#include <plat/platsmp.h>
22 27
23/* 28/*
24 * Write pen_release in a way that is guaranteed to be visible to all 29 * versatile_cpu_release controls the release of CPUs from the holding
25 * observers, irrespective of whether they're taking part in coherency 30 * pen in headsmp.S, which exists because we are not always able to
31 * control the release of individual CPUs from the board firmware.
32 * Production platforms do not need this.
33 */
34volatile int versatile_cpu_release = -1;
35
36/*
37 * Write versatile_cpu_release in a way that is guaranteed to be visible to
38 * all observers, irrespective of whether they're taking part in coherency
26 * or not. This is necessary for the hotplug code to work reliably. 39 * or not. This is necessary for the hotplug code to work reliably.
27 */ 40 */
28static void write_pen_release(int val) 41static void versatile_write_cpu_release(int val)
29{ 42{
30 pen_release = val; 43 versatile_cpu_release = val;
31 smp_wmb(); 44 smp_wmb();
32 sync_cache_w(&pen_release); 45 sync_cache_w(&versatile_cpu_release);
33} 46}
34 47
35static DEFINE_SPINLOCK(boot_lock); 48/*
49 * versatile_lock exists to avoid running the loops_per_jiffy delay loop
50 * calibrations on the secondary CPU while the requesting CPU is using
51 * the limited-bandwidth bus - which affects the calibration value.
52 * Production platforms do not need this.
53 */
54static DEFINE_RAW_SPINLOCK(versatile_lock);
36 55
37void versatile_secondary_init(unsigned int cpu) 56void versatile_secondary_init(unsigned int cpu)
38{ 57{
@@ -40,13 +59,13 @@ void versatile_secondary_init(unsigned int cpu)
40 * let the primary processor know we're out of the 59 * let the primary processor know we're out of the
41 * pen, then head off into the C entry point 60 * pen, then head off into the C entry point
42 */ 61 */
43 write_pen_release(-1); 62 versatile_write_cpu_release(-1);
44 63
45 /* 64 /*
46 * Synchronise with the boot thread. 65 * Synchronise with the boot thread.
47 */ 66 */
48 spin_lock(&boot_lock); 67 raw_spin_lock(&versatile_lock);
49 spin_unlock(&boot_lock); 68 raw_spin_unlock(&versatile_lock);
50} 69}
51 70
52int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle) 71int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -57,7 +76,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
57 * Set synchronisation state between this boot processor 76 * Set synchronisation state between this boot processor
58 * and the secondary one 77 * and the secondary one
59 */ 78 */
60 spin_lock(&boot_lock); 79 raw_spin_lock(&versatile_lock);
61 80
62 /* 81 /*
63 * This is really belt and braces; we hold unintended secondary 82 * This is really belt and braces; we hold unintended secondary
@@ -65,7 +84,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
65 * since we haven't sent them a soft interrupt, they shouldn't 84 * since we haven't sent them a soft interrupt, they shouldn't
66 * be there. 85 * be there.
67 */ 86 */
68 write_pen_release(cpu_logical_map(cpu)); 87 versatile_write_cpu_release(cpu_logical_map(cpu));
69 88
70 /* 89 /*
71 * Send the secondary CPU a soft interrupt, thereby causing 90 * Send the secondary CPU a soft interrupt, thereby causing
@@ -77,7 +96,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
77 timeout = jiffies + (1 * HZ); 96 timeout = jiffies + (1 * HZ);
78 while (time_before(jiffies, timeout)) { 97 while (time_before(jiffies, timeout)) {
79 smp_rmb(); 98 smp_rmb();
80 if (pen_release == -1) 99 if (versatile_cpu_release == -1)
81 break; 100 break;
82 101
83 udelay(10); 102 udelay(10);
@@ -87,7 +106,7 @@ int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
87 * now the secondary core is starting up let it run its 106 * now the secondary core is starting up let it run its
88 * calibrations, then wait for it to finish 107 * calibrations, then wait for it to finish
89 */ 108 */
90 spin_unlock(&boot_lock); 109 raw_spin_unlock(&versatile_lock);
91 110
92 return pen_release != -1 ? -ENOSYS : 0; 111 return versatile_cpu_release != -1 ? -ENOSYS : 0;
93} 112}
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index c9bdbb463a7e..fab92ba8e566 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -64,6 +64,9 @@ config CARDBUS
64 64
65 If unsure, say Y. 65 If unsure, say Y.
66 66
67config PCMCIA_MAX1600
68 tristate
69
67comment "PC-card bridges" 70comment "PC-card bridges"
68 71
69config YENTA 72config YENTA
@@ -192,6 +195,8 @@ config PCMCIA_SA1111
192 select PCMCIA_SOC_COMMON 195 select PCMCIA_SOC_COMMON
193 select PCMCIA_SA11XX_BASE if ARCH_SA1100 196 select PCMCIA_SA11XX_BASE if ARCH_SA1100
194 select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111 197 select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
198 select PCMCIA_MAX1600 if ASSABET_NEPONSET
199 select PCMCIA_MAX1600 if ARCH_LUBBOCK && SA1111
195 help 200 help
196 Say Y here to include support for SA1111-based PCMCIA or CF 201 Say Y here to include support for SA1111-based PCMCIA or CF
197 sockets, found on the Jornada 720, Graphicsmaster and other 202 sockets, found on the Jornada 720, Graphicsmaster and other
@@ -208,6 +213,7 @@ config PCMCIA_PXA2XX
208 || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \ 213 || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
209 || MACH_COLIBRI320 || MACH_H4700) 214 || MACH_COLIBRI320 || MACH_H4700)
210 select PCMCIA_SOC_COMMON 215 select PCMCIA_SOC_COMMON
216 select PCMCIA_MAX1600 if MACH_MAINSTONE
211 help 217 help
212 Say Y here to include support for the PXA2xx PCMCIA controller 218 Say Y here to include support for the PXA2xx PCMCIA controller
213 219
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 28502bd159e0..01779c5c45f3 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_OMAP_CF) += omap_cf.o
35obj-$(CONFIG_AT91_CF) += at91_cf.o 35obj-$(CONFIG_AT91_CF) += at91_cf.o
36obj-$(CONFIG_ELECTRA_CF) += electra_cf.o 36obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
37obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o 37obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
38obj-$(CONFIG_PCMCIA_MAX1600) += max1600.o
38 39
39sa1111_cs-y += sa1111_generic.o 40sa1111_cs-y += sa1111_generic.o
40sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o 41sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1111_neponset.o
diff --git a/drivers/pcmcia/max1600.c b/drivers/pcmcia/max1600.c
new file mode 100644
index 000000000000..379875a5e7cd
--- /dev/null
+++ b/drivers/pcmcia/max1600.c
@@ -0,0 +1,122 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * MAX1600 PCMCIA power switch library
4 *
5 * Copyright (C) 2016 Russell King
6 */
7#include <linux/device.h>
8#include <linux/module.h>
9#include <linux/gpio/consumer.h>
10#include <linux/slab.h>
11#include "max1600.h"
12
13static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = {
14 { "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
15 { "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
16};
17
18int max1600_init(struct device *dev, struct max1600 **ptr,
19 unsigned int channel, unsigned int code)
20{
21 struct max1600 *m;
22 int chan;
23 int i;
24
25 switch (channel) {
26 case MAX1600_CHAN_A:
27 chan = 0;
28 break;
29 case MAX1600_CHAN_B:
30 chan = 1;
31 break;
32 default:
33 return -EINVAL;
34 }
35
36 if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH)
37 return -EINVAL;
38
39 m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
40 if (!m)
41 return -ENOMEM;
42
43 m->dev = dev;
44 m->code = code;
45
46 for (i = 0; i < MAX1600_GPIO_MAX; i++) {
47 const char *name;
48
49 name = max1600_gpio_name[chan][i];
50 if (i != MAX1600_GPIO_0VPP) {
51 m->gpio[i] = devm_gpiod_get(dev, name, GPIOD_OUT_LOW);
52 } else {
53 m->gpio[i] = devm_gpiod_get_optional(dev, name,
54 GPIOD_OUT_LOW);
55 if (!m->gpio[i])
56 break;
57 }
58 if (IS_ERR(m->gpio[i]))
59 return PTR_ERR(m->gpio[i]);
60 }
61
62 *ptr = m;
63
64 return 0;
65}
66EXPORT_SYMBOL_GPL(max1600_init);
67
68int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp)
69{
70 DECLARE_BITMAP(values, MAX1600_GPIO_MAX) = { 0, };
71 int n = MAX1600_GPIO_0VPP;
72
73 if (m->gpio[MAX1600_GPIO_0VPP]) {
74 if (vpp == 0) {
75 __assign_bit(MAX1600_GPIO_0VPP, values, 0);
76 __assign_bit(MAX1600_GPIO_1VPP, values, 0);
77 } else if (vpp == 120) {
78 __assign_bit(MAX1600_GPIO_0VPP, values, 0);
79 __assign_bit(MAX1600_GPIO_1VPP, values, 1);
80 } else if (vpp == vcc) {
81 __assign_bit(MAX1600_GPIO_0VPP, values, 1);
82 __assign_bit(MAX1600_GPIO_1VPP, values, 0);
83 } else {
84 dev_err(m->dev, "unrecognised Vpp %u.%uV\n",
85 vpp / 10, vpp % 10);
86 return -EINVAL;
87 }
88 n = MAX1600_GPIO_MAX;
89 } else if (vpp != vcc && vpp != 0) {
90 dev_err(m->dev, "no VPP control\n");
91 return -EINVAL;
92 }
93
94 if (vcc == 0) {
95 __assign_bit(MAX1600_GPIO_0VCC, values, 0);
96 __assign_bit(MAX1600_GPIO_1VCC, values, 0);
97 } else if (vcc == 33) { /* VY */
98 __assign_bit(MAX1600_GPIO_0VCC, values, 1);
99 __assign_bit(MAX1600_GPIO_1VCC, values, 0);
100 } else if (vcc == 50) { /* VX */
101 __assign_bit(MAX1600_GPIO_0VCC, values, 0);
102 __assign_bit(MAX1600_GPIO_1VCC, values, 1);
103 } else {
104 dev_err(m->dev, "unrecognised Vcc %u.%uV\n",
105 vcc / 10, vcc % 10);
106 return -EINVAL;
107 }
108
109 if (m->code == MAX1600_CODE_HIGH) {
110 /*
111 * Cirrus mode appears to be the same as Intel mode,
112 * except the VCC pins are inverted.
113 */
114 __change_bit(MAX1600_GPIO_0VCC, values);
115 __change_bit(MAX1600_GPIO_1VCC, values);
116 }
117
118 return gpiod_set_array_value_cansleep(n, m->gpio, NULL, values);
119}
120EXPORT_SYMBOL_GPL(max1600_configure);
121
122MODULE_LICENSE("GPL v2");
diff --git a/drivers/pcmcia/max1600.h b/drivers/pcmcia/max1600.h
new file mode 100644
index 000000000000..00bf1a09464f
--- /dev/null
+++ b/drivers/pcmcia/max1600.h
@@ -0,0 +1,32 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef MAX1600_H
3#define MAX1600_H
4
5struct gpio_desc;
6
7enum {
8 MAX1600_GPIO_0VCC = 0,
9 MAX1600_GPIO_1VCC,
10 MAX1600_GPIO_0VPP,
11 MAX1600_GPIO_1VPP,
12 MAX1600_GPIO_MAX,
13
14 MAX1600_CHAN_A,
15 MAX1600_CHAN_B,
16
17 MAX1600_CODE_LOW,
18 MAX1600_CODE_HIGH,
19};
20
21struct max1600 {
22 struct gpio_desc *gpio[MAX1600_GPIO_MAX];
23 struct device *dev;
24 unsigned int code;
25};
26
27int max1600_init(struct device *dev, struct max1600 **ptr,
28 unsigned int channel, unsigned int code);
29
30int max1600_configure(struct max1600 *, unsigned int vcc, unsigned int vpp);
31
32#endif
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 7e32e25cdcb2..770c7bf0171d 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -11,56 +11,55 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14#include <linux/gpio/consumer.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/interrupt.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21 21
22#include <pcmcia/ss.h> 22#include <pcmcia/ss.h>
23 23
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/irq.h>
26
27#include <mach/pxa2xx-regs.h>
28#include <mach/mainstone.h>
29 25
30#include "soc_common.h" 26#include "soc_common.h"
31 27#include "max1600.h"
32 28
33static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 29static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
34{ 30{
35 /* 31 struct device *dev = skt->socket.dev.parent;
36 * Setup default state of GPIO outputs 32 struct max1600 *m;
37 * before we enable them as outputs. 33 int ret;
38 */ 34
39 if (skt->nr == 0) { 35 skt->stat[SOC_STAT_CD].name = skt->nr ? "bdetect" : "adetect";
40 skt->socket.pci_irq = MAINSTONE_S0_IRQ; 36 skt->stat[SOC_STAT_BVD1].name = skt->nr ? "bbvd1" : "abvd1";
41 skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ; 37 skt->stat[SOC_STAT_BVD2].name = skt->nr ? "bbvd2" : "abvd2";
42 skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD"; 38 skt->stat[SOC_STAT_RDY].name = skt->nr ? "bready" : "aready";
43 skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ; 39 skt->stat[SOC_STAT_VS1].name = skt->nr ? "bvs1" : "avs1";
44 skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG"; 40 skt->stat[SOC_STAT_VS2].name = skt->nr ? "bvs2" : "avs2";
45 } else { 41
46 skt->socket.pci_irq = MAINSTONE_S1_IRQ; 42 skt->gpio_reset = devm_gpiod_get(dev, skt->nr ? "breset" : "areset",
47 skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ; 43 GPIOD_OUT_HIGH);
48 skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD"; 44 if (IS_ERR(skt->gpio_reset))
49 skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ; 45 return PTR_ERR(skt->gpio_reset);
50 skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG"; 46
51 } 47 ret = max1600_init(dev, &m, skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
52 return 0; 48 MAX1600_CODE_HIGH);
49 if (ret)
50 return ret;
51
52 skt->driver_data = m;
53
54 return soc_pcmcia_request_gpiods(skt);
53} 55}
54 56
55static unsigned long mst_pcmcia_status[2]; 57static unsigned int mst_pcmcia_bvd1_status[2];
56 58
57static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 59static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
58 struct pcmcia_state *state) 60 struct pcmcia_state *state)
59{ 61{
60 unsigned long status, flip; 62 unsigned int flip = mst_pcmcia_bvd1_status[skt->nr] ^ state->bvd1;
61
62 status = (skt->nr == 0) ? MST_PCMCIA0 : MST_PCMCIA1;
63 flip = (status ^ mst_pcmcia_status[skt->nr]) & MST_PCMCIA_nSTSCHG_BVD1;
64 63
65 /* 64 /*
66 * Workaround for STSCHG which can't be deasserted: 65 * Workaround for STSCHG which can't be deasserted:
@@ -68,62 +67,18 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
68 * as needed to avoid IRQ locks. 67 * as needed to avoid IRQ locks.
69 */ 68 */
70 if (flip) { 69 if (flip) {
71 mst_pcmcia_status[skt->nr] = status; 70 mst_pcmcia_bvd1_status[skt->nr] = state->bvd1;
72 if (status & MST_PCMCIA_nSTSCHG_BVD1) 71 if (state->bvd1)
73 enable_irq( (skt->nr == 0) ? MAINSTONE_S0_STSCHG_IRQ 72 enable_irq(skt->stat[SOC_STAT_BVD1].irq);
74 : MAINSTONE_S1_STSCHG_IRQ );
75 else 73 else
76 disable_irq( (skt->nr == 0) ? MAINSTONE_S0_STSCHG_IRQ 74 disable_irq(skt->stat[SOC_STAT_BVD2].irq);
77 : MAINSTONE_S1_STSCHG_IRQ );
78 } 75 }
79
80 state->detect = (status & MST_PCMCIA_nCD) ? 0 : 1;
81 state->ready = (status & MST_PCMCIA_nIRQ) ? 1 : 0;
82 state->bvd1 = (status & MST_PCMCIA_nSTSCHG_BVD1) ? 1 : 0;
83 state->bvd2 = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
84 state->vs_3v = (status & MST_PCMCIA_nVS1) ? 0 : 1;
85 state->vs_Xv = (status & MST_PCMCIA_nVS2) ? 0 : 1;
86} 76}
87 77
88static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 78static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
89 const socket_state_t *state) 79 const socket_state_t *state)
90{ 80{
91 unsigned long power = 0; 81 return max1600_configure(skt->driver_data, state->Vcc, state->Vpp);
92 int ret = 0;
93
94 switch (state->Vcc) {
95 case 0: power |= MST_PCMCIA_PWR_VCC_0; break;
96 case 33: power |= MST_PCMCIA_PWR_VCC_33; break;
97 case 50: power |= MST_PCMCIA_PWR_VCC_50; break;
98 default:
99 printk(KERN_ERR "%s(): bad Vcc %u\n",
100 __func__, state->Vcc);
101 ret = -1;
102 }
103
104 switch (state->Vpp) {
105 case 0: power |= MST_PCMCIA_PWR_VPP_0; break;
106 case 120: power |= MST_PCMCIA_PWR_VPP_120; break;
107 default:
108 if(state->Vpp == state->Vcc) {
109 power |= MST_PCMCIA_PWR_VPP_VCC;
110 } else {
111 printk(KERN_ERR "%s(): bad Vpp %u\n",
112 __func__, state->Vpp);
113 ret = -1;
114 }
115 }
116
117 if (state->flags & SS_RESET)
118 power |= MST_PCMCIA_RESET;
119
120 switch (skt->nr) {
121 case 0: MST_PCMCIA0 = power; break;
122 case 1: MST_PCMCIA1 = power; break;
123 default: ret = -1;
124 }
125
126 return ret;
127} 82}
128 83
129static struct pcmcia_low_level mst_pcmcia_ops __initdata = { 84static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index e235ee14eaa6..e2e8729afd9d 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -39,8 +39,8 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
39{ 39{
40 long cs3reg = simpad_get_cs3_ro(); 40 long cs3reg = simpad_get_cs3_ro();
41 41
42 state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ 42 /* bvd1 might be cs3reg & PCMCIA_BVD1 */
43 state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ 43 /* bvd2 might be cs3reg & PCMCIA_BVD2 */
44 44
45 if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) == 45 if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
46 (PCMCIA_VS1|PCMCIA_VS2)) { 46 (PCMCIA_VS1|PCMCIA_VS2)) {
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index 3d4ca87ca76c..1083e1b4f25d 100644
--- a/drivers/pcmcia/sa1111_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -6,29 +6,62 @@
6 * 6 *
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/kernel.h>
10#include <linux/device.h> 9#include <linux/device.h>
11#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/gpio/consumer.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/io.h> 13#include <linux/io.h>
14 14
15#include <mach/hardware.h> 15#include <mach/hardware.h>
16#include <asm/hardware/sa1111.h>
17#include <asm/mach-types.h> 16#include <asm/mach-types.h>
18 17
19#include "sa1111_generic.h" 18#include "sa1111_generic.h"
20 19
21/* Does SOCKET1_3V actually do anything? */ 20/*
22#define SOCKET0_POWER GPIO_GPIO0 21 * Socket 0 power: GPIO A0
23#define SOCKET0_3V GPIO_GPIO2 22 * Socket 0 3V: GPIO A2
24#define SOCKET1_POWER (GPIO_GPIO1 | GPIO_GPIO3) 23 * Socket 1 power: GPIO A1 & GPIO A3
25#define SOCKET1_3V GPIO_GPIO3 24 * Socket 1 3V: GPIO A3
25 * Does Socket 1 3V actually do anything?
26 */
27enum {
28 J720_GPIO_PWR,
29 J720_GPIO_3V,
30 J720_GPIO_MAX,
31};
32struct jornada720_data {
33 struct gpio_desc *gpio[J720_GPIO_MAX];
34};
35
36static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
37{
38 struct device *dev = skt->socket.dev.parent;
39 struct jornada720_data *j;
40
41 j = devm_kzalloc(dev, sizeof(*j), GFP_KERNEL);
42 if (!j)
43 return -ENOMEM;
44
45 j->gpio[J720_GPIO_PWR] = devm_gpiod_get(dev, skt->nr ? "s1-power" :
46 "s0-power", GPIOD_OUT_LOW);
47 if (IS_ERR(j->gpio[J720_GPIO_PWR]))
48 return PTR_ERR(j->gpio[J720_GPIO_PWR]);
49
50 j->gpio[J720_GPIO_3V] = devm_gpiod_get(dev, skt->nr ? "s1-3v" :
51 "s0-3v", GPIOD_OUT_LOW);
52 if (IS_ERR(j->gpio[J720_GPIO_3V]))
53 return PTR_ERR(j->gpio[J720_GPIO_3V]);
54
55 skt->driver_data = j;
56
57 return 0;
58}
26 59
27static int 60static int
28jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 61jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
29{ 62{
30 struct sa1111_pcmcia_socket *s = to_skt(skt); 63 struct jornada720_data *j = skt->driver_data;
31 unsigned int pa_dwr_mask, pa_dwr_set; 64 DECLARE_BITMAP(values, J720_GPIO_MAX) = { 0, };
32 int ret; 65 int ret;
33 66
34 printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__, 67 printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
@@ -36,35 +69,34 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
36 69
37 switch (skt->nr) { 70 switch (skt->nr) {
38 case 0: 71 case 0:
39 pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
40
41 switch (state->Vcc) { 72 switch (state->Vcc) {
42 default: 73 default:
43 case 0: 74 case 0:
44 pa_dwr_set = 0; 75 __assign_bit(J720_GPIO_PWR, values, 0);
76 __assign_bit(J720_GPIO_3V, values, 0);
45 break; 77 break;
46 case 33: 78 case 33:
47 pa_dwr_set = SOCKET0_POWER | SOCKET0_3V; 79 __assign_bit(J720_GPIO_PWR, values, 1);
80 __assign_bit(J720_GPIO_3V, values, 1);
48 break; 81 break;
49 case 50: 82 case 50:
50 pa_dwr_set = SOCKET0_POWER; 83 __assign_bit(J720_GPIO_PWR, values, 1);
84 __assign_bit(J720_GPIO_3V, values, 0);
51 break; 85 break;
52 } 86 }
53 break; 87 break;
54 88
55 case 1: 89 case 1:
56 pa_dwr_mask = SOCKET1_POWER;
57
58 switch (state->Vcc) { 90 switch (state->Vcc) {
59 default: 91 default:
60 case 0: 92 case 0:
61 pa_dwr_set = 0; 93 __assign_bit(J720_GPIO_PWR, values, 0);
94 __assign_bit(J720_GPIO_3V, values, 0);
62 break; 95 break;
63 case 33: 96 case 33:
64 pa_dwr_set = SOCKET1_POWER;
65 break;
66 case 50: 97 case 50:
67 pa_dwr_set = SOCKET1_POWER; 98 __assign_bit(J720_GPIO_PWR, values, 1);
99 __assign_bit(J720_GPIO_3V, values, 1);
68 break; 100 break;
69 } 101 }
70 break; 102 break;
@@ -81,13 +113,15 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
81 113
82 ret = sa1111_pcmcia_configure_socket(skt, state); 114 ret = sa1111_pcmcia_configure_socket(skt, state);
83 if (ret == 0) 115 if (ret == 0)
84 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); 116 ret = gpiod_set_array_value_cansleep(J720_GPIO_MAX, j->gpio,
117 NULL, values);
85 118
86 return ret; 119 return ret;
87} 120}
88 121
89static struct pcmcia_low_level jornada720_pcmcia_ops = { 122static struct pcmcia_low_level jornada720_pcmcia_ops = {
90 .owner = THIS_MODULE, 123 .owner = THIS_MODULE,
124 .hw_init = jornada720_pcmcia_hw_init,
91 .configure_socket = jornada720_pcmcia_configure_socket, 125 .configure_socket = jornada720_pcmcia_configure_socket,
92 .first = 0, 126 .first = 0,
93 .nr = 2, 127 .nr = 2,
@@ -95,16 +129,9 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = {
95 129
96int pcmcia_jornada720_init(struct sa1111_dev *sadev) 130int pcmcia_jornada720_init(struct sa1111_dev *sadev)
97{ 131{
98 unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
99
100 /* Fixme: why messing around with SA11x0's GPIO1? */ 132 /* Fixme: why messing around with SA11x0's GPIO1? */
101 GRER |= 0x00000002; 133 GRER |= 0x00000002;
102 134
103 /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
104 sa1111_set_io_dir(sadev, pin, 0, 0);
105 sa1111_set_io(sadev, pin, 0);
106 sa1111_set_sleep_io(sadev, pin, 0);
107
108 sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); 135 sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
109 return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops, 136 return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
110 sa11xx_drv_pcmcia_add_one); 137 sa11xx_drv_pcmcia_add_one);
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index e741f499c875..e3fc14cfb42b 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -24,20 +24,31 @@
24#include <mach/hardware.h> 24#include <mach/hardware.h>
25#include <asm/hardware/sa1111.h> 25#include <asm/hardware/sa1111.h>
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <mach/lubbock.h>
28 27
29#include "sa1111_generic.h" 28#include "sa1111_generic.h"
29#include "max1600.h"
30
31static int lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
32{
33 struct max1600 *m;
34 int ret;
35
36 ret = max1600_init(skt->socket.dev.parent, &m,
37 skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
38 MAX1600_CODE_HIGH);
39 if (ret == 0)
40 skt->driver_data = m;
41
42 return ret;
43}
30 44
31static int 45static int
32lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 46lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
33 const socket_state_t *state) 47 const socket_state_t *state)
34{ 48{
35 struct sa1111_pcmcia_socket *s = to_skt(skt); 49 struct max1600 *m = skt->driver_data;
36 unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
37 int ret = 0; 50 int ret = 0;
38 51
39 pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
40
41 /* Lubbock uses the Maxim MAX1602, with the following connections: 52 /* Lubbock uses the Maxim MAX1602, with the following connections:
42 * 53 *
43 * Socket 0 (PCMCIA): 54 * Socket 0 (PCMCIA):
@@ -71,74 +82,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
71 again: 82 again:
72 switch (skt->nr) { 83 switch (skt->nr) {
73 case 0: 84 case 0:
74 pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
75
76 switch (state->Vcc) {
77 case 0: /* Hi-Z */
78 break;
79
80 case 33: /* VY */
81 pa_dwr_set |= GPIO_A3;
82 break;
83
84 case 50: /* VX */
85 pa_dwr_set |= GPIO_A2;
86 break;
87
88 default:
89 printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
90 __func__, state->Vcc);
91 ret = -1;
92 }
93
94 switch (state->Vpp) {
95 case 0: /* Hi-Z */
96 break;
97
98 case 120: /* 12IN */
99 pa_dwr_set |= GPIO_A1;
100 break;
101
102 default: /* VCC */
103 if (state->Vpp == state->Vcc)
104 pa_dwr_set |= GPIO_A0;
105 else {
106 printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
107 __func__, state->Vpp);
108 ret = -1;
109 break;
110 }
111 }
112 break;
113
114 case 1: 85 case 1:
115 misc_mask = (1 << 15) | (1 << 14);
116
117 switch (state->Vcc) {
118 case 0: /* Hi-Z */
119 break;
120
121 case 33: /* VY */
122 misc_set |= 1 << 15;
123 break;
124
125 case 50: /* VX */
126 misc_set |= 1 << 14;
127 break;
128
129 default:
130 printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
131 __func__, state->Vcc);
132 ret = -1;
133 break;
134 }
135
136 if (state->Vpp != state->Vcc && state->Vpp != 0) {
137 printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
138 __func__, state->Vpp);
139 ret = -1;
140 break;
141 }
142 break; 86 break;
143 87
144 default: 88 default:
@@ -147,11 +91,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
147 91
148 if (ret == 0) 92 if (ret == 0)
149 ret = sa1111_pcmcia_configure_socket(skt, state); 93 ret = sa1111_pcmcia_configure_socket(skt, state);
150 94 if (ret == 0)
151 if (ret == 0) { 95 ret = max1600_configure(m, state->Vcc, state->Vpp);
152 lubbock_set_misc_wr(misc_mask, misc_set);
153 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
154 }
155 96
156#if 1 97#if 1
157 if (ret == 0 && state->Vcc == 33) { 98 if (ret == 0 && state->Vcc == 33) {
@@ -175,8 +116,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
175 /* 116 /*
176 * Switch to 5V, Configure socket with 5V voltage 117 * Switch to 5V, Configure socket with 5V voltage
177 */ 118 */
178 lubbock_set_misc_wr(misc_mask, 0); 119 max1600_configure(m, 0, 0);
179 sa1111_set_io(s->dev, pa_dwr_mask, 0);
180 120
181 /* 121 /*
182 * It takes about 100ms to turn off Vcc. 122 * It takes about 100ms to turn off Vcc.
@@ -201,6 +141,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
201 141
202static struct pcmcia_low_level lubbock_pcmcia_ops = { 142static struct pcmcia_low_level lubbock_pcmcia_ops = {
203 .owner = THIS_MODULE, 143 .owner = THIS_MODULE,
144 .hw_init = lubbock_pcmcia_hw_init,
204 .configure_socket = lubbock_pcmcia_configure_socket, 145 .configure_socket = lubbock_pcmcia_configure_socket,
205 .first = 0, 146 .first = 0,
206 .nr = 2, 147 .nr = 2,
@@ -210,17 +151,6 @@ static struct pcmcia_low_level lubbock_pcmcia_ops = {
210 151
211int pcmcia_lubbock_init(struct sa1111_dev *sadev) 152int pcmcia_lubbock_init(struct sa1111_dev *sadev)
212{ 153{
213 /*
214 * Set GPIO_A<3:0> to be outputs for the MAX1600,
215 * and switch to standby mode.
216 */
217 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
218 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
219 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
220
221 /* Set CF Socket 1 power to standby mode. */
222 lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
223
224 pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); 154 pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
225 pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops); 155 pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
226 return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, 156 return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index 0ccf05a28a4b..de0ce13355b4 100644
--- a/drivers/pcmcia/sa1111_neponset.c
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -10,12 +10,10 @@
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/init.h> 11#include <linux/init.h>
12 12
13#include <mach/hardware.h>
14#include <asm/mach-types.h> 13#include <asm/mach-types.h>
15#include <mach/neponset.h>
16#include <asm/hardware/sa1111.h>
17 14
18#include "sa1111_generic.h" 15#include "sa1111_generic.h"
16#include "max1600.h"
19 17
20/* 18/*
21 * Neponset uses the Maxim MAX1600, with the following connections: 19 * Neponset uses the Maxim MAX1600, with the following connections:
@@ -40,70 +38,36 @@
40 * "Standard Intel code" mode. Refer to the Maxim data sheet for 38 * "Standard Intel code" mode. Refer to the Maxim data sheet for
41 * the corresponding truth table. 39 * the corresponding truth table.
42 */ 40 */
43 41static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
44static int
45neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
46{ 42{
47 struct sa1111_pcmcia_socket *s = to_skt(skt); 43 struct max1600 *m;
48 unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
49 int ret; 44 int ret;
50 45
51 switch (skt->nr) { 46 ret = max1600_init(skt->socket.dev.parent, &m,
52 case 0: 47 skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
53 pa_dwr_mask = GPIO_A0 | GPIO_A1; 48 MAX1600_CODE_LOW);
54 ncr_mask = NCR_A0VPP | NCR_A1VPP; 49 if (ret == 0)
55 50 skt->driver_data = m;
56 if (state->Vpp == 0)
57 ncr_set = 0;
58 else if (state->Vpp == 120)
59 ncr_set = NCR_A1VPP;
60 else if (state->Vpp == state->Vcc)
61 ncr_set = NCR_A0VPP;
62 else {
63 printk(KERN_ERR "%s(): unrecognized VPP %u\n",
64 __func__, state->Vpp);
65 return -1;
66 }
67 break;
68
69 case 1:
70 pa_dwr_mask = GPIO_A2 | GPIO_A3;
71 ncr_mask = 0;
72 ncr_set = 0;
73
74 if (state->Vpp != state->Vcc && state->Vpp != 0) {
75 printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
76 __func__, state->Vpp);
77 return -1;
78 }
79 break;
80 51
81 default: 52 return ret;
82 return -1; 53}
83 }
84 54
85 /* 55static int
86 * pa_dwr_set is the mask for selecting Vcc on both sockets. 56neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
87 * pa_dwr_mask selects which bits (and therefore socket) we change. 57{
88 */ 58 struct max1600 *m = skt->driver_data;
89 switch (state->Vcc) { 59 int ret;
90 default:
91 case 0: pa_dwr_set = 0; break;
92 case 33: pa_dwr_set = GPIO_A1|GPIO_A2; break;
93 case 50: pa_dwr_set = GPIO_A0|GPIO_A3; break;
94 }
95 60
96 ret = sa1111_pcmcia_configure_socket(skt, state); 61 ret = sa1111_pcmcia_configure_socket(skt, state);
97 if (ret == 0) { 62 if (ret == 0)
98 neponset_ncr_frob(ncr_mask, ncr_set); 63 ret = max1600_configure(m, state->Vcc, state->Vpp);
99 sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
100 }
101 64
102 return ret; 65 return ret;
103} 66}
104 67
105static struct pcmcia_low_level neponset_pcmcia_ops = { 68static struct pcmcia_low_level neponset_pcmcia_ops = {
106 .owner = THIS_MODULE, 69 .owner = THIS_MODULE,
70 .hw_init = neponset_pcmcia_hw_init,
107 .configure_socket = neponset_pcmcia_configure_socket, 71 .configure_socket = neponset_pcmcia_configure_socket,
108 .first = 0, 72 .first = 0,
109 .nr = 2, 73 .nr = 2,
@@ -111,13 +75,6 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
111 75
112int pcmcia_neponset_init(struct sa1111_dev *sadev) 76int pcmcia_neponset_init(struct sa1111_dev *sadev)
113{ 77{
114 /*
115 * Set GPIO_A<3:0> to be outputs for the MAX1600,
116 * and switch to standby mode.
117 */
118 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
119 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
120 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
121 sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); 78 sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
122 return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, 79 return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
123 sa11xx_drv_pcmcia_add_one); 80 sa11xx_drv_pcmcia_add_one);