aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/00-INDEX2
-rw-r--r--Documentation/arm/swp_emulation27
-rw-r--r--arch/arm/Kconfig65
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/common/Kconfig4
-rw-r--r--arch/arm/common/dmabounce.c16
-rw-r--r--arch/arm/include/asm/assembler.h35
-rw-r--r--arch/arm/include/asm/cache.h2
-rw-r--r--arch/arm/include/asm/clkdev.h22
-rw-r--r--arch/arm/include/asm/dma-mapping.h93
-rw-r--r--arch/arm/include/asm/domain.h31
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S44
-rw-r--r--arch/arm/include/asm/futex.h9
-rw-r--r--arch/arm/include/asm/hardirq.h18
-rw-r--r--arch/arm/include/asm/localtimer.h12
-rw-r--r--arch/arm/include/asm/mach/arch.h9
-rw-r--r--arch/arm/include/asm/mach/irq.h8
-rw-r--r--arch/arm/include/asm/mach/time.h1
-rw-r--r--arch/arm/include/asm/smp.h17
-rw-r--r--arch/arm/include/asm/smp_mpidr.h17
-rw-r--r--arch/arm/include/asm/smp_twd.h1
-rw-r--r--arch/arm/include/asm/system.h7
-rw-r--r--arch/arm/include/asm/traps.h2
-rw-r--r--arch/arm/include/asm/uaccess.h16
-rw-r--r--arch/arm/kernel/Makefile4
-rw-r--r--arch/arm/kernel/entry-armv.S52
-rw-r--r--arch/arm/kernel/fiq.c10
-rw-r--r--arch/arm/kernel/head.S50
-rw-r--r--arch/arm/kernel/irq.c30
-rw-r--r--arch/arm/kernel/setup.c37
-rw-r--r--arch/arm/kernel/smp.c409
-rw-r--r--arch/arm/kernel/smp_tlb.c139
-rw-r--r--arch/arm/kernel/smp_twd.c10
-rw-r--r--arch/arm/kernel/swp_emulate.c267
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c14
-rw-r--r--arch/arm/kernel/vmlinux.lds.S1
-rw-r--r--arch/arm/lib/getuser.S13
-rw-r--r--arch/arm/lib/putuser.S29
-rw-r--r--arch/arm/lib/uaccess.S83
-rw-r--r--arch/arm/mach-bcmring/clock.c3
-rw-r--r--arch/arm/mach-bcmring/core.c2
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig1
-rw-r--r--arch/arm/mach-davinci/clock.h2
-rw-r--r--arch/arm/mach-ep93xx/clock.c2
-rw-r--r--arch/arm/mach-imx/clock-imx1.c3
-rw-r--r--arch/arm/mach-imx/clock-imx21.c2
-rw-r--r--arch/arm/mach-imx/clock-imx27.c2
-rw-r--r--arch/arm/mach-integrator/Kconfig1
-rw-r--r--arch/arm/mach-integrator/core.c3
-rw-r--r--arch/arm/mach-integrator/impd1.c3
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c3
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h6
-rw-r--r--arch/arm/mach-ks8695/Kconfig1
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h8
-rw-r--r--arch/arm/mach-lpc32xx/clock.c3
-rw-r--r--arch/arm/mach-mmp/clock.h2
-rw-r--r--arch/arm/mach-msm/include/mach/smp.h4
-rw-r--r--arch/arm/mach-mx25/clock.c3
-rw-r--r--arch/arm/mach-mx3/clock-imx31.c2
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c3
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c2
-rw-r--r--arch/arm/mach-mxc91231/clock.c2
-rw-r--r--arch/arm/mach-nomadik/clock.c2
-rw-r--r--arch/arm/mach-nuc93x/clock.h2
-rw-r--r--arch/arm/mach-omap1/clock.c2
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c2
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c14
-rw-r--r--arch/arm/mach-omap2/omap-smp.c66
-rw-r--r--arch/arm/mach-pnx4008/clock.c3
-rw-r--r--arch/arm/mach-pxa/Kconfig1
-rw-r--r--arch/arm/mach-pxa/clock.c2
-rw-r--r--arch/arm/mach-pxa/clock.h2
-rw-r--r--arch/arm/mach-realview/core.c3
-rw-r--r--arch/arm/mach-realview/hotplug.c44
-rw-r--r--arch/arm/mach-realview/include/mach/smp.h5
-rw-r--r--arch/arm/mach-realview/platsmp.c114
-rw-r--r--arch/arm/mach-s3c2412/Kconfig2
-rw-r--r--arch/arm/mach-s5pv310/hotplug.c44
-rw-r--r--arch/arm/mach-s5pv310/include/mach/smp.h5
-rw-r--r--arch/arm/mach-s5pv310/platsmp.c66
-rw-r--r--arch/arm/mach-shmobile/Kconfig6
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-tcc8k/clock.c3
-rw-r--r--arch/arm/mach-tegra/clock.c2
-rw-r--r--arch/arm/mach-tegra/clock.h2
-rw-r--r--arch/arm/mach-tegra/hotplug.c44
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h12
-rw-r--r--arch/arm/mach-tegra/platsmp.c33
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c3
-rw-r--r--arch/arm/mach-u300/clock.c2
-rw-r--r--arch/arm/mach-ux500/clock.c3
-rw-r--r--arch/arm/mach-ux500/headsmp.S1
-rw-r--r--arch/arm/mach-ux500/hotplug.c18
-rw-r--r--arch/arm/mach-ux500/include/mach/smp.h5
-rw-r--r--arch/arm/mach-ux500/platsmp.c73
-rw-r--r--arch/arm/mach-versatile/Kconfig1
-rw-r--r--arch/arm/mach-versatile/core.c3
-rw-r--r--arch/arm/mach-vexpress/Makefile1
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c3
-rw-r--r--arch/arm/mach-vexpress/hotplug.c128
-rw-r--r--arch/arm/mach-vexpress/include/mach/smp.h5
-rw-r--r--arch/arm/mach-vexpress/platsmp.c74
-rw-r--r--arch/arm/mach-vexpress/v2m.c3
-rw-r--r--arch/arm/mach-w90x900/clock.h2
-rw-r--r--arch/arm/mm/Kconfig35
-rw-r--r--arch/arm/mm/dma-mapping.c28
-rw-r--r--arch/arm/mm/ioremap.c8
-rw-r--r--arch/arm/mm/mmu.c6
-rw-r--r--arch/arm/mm/proc-macros.S7
-rw-r--r--arch/arm/mm/proc-v7.S9
-rw-r--r--arch/arm/plat-omap/Kconfig4
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h2
-rw-r--r--arch/arm/plat-omap/include/plat/memory.h8
-rw-r--r--arch/arm/plat-omap/include/plat/smp.h5
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h2
-rw-r--r--arch/arm/plat-stmp3xxx/clock.c2
-rw-r--r--arch/arm/vfp/vfpmodule.c24
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/boards/mach-highlander/setup.c2
-rw-r--r--arch/sh/include/asm/clkdev.h38
-rw-r--r--arch/sh/kernel/Makefile2
-rw-r--r--arch/sh/kernel/clkdev.c171
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c2
-rw-r--r--arch/sh/kernel/cpu/clock.c16
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c2
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/amba/bus.c39
-rw-r--r--drivers/clk/Kconfig4
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/clkdev.c (renamed from arch/arm/common/clkdev.c)13
-rw-r--r--include/linux/amba/bus.h8
-rw-r--r--include/linux/clkdev.h36
147 files changed, 1674 insertions, 1316 deletions
diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index ecf7d04bca26..91c24a1e8a9e 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -34,3 +34,5 @@ memory.txt
34 - description of the virtual memory layout 34 - description of the virtual memory layout
35nwfpe/ 35nwfpe/
36 - NWFPE floating point emulator documentation 36 - NWFPE floating point emulator documentation
37swp_emulation
38 - SWP/SWPB emulation handler/logging description
diff --git a/Documentation/arm/swp_emulation b/Documentation/arm/swp_emulation
new file mode 100644
index 000000000000..af903d22fd93
--- /dev/null
+++ b/Documentation/arm/swp_emulation
@@ -0,0 +1,27 @@
1Software emulation of deprecated SWP instruction (CONFIG_SWP_EMULATE)
2---------------------------------------------------------------------
3
4ARMv6 architecture deprecates use of the SWP/SWPB instructions, and recommeds
5moving to the load-locked/store-conditional instructions LDREX and STREX.
6
7ARMv7 multiprocessing extensions introduce the ability to disable these
8instructions, triggering an undefined instruction exception when executed.
9Trapped instructions are emulated using an LDREX/STREX or LDREXB/STREXB
10sequence. If a memory access fault (an abort) occurs, a segmentation fault is
11signalled to the triggering process.
12
13/proc/cpu/swp_emulation holds some statistics/information, including the PID of
14the last process to trigger the emulation to be invocated. For example:
15---
16Emulated SWP: 12
17Emulated SWPB: 0
18Aborted SWP{B}: 1
19Last process: 314
20---
21
22NOTE: when accessing uncached shared regions, LDREX/STREX rely on an external
23transaction monitoring block called a global monitor to maintain update
24atomicity. If your system does not implement a global monitor, this option can
25cause programs that perform SWP operations to uncached memory to deadlock, as
26the STREX operation will always fail.
27
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2e86b8f62104..32cbf3e888ff 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
2 bool 2 bool
3 default y 3 default y
4 select HAVE_AOUT 4 select HAVE_AOUT
5 select HAVE_DMA_API_DEBUG
5 select HAVE_IDE 6 select HAVE_IDE
6 select HAVE_MEMBLOCK 7 select HAVE_MEMBLOCK
7 select RTC_LIB 8 select RTC_LIB
@@ -36,6 +37,9 @@ config ARM
36config HAVE_PWM 37config HAVE_PWM
37 bool 38 bool
38 39
40config MIGHT_HAVE_PCI
41 bool
42
39config SYS_SUPPORTS_APM_EMULATION 43config SYS_SUPPORTS_APM_EMULATION
40 bool 44 bool
41 45
@@ -226,7 +230,7 @@ config ARCH_INTEGRATOR
226 bool "ARM Ltd. Integrator family" 230 bool "ARM Ltd. Integrator family"
227 select ARM_AMBA 231 select ARM_AMBA
228 select ARCH_HAS_CPUFREQ 232 select ARCH_HAS_CPUFREQ
229 select COMMON_CLKDEV 233 select CLKDEV_LOOKUP
230 select ICST 234 select ICST
231 select GENERIC_CLOCKEVENTS 235 select GENERIC_CLOCKEVENTS
232 select PLAT_VERSATILE 236 select PLAT_VERSATILE
@@ -236,7 +240,7 @@ config ARCH_INTEGRATOR
236config ARCH_REALVIEW 240config ARCH_REALVIEW
237 bool "ARM Ltd. RealView family" 241 bool "ARM Ltd. RealView family"
238 select ARM_AMBA 242 select ARM_AMBA
239 select COMMON_CLKDEV 243 select CLKDEV_LOOKUP
240 select HAVE_SCHED_CLOCK 244 select HAVE_SCHED_CLOCK
241 select ICST 245 select ICST
242 select GENERIC_CLOCKEVENTS 246 select GENERIC_CLOCKEVENTS
@@ -251,7 +255,7 @@ config ARCH_VERSATILE
251 bool "ARM Ltd. Versatile family" 255 bool "ARM Ltd. Versatile family"
252 select ARM_AMBA 256 select ARM_AMBA
253 select ARM_VIC 257 select ARM_VIC
254 select COMMON_CLKDEV 258 select CLKDEV_LOOKUP
255 select HAVE_SCHED_CLOCK 259 select HAVE_SCHED_CLOCK
256 select ICST 260 select ICST
257 select GENERIC_CLOCKEVENTS 261 select GENERIC_CLOCKEVENTS
@@ -266,7 +270,7 @@ config ARCH_VEXPRESS
266 select ARCH_WANT_OPTIONAL_GPIOLIB 270 select ARCH_WANT_OPTIONAL_GPIOLIB
267 select ARM_AMBA 271 select ARM_AMBA
268 select ARM_TIMER_SP804 272 select ARM_TIMER_SP804
269 select COMMON_CLKDEV 273 select CLKDEV_LOOKUP
270 select GENERIC_CLOCKEVENTS 274 select GENERIC_CLOCKEVENTS
271 select HAVE_CLK 275 select HAVE_CLK
272 select HAVE_SCHED_CLOCK 276 select HAVE_SCHED_CLOCK
@@ -288,7 +292,7 @@ config ARCH_BCMRING
288 depends on MMU 292 depends on MMU
289 select CPU_V6 293 select CPU_V6
290 select ARM_AMBA 294 select ARM_AMBA
291 select COMMON_CLKDEV 295 select CLKDEV_LOOKUP
292 select GENERIC_CLOCKEVENTS 296 select GENERIC_CLOCKEVENTS
293 select ARCH_WANT_OPTIONAL_GPIOLIB 297 select ARCH_WANT_OPTIONAL_GPIOLIB
294 help 298 help
@@ -306,6 +310,7 @@ config ARCH_CNS3XXX
306 select CPU_V6 310 select CPU_V6
307 select GENERIC_CLOCKEVENTS 311 select GENERIC_CLOCKEVENTS
308 select ARM_GIC 312 select ARM_GIC
313 select MIGHT_HAVE_PCI
309 select PCI_DOMAINS if PCI 314 select PCI_DOMAINS if PCI
310 help 315 help
311 Support for Cavium Networks CNS3XXX platform. 316 Support for Cavium Networks CNS3XXX platform.
@@ -335,7 +340,7 @@ config ARCH_EP93XX
335 select CPU_ARM920T 340 select CPU_ARM920T
336 select ARM_AMBA 341 select ARM_AMBA
337 select ARM_VIC 342 select ARM_VIC
338 select COMMON_CLKDEV 343 select CLKDEV_LOOKUP
339 select ARCH_REQUIRE_GPIOLIB 344 select ARCH_REQUIRE_GPIOLIB
340 select ARCH_HAS_HOLES_MEMORYMODEL 345 select ARCH_HAS_HOLES_MEMORYMODEL
341 select ARCH_USES_GETTIMEOFFSET 346 select ARCH_USES_GETTIMEOFFSET
@@ -355,14 +360,14 @@ config ARCH_MXC
355 bool "Freescale MXC/iMX-based" 360 bool "Freescale MXC/iMX-based"
356 select GENERIC_CLOCKEVENTS 361 select GENERIC_CLOCKEVENTS
357 select ARCH_REQUIRE_GPIOLIB 362 select ARCH_REQUIRE_GPIOLIB
358 select COMMON_CLKDEV 363 select CLKDEV_LOOKUP
359 help 364 help
360 Support for Freescale MXC/iMX-based family of processors 365 Support for Freescale MXC/iMX-based family of processors
361 366
362config ARCH_STMP3XXX 367config ARCH_STMP3XXX
363 bool "Freescale STMP3xxx" 368 bool "Freescale STMP3xxx"
364 select CPU_ARM926T 369 select CPU_ARM926T
365 select COMMON_CLKDEV 370 select CLKDEV_LOOKUP
366 select ARCH_REQUIRE_GPIOLIB 371 select ARCH_REQUIRE_GPIOLIB
367 select GENERIC_CLOCKEVENTS 372 select GENERIC_CLOCKEVENTS
368 select USB_ARCH_HAS_EHCI 373 select USB_ARCH_HAS_EHCI
@@ -442,6 +447,7 @@ config ARCH_IXP4XX
442 select GENERIC_GPIO 447 select GENERIC_GPIO
443 select GENERIC_CLOCKEVENTS 448 select GENERIC_CLOCKEVENTS
444 select HAVE_SCHED_CLOCK 449 select HAVE_SCHED_CLOCK
450 select MIGHT_HAVE_PCI
445 select DMABOUNCE if PCI 451 select DMABOUNCE if PCI
446 help 452 help
447 Support for Intel's IXP4XX (XScale) family of processors. 453 Support for Intel's IXP4XX (XScale) family of processors.
@@ -481,7 +487,7 @@ config ARCH_LPC32XX
481 select HAVE_IDE 487 select HAVE_IDE
482 select ARM_AMBA 488 select ARM_AMBA
483 select USB_ARCH_HAS_OHCI 489 select USB_ARCH_HAS_OHCI
484 select COMMON_CLKDEV 490 select CLKDEV_LOOKUP
485 select GENERIC_TIME 491 select GENERIC_TIME
486 select GENERIC_CLOCKEVENTS 492 select GENERIC_CLOCKEVENTS
487 help 493 help
@@ -515,7 +521,7 @@ config ARCH_MMP
515 bool "Marvell PXA168/910/MMP2" 521 bool "Marvell PXA168/910/MMP2"
516 depends on MMU 522 depends on MMU
517 select ARCH_REQUIRE_GPIOLIB 523 select ARCH_REQUIRE_GPIOLIB
518 select COMMON_CLKDEV 524 select CLKDEV_LOOKUP
519 select GENERIC_CLOCKEVENTS 525 select GENERIC_CLOCKEVENTS
520 select HAVE_SCHED_CLOCK 526 select HAVE_SCHED_CLOCK
521 select TICK_ONESHOT 527 select TICK_ONESHOT
@@ -549,7 +555,7 @@ config ARCH_W90X900
549 bool "Nuvoton W90X900 CPU" 555 bool "Nuvoton W90X900 CPU"
550 select CPU_ARM926T 556 select CPU_ARM926T
551 select ARCH_REQUIRE_GPIOLIB 557 select ARCH_REQUIRE_GPIOLIB
552 select COMMON_CLKDEV 558 select CLKDEV_LOOKUP
553 select GENERIC_CLOCKEVENTS 559 select GENERIC_CLOCKEVENTS
554 help 560 help
555 Support for Nuvoton (Winbond logic dept.) ARM9 processor, 561 Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -563,19 +569,19 @@ config ARCH_W90X900
563config ARCH_NUC93X 569config ARCH_NUC93X
564 bool "Nuvoton NUC93X CPU" 570 bool "Nuvoton NUC93X CPU"
565 select CPU_ARM926T 571 select CPU_ARM926T
566 select COMMON_CLKDEV 572 select CLKDEV_LOOKUP
567 help 573 help
568 Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a 574 Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
569 low-power and high performance MPEG-4/JPEG multimedia controller chip. 575 low-power and high performance MPEG-4/JPEG multimedia controller chip.
570 576
571config ARCH_TEGRA 577config ARCH_TEGRA
572 bool "NVIDIA Tegra" 578 bool "NVIDIA Tegra"
579 select CLKDEV_LOOKUP
573 select GENERIC_TIME 580 select GENERIC_TIME
574 select GENERIC_CLOCKEVENTS 581 select GENERIC_CLOCKEVENTS
575 select GENERIC_GPIO 582 select GENERIC_GPIO
576 select HAVE_CLK 583 select HAVE_CLK
577 select HAVE_SCHED_CLOCK 584 select HAVE_SCHED_CLOCK
578 select COMMON_CLKDEV
579 select ARCH_HAS_BARRIERS if CACHE_L2X0 585 select ARCH_HAS_BARRIERS if CACHE_L2X0
580 select ARCH_HAS_CPUFREQ 586 select ARCH_HAS_CPUFREQ
581 help 587 help
@@ -585,7 +591,7 @@ config ARCH_TEGRA
585config ARCH_PNX4008 591config ARCH_PNX4008
586 bool "Philips Nexperia PNX4008 Mobile" 592 bool "Philips Nexperia PNX4008 Mobile"
587 select CPU_ARM926T 593 select CPU_ARM926T
588 select COMMON_CLKDEV 594 select CLKDEV_LOOKUP
589 select ARCH_USES_GETTIMEOFFSET 595 select ARCH_USES_GETTIMEOFFSET
590 help 596 help
591 This enables support for Philips PNX4008 mobile platform. 597 This enables support for Philips PNX4008 mobile platform.
@@ -595,7 +601,7 @@ config ARCH_PXA
595 depends on MMU 601 depends on MMU
596 select ARCH_MTD_XIP 602 select ARCH_MTD_XIP
597 select ARCH_HAS_CPUFREQ 603 select ARCH_HAS_CPUFREQ
598 select COMMON_CLKDEV 604 select CLKDEV_LOOKUP
599 select ARCH_REQUIRE_GPIOLIB 605 select ARCH_REQUIRE_GPIOLIB
600 select GENERIC_CLOCKEVENTS 606 select GENERIC_CLOCKEVENTS
601 select HAVE_SCHED_CLOCK 607 select HAVE_SCHED_CLOCK
@@ -774,7 +780,7 @@ config ARCH_TCC_926
774 bool "Telechips TCC ARM926-based systems" 780 bool "Telechips TCC ARM926-based systems"
775 select CPU_ARM926T 781 select CPU_ARM926T
776 select HAVE_CLK 782 select HAVE_CLK
777 select COMMON_CLKDEV 783 select CLKDEV_LOOKUP
778 select GENERIC_CLOCKEVENTS 784 select GENERIC_CLOCKEVENTS
779 help 785 help
780 Support for Telechips TCC ARM926-based systems. 786 Support for Telechips TCC ARM926-based systems.
@@ -799,7 +805,7 @@ config ARCH_U300
799 select ARM_AMBA 805 select ARM_AMBA
800 select ARM_VIC 806 select ARM_VIC
801 select GENERIC_CLOCKEVENTS 807 select GENERIC_CLOCKEVENTS
802 select COMMON_CLKDEV 808 select CLKDEV_LOOKUP
803 select GENERIC_GPIO 809 select GENERIC_GPIO
804 help 810 help
805 Support for ST-Ericsson U300 series mobile platforms. 811 Support for ST-Ericsson U300 series mobile platforms.
@@ -809,7 +815,7 @@ config ARCH_U8500
809 select CPU_V7 815 select CPU_V7
810 select ARM_AMBA 816 select ARM_AMBA
811 select GENERIC_CLOCKEVENTS 817 select GENERIC_CLOCKEVENTS
812 select COMMON_CLKDEV 818 select CLKDEV_LOOKUP
813 select ARCH_REQUIRE_GPIOLIB 819 select ARCH_REQUIRE_GPIOLIB
814 help 820 help
815 Support for ST-Ericsson's Ux500 architecture 821 Support for ST-Ericsson's Ux500 architecture
@@ -819,7 +825,7 @@ config ARCH_NOMADIK
819 select ARM_AMBA 825 select ARM_AMBA
820 select ARM_VIC 826 select ARM_VIC
821 select CPU_ARM926T 827 select CPU_ARM926T
822 select COMMON_CLKDEV 828 select CLKDEV_LOOKUP
823 select GENERIC_CLOCKEVENTS 829 select GENERIC_CLOCKEVENTS
824 select ARCH_REQUIRE_GPIOLIB 830 select ARCH_REQUIRE_GPIOLIB
825 help 831 help
@@ -831,7 +837,7 @@ config ARCH_DAVINCI
831 select ARCH_REQUIRE_GPIOLIB 837 select ARCH_REQUIRE_GPIOLIB
832 select ZONE_DMA 838 select ZONE_DMA
833 select HAVE_IDE 839 select HAVE_IDE
834 select COMMON_CLKDEV 840 select CLKDEV_LOOKUP
835 select GENERIC_ALLOCATOR 841 select GENERIC_ALLOCATOR
836 select ARCH_HAS_HOLES_MEMORYMODEL 842 select ARCH_HAS_HOLES_MEMORYMODEL
837 help 843 help
@@ -852,7 +858,7 @@ config PLAT_SPEAR
852 bool "ST SPEAr" 858 bool "ST SPEAr"
853 select ARM_AMBA 859 select ARM_AMBA
854 select ARCH_REQUIRE_GPIOLIB 860 select ARCH_REQUIRE_GPIOLIB
855 select COMMON_CLKDEV 861 select CLKDEV_LOOKUP
856 select GENERIC_CLOCKEVENTS 862 select GENERIC_CLOCKEVENTS
857 select HAVE_CLK 863 select HAVE_CLK
858 help 864 help
@@ -1034,6 +1040,11 @@ config CPU_HAS_PMU
1034 default y 1040 default y
1035 bool 1041 bool
1036 1042
1043config MULTI_IRQ_HANDLER
1044 bool
1045 help
1046 Allow each machine to specify it's own IRQ handler at run time.
1047
1037if !MMU 1048if !MMU
1038source "arch/arm/Kconfig-nommu" 1049source "arch/arm/Kconfig-nommu"
1039endif 1050endif
@@ -1181,7 +1192,7 @@ config ISA_DMA_API
1181 bool 1192 bool
1182 1193
1183config PCI 1194config PCI
1184 bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX || SA1100_NANOENGINE 1195 bool "PCI support" if MIGHT_HAVE_PCI
1185 help 1196 help
1186 Find out whether you have a PCI motherboard. PCI is the name of a 1197 Find out whether you have a PCI motherboard. PCI is the name of a
1187 bus system, i.e. the way the CPU talks to the other stuff inside 1198 bus system, i.e. the way the CPU talks to the other stuff inside
@@ -1253,7 +1264,7 @@ config SMP
1253config SMP_ON_UP 1264config SMP_ON_UP
1254 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)" 1265 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
1255 depends on EXPERIMENTAL 1266 depends on EXPERIMENTAL
1256 depends on SMP && !XIP && !THUMB2_KERNEL 1267 depends on SMP && !XIP
1257 default y 1268 default y
1258 help 1269 help
1259 SMP kernels contain instructions which fail on non-SMP processors. 1270 SMP kernels contain instructions which fail on non-SMP processors.
@@ -1272,6 +1283,7 @@ config HAVE_ARM_SCU
1272config HAVE_ARM_TWD 1283config HAVE_ARM_TWD
1273 bool 1284 bool
1274 depends on SMP 1285 depends on SMP
1286 select TICK_ONESHOT
1275 help 1287 help
1276 This options enables support for the ARM timer and watchdog unit 1288 This options enables support for the ARM timer and watchdog unit
1277 1289
@@ -1335,7 +1347,7 @@ config HZ
1335 default 100 1347 default 100
1336 1348
1337config THUMB2_KERNEL 1349config THUMB2_KERNEL
1338 bool "Compile the kernel in Thumb-2 mode" 1350 bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
1339 depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL 1351 depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
1340 select AEABI 1352 select AEABI
1341 select ARM_ASM_UNIFIED 1353 select ARM_ASM_UNIFIED
@@ -1549,6 +1561,7 @@ config SECCOMP
1549 1561
1550config CC_STACKPROTECTOR 1562config CC_STACKPROTECTOR
1551 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" 1563 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
1564 depends on EXPERIMENTAL
1552 help 1565 help
1553 This option turns on the -fstack-protector GCC feature. This 1566 This option turns on the -fstack-protector GCC feature. This
1554 feature puts, at the beginning of functions, a canary value on 1567 feature puts, at the beginning of functions, a canary value on
@@ -1745,7 +1758,7 @@ config CPU_FREQ_S3C
1745 Internal configuration node for common cpufreq on Samsung SoC 1758 Internal configuration node for common cpufreq on Samsung SoC
1746 1759
1747config CPU_FREQ_S3C24XX 1760config CPU_FREQ_S3C24XX
1748 bool "CPUfreq driver for Samsung S3C24XX series CPUs" 1761 bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
1749 depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL 1762 depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
1750 select CPU_FREQ_S3C 1763 select CPU_FREQ_S3C
1751 help 1764 help
@@ -1757,7 +1770,7 @@ config CPU_FREQ_S3C24XX
1757 If in doubt, say N. 1770 If in doubt, say N.
1758 1771
1759config CPU_FREQ_S3C24XX_PLL 1772config CPU_FREQ_S3C24XX_PLL
1760 bool "Support CPUfreq changing of PLL frequency" 1773 bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
1761 depends on CPU_FREQ_S3C24XX && EXPERIMENTAL 1774 depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
1762 help 1775 help
1763 Compile in support for changing the PLL frequency from the 1776 Compile in support for changing the PLL frequency from the
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index eac62085f5b2..494224a9b459 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -31,7 +31,7 @@ config FRAME_POINTER
31 reported is severely limited. 31 reported is severely limited.
32 32
33config ARM_UNWIND 33config ARM_UNWIND
34 bool "Enable stack unwinding support" 34 bool "Enable stack unwinding support (EXPERIMENTAL)"
35 depends on AEABI && EXPERIMENTAL 35 depends on AEABI && EXPERIMENTAL
36 default y 36 default y
37 help 37 help
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 0a34c8186924..778655f0257a 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -37,7 +37,3 @@ config SHARP_PARAM
37 37
38config SHARP_SCOOP 38config SHARP_SCOOP
39 bool 39 bool
40
41config COMMON_CLKDEV
42 bool
43 select HAVE_CLK
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index cc0a932bbea9..e5681636626f 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -328,7 +328,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
328 * substitute the safe buffer for the unsafe one. 328 * substitute the safe buffer for the unsafe one.
329 * (basically move the buffer from an unsafe area to a safe one) 329 * (basically move the buffer from an unsafe area to a safe one)
330 */ 330 */
331dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, 331dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
332 enum dma_data_direction dir) 332 enum dma_data_direction dir)
333{ 333{
334 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 334 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -338,7 +338,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
338 338
339 return map_single(dev, ptr, size, dir); 339 return map_single(dev, ptr, size, dir);
340} 340}
341EXPORT_SYMBOL(dma_map_single); 341EXPORT_SYMBOL(__dma_map_single);
342 342
343/* 343/*
344 * see if a mapped address was really a "safe" buffer and if so, copy 344 * see if a mapped address was really a "safe" buffer and if so, copy
@@ -346,7 +346,7 @@ EXPORT_SYMBOL(dma_map_single);
346 * the safe buffer. (basically return things back to the way they 346 * the safe buffer. (basically return things back to the way they
347 * should be) 347 * should be)
348 */ 348 */
349void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 349void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
350 enum dma_data_direction dir) 350 enum dma_data_direction dir)
351{ 351{
352 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 352 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -354,9 +354,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
354 354
355 unmap_single(dev, dma_addr, size, dir); 355 unmap_single(dev, dma_addr, size, dir);
356} 356}
357EXPORT_SYMBOL(dma_unmap_single); 357EXPORT_SYMBOL(__dma_unmap_single);
358 358
359dma_addr_t dma_map_page(struct device *dev, struct page *page, 359dma_addr_t __dma_map_page(struct device *dev, struct page *page,
360 unsigned long offset, size_t size, enum dma_data_direction dir) 360 unsigned long offset, size_t size, enum dma_data_direction dir)
361{ 361{
362 dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n", 362 dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
@@ -372,7 +372,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
372 372
373 return map_single(dev, page_address(page) + offset, size, dir); 373 return map_single(dev, page_address(page) + offset, size, dir);
374} 374}
375EXPORT_SYMBOL(dma_map_page); 375EXPORT_SYMBOL(__dma_map_page);
376 376
377/* 377/*
378 * see if a mapped address was really a "safe" buffer and if so, copy 378 * see if a mapped address was really a "safe" buffer and if so, copy
@@ -380,7 +380,7 @@ EXPORT_SYMBOL(dma_map_page);
380 * the safe buffer. (basically return things back to the way they 380 * the safe buffer. (basically return things back to the way they
381 * should be) 381 * should be)
382 */ 382 */
383void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, 383void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
384 enum dma_data_direction dir) 384 enum dma_data_direction dir)
385{ 385{
386 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 386 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -388,7 +388,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
388 388
389 unmap_single(dev, dma_addr, size, dir); 389 unmap_single(dev, dma_addr, size, dir);
390} 390}
391EXPORT_SYMBOL(dma_unmap_page); 391EXPORT_SYMBOL(__dma_unmap_page);
392 392
393int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, 393int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
394 unsigned long off, size_t sz, enum dma_data_direction dir) 394 unsigned long off, size_t sz, enum dma_data_direction dir)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 749bb6622404..bc2d2d75f706 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -18,6 +18,7 @@
18#endif 18#endif
19 19
20#include <asm/ptrace.h> 20#include <asm/ptrace.h>
21#include <asm/domain.h>
21 22
22/* 23/*
23 * Endian independent macros for shifting bytes within registers. 24 * Endian independent macros for shifting bytes within registers.
@@ -157,16 +158,24 @@
157#ifdef CONFIG_SMP 158#ifdef CONFIG_SMP
158#define ALT_SMP(instr...) \ 159#define ALT_SMP(instr...) \
1599998: instr 1609998: instr
161/*
162 * Note: if you get assembler errors from ALT_UP() when building with
163 * CONFIG_THUMB2_KERNEL, you almost certainly need to use
164 * ALT_SMP( W(instr) ... )
165 */
160#define ALT_UP(instr...) \ 166#define ALT_UP(instr...) \
161 .pushsection ".alt.smp.init", "a" ;\ 167 .pushsection ".alt.smp.init", "a" ;\
162 .long 9998b ;\ 168 .long 9998b ;\
163 instr ;\ 1699997: instr ;\
170 .if . - 9997b != 4 ;\
171 .error "ALT_UP() content must assemble to exactly 4 bytes";\
172 .endif ;\
164 .popsection 173 .popsection
165#define ALT_UP_B(label) \ 174#define ALT_UP_B(label) \
166 .equ up_b_offset, label - 9998b ;\ 175 .equ up_b_offset, label - 9998b ;\
167 .pushsection ".alt.smp.init", "a" ;\ 176 .pushsection ".alt.smp.init", "a" ;\
168 .long 9998b ;\ 177 .long 9998b ;\
169 b . + up_b_offset ;\ 178 W(b) . + up_b_offset ;\
170 .popsection 179 .popsection
171#else 180#else
172#define ALT_SMP(instr...) 181#define ALT_SMP(instr...)
@@ -177,16 +186,24 @@
177/* 186/*
178 * SMP data memory barrier 187 * SMP data memory barrier
179 */ 188 */
180 .macro smp_dmb 189 .macro smp_dmb mode
181#ifdef CONFIG_SMP 190#ifdef CONFIG_SMP
182#if __LINUX_ARM_ARCH__ >= 7 191#if __LINUX_ARM_ARCH__ >= 7
192 .ifeqs "\mode","arm"
183 ALT_SMP(dmb) 193 ALT_SMP(dmb)
194 .else
195 ALT_SMP(W(dmb))
196 .endif
184#elif __LINUX_ARM_ARCH__ == 6 197#elif __LINUX_ARM_ARCH__ == 6
185 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb 198 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
186#else 199#else
187#error Incompatible SMP platform 200#error Incompatible SMP platform
188#endif 201#endif
202 .ifeqs "\mode","arm"
189 ALT_UP(nop) 203 ALT_UP(nop)
204 .else
205 ALT_UP(W(nop))
206 .endif
190#endif 207#endif
191 .endm 208 .endm
192 209
@@ -206,12 +223,12 @@
206 */ 223 */
207#ifdef CONFIG_THUMB2_KERNEL 224#ifdef CONFIG_THUMB2_KERNEL
208 225
209 .macro usraccoff, instr, reg, ptr, inc, off, cond, abort 226 .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()
2109999: 2279999:
211 .if \inc == 1 228 .if \inc == 1
212 \instr\cond\()bt \reg, [\ptr, #\off] 229 \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
213 .elseif \inc == 4 230 .elseif \inc == 4
214 \instr\cond\()t \reg, [\ptr, #\off] 231 \instr\cond\()\t\().w \reg, [\ptr, #\off]
215 .else 232 .else
216 .error "Unsupported inc macro argument" 233 .error "Unsupported inc macro argument"
217 .endif 234 .endif
@@ -246,13 +263,13 @@
246 263
247#else /* !CONFIG_THUMB2_KERNEL */ 264#else /* !CONFIG_THUMB2_KERNEL */
248 265
249 .macro usracc, instr, reg, ptr, inc, cond, rept, abort 266 .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()
250 .rept \rept 267 .rept \rept
2519999: 2689999:
252 .if \inc == 1 269 .if \inc == 1
253 \instr\cond\()bt \reg, [\ptr], #\inc 270 \instr\cond\()b\()\t \reg, [\ptr], #\inc
254 .elseif \inc == 4 271 .elseif \inc == 4
255 \instr\cond\()t \reg, [\ptr], #\inc 272 \instr\cond\()\t \reg, [\ptr], #\inc
256 .else 273 .else
257 .error "Unsupported inc macro argument" 274 .error "Unsupported inc macro argument"
258 .endif 275 .endif
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 9d6122096fbe..75fe66bc02b4 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -23,4 +23,6 @@
23#define ARCH_SLAB_MINALIGN 8 23#define ARCH_SLAB_MINALIGN 8
24#endif 24#endif
25 25
26#define __read_mostly __attribute__((__section__(".data..read_mostly")))
27
26#endif 28#endif
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
index b56c1389b6fa..765d33222369 100644
--- a/arch/arm/include/asm/clkdev.h
+++ b/arch/arm/include/asm/clkdev.h
@@ -12,23 +12,13 @@
12#ifndef __ASM_CLKDEV_H 12#ifndef __ASM_CLKDEV_H
13#define __ASM_CLKDEV_H 13#define __ASM_CLKDEV_H
14 14
15struct clk; 15#include <linux/slab.h>
16struct device;
17 16
18struct clk_lookup { 17#include <mach/clkdev.h>
19 struct list_head node;
20 const char *dev_id;
21 const char *con_id;
22 struct clk *clk;
23};
24 18
25struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 19static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
26 const char *dev_fmt, ...); 20{
27 21 return kzalloc(size, GFP_KERNEL);
28void clkdev_add(struct clk_lookup *cl); 22}
29void clkdev_drop(struct clk_lookup *cl);
30
31void clkdev_add_table(struct clk_lookup *, size_t);
32int clk_add_alias(const char *, const char *, char *, struct device *);
33 23
34#endif 24#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index c568da7dcae4..4fff837363ed 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,24 +5,29 @@
5 5
6#include <linux/mm_types.h> 6#include <linux/mm_types.h>
7#include <linux/scatterlist.h> 7#include <linux/scatterlist.h>
8#include <linux/dma-debug.h>
8 9
9#include <asm-generic/dma-coherent.h> 10#include <asm-generic/dma-coherent.h>
10#include <asm/memory.h> 11#include <asm/memory.h>
11 12
13#ifdef __arch_page_to_dma
14#error Please update to __arch_pfn_to_dma
15#endif
16
12/* 17/*
13 * page_to_dma/dma_to_virt/virt_to_dma are architecture private functions 18 * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
14 * used internally by the DMA-mapping API to provide DMA addresses. They 19 * functions used internally by the DMA-mapping API to provide DMA
15 * must not be used by drivers. 20 * addresses. They must not be used by drivers.
16 */ 21 */
17#ifndef __arch_page_to_dma 22#ifndef __arch_pfn_to_dma
18static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) 23static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
19{ 24{
20 return (dma_addr_t)__pfn_to_bus(page_to_pfn(page)); 25 return (dma_addr_t)__pfn_to_bus(pfn);
21} 26}
22 27
23static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) 28static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
24{ 29{
25 return pfn_to_page(__bus_to_pfn(addr)); 30 return __bus_to_pfn(addr);
26} 31}
27 32
28static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) 33static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
@@ -35,14 +40,14 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
35 return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); 40 return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
36} 41}
37#else 42#else
38static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) 43static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
39{ 44{
40 return __arch_page_to_dma(dev, page); 45 return __arch_pfn_to_dma(dev, pfn);
41} 46}
42 47
43static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) 48static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
44{ 49{
45 return __arch_dma_to_page(dev, addr); 50 return __arch_dma_to_pfn(dev, addr);
46} 51}
47 52
48static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) 53static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
@@ -293,13 +298,13 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
293/* 298/*
294 * The DMA API, implemented by dmabounce.c. See below for descriptions. 299 * The DMA API, implemented by dmabounce.c. See below for descriptions.
295 */ 300 */
296extern dma_addr_t dma_map_single(struct device *, void *, size_t, 301extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
297 enum dma_data_direction); 302 enum dma_data_direction);
298extern void dma_unmap_single(struct device *, dma_addr_t, size_t, 303extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
299 enum dma_data_direction); 304 enum dma_data_direction);
300extern dma_addr_t dma_map_page(struct device *, struct page *, 305extern dma_addr_t __dma_map_page(struct device *, struct page *,
301 unsigned long, size_t, enum dma_data_direction); 306 unsigned long, size_t, enum dma_data_direction);
302extern void dma_unmap_page(struct device *, dma_addr_t, size_t, 307extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
303 enum dma_data_direction); 308 enum dma_data_direction);
304 309
305/* 310/*
@@ -323,6 +328,34 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
323} 328}
324 329
325 330
331static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
332 size_t size, enum dma_data_direction dir)
333{
334 __dma_single_cpu_to_dev(cpu_addr, size, dir);
335 return virt_to_dma(dev, cpu_addr);
336}
337
338static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
339 unsigned long offset, size_t size, enum dma_data_direction dir)
340{
341 __dma_page_cpu_to_dev(page, offset, size, dir);
342 return pfn_to_dma(dev, page_to_pfn(page)) + offset;
343}
344
345static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
346 size_t size, enum dma_data_direction dir)
347{
348 __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
349}
350
351static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
352 size_t size, enum dma_data_direction dir)
353{
354 __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
355 handle & ~PAGE_MASK, size, dir);
356}
357#endif /* CONFIG_DMABOUNCE */
358
326/** 359/**
327 * dma_map_single - map a single buffer for streaming DMA 360 * dma_map_single - map a single buffer for streaming DMA
328 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 361 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -340,11 +373,16 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
340static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, 373static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
341 size_t size, enum dma_data_direction dir) 374 size_t size, enum dma_data_direction dir)
342{ 375{
376 dma_addr_t addr;
377
343 BUG_ON(!valid_dma_direction(dir)); 378 BUG_ON(!valid_dma_direction(dir));
344 379
345 __dma_single_cpu_to_dev(cpu_addr, size, dir); 380 addr = __dma_map_single(dev, cpu_addr, size, dir);
381 debug_dma_map_page(dev, virt_to_page(cpu_addr),
382 (unsigned long)cpu_addr & ~PAGE_MASK, size,
383 dir, addr, true);
346 384
347 return virt_to_dma(dev, cpu_addr); 385 return addr;
348} 386}
349 387
350/** 388/**
@@ -364,11 +402,14 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
364static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, 402static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
365 unsigned long offset, size_t size, enum dma_data_direction dir) 403 unsigned long offset, size_t size, enum dma_data_direction dir)
366{ 404{
405 dma_addr_t addr;
406
367 BUG_ON(!valid_dma_direction(dir)); 407 BUG_ON(!valid_dma_direction(dir));
368 408
369 __dma_page_cpu_to_dev(page, offset, size, dir); 409 addr = __dma_map_page(dev, page, offset, size, dir);
410 debug_dma_map_page(dev, page, offset, size, dir, addr, false);
370 411
371 return page_to_dma(dev, page) + offset; 412 return addr;
372} 413}
373 414
374/** 415/**
@@ -388,7 +429,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
388static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, 429static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
389 size_t size, enum dma_data_direction dir) 430 size_t size, enum dma_data_direction dir)
390{ 431{
391 __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); 432 debug_dma_unmap_page(dev, handle, size, dir, true);
433 __dma_unmap_single(dev, handle, size, dir);
392} 434}
393 435
394/** 436/**
@@ -408,10 +450,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
408static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, 450static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
409 size_t size, enum dma_data_direction dir) 451 size_t size, enum dma_data_direction dir)
410{ 452{
411 __dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK, 453 debug_dma_unmap_page(dev, handle, size, dir, false);
412 size, dir); 454 __dma_unmap_page(dev, handle, size, dir);
413} 455}
414#endif /* CONFIG_DMABOUNCE */
415 456
416/** 457/**
417 * dma_sync_single_range_for_cpu 458 * dma_sync_single_range_for_cpu
@@ -437,6 +478,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
437{ 478{
438 BUG_ON(!valid_dma_direction(dir)); 479 BUG_ON(!valid_dma_direction(dir));
439 480
481 debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
482
440 if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) 483 if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
441 return; 484 return;
442 485
@@ -449,6 +492,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
449{ 492{
450 BUG_ON(!valid_dma_direction(dir)); 493 BUG_ON(!valid_dma_direction(dir));
451 494
495 debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
496
452 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) 497 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
453 return; 498 return;
454 499
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index cc7ef4080711..af18ceaacf5d 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -45,13 +45,17 @@
45 */ 45 */
46#define DOMAIN_NOACCESS 0 46#define DOMAIN_NOACCESS 0
47#define DOMAIN_CLIENT 1 47#define DOMAIN_CLIENT 1
48#ifdef CONFIG_CPU_USE_DOMAINS
48#define DOMAIN_MANAGER 3 49#define DOMAIN_MANAGER 3
50#else
51#define DOMAIN_MANAGER 1
52#endif
49 53
50#define domain_val(dom,type) ((type) << (2*(dom))) 54#define domain_val(dom,type) ((type) << (2*(dom)))
51 55
52#ifndef __ASSEMBLY__ 56#ifndef __ASSEMBLY__
53 57
54#ifdef CONFIG_MMU 58#ifdef CONFIG_CPU_USE_DOMAINS
55#define set_domain(x) \ 59#define set_domain(x) \
56 do { \ 60 do { \
57 __asm__ __volatile__( \ 61 __asm__ __volatile__( \
@@ -74,5 +78,28 @@
74#define modify_domain(dom,type) do { } while (0) 78#define modify_domain(dom,type) do { } while (0)
75#endif 79#endif
76 80
81/*
82 * Generate the T (user) versions of the LDR/STR and related
83 * instructions (inline assembly)
84 */
85#ifdef CONFIG_CPU_USE_DOMAINS
86#define T(instr) #instr "t"
87#else
88#define T(instr) #instr
77#endif 89#endif
78#endif /* !__ASSEMBLY__ */ 90
91#else /* __ASSEMBLY__ */
92
93/*
94 * Generate the T (user) versions of the LDR/STR and related
95 * instructions
96 */
97#ifdef CONFIG_CPU_USE_DOMAINS
98#define T(instr) instr ## t
99#else
100#define T(instr) instr
101#endif
102
103#endif /* __ASSEMBLY__ */
104
105#endif /* !__ASM_PROC_DOMAIN_H */
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
new file mode 100644
index 000000000000..ec0bbf79c71f
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -0,0 +1,44 @@
1/*
2 * Interrupt handling. Preserves r7, r8, r9
3 */
4 .macro arch_irq_handler_default
5 get_irqnr_preamble r5, lr
61: get_irqnr_and_base r0, r6, r5, lr
7 movne r1, sp
8 @
9 @ routine called with r0 = irq number, r1 = struct pt_regs *
10 @
11 adrne lr, BSYM(1b)
12 bne asm_do_IRQ
13
14#ifdef CONFIG_SMP
15 /*
16 * XXX
17 *
18 * this macro assumes that irqstat (r6) and base (r5) are
19 * preserved from get_irqnr_and_base above
20 */
21 ALT_SMP(test_for_ipi r0, r6, r5, lr)
22 ALT_UP_B(9997f)
23 movne r1, sp
24 adrne lr, BSYM(1b)
25 bne do_IPI
26
27#ifdef CONFIG_LOCAL_TIMERS
28 test_for_ltirq r0, r6, r5, lr
29 movne r0, sp
30 adrne lr, BSYM(1b)
31 bne do_local_timer
32#endif
33#endif
349997:
35 .endm
36
37 .macro arch_irq_handler, symbol_name
38 .align 5
39 .global \symbol_name
40\symbol_name:
41 mov r4, lr
42 arch_irq_handler_default
43 mov pc, r4
44 .endm
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 540a044153a5..b33fe7065b38 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -13,12 +13,13 @@
13#include <linux/preempt.h> 13#include <linux/preempt.h>
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <asm/errno.h> 15#include <asm/errno.h>
16#include <asm/domain.h>
16 17
17#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ 18#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
18 __asm__ __volatile__( \ 19 __asm__ __volatile__( \
19 "1: ldrt %1, [%2]\n" \ 20 "1: " T(ldr) " %1, [%2]\n" \
20 " " insn "\n" \ 21 " " insn "\n" \
21 "2: strt %0, [%2]\n" \ 22 "2: " T(str) " %0, [%2]\n" \
22 " mov %0, #0\n" \ 23 " mov %0, #0\n" \
23 "3:\n" \ 24 "3:\n" \
24 " .pushsection __ex_table,\"a\"\n" \ 25 " .pushsection __ex_table,\"a\"\n" \
@@ -97,10 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
97 pagefault_disable(); /* implies preempt_disable() */ 98 pagefault_disable(); /* implies preempt_disable() */
98 99
99 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" 100 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
100 "1: ldrt %0, [%3]\n" 101 "1: " T(ldr) " %0, [%3]\n"
101 " teq %0, %1\n" 102 " teq %0, %1\n"
102 " it eq @ explicit IT needed for the 2b label\n" 103 " it eq @ explicit IT needed for the 2b label\n"
103 "2: streqt %2, [%3]\n" 104 "2: " T(streq) " %2, [%3]\n"
104 "3:\n" 105 "3:\n"
105 " .pushsection __ex_table,\"a\"\n" 106 " .pushsection __ex_table,\"a\"\n"
106 " .align 3\n" 107 " .align 3\n"
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 6d7485aff955..89ad1805e579 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,13 +5,31 @@
5#include <linux/threads.h> 5#include <linux/threads.h>
6#include <asm/irq.h> 6#include <asm/irq.h>
7 7
8#define NR_IPI 5
9
8typedef struct { 10typedef struct {
9 unsigned int __softirq_pending; 11 unsigned int __softirq_pending;
12#ifdef CONFIG_LOCAL_TIMERS
10 unsigned int local_timer_irqs; 13 unsigned int local_timer_irqs;
14#endif
15#ifdef CONFIG_SMP
16 unsigned int ipi_irqs[NR_IPI];
17#endif
11} ____cacheline_aligned irq_cpustat_t; 18} ____cacheline_aligned irq_cpustat_t;
12 19
13#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 20#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
14 21
22#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++
23#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member)
24
25#ifdef CONFIG_SMP
26u64 smp_irq_stat_cpu(unsigned int cpu);
27#else
28#define smp_irq_stat_cpu(cpu) 0
29#endif
30
31#define arch_irq_stat_cpu smp_irq_stat_cpu
32
15#if NR_IRQS > 512 33#if NR_IRQS > 512
16#define HARDIRQ_BITS 10 34#define HARDIRQ_BITS 10
17#elif NR_IRQS > 256 35#elif NR_IRQS > 256
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 50c7e7cfd670..6bc63ab498ce 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -30,7 +30,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
30#include "smp_twd.h" 30#include "smp_twd.h"
31 31
32#define local_timer_ack() twd_timer_ack() 32#define local_timer_ack() twd_timer_ack()
33#define local_timer_stop() twd_timer_stop()
34 33
35#else 34#else
36 35
@@ -40,11 +39,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
40 */ 39 */
41int local_timer_ack(void); 40int local_timer_ack(void);
42 41
43/*
44 * Stop a local timer interrupt.
45 */
46void local_timer_stop(void);
47
48#endif 42#endif
49 43
50/* 44/*
@@ -52,12 +46,6 @@ void local_timer_stop(void);
52 */ 46 */
53void local_timer_setup(struct clock_event_device *); 47void local_timer_setup(struct clock_event_device *);
54 48
55#else
56
57static inline void local_timer_stop(void)
58{
59}
60
61#endif 49#endif
62 50
63#endif 51#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index d97a964207fa..3a0893a76a3b 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,12 +37,21 @@ struct machine_desc {
37 struct meminfo *); 37 struct meminfo *);
38 void (*reserve)(void);/* reserve mem blocks */ 38 void (*reserve)(void);/* reserve mem blocks */
39 void (*map_io)(void);/* IO mapping function */ 39 void (*map_io)(void);/* IO mapping function */
40 void (*init_early)(void);
40 void (*init_irq)(void); 41 void (*init_irq)(void);
41 struct sys_timer *timer; /* system tick timer */ 42 struct sys_timer *timer; /* system tick timer */
42 void (*init_machine)(void); 43 void (*init_machine)(void);
44#ifdef CONFIG_MULTI_IRQ_HANDLER
45 void (*handle_irq)(struct pt_regs *);
46#endif
43}; 47};
44 48
45/* 49/*
50 * Current machine - only accessible during boot.
51 */
52extern struct machine_desc *machine_desc;
53
54/*
46 * Set of macros to define architecture features. This is built into 55 * Set of macros to define architecture features. This is built into
47 * a table by the linker. 56 * a table by the linker.
48 */ 57 */
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
index ce3eee9fe26c..22ac140edd9e 100644
--- a/arch/arm/include/asm/mach/irq.h
+++ b/arch/arm/include/asm/mach/irq.h
@@ -17,10 +17,12 @@ struct seq_file;
17/* 17/*
18 * This is internal. Do not use it. 18 * This is internal. Do not use it.
19 */ 19 */
20extern unsigned int arch_nr_irqs;
21extern void (*init_arch_irq)(void);
22extern void init_FIQ(void); 20extern void init_FIQ(void);
23extern int show_fiq_list(struct seq_file *, void *); 21extern int show_fiq_list(struct seq_file *, int);
22
23#ifdef CONFIG_MULTI_IRQ_HANDLER
24extern void (*handle_arch_irq)(struct pt_regs *);
25#endif
24 26
25/* 27/*
26 * This is for easy migration, but should be changed in the source 28 * This is for easy migration, but should be changed in the source
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index 35d408f6dccf..883f6be5117a 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -43,7 +43,6 @@ struct sys_timer {
43#endif 43#endif
44}; 44};
45 45
46extern struct sys_timer *system_timer;
47extern void timer_tick(void); 46extern void timer_tick(void);
48 47
49#endif 48#endif
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 3d05190797cb..96ed521f2408 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -33,27 +33,23 @@ struct seq_file;
33/* 33/*
34 * generate IPI list text 34 * generate IPI list text
35 */ 35 */
36extern void show_ipi_list(struct seq_file *p); 36extern void show_ipi_list(struct seq_file *, int);
37 37
38/* 38/*
39 * Called from assembly code, this handles an IPI. 39 * Called from assembly code, this handles an IPI.
40 */ 40 */
41asmlinkage void do_IPI(struct pt_regs *regs); 41asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
42 42
43/* 43/*
44 * Setup the set of possible CPUs (via set_cpu_possible) 44 * Setup the set of possible CPUs (via set_cpu_possible)
45 */ 45 */
46extern void smp_init_cpus(void); 46extern void smp_init_cpus(void);
47 47
48/*
49 * Move global data into per-processor storage.
50 */
51extern void smp_store_cpu_info(unsigned int cpuid);
52 48
53/* 49/*
54 * Raise an IPI cross call on CPUs in callmap. 50 * Raise an IPI cross call on CPUs in callmap.
55 */ 51 */
56extern void smp_cross_call(const struct cpumask *mask); 52extern void smp_cross_call(const struct cpumask *mask, int ipi);
57 53
58/* 54/*
59 * Boot a secondary CPU, and assign it the specified idle task. 55 * Boot a secondary CPU, and assign it the specified idle task.
@@ -73,6 +69,11 @@ asmlinkage void secondary_start_kernel(void);
73extern void platform_secondary_init(unsigned int cpu); 69extern void platform_secondary_init(unsigned int cpu);
74 70
75/* 71/*
72 * Initialize cpu_possible map, and enable coherency
73 */
74extern void platform_smp_prepare_cpus(unsigned int);
75
76/*
76 * Initial data for bringing up a secondary CPU. 77 * Initial data for bringing up a secondary CPU.
77 */ 78 */
78struct secondary_data { 79struct secondary_data {
@@ -97,6 +98,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
97/* 98/*
98 * show local interrupt info 99 * show local interrupt info
99 */ 100 */
100extern void show_local_irqs(struct seq_file *); 101extern void show_local_irqs(struct seq_file *, int);
101 102
102#endif /* ifndef __ASM_ARM_SMP_H */ 103#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/smp_mpidr.h b/arch/arm/include/asm/smp_mpidr.h
deleted file mode 100644
index 6a9307d64900..000000000000
--- a/arch/arm/include/asm/smp_mpidr.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#ifndef ASMARM_SMP_MIDR_H
2#define ASMARM_SMP_MIDR_H
3
4#define hard_smp_processor_id() \
5 ({ \
6 unsigned int cpunum; \
7 __asm__("\n" \
8 "1: mrc p15, 0, %0, c0, c0, 5\n" \
9 " .pushsection \".alt.smp.init\", \"a\"\n"\
10 " .long 1b\n" \
11 " mov %0, #0\n" \
12 " .popsection" \
13 : "=r" (cpunum)); \
14 cpunum &= 0x0F; \
15 })
16
17#endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index 634f357be6bb..fed9981fba08 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -22,7 +22,6 @@ struct clock_event_device;
22 22
23extern void __iomem *twd_base; 23extern void __iomem *twd_base;
24 24
25void twd_timer_stop(void);
26int twd_timer_ack(void); 25int twd_timer_ack(void);
27void twd_timer_setup(struct clock_event_device *); 26void twd_timer_setup(struct clock_event_device *);
28 27
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 3222ab8b3447..97f6d60297d5 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -124,6 +124,13 @@ extern unsigned int user_debug;
124#define vectors_high() (0) 124#define vectors_high() (0)
125#endif 125#endif
126 126
127#if __LINUX_ARM_ARCH__ >= 7 || \
128 (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
129#define sev() __asm__ __volatile__ ("sev" : : : "memory")
130#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
131#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
132#endif
133
127#if __LINUX_ARM_ARCH__ >= 7 134#if __LINUX_ARM_ARCH__ >= 7
128#define isb() __asm__ __volatile__ ("isb" : : : "memory") 135#define isb() __asm__ __volatile__ ("isb" : : : "memory")
129#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") 136#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index 124475afb007..1b960d5ef6a5 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -46,4 +46,6 @@ static inline int in_exception_text(unsigned long ptr)
46extern void __init early_trap_init(void); 46extern void __init early_trap_init(void);
47extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); 47extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
48 48
49extern void *vectors_page;
50
49#endif 51#endif
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 33e4a48fe103..b293616a1a1a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -227,7 +227,7 @@ do { \
227 227
228#define __get_user_asm_byte(x,addr,err) \ 228#define __get_user_asm_byte(x,addr,err) \
229 __asm__ __volatile__( \ 229 __asm__ __volatile__( \
230 "1: ldrbt %1,[%2]\n" \ 230 "1: " T(ldrb) " %1,[%2],#0\n" \
231 "2:\n" \ 231 "2:\n" \
232 " .pushsection .fixup,\"ax\"\n" \ 232 " .pushsection .fixup,\"ax\"\n" \
233 " .align 2\n" \ 233 " .align 2\n" \
@@ -263,7 +263,7 @@ do { \
263 263
264#define __get_user_asm_word(x,addr,err) \ 264#define __get_user_asm_word(x,addr,err) \
265 __asm__ __volatile__( \ 265 __asm__ __volatile__( \
266 "1: ldrt %1,[%2]\n" \ 266 "1: " T(ldr) " %1,[%2],#0\n" \
267 "2:\n" \ 267 "2:\n" \
268 " .pushsection .fixup,\"ax\"\n" \ 268 " .pushsection .fixup,\"ax\"\n" \
269 " .align 2\n" \ 269 " .align 2\n" \
@@ -308,7 +308,7 @@ do { \
308 308
309#define __put_user_asm_byte(x,__pu_addr,err) \ 309#define __put_user_asm_byte(x,__pu_addr,err) \
310 __asm__ __volatile__( \ 310 __asm__ __volatile__( \
311 "1: strbt %1,[%2]\n" \ 311 "1: " T(strb) " %1,[%2],#0\n" \
312 "2:\n" \ 312 "2:\n" \
313 " .pushsection .fixup,\"ax\"\n" \ 313 " .pushsection .fixup,\"ax\"\n" \
314 " .align 2\n" \ 314 " .align 2\n" \
@@ -341,7 +341,7 @@ do { \
341 341
342#define __put_user_asm_word(x,__pu_addr,err) \ 342#define __put_user_asm_word(x,__pu_addr,err) \
343 __asm__ __volatile__( \ 343 __asm__ __volatile__( \
344 "1: strt %1,[%2]\n" \ 344 "1: " T(str) " %1,[%2],#0\n" \
345 "2:\n" \ 345 "2:\n" \
346 " .pushsection .fixup,\"ax\"\n" \ 346 " .pushsection .fixup,\"ax\"\n" \
347 " .align 2\n" \ 347 " .align 2\n" \
@@ -366,10 +366,10 @@ do { \
366 366
367#define __put_user_asm_dword(x,__pu_addr,err) \ 367#define __put_user_asm_dword(x,__pu_addr,err) \
368 __asm__ __volatile__( \ 368 __asm__ __volatile__( \
369 ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \ 369 ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \
370 ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \ 370 ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \
371 THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \ 371 THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \
372 THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \ 372 THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \
373 "3:\n" \ 373 "3:\n" \
374 " .pushsection .fixup,\"ax\"\n" \ 374 " .pushsection .fixup,\"ax\"\n" \
375 " .align 2\n" \ 375 " .align 2\n" \
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index fd3ec49bfba6..7c33e6f29bcc 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -30,7 +30,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
30obj-$(CONFIG_ISA_DMA) += dma-isa.o 30obj-$(CONFIG_ISA_DMA) += dma-isa.o
31obj-$(CONFIG_PCI) += bios32.o isa.o 31obj-$(CONFIG_PCI) += bios32.o isa.o
32obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o 32obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
33obj-$(CONFIG_SMP) += smp.o 33obj-$(CONFIG_SMP) += smp.o smp_tlb.o
34obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 34obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
35obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 35obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
36obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 36obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
@@ -44,6 +44,8 @@ obj-$(CONFIG_KGDB) += kgdb.o
44obj-$(CONFIG_ARM_UNWIND) += unwind.o 44obj-$(CONFIG_ARM_UNWIND) += unwind.o
45obj-$(CONFIG_HAVE_TCM) += tcm.o 45obj-$(CONFIG_HAVE_TCM) += tcm.o
46obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 46obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
47obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
48CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
47obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 49obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
48 50
49obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o 51obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb96a7d4bbf5..27f64489c1cb 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -25,42 +25,22 @@
25#include <asm/tls.h> 25#include <asm/tls.h>
26 26
27#include "entry-header.S" 27#include "entry-header.S"
28#include <asm/entry-macro-multi.S>
28 29
29/* 30/*
30 * Interrupt handling. Preserves r7, r8, r9 31 * Interrupt handling. Preserves r7, r8, r9
31 */ 32 */
32 .macro irq_handler 33 .macro irq_handler
33 get_irqnr_preamble r5, lr 34#ifdef CONFIG_MULTI_IRQ_HANDLER
341: get_irqnr_and_base r0, r6, r5, lr 35 ldr r5, =handle_arch_irq
35 movne r1, sp 36 mov r0, sp
36 @ 37 ldr r5, [r5]
37 @ routine called with r0 = irq number, r1 = struct pt_regs * 38 adr lr, BSYM(9997f)
38 @ 39 teq r5, #0
39 adrne lr, BSYM(1b) 40 movne pc, r5
40 bne asm_do_IRQ
41
42#ifdef CONFIG_SMP
43 /*
44 * XXX
45 *
46 * this macro assumes that irqstat (r6) and base (r5) are
47 * preserved from get_irqnr_and_base above
48 */
49 ALT_SMP(test_for_ipi r0, r6, r5, lr)
50 ALT_UP_B(9997f)
51 movne r0, sp
52 adrne lr, BSYM(1b)
53 bne do_IPI
54
55#ifdef CONFIG_LOCAL_TIMERS
56 test_for_ltirq r0, r6, r5, lr
57 movne r0, sp
58 adrne lr, BSYM(1b)
59 bne do_local_timer
60#endif 41#endif
42 arch_irq_handler_default
619997: 439997:
62#endif
63
64 .endm 44 .endm
65 45
66#ifdef CONFIG_KPROBES 46#ifdef CONFIG_KPROBES
@@ -735,7 +715,7 @@ ENTRY(__switch_to)
735 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack 715 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
736 THUMB( str sp, [ip], #4 ) 716 THUMB( str sp, [ip], #4 )
737 THUMB( str lr, [ip], #4 ) 717 THUMB( str lr, [ip], #4 )
738#ifdef CONFIG_MMU 718#ifdef CONFIG_CPU_USE_DOMAINS
739 ldr r6, [r2, #TI_CPU_DOMAIN] 719 ldr r6, [r2, #TI_CPU_DOMAIN]
740#endif 720#endif
741 set_tls r3, r4, r5 721 set_tls r3, r4, r5
@@ -744,7 +724,7 @@ ENTRY(__switch_to)
744 ldr r8, =__stack_chk_guard 724 ldr r8, =__stack_chk_guard
745 ldr r7, [r7, #TSK_STACK_CANARY] 725 ldr r7, [r7, #TSK_STACK_CANARY]
746#endif 726#endif
747#ifdef CONFIG_MMU 727#ifdef CONFIG_CPU_USE_DOMAINS
748 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 728 mcr p15, 0, r6, c3, c0, 0 @ Set domain register
749#endif 729#endif
750 mov r5, r0 730 mov r5, r0
@@ -842,7 +822,7 @@ __kuser_helper_start:
842 */ 822 */
843 823
844__kuser_memory_barrier: @ 0xffff0fa0 824__kuser_memory_barrier: @ 0xffff0fa0
845 smp_dmb 825 smp_dmb arm
846 usr_ret lr 826 usr_ret lr
847 827
848 .align 5 828 .align 5
@@ -959,7 +939,7 @@ kuser_cmpxchg_fixup:
959 939
960#else 940#else
961 941
962 smp_dmb 942 smp_dmb arm
9631: ldrex r3, [r2] 9431: ldrex r3, [r2]
964 subs r3, r3, r0 944 subs r3, r3, r0
965 strexeq r3, r1, [r2] 945 strexeq r3, r1, [r2]
@@ -1245,3 +1225,9 @@ cr_alignment:
1245 .space 4 1225 .space 4
1246cr_no_alignment: 1226cr_no_alignment:
1247 .space 4 1227 .space 4
1228
1229#ifdef CONFIG_MULTI_IRQ_HANDLER
1230 .globl handle_arch_irq
1231handle_arch_irq:
1232 .space 4
1233#endif
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 6ff7919613d7..e72dc34eea1c 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -45,6 +45,7 @@
45#include <asm/fiq.h> 45#include <asm/fiq.h>
46#include <asm/irq.h> 46#include <asm/irq.h>
47#include <asm/system.h> 47#include <asm/system.h>
48#include <asm/traps.h>
48 49
49static unsigned long no_fiq_insn; 50static unsigned long no_fiq_insn;
50 51
@@ -67,17 +68,22 @@ static struct fiq_handler default_owner = {
67 68
68static struct fiq_handler *current_fiq = &default_owner; 69static struct fiq_handler *current_fiq = &default_owner;
69 70
70int show_fiq_list(struct seq_file *p, void *v) 71int show_fiq_list(struct seq_file *p, int prec)
71{ 72{
72 if (current_fiq != &default_owner) 73 if (current_fiq != &default_owner)
73 seq_printf(p, "FIQ: %s\n", current_fiq->name); 74 seq_printf(p, "%*s: %s\n", prec, "FIQ",
75 current_fiq->name);
74 76
75 return 0; 77 return 0;
76} 78}
77 79
78void set_fiq_handler(void *start, unsigned int length) 80void set_fiq_handler(void *start, unsigned int length)
79{ 81{
82#if defined(CONFIG_CPU_USE_DOMAINS)
80 memcpy((void *)0xffff001c, start, length); 83 memcpy((void *)0xffff001c, start, length);
84#else
85 memcpy(vectors_page + 0x1c, start, length);
86#endif
81 flush_icache_range(0xffff001c, 0xffff001c + length); 87 flush_icache_range(0xffff001c, 0xffff001c + length);
82 if (!vectors_high()) 88 if (!vectors_high())
83 flush_icache_range(0x1c, 0x1c + length); 89 flush_icache_range(0x1c, 0x1c + length);
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 6bd82d25683c..f17d9a09e8fb 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -91,6 +91,11 @@ ENTRY(stext)
91 movs r8, r5 @ invalid machine (r5=0)? 91 movs r8, r5 @ invalid machine (r5=0)?
92 THUMB( it eq ) @ force fixup-able long branch encoding 92 THUMB( it eq ) @ force fixup-able long branch encoding
93 beq __error_a @ yes, error 'a' 93 beq __error_a @ yes, error 'a'
94
95 /*
96 * r1 = machine no, r2 = atags,
97 * r8 = machinfo, r9 = cpuid, r10 = procinfo
98 */
94 bl __vet_atags 99 bl __vet_atags
95#ifdef CONFIG_SMP_ON_UP 100#ifdef CONFIG_SMP_ON_UP
96 bl __fixup_smp 101 bl __fixup_smp
@@ -387,19 +392,19 @@ ENDPROC(__turn_mmu_on)
387 392
388#ifdef CONFIG_SMP_ON_UP 393#ifdef CONFIG_SMP_ON_UP
389__fixup_smp: 394__fixup_smp:
390 mov r7, #0x00070000 395 mov r4, #0x00070000
391 orr r6, r7, #0xff000000 @ mask 0xff070000 396 orr r3, r4, #0xff000000 @ mask 0xff070000
392 orr r7, r7, #0x41000000 @ val 0x41070000 397 orr r4, r4, #0x41000000 @ val 0x41070000
393 and r0, r9, r6 398 and r0, r9, r3
394 teq r0, r7 @ ARM CPU and ARMv6/v7? 399 teq r0, r4 @ ARM CPU and ARMv6/v7?
395 bne __fixup_smp_on_up @ no, assume UP 400 bne __fixup_smp_on_up @ no, assume UP
396 401
397 orr r6, r6, #0x0000ff00 402 orr r3, r3, #0x0000ff00
398 orr r6, r6, #0x000000f0 @ mask 0xff07fff0 403 orr r3, r3, #0x000000f0 @ mask 0xff07fff0
399 orr r7, r7, #0x0000b000 404 orr r4, r4, #0x0000b000
400 orr r7, r7, #0x00000020 @ val 0x4107b020 405 orr r4, r4, #0x00000020 @ val 0x4107b020
401 and r0, r9, r6 406 and r0, r9, r3
402 teq r0, r7 @ ARM 11MPCore? 407 teq r0, r4 @ ARM 11MPCore?
403 moveq pc, lr @ yes, assume SMP 408 moveq pc, lr @ yes, assume SMP
404 409
405 mrc p15, 0, r0, c0, c0, 5 @ read MPIDR 410 mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
@@ -408,15 +413,22 @@ __fixup_smp:
408 413
409__fixup_smp_on_up: 414__fixup_smp_on_up:
410 adr r0, 1f 415 adr r0, 1f
411 ldmia r0, {r3, r6, r7} 416 ldmia r0, {r3 - r5}
412 sub r3, r0, r3 417 sub r3, r0, r3
413 add r6, r6, r3 418 add r4, r4, r3
414 add r7, r7, r3 419 add r5, r5, r3
4152: cmp r6, r7 4202: cmp r4, r5
416 ldmia r6!, {r0, r4} 421 movhs pc, lr
417 strlo r4, [r0, r3] 422 ldmia r4!, {r0, r6}
418 blo 2b 423 ARM( str r6, [r0, r3] )
419 mov pc, lr 424 THUMB( add r0, r0, r3 )
425#ifdef __ARMEB__
426 THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
427#endif
428 THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
429 THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
430 THUMB( strh r6, [r0] )
431 b 2b
420ENDPROC(__fixup_smp) 432ENDPROC(__fixup_smp)
421 433
422 .align 434 .align
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 6d616333340f..8135438b8818 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -38,6 +38,7 @@
38#include <linux/ftrace.h> 38#include <linux/ftrace.h>
39 39
40#include <asm/system.h> 40#include <asm/system.h>
41#include <asm/mach/arch.h>
41#include <asm/mach/irq.h> 42#include <asm/mach/irq.h>
42#include <asm/mach/time.h> 43#include <asm/mach/time.h>
43 44
@@ -48,8 +49,6 @@
48#define irq_finish(irq) do { } while (0) 49#define irq_finish(irq) do { } while (0)
49#endif 50#endif
50 51
51unsigned int arch_nr_irqs;
52void (*init_arch_irq)(void) __initdata = NULL;
53unsigned long irq_err_count; 52unsigned long irq_err_count;
54 53
55int show_interrupts(struct seq_file *p, void *v) 54int show_interrupts(struct seq_file *p, void *v)
@@ -58,11 +57,20 @@ int show_interrupts(struct seq_file *p, void *v)
58 struct irq_desc *desc; 57 struct irq_desc *desc;
59 struct irqaction * action; 58 struct irqaction * action;
60 unsigned long flags; 59 unsigned long flags;
60 int prec, n;
61
62 for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
63 n *= 10;
64
65#ifdef CONFIG_SMP
66 if (prec < 4)
67 prec = 4;
68#endif
61 69
62 if (i == 0) { 70 if (i == 0) {
63 char cpuname[12]; 71 char cpuname[12];
64 72
65 seq_printf(p, " "); 73 seq_printf(p, "%*s ", prec, "");
66 for_each_present_cpu(cpu) { 74 for_each_present_cpu(cpu) {
67 sprintf(cpuname, "CPU%d", cpu); 75 sprintf(cpuname, "CPU%d", cpu);
68 seq_printf(p, " %10s", cpuname); 76 seq_printf(p, " %10s", cpuname);
@@ -77,7 +85,7 @@ int show_interrupts(struct seq_file *p, void *v)
77 if (!action) 85 if (!action)
78 goto unlock; 86 goto unlock;
79 87
80 seq_printf(p, "%3d: ", i); 88 seq_printf(p, "%*d: ", prec, i);
81 for_each_present_cpu(cpu) 89 for_each_present_cpu(cpu)
82 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); 90 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
83 seq_printf(p, " %10s", desc->chip->name ? : "-"); 91 seq_printf(p, " %10s", desc->chip->name ? : "-");
@@ -90,13 +98,15 @@ unlock:
90 raw_spin_unlock_irqrestore(&desc->lock, flags); 98 raw_spin_unlock_irqrestore(&desc->lock, flags);
91 } else if (i == nr_irqs) { 99 } else if (i == nr_irqs) {
92#ifdef CONFIG_FIQ 100#ifdef CONFIG_FIQ
93 show_fiq_list(p, v); 101 show_fiq_list(p, prec);
94#endif 102#endif
95#ifdef CONFIG_SMP 103#ifdef CONFIG_SMP
96 show_ipi_list(p); 104 show_ipi_list(p, prec);
97 show_local_irqs(p); 105#endif
106#ifdef CONFIG_LOCAL_TIMERS
107 show_local_irqs(p, prec);
98#endif 108#endif
99 seq_printf(p, "Err: %10lu\n", irq_err_count); 109 seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
100 } 110 }
101 return 0; 111 return 0;
102} 112}
@@ -156,13 +166,13 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
156 166
157void __init init_IRQ(void) 167void __init init_IRQ(void)
158{ 168{
159 init_arch_irq(); 169 machine_desc->init_irq();
160} 170}
161 171
162#ifdef CONFIG_SPARSE_IRQ 172#ifdef CONFIG_SPARSE_IRQ
163int __init arch_probe_nr_irqs(void) 173int __init arch_probe_nr_irqs(void)
164{ 174{
165 nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS; 175 nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
166 return nr_irqs; 176 return nr_irqs;
167} 177}
168#endif 178#endif
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 336f14e0e5c2..3455ad33de4c 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -75,9 +75,9 @@ extern void reboot_setup(char *str);
75 75
76unsigned int processor_id; 76unsigned int processor_id;
77EXPORT_SYMBOL(processor_id); 77EXPORT_SYMBOL(processor_id);
78unsigned int __machine_arch_type; 78unsigned int __machine_arch_type __read_mostly;
79EXPORT_SYMBOL(__machine_arch_type); 79EXPORT_SYMBOL(__machine_arch_type);
80unsigned int cacheid; 80unsigned int cacheid __read_mostly;
81EXPORT_SYMBOL(cacheid); 81EXPORT_SYMBOL(cacheid);
82 82
83unsigned int __atags_pointer __initdata; 83unsigned int __atags_pointer __initdata;
@@ -91,24 +91,24 @@ EXPORT_SYMBOL(system_serial_low);
91unsigned int system_serial_high; 91unsigned int system_serial_high;
92EXPORT_SYMBOL(system_serial_high); 92EXPORT_SYMBOL(system_serial_high);
93 93
94unsigned int elf_hwcap; 94unsigned int elf_hwcap __read_mostly;
95EXPORT_SYMBOL(elf_hwcap); 95EXPORT_SYMBOL(elf_hwcap);
96 96
97 97
98#ifdef MULTI_CPU 98#ifdef MULTI_CPU
99struct processor processor; 99struct processor processor __read_mostly;
100#endif 100#endif
101#ifdef MULTI_TLB 101#ifdef MULTI_TLB
102struct cpu_tlb_fns cpu_tlb; 102struct cpu_tlb_fns cpu_tlb __read_mostly;
103#endif 103#endif
104#ifdef MULTI_USER 104#ifdef MULTI_USER
105struct cpu_user_fns cpu_user; 105struct cpu_user_fns cpu_user __read_mostly;
106#endif 106#endif
107#ifdef MULTI_CACHE 107#ifdef MULTI_CACHE
108struct cpu_cache_fns cpu_cache; 108struct cpu_cache_fns cpu_cache __read_mostly;
109#endif 109#endif
110#ifdef CONFIG_OUTER_CACHE 110#ifdef CONFIG_OUTER_CACHE
111struct outer_cache_fns outer_cache; 111struct outer_cache_fns outer_cache __read_mostly;
112EXPORT_SYMBOL(outer_cache); 112EXPORT_SYMBOL(outer_cache);
113#endif 113#endif
114 114
@@ -126,6 +126,7 @@ EXPORT_SYMBOL(elf_platform);
126static const char *cpu_name; 126static const char *cpu_name;
127static const char *machine_name; 127static const char *machine_name;
128static char __initdata cmd_line[COMMAND_LINE_SIZE]; 128static char __initdata cmd_line[COMMAND_LINE_SIZE];
129struct machine_desc *machine_desc __initdata;
129 130
130static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; 131static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
131static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; 132static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -708,13 +709,11 @@ static struct init_tags {
708 { 0, ATAG_NONE } 709 { 0, ATAG_NONE }
709}; 710};
710 711
711static void (*init_machine)(void) __initdata;
712
713static int __init customize_machine(void) 712static int __init customize_machine(void)
714{ 713{
715 /* customizes platform devices, or adds new ones */ 714 /* customizes platform devices, or adds new ones */
716 if (init_machine) 715 if (machine_desc->init_machine)
717 init_machine(); 716 machine_desc->init_machine();
718 return 0; 717 return 0;
719} 718}
720arch_initcall(customize_machine); 719arch_initcall(customize_machine);
@@ -809,6 +808,7 @@ void __init setup_arch(char **cmdline_p)
809 808
810 setup_processor(); 809 setup_processor();
811 mdesc = setup_machine(machine_arch_type); 810 mdesc = setup_machine(machine_arch_type);
811 machine_desc = mdesc;
812 machine_name = mdesc->name; 812 machine_name = mdesc->name;
813 813
814 if (mdesc->soft_reboot) 814 if (mdesc->soft_reboot)
@@ -868,13 +868,9 @@ void __init setup_arch(char **cmdline_p)
868 cpu_init(); 868 cpu_init();
869 tcm_init(); 869 tcm_init();
870 870
871 /* 871#ifdef CONFIG_MULTI_IRQ_HANDLER
872 * Set up various architecture-specific pointers 872 handle_arch_irq = mdesc->handle_irq;
873 */ 873#endif
874 arch_nr_irqs = mdesc->nr_irqs;
875 init_arch_irq = mdesc->init_irq;
876 system_timer = mdesc->timer;
877 init_machine = mdesc->init_machine;
878 874
879#ifdef CONFIG_VT 875#ifdef CONFIG_VT
880#if defined(CONFIG_VGA_CONSOLE) 876#if defined(CONFIG_VGA_CONSOLE)
@@ -884,6 +880,9 @@ void __init setup_arch(char **cmdline_p)
884#endif 880#endif
885#endif 881#endif
886 early_trap_init(); 882 early_trap_init();
883
884 if (mdesc->init_early)
885 mdesc->init_early();
887} 886}
888 887
889 888
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index b6b78b22031b..5ec79b4ff950 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -25,6 +25,7 @@
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/percpu.h> 26#include <linux/percpu.h>
27#include <linux/clockchips.h> 27#include <linux/clockchips.h>
28#include <linux/completion.h>
28 29
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/cacheflush.h> 31#include <asm/cacheflush.h>
@@ -38,7 +39,6 @@
38#include <asm/tlbflush.h> 39#include <asm/tlbflush.h>
39#include <asm/ptrace.h> 40#include <asm/ptrace.h>
40#include <asm/localtimer.h> 41#include <asm/localtimer.h>
41#include <asm/smp_plat.h>
42 42
43/* 43/*
44 * as from 2.5, kernels no longer have an init_tasks structure 44 * as from 2.5, kernels no longer have an init_tasks structure
@@ -47,22 +47,8 @@
47 */ 47 */
48struct secondary_data secondary_data; 48struct secondary_data secondary_data;
49 49
50/*
51 * structures for inter-processor calls
52 * - A collection of single bit ipi messages.
53 */
54struct ipi_data {
55 spinlock_t lock;
56 unsigned long ipi_count;
57 unsigned long bits;
58};
59
60static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
61 .lock = SPIN_LOCK_UNLOCKED,
62};
63
64enum ipi_msg_type { 50enum ipi_msg_type {
65 IPI_TIMER, 51 IPI_TIMER = 2,
66 IPI_RESCHEDULE, 52 IPI_RESCHEDULE,
67 IPI_CALL_FUNC, 53 IPI_CALL_FUNC,
68 IPI_CALL_FUNC_SINGLE, 54 IPI_CALL_FUNC_SINGLE,
@@ -178,8 +164,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
178 barrier(); 164 barrier();
179 } 165 }
180 166
181 if (!cpu_online(cpu)) 167 if (!cpu_online(cpu)) {
168 pr_crit("CPU%u: failed to come online\n", cpu);
182 ret = -EIO; 169 ret = -EIO;
170 }
171 } else {
172 pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
183 } 173 }
184 174
185 secondary_data.stack = NULL; 175 secondary_data.stack = NULL;
@@ -195,18 +185,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
195 185
196 pgd_free(&init_mm, pgd); 186 pgd_free(&init_mm, pgd);
197 187
198 if (ret) {
199 printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
200
201 /*
202 * FIXME: We need to clean up the new idle thread. --rmk
203 */
204 }
205
206 return ret; 188 return ret;
207} 189}
208 190
209#ifdef CONFIG_HOTPLUG_CPU 191#ifdef CONFIG_HOTPLUG_CPU
192static void percpu_timer_stop(void);
193
210/* 194/*
211 * __cpu_disable runs on the processor to be shutdown. 195 * __cpu_disable runs on the processor to be shutdown.
212 */ 196 */
@@ -234,7 +218,7 @@ int __cpu_disable(void)
234 /* 218 /*
235 * Stop the local timer for this CPU. 219 * Stop the local timer for this CPU.
236 */ 220 */
237 local_timer_stop(); 221 percpu_timer_stop();
238 222
239 /* 223 /*
240 * Flush user cache and TLB mappings, and then remove this CPU 224 * Flush user cache and TLB mappings, and then remove this CPU
@@ -253,12 +237,20 @@ int __cpu_disable(void)
253 return 0; 237 return 0;
254} 238}
255 239
240static DECLARE_COMPLETION(cpu_died);
241
256/* 242/*
257 * called on the thread which is asking for a CPU to be shutdown - 243 * called on the thread which is asking for a CPU to be shutdown -
258 * waits until shutdown has completed, or it is timed out. 244 * waits until shutdown has completed, or it is timed out.
259 */ 245 */
260void __cpu_die(unsigned int cpu) 246void __cpu_die(unsigned int cpu)
261{ 247{
248 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
249 pr_err("CPU%u: cpu didn't die\n", cpu);
250 return;
251 }
252 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
253
262 if (!platform_cpu_kill(cpu)) 254 if (!platform_cpu_kill(cpu))
263 printk("CPU%u: unable to kill\n", cpu); 255 printk("CPU%u: unable to kill\n", cpu);
264} 256}
@@ -275,12 +267,17 @@ void __ref cpu_die(void)
275{ 267{
276 unsigned int cpu = smp_processor_id(); 268 unsigned int cpu = smp_processor_id();
277 269
278 local_irq_disable();
279 idle_task_exit(); 270 idle_task_exit();
280 271
272 local_irq_disable();
273 mb();
274
275 /* Tell __cpu_die() that this CPU is now safe to dispose of */
276 complete(&cpu_died);
277
281 /* 278 /*
282 * actual CPU shutdown procedure is at least platform (if not 279 * actual CPU shutdown procedure is at least platform (if not
283 * CPU) specific 280 * CPU) specific.
284 */ 281 */
285 platform_cpu_die(cpu); 282 platform_cpu_die(cpu);
286 283
@@ -290,6 +287,7 @@ void __ref cpu_die(void)
290 * to be repeated to undo the effects of taking the CPU offline. 287 * to be repeated to undo the effects of taking the CPU offline.
291 */ 288 */
292 __asm__("mov sp, %0\n" 289 __asm__("mov sp, %0\n"
290 " mov fp, #0\n"
293 " b secondary_start_kernel" 291 " b secondary_start_kernel"
294 : 292 :
295 : "r" (task_stack_page(current) + THREAD_SIZE - 8)); 293 : "r" (task_stack_page(current) + THREAD_SIZE - 8));
@@ -297,6 +295,17 @@ void __ref cpu_die(void)
297#endif /* CONFIG_HOTPLUG_CPU */ 295#endif /* CONFIG_HOTPLUG_CPU */
298 296
299/* 297/*
298 * Called by both boot and secondaries to move global data into
299 * per-processor storage.
300 */
301static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
302{
303 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
304
305 cpu_info->loops_per_jiffy = loops_per_jiffy;
306}
307
308/*
300 * This is the secondary CPU boot entry. We're using this CPUs 309 * This is the secondary CPU boot entry. We're using this CPUs
301 * idle thread stack, but a set of temporary page tables. 310 * idle thread stack, but a set of temporary page tables.
302 */ 311 */
@@ -320,6 +329,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
320 329
321 cpu_init(); 330 cpu_init();
322 preempt_disable(); 331 preempt_disable();
332 trace_hardirqs_off();
323 333
324 /* 334 /*
325 * Give the platform a chance to do its own initialisation. 335 * Give the platform a chance to do its own initialisation.
@@ -353,17 +363,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
353 cpu_idle(); 363 cpu_idle();
354} 364}
355 365
356/*
357 * Called by both boot and secondaries to move global data into
358 * per-processor storage.
359 */
360void __cpuinit smp_store_cpu_info(unsigned int cpuid)
361{
362 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
363
364 cpu_info->loops_per_jiffy = loops_per_jiffy;
365}
366
367void __init smp_cpus_done(unsigned int max_cpus) 366void __init smp_cpus_done(unsigned int max_cpus)
368{ 367{
369 int cpu; 368 int cpu;
@@ -386,61 +385,80 @@ void __init smp_prepare_boot_cpu(void)
386 per_cpu(cpu_data, cpu).idle = current; 385 per_cpu(cpu_data, cpu).idle = current;
387} 386}
388 387
389static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) 388void __init smp_prepare_cpus(unsigned int max_cpus)
390{ 389{
391 unsigned long flags; 390 unsigned int ncores = num_possible_cpus();
392 unsigned int cpu;
393
394 local_irq_save(flags);
395 391
396 for_each_cpu(cpu, mask) { 392 smp_store_cpu_info(smp_processor_id());
397 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
398
399 spin_lock(&ipi->lock);
400 ipi->bits |= 1 << msg;
401 spin_unlock(&ipi->lock);
402 }
403 393
404 /* 394 /*
405 * Call the platform specific cross-CPU call function. 395 * are we trying to boot more cores than exist?
406 */ 396 */
407 smp_cross_call(mask); 397 if (max_cpus > ncores)
398 max_cpus = ncores;
399
400 if (max_cpus > 1) {
401 /*
402 * Enable the local timer or broadcast device for the
403 * boot CPU, but only if we have more than one CPU.
404 */
405 percpu_timer_setup();
408 406
409 local_irq_restore(flags); 407 /*
408 * Initialise the SCU if there are more than one CPU
409 * and let them know where to start.
410 */
411 platform_smp_prepare_cpus(max_cpus);
412 }
410} 413}
411 414
412void arch_send_call_function_ipi_mask(const struct cpumask *mask) 415void arch_send_call_function_ipi_mask(const struct cpumask *mask)
413{ 416{
414 send_ipi_message(mask, IPI_CALL_FUNC); 417 smp_cross_call(mask, IPI_CALL_FUNC);
415} 418}
416 419
417void arch_send_call_function_single_ipi(int cpu) 420void arch_send_call_function_single_ipi(int cpu)
418{ 421{
419 send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); 422 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
420} 423}
421 424
422void show_ipi_list(struct seq_file *p) 425static const char *ipi_types[NR_IPI] = {
426#define S(x,s) [x - IPI_TIMER] = s
427 S(IPI_TIMER, "Timer broadcast interrupts"),
428 S(IPI_RESCHEDULE, "Rescheduling interrupts"),
429 S(IPI_CALL_FUNC, "Function call interrupts"),
430 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
431 S(IPI_CPU_STOP, "CPU stop interrupts"),
432};
433
434void show_ipi_list(struct seq_file *p, int prec)
423{ 435{
424 unsigned int cpu; 436 unsigned int cpu, i;
425 437
426 seq_puts(p, "IPI:"); 438 for (i = 0; i < NR_IPI; i++) {
439 seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
427 440
428 for_each_present_cpu(cpu) 441 for_each_present_cpu(cpu)
429 seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count); 442 seq_printf(p, "%10u ",
443 __get_irq_stat(cpu, ipi_irqs[i]));
430 444
431 seq_putc(p, '\n'); 445 seq_printf(p, " %s\n", ipi_types[i]);
446 }
432} 447}
433 448
434void show_local_irqs(struct seq_file *p) 449u64 smp_irq_stat_cpu(unsigned int cpu)
435{ 450{
436 unsigned int cpu; 451 u64 sum = 0;
452 int i;
437 453
438 seq_printf(p, "LOC: "); 454 for (i = 0; i < NR_IPI; i++)
455 sum += __get_irq_stat(cpu, ipi_irqs[i]);
439 456
440 for_each_present_cpu(cpu) 457#ifdef CONFIG_LOCAL_TIMERS
441 seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs); 458 sum += __get_irq_stat(cpu, local_timer_irqs);
459#endif
442 460
443 seq_putc(p, '\n'); 461 return sum;
444} 462}
445 463
446/* 464/*
@@ -463,18 +481,30 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
463 int cpu = smp_processor_id(); 481 int cpu = smp_processor_id();
464 482
465 if (local_timer_ack()) { 483 if (local_timer_ack()) {
466 irq_stat[cpu].local_timer_irqs++; 484 __inc_irq_stat(cpu, local_timer_irqs);
467 ipi_timer(); 485 ipi_timer();
468 } 486 }
469 487
470 set_irq_regs(old_regs); 488 set_irq_regs(old_regs);
471} 489}
490
491void show_local_irqs(struct seq_file *p, int prec)
492{
493 unsigned int cpu;
494
495 seq_printf(p, "%*s: ", prec, "LOC");
496
497 for_each_present_cpu(cpu)
498 seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
499
500 seq_printf(p, " Local timer interrupts\n");
501}
472#endif 502#endif
473 503
474#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 504#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
475static void smp_timer_broadcast(const struct cpumask *mask) 505static void smp_timer_broadcast(const struct cpumask *mask)
476{ 506{
477 send_ipi_message(mask, IPI_TIMER); 507 smp_cross_call(mask, IPI_TIMER);
478} 508}
479#else 509#else
480#define smp_timer_broadcast NULL 510#define smp_timer_broadcast NULL
@@ -511,6 +541,21 @@ void __cpuinit percpu_timer_setup(void)
511 local_timer_setup(evt); 541 local_timer_setup(evt);
512} 542}
513 543
544#ifdef CONFIG_HOTPLUG_CPU
545/*
546 * The generic clock events code purposely does not stop the local timer
547 * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
548 * manually here.
549 */
550static void percpu_timer_stop(void)
551{
552 unsigned int cpu = smp_processor_id();
553 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
554
555 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
556}
557#endif
558
514static DEFINE_SPINLOCK(stop_lock); 559static DEFINE_SPINLOCK(stop_lock);
515 560
516/* 561/*
@@ -537,216 +582,76 @@ static void ipi_cpu_stop(unsigned int cpu)
537 582
538/* 583/*
539 * Main handler for inter-processor interrupts 584 * Main handler for inter-processor interrupts
540 *
541 * For ARM, the ipimask now only identifies a single
542 * category of IPI (Bit 1 IPIs have been replaced by a
543 * different mechanism):
544 *
545 * Bit 0 - Inter-processor function call
546 */ 585 */
547asmlinkage void __exception_irq_entry do_IPI(struct pt_regs *regs) 586asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
548{ 587{
549 unsigned int cpu = smp_processor_id(); 588 unsigned int cpu = smp_processor_id();
550 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
551 struct pt_regs *old_regs = set_irq_regs(regs); 589 struct pt_regs *old_regs = set_irq_regs(regs);
552 590
553 ipi->ipi_count++; 591 if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
554 592 __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
555 for (;;) {
556 unsigned long msgs;
557 593
558 spin_lock(&ipi->lock); 594 switch (ipinr) {
559 msgs = ipi->bits; 595 case IPI_TIMER:
560 ipi->bits = 0; 596 ipi_timer();
561 spin_unlock(&ipi->lock); 597 break;
562
563 if (!msgs)
564 break;
565
566 do {
567 unsigned nextmsg;
568
569 nextmsg = msgs & -msgs;
570 msgs &= ~nextmsg;
571 nextmsg = ffz(~nextmsg);
572
573 switch (nextmsg) {
574 case IPI_TIMER:
575 ipi_timer();
576 break;
577 598
578 case IPI_RESCHEDULE: 599 case IPI_RESCHEDULE:
579 /* 600 /*
580 * nothing more to do - eveything is 601 * nothing more to do - eveything is
581 * done on the interrupt return path 602 * done on the interrupt return path
582 */ 603 */
583 break; 604 break;
584 605
585 case IPI_CALL_FUNC: 606 case IPI_CALL_FUNC:
586 generic_smp_call_function_interrupt(); 607 generic_smp_call_function_interrupt();
587 break; 608 break;
588 609
589 case IPI_CALL_FUNC_SINGLE: 610 case IPI_CALL_FUNC_SINGLE:
590 generic_smp_call_function_single_interrupt(); 611 generic_smp_call_function_single_interrupt();
591 break; 612 break;
592 613
593 case IPI_CPU_STOP: 614 case IPI_CPU_STOP:
594 ipi_cpu_stop(cpu); 615 ipi_cpu_stop(cpu);
595 break; 616 break;
596 617
597 default: 618 default:
598 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", 619 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
599 cpu, nextmsg); 620 cpu, ipinr);
600 break; 621 break;
601 }
602 } while (msgs);
603 } 622 }
604
605 set_irq_regs(old_regs); 623 set_irq_regs(old_regs);
606} 624}
607 625
608void smp_send_reschedule(int cpu) 626void smp_send_reschedule(int cpu)
609{ 627{
610 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); 628 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
611} 629}
612 630
613void smp_send_stop(void) 631void smp_send_stop(void)
614{ 632{
615 cpumask_t mask = cpu_online_map; 633 unsigned long timeout;
616 cpu_clear(smp_processor_id(), mask);
617 if (!cpus_empty(mask))
618 send_ipi_message(&mask, IPI_CPU_STOP);
619}
620 634
621/* 635 if (num_online_cpus() > 1) {
622 * not supported here 636 cpumask_t mask = cpu_online_map;
623 */ 637 cpu_clear(smp_processor_id(), mask);
624int setup_profiling_timer(unsigned int multiplier)
625{
626 return -EINVAL;
627}
628 638
629static void 639 smp_cross_call(&mask, IPI_CPU_STOP);
630on_each_cpu_mask(void (*func)(void *), void *info, int wait, 640 }
631 const struct cpumask *mask)
632{
633 preempt_disable();
634 641
635 smp_call_function_many(mask, func, info, wait); 642 /* Wait up to one second for other CPUs to stop */
636 if (cpumask_test_cpu(smp_processor_id(), mask)) 643 timeout = USEC_PER_SEC;
637 func(info); 644 while (num_online_cpus() > 1 && timeout--)
645 udelay(1);
638 646
639 preempt_enable(); 647 if (num_online_cpus() > 1)
648 pr_warning("SMP: failed to stop secondary CPUs\n");
640} 649}
641 650
642/**********************************************************************/
643
644/* 651/*
645 * TLB operations 652 * not supported here
646 */ 653 */
647struct tlb_args { 654int setup_profiling_timer(unsigned int multiplier)
648 struct vm_area_struct *ta_vma;
649 unsigned long ta_start;
650 unsigned long ta_end;
651};
652
653static inline void ipi_flush_tlb_all(void *ignored)
654{
655 local_flush_tlb_all();
656}
657
658static inline void ipi_flush_tlb_mm(void *arg)
659{
660 struct mm_struct *mm = (struct mm_struct *)arg;
661
662 local_flush_tlb_mm(mm);
663}
664
665static inline void ipi_flush_tlb_page(void *arg)
666{
667 struct tlb_args *ta = (struct tlb_args *)arg;
668
669 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
670}
671
672static inline void ipi_flush_tlb_kernel_page(void *arg)
673{
674 struct tlb_args *ta = (struct tlb_args *)arg;
675
676 local_flush_tlb_kernel_page(ta->ta_start);
677}
678
679static inline void ipi_flush_tlb_range(void *arg)
680{
681 struct tlb_args *ta = (struct tlb_args *)arg;
682
683 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
684}
685
686static inline void ipi_flush_tlb_kernel_range(void *arg)
687{
688 struct tlb_args *ta = (struct tlb_args *)arg;
689
690 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
691}
692
693void flush_tlb_all(void)
694{
695 if (tlb_ops_need_broadcast())
696 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
697 else
698 local_flush_tlb_all();
699}
700
701void flush_tlb_mm(struct mm_struct *mm)
702{
703 if (tlb_ops_need_broadcast())
704 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
705 else
706 local_flush_tlb_mm(mm);
707}
708
709void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
710{
711 if (tlb_ops_need_broadcast()) {
712 struct tlb_args ta;
713 ta.ta_vma = vma;
714 ta.ta_start = uaddr;
715 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
716 } else
717 local_flush_tlb_page(vma, uaddr);
718}
719
720void flush_tlb_kernel_page(unsigned long kaddr)
721{
722 if (tlb_ops_need_broadcast()) {
723 struct tlb_args ta;
724 ta.ta_start = kaddr;
725 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
726 } else
727 local_flush_tlb_kernel_page(kaddr);
728}
729
730void flush_tlb_range(struct vm_area_struct *vma,
731 unsigned long start, unsigned long end)
732{
733 if (tlb_ops_need_broadcast()) {
734 struct tlb_args ta;
735 ta.ta_vma = vma;
736 ta.ta_start = start;
737 ta.ta_end = end;
738 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
739 } else
740 local_flush_tlb_range(vma, start, end);
741}
742
743void flush_tlb_kernel_range(unsigned long start, unsigned long end)
744{ 655{
745 if (tlb_ops_need_broadcast()) { 656 return -EINVAL;
746 struct tlb_args ta;
747 ta.ta_start = start;
748 ta.ta_end = end;
749 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
750 } else
751 local_flush_tlb_kernel_range(start, end);
752} 657}
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
new file mode 100644
index 000000000000..7dcb35285be7
--- /dev/null
+++ b/arch/arm/kernel/smp_tlb.c
@@ -0,0 +1,139 @@
1/*
2 * linux/arch/arm/kernel/smp_tlb.c
3 *
4 * Copyright (C) 2002 ARM Limited, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/preempt.h>
11#include <linux/smp.h>
12
13#include <asm/smp_plat.h>
14#include <asm/tlbflush.h>
15
16static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
17 const struct cpumask *mask)
18{
19 preempt_disable();
20
21 smp_call_function_many(mask, func, info, wait);
22 if (cpumask_test_cpu(smp_processor_id(), mask))
23 func(info);
24
25 preempt_enable();
26}
27
28/**********************************************************************/
29
30/*
31 * TLB operations
32 */
33struct tlb_args {
34 struct vm_area_struct *ta_vma;
35 unsigned long ta_start;
36 unsigned long ta_end;
37};
38
39static inline void ipi_flush_tlb_all(void *ignored)
40{
41 local_flush_tlb_all();
42}
43
44static inline void ipi_flush_tlb_mm(void *arg)
45{
46 struct mm_struct *mm = (struct mm_struct *)arg;
47
48 local_flush_tlb_mm(mm);
49}
50
51static inline void ipi_flush_tlb_page(void *arg)
52{
53 struct tlb_args *ta = (struct tlb_args *)arg;
54
55 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
56}
57
58static inline void ipi_flush_tlb_kernel_page(void *arg)
59{
60 struct tlb_args *ta = (struct tlb_args *)arg;
61
62 local_flush_tlb_kernel_page(ta->ta_start);
63}
64
65static inline void ipi_flush_tlb_range(void *arg)
66{
67 struct tlb_args *ta = (struct tlb_args *)arg;
68
69 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
70}
71
72static inline void ipi_flush_tlb_kernel_range(void *arg)
73{
74 struct tlb_args *ta = (struct tlb_args *)arg;
75
76 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
77}
78
79void flush_tlb_all(void)
80{
81 if (tlb_ops_need_broadcast())
82 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
83 else
84 local_flush_tlb_all();
85}
86
87void flush_tlb_mm(struct mm_struct *mm)
88{
89 if (tlb_ops_need_broadcast())
90 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
91 else
92 local_flush_tlb_mm(mm);
93}
94
95void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
96{
97 if (tlb_ops_need_broadcast()) {
98 struct tlb_args ta;
99 ta.ta_vma = vma;
100 ta.ta_start = uaddr;
101 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
102 } else
103 local_flush_tlb_page(vma, uaddr);
104}
105
106void flush_tlb_kernel_page(unsigned long kaddr)
107{
108 if (tlb_ops_need_broadcast()) {
109 struct tlb_args ta;
110 ta.ta_start = kaddr;
111 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
112 } else
113 local_flush_tlb_kernel_page(kaddr);
114}
115
116void flush_tlb_range(struct vm_area_struct *vma,
117 unsigned long start, unsigned long end)
118{
119 if (tlb_ops_need_broadcast()) {
120 struct tlb_args ta;
121 ta.ta_vma = vma;
122 ta.ta_start = start;
123 ta.ta_end = end;
124 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
125 } else
126 local_flush_tlb_range(vma, start, end);
127}
128
129void flush_tlb_kernel_range(unsigned long start, unsigned long end)
130{
131 if (tlb_ops_need_broadcast()) {
132 struct tlb_args ta;
133 ta.ta_start = start;
134 ta.ta_end = end;
135 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
136 } else
137 local_flush_tlb_kernel_range(start, end);
138}
139
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 67f933ec4177..dd790745b3ef 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -145,13 +145,3 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
145 145
146 clockevents_register_device(clk); 146 clockevents_register_device(clk);
147} 147}
148
149#ifdef CONFIG_HOTPLUG_CPU
150/*
151 * take a local timer down
152 */
153void twd_timer_stop(void)
154{
155 __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
156}
157#endif
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
new file mode 100644
index 000000000000..7a5760922914
--- /dev/null
+++ b/arch/arm/kernel/swp_emulate.c
@@ -0,0 +1,267 @@
1/*
2 * linux/arch/arm/kernel/swp_emulate.c
3 *
4 * Copyright (C) 2009 ARM Limited
5 * __user_* functions adapted from include/asm/uaccess.h
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 * Implements emulation of the SWP/SWPB instructions using load-exclusive and
12 * store-exclusive for processors that have them disabled (or future ones that
13 * might not implement them).
14 *
15 * Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
16 * Where: Rt = destination
17 * Rt2 = source
18 * Rn = address
19 */
20
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/proc_fs.h>
24#include <linux/sched.h>
25#include <linux/syscalls.h>
26#include <linux/perf_event.h>
27
28#include <asm/traps.h>
29#include <asm/uaccess.h>
30
31/*
32 * Error-checking SWP macros implemented using ldrex{b}/strex{b}
33 */
34#define __user_swpX_asm(data, addr, res, temp, B) \
35 __asm__ __volatile__( \
36 " mov %2, %1\n" \
37 "0: ldrex"B" %1, [%3]\n" \
38 "1: strex"B" %0, %2, [%3]\n" \
39 " cmp %0, #0\n" \
40 " movne %0, %4\n" \
41 "2:\n" \
42 " .section .fixup,\"ax\"\n" \
43 " .align 2\n" \
44 "3: mov %0, %5\n" \
45 " b 2b\n" \
46 " .previous\n" \
47 " .section __ex_table,\"a\"\n" \
48 " .align 3\n" \
49 " .long 0b, 3b\n" \
50 " .long 1b, 3b\n" \
51 " .previous" \
52 : "=&r" (res), "+r" (data), "=&r" (temp) \
53 : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
54 : "cc", "memory")
55
56#define __user_swp_asm(data, addr, res, temp) \
57 __user_swpX_asm(data, addr, res, temp, "")
58#define __user_swpb_asm(data, addr, res, temp) \
59 __user_swpX_asm(data, addr, res, temp, "b")
60
61/*
62 * Macros/defines for extracting register numbers from instruction.
63 */
64#define EXTRACT_REG_NUM(instruction, offset) \
65 (((instruction) & (0xf << (offset))) >> (offset))
66#define RN_OFFSET 16
67#define RT_OFFSET 12
68#define RT2_OFFSET 0
69/*
70 * Bit 22 of the instruction encoding distinguishes between
71 * the SWP and SWPB variants (bit set means SWPB).
72 */
73#define TYPE_SWPB (1 << 22)
74
75static unsigned long swpcounter;
76static unsigned long swpbcounter;
77static unsigned long abtcounter;
78static pid_t previous_pid;
79
80#ifdef CONFIG_PROC_FS
81static int proc_read_status(char *page, char **start, off_t off, int count,
82 int *eof, void *data)
83{
84 char *p = page;
85 int len;
86
87 p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
88 p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
89 p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
90 if (previous_pid != 0)
91 p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
92
93 len = (p - page) - off;
94 if (len < 0)
95 len = 0;
96
97 *eof = (len <= count) ? 1 : 0;
98 *start = page + off;
99
100 return len;
101}
102#endif
103
104/*
105 * Set up process info to signal segmentation fault - called on access error.
106 */
107static void set_segfault(struct pt_regs *regs, unsigned long addr)
108{
109 siginfo_t info;
110
111 if (find_vma(current->mm, addr) == NULL)
112 info.si_code = SEGV_MAPERR;
113 else
114 info.si_code = SEGV_ACCERR;
115
116 info.si_signo = SIGSEGV;
117 info.si_errno = 0;
118 info.si_addr = (void *) instruction_pointer(regs);
119
120 pr_debug("SWP{B} emulation: access caused memory abort!\n");
121 arm_notify_die("Illegal memory access", regs, &info, 0, 0);
122
123 abtcounter++;
124}
125
126static int emulate_swpX(unsigned int address, unsigned int *data,
127 unsigned int type)
128{
129 unsigned int res = 0;
130
131 if ((type != TYPE_SWPB) && (address & 0x3)) {
132 /* SWP to unaligned address not permitted */
133 pr_debug("SWP instruction on unaligned pointer!\n");
134 return -EFAULT;
135 }
136
137 while (1) {
138 unsigned long temp;
139
140 /*
141 * Barrier required between accessing protected resource and
142 * releasing a lock for it. Legacy code might not have done
143 * this, and we cannot determine that this is not the case
144 * being emulated, so insert always.
145 */
146 smp_mb();
147
148 if (type == TYPE_SWPB)
149 __user_swpb_asm(*data, address, res, temp);
150 else
151 __user_swp_asm(*data, address, res, temp);
152
153 if (likely(res != -EAGAIN) || signal_pending(current))
154 break;
155
156 cond_resched();
157 }
158
159 if (res == 0) {
160 /*
161 * Barrier also required between aquiring a lock for a
162 * protected resource and accessing the resource. Inserted for
163 * same reason as above.
164 */
165 smp_mb();
166
167 if (type == TYPE_SWPB)
168 swpbcounter++;
169 else
170 swpcounter++;
171 }
172
173 return res;
174}
175
176/*
177 * swp_handler logs the id of calling process, dissects the instruction, sanity
178 * checks the memory location, calls emulate_swpX for the actual operation and
179 * deals with fixup/error handling before returning
180 */
181static int swp_handler(struct pt_regs *regs, unsigned int instr)
182{
183 unsigned int address, destreg, data, type;
184 unsigned int res = 0;
185
186 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, regs->ARM_pc);
187
188 if (current->pid != previous_pid) {
189 pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
190 current->comm, (unsigned long)current->pid);
191 previous_pid = current->pid;
192 }
193
194 address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
195 data = regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
196 destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
197
198 type = instr & TYPE_SWPB;
199
200 pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n",
201 EXTRACT_REG_NUM(instr, RN_OFFSET), address,
202 destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
203
204 /* Check access in reasonable access range for both SWP and SWPB */
205 if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
206 pr_debug("SWP{B} emulation: access to %p not allowed!\n",
207 (void *)address);
208 res = -EFAULT;
209 } else {
210 res = emulate_swpX(address, &data, type);
211 }
212
213 if (res == 0) {
214 /*
215 * On successful emulation, revert the adjustment to the PC
216 * made in kernel/traps.c in order to resume execution at the
217 * instruction following the SWP{B}.
218 */
219 regs->ARM_pc += 4;
220 regs->uregs[destreg] = data;
221 } else if (res == -EFAULT) {
222 /*
223 * Memory errors do not mean emulation failed.
224 * Set up signal info to return SEGV, then return OK
225 */
226 set_segfault(regs, address);
227 }
228
229 return 0;
230}
231
232/*
233 * Only emulate SWP/SWPB executed in ARM state/User mode.
234 * The kernel must be SWP free and SWP{B} does not exist in Thumb/ThumbEE.
235 */
236static struct undef_hook swp_hook = {
237 .instr_mask = 0x0fb00ff0,
238 .instr_val = 0x01000090,
239 .cpsr_mask = MODE_MASK | PSR_T_BIT | PSR_J_BIT,
240 .cpsr_val = USR_MODE,
241 .fn = swp_handler
242};
243
244/*
245 * Register handler and create status file in /proc/cpu
246 * Invoked as late_initcall, since not needed before init spawned.
247 */
248static int __init swp_emulation_init(void)
249{
250#ifdef CONFIG_PROC_FS
251 struct proc_dir_entry *res;
252
253 res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
254
255 if (!res)
256 return -ENOMEM;
257
258 res->read_proc = proc_read_status;
259#endif /* CONFIG_PROC_FS */
260
261 printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
262 register_undef_hook(&swp_hook);
263
264 return 0;
265}
266
267late_initcall(swp_emulation_init);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 38c261f9951c..f1e2eb19a67d 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -30,12 +30,13 @@
30#include <asm/leds.h> 30#include <asm/leds.h>
31#include <asm/thread_info.h> 31#include <asm/thread_info.h>
32#include <asm/stacktrace.h> 32#include <asm/stacktrace.h>
33#include <asm/mach/arch.h>
33#include <asm/mach/time.h> 34#include <asm/mach/time.h>
34 35
35/* 36/*
36 * Our system timer. 37 * Our system timer.
37 */ 38 */
38struct sys_timer *system_timer; 39static struct sys_timer *system_timer;
39 40
40#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 41#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
41/* this needs a better home */ 42/* this needs a better home */
@@ -160,6 +161,7 @@ device_initcall(timer_init_sysfs);
160 161
161void __init time_init(void) 162void __init time_init(void)
162{ 163{
164 system_timer = machine_desc->timer;
163 system_timer->init(); 165 system_timer->init();
164} 166}
165 167
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 446aee97436f..e02f4f7537c5 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -37,6 +37,8 @@
37 37
38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; 38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
39 39
40void *vectors_page;
41
40#ifdef CONFIG_DEBUG_USER 42#ifdef CONFIG_DEBUG_USER
41unsigned int user_debug; 43unsigned int user_debug;
42 44
@@ -756,7 +758,11 @@ static void __init kuser_get_tls_init(unsigned long vectors)
756 758
757void __init early_trap_init(void) 759void __init early_trap_init(void)
758{ 760{
761#if defined(CONFIG_CPU_USE_DOMAINS)
759 unsigned long vectors = CONFIG_VECTORS_BASE; 762 unsigned long vectors = CONFIG_VECTORS_BASE;
763#else
764 unsigned long vectors = (unsigned long)vectors_page;
765#endif
760 extern char __stubs_start[], __stubs_end[]; 766 extern char __stubs_start[], __stubs_end[];
761 extern char __vectors_start[], __vectors_end[]; 767 extern char __vectors_start[], __vectors_end[];
762 extern char __kuser_helper_start[], __kuser_helper_end[]; 768 extern char __kuser_helper_start[], __kuser_helper_end[];
@@ -780,10 +786,10 @@ void __init early_trap_init(void)
780 * Copy signal return handlers into the vector page, and 786 * Copy signal return handlers into the vector page, and
781 * set sigreturn to be a pointer to these. 787 * set sigreturn to be a pointer to these.
782 */ 788 */
783 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, 789 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
784 sizeof(sigreturn_codes)); 790 sigreturn_codes, sizeof(sigreturn_codes));
785 memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, 791 memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
786 sizeof(syscall_restart_code)); 792 syscall_restart_code, sizeof(syscall_restart_code));
787 793
788 flush_icache_range(vectors, vectors + PAGE_SIZE); 794 flush_icache_range(vectors, vectors + PAGE_SIZE);
789 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 795 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 897c1a8f1694..86b66f3f2031 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -168,6 +168,7 @@ SECTIONS
168 168
169 NOSAVE_DATA 169 NOSAVE_DATA
170 CACHELINE_ALIGNED_DATA(32) 170 CACHELINE_ALIGNED_DATA(32)
171 READ_MOSTLY_DATA(32)
171 172
172 /* 173 /*
173 * The exception fixup table (might need resorting at runtime) 174 * The exception fixup table (might need resorting at runtime)
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index b1631a7dbe75..1b049cd7a49a 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -28,20 +28,21 @@
28 */ 28 */
29#include <linux/linkage.h> 29#include <linux/linkage.h>
30#include <asm/errno.h> 30#include <asm/errno.h>
31#include <asm/domain.h>
31 32
32ENTRY(__get_user_1) 33ENTRY(__get_user_1)
331: ldrbt r2, [r0] 341: T(ldrb) r2, [r0]
34 mov r0, #0 35 mov r0, #0
35 mov pc, lr 36 mov pc, lr
36ENDPROC(__get_user_1) 37ENDPROC(__get_user_1)
37 38
38ENTRY(__get_user_2) 39ENTRY(__get_user_2)
39#ifdef CONFIG_THUMB2_KERNEL 40#ifdef CONFIG_THUMB2_KERNEL
402: ldrbt r2, [r0] 412: T(ldrb) r2, [r0]
413: ldrbt r3, [r0, #1] 423: T(ldrb) r3, [r0, #1]
42#else 43#else
432: ldrbt r2, [r0], #1 442: T(ldrb) r2, [r0], #1
443: ldrbt r3, [r0] 453: T(ldrb) r3, [r0]
45#endif 46#endif
46#ifndef __ARMEB__ 47#ifndef __ARMEB__
47 orr r2, r2, r3, lsl #8 48 orr r2, r2, r3, lsl #8
@@ -53,7 +54,7 @@ ENTRY(__get_user_2)
53ENDPROC(__get_user_2) 54ENDPROC(__get_user_2)
54 55
55ENTRY(__get_user_4) 56ENTRY(__get_user_4)
564: ldrt r2, [r0] 574: T(ldr) r2, [r0]
57 mov r0, #0 58 mov r0, #0
58 mov pc, lr 59 mov pc, lr
59ENDPROC(__get_user_4) 60ENDPROC(__get_user_4)
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 5a01a23c6c06..c023fc11e86c 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -28,9 +28,10 @@
28 */ 28 */
29#include <linux/linkage.h> 29#include <linux/linkage.h>
30#include <asm/errno.h> 30#include <asm/errno.h>
31#include <asm/domain.h>
31 32
32ENTRY(__put_user_1) 33ENTRY(__put_user_1)
331: strbt r2, [r0] 341: T(strb) r2, [r0]
34 mov r0, #0 35 mov r0, #0
35 mov pc, lr 36 mov pc, lr
36ENDPROC(__put_user_1) 37ENDPROC(__put_user_1)
@@ -39,19 +40,19 @@ ENTRY(__put_user_2)
39 mov ip, r2, lsr #8 40 mov ip, r2, lsr #8
40#ifdef CONFIG_THUMB2_KERNEL 41#ifdef CONFIG_THUMB2_KERNEL
41#ifndef __ARMEB__ 42#ifndef __ARMEB__
422: strbt r2, [r0] 432: T(strb) r2, [r0]
433: strbt ip, [r0, #1] 443: T(strb) ip, [r0, #1]
44#else 45#else
452: strbt ip, [r0] 462: T(strb) ip, [r0]
463: strbt r2, [r0, #1] 473: T(strb) r2, [r0, #1]
47#endif 48#endif
48#else /* !CONFIG_THUMB2_KERNEL */ 49#else /* !CONFIG_THUMB2_KERNEL */
49#ifndef __ARMEB__ 50#ifndef __ARMEB__
502: strbt r2, [r0], #1 512: T(strb) r2, [r0], #1
513: strbt ip, [r0] 523: T(strb) ip, [r0]
52#else 53#else
532: strbt ip, [r0], #1 542: T(strb) ip, [r0], #1
543: strbt r2, [r0] 553: T(strb) r2, [r0]
55#endif 56#endif
56#endif /* CONFIG_THUMB2_KERNEL */ 57#endif /* CONFIG_THUMB2_KERNEL */
57 mov r0, #0 58 mov r0, #0
@@ -59,18 +60,18 @@ ENTRY(__put_user_2)
59ENDPROC(__put_user_2) 60ENDPROC(__put_user_2)
60 61
61ENTRY(__put_user_4) 62ENTRY(__put_user_4)
624: strt r2, [r0] 634: T(str) r2, [r0]
63 mov r0, #0 64 mov r0, #0
64 mov pc, lr 65 mov pc, lr
65ENDPROC(__put_user_4) 66ENDPROC(__put_user_4)
66 67
67ENTRY(__put_user_8) 68ENTRY(__put_user_8)
68#ifdef CONFIG_THUMB2_KERNEL 69#ifdef CONFIG_THUMB2_KERNEL
695: strt r2, [r0] 705: T(str) r2, [r0]
706: strt r3, [r0, #4] 716: T(str) r3, [r0, #4]
71#else 72#else
725: strt r2, [r0], #4 735: T(str) r2, [r0], #4
736: strt r3, [r0] 746: T(str) r3, [r0]
74#endif 75#endif
75 mov r0, #0 76 mov r0, #0
76 mov pc, lr 77 mov pc, lr
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index fee9f6f88adb..d0ece2aeb70d 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -14,6 +14,7 @@
14#include <linux/linkage.h> 14#include <linux/linkage.h>
15#include <asm/assembler.h> 15#include <asm/assembler.h>
16#include <asm/errno.h> 16#include <asm/errno.h>
17#include <asm/domain.h>
17 18
18 .text 19 .text
19 20
@@ -31,11 +32,11 @@
31 rsb ip, ip, #4 32 rsb ip, ip, #4
32 cmp ip, #2 33 cmp ip, #2
33 ldrb r3, [r1], #1 34 ldrb r3, [r1], #1
34USER( strbt r3, [r0], #1) @ May fault 35USER( T(strb) r3, [r0], #1) @ May fault
35 ldrgeb r3, [r1], #1 36 ldrgeb r3, [r1], #1
36USER( strgebt r3, [r0], #1) @ May fault 37USER( T(strgeb) r3, [r0], #1) @ May fault
37 ldrgtb r3, [r1], #1 38 ldrgtb r3, [r1], #1
38USER( strgtbt r3, [r0], #1) @ May fault 39USER( T(strgtb) r3, [r0], #1) @ May fault
39 sub r2, r2, ip 40 sub r2, r2, ip
40 b .Lc2u_dest_aligned 41 b .Lc2u_dest_aligned
41 42
@@ -58,7 +59,7 @@ ENTRY(__copy_to_user)
58 addmi ip, r2, #4 59 addmi ip, r2, #4
59 bmi .Lc2u_0nowords 60 bmi .Lc2u_0nowords
60 ldr r3, [r1], #4 61 ldr r3, [r1], #4
61USER( strt r3, [r0], #4) @ May fault 62USER( T(str) r3, [r0], #4) @ May fault
62 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction 63 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
63 rsb ip, ip, #0 64 rsb ip, ip, #0
64 movs ip, ip, lsr #32 - PAGE_SHIFT 65 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -87,18 +88,18 @@ USER( strt r3, [r0], #4) @ May fault
87 stmneia r0!, {r3 - r4} @ Shouldnt fault 88 stmneia r0!, {r3 - r4} @ Shouldnt fault
88 tst ip, #4 89 tst ip, #4
89 ldrne r3, [r1], #4 90 ldrne r3, [r1], #4
90 strnet r3, [r0], #4 @ Shouldnt fault 91 T(strne) r3, [r0], #4 @ Shouldnt fault
91 ands ip, ip, #3 92 ands ip, ip, #3
92 beq .Lc2u_0fupi 93 beq .Lc2u_0fupi
93.Lc2u_0nowords: teq ip, #0 94.Lc2u_0nowords: teq ip, #0
94 beq .Lc2u_finished 95 beq .Lc2u_finished
95.Lc2u_nowords: cmp ip, #2 96.Lc2u_nowords: cmp ip, #2
96 ldrb r3, [r1], #1 97 ldrb r3, [r1], #1
97USER( strbt r3, [r0], #1) @ May fault 98USER( T(strb) r3, [r0], #1) @ May fault
98 ldrgeb r3, [r1], #1 99 ldrgeb r3, [r1], #1
99USER( strgebt r3, [r0], #1) @ May fault 100USER( T(strgeb) r3, [r0], #1) @ May fault
100 ldrgtb r3, [r1], #1 101 ldrgtb r3, [r1], #1
101USER( strgtbt r3, [r0], #1) @ May fault 102USER( T(strgtb) r3, [r0], #1) @ May fault
102 b .Lc2u_finished 103 b .Lc2u_finished
103 104
104.Lc2u_not_enough: 105.Lc2u_not_enough:
@@ -119,7 +120,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
119 mov r3, r7, pull #8 120 mov r3, r7, pull #8
120 ldr r7, [r1], #4 121 ldr r7, [r1], #4
121 orr r3, r3, r7, push #24 122 orr r3, r3, r7, push #24
122USER( strt r3, [r0], #4) @ May fault 123USER( T(str) r3, [r0], #4) @ May fault
123 mov ip, r0, lsl #32 - PAGE_SHIFT 124 mov ip, r0, lsl #32 - PAGE_SHIFT
124 rsb ip, ip, #0 125 rsb ip, ip, #0
125 movs ip, ip, lsr #32 - PAGE_SHIFT 126 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -154,18 +155,18 @@ USER( strt r3, [r0], #4) @ May fault
154 movne r3, r7, pull #8 155 movne r3, r7, pull #8
155 ldrne r7, [r1], #4 156 ldrne r7, [r1], #4
156 orrne r3, r3, r7, push #24 157 orrne r3, r3, r7, push #24
157 strnet r3, [r0], #4 @ Shouldnt fault 158 T(strne) r3, [r0], #4 @ Shouldnt fault
158 ands ip, ip, #3 159 ands ip, ip, #3
159 beq .Lc2u_1fupi 160 beq .Lc2u_1fupi
160.Lc2u_1nowords: mov r3, r7, get_byte_1 161.Lc2u_1nowords: mov r3, r7, get_byte_1
161 teq ip, #0 162 teq ip, #0
162 beq .Lc2u_finished 163 beq .Lc2u_finished
163 cmp ip, #2 164 cmp ip, #2
164USER( strbt r3, [r0], #1) @ May fault 165USER( T(strb) r3, [r0], #1) @ May fault
165 movge r3, r7, get_byte_2 166 movge r3, r7, get_byte_2
166USER( strgebt r3, [r0], #1) @ May fault 167USER( T(strgeb) r3, [r0], #1) @ May fault
167 movgt r3, r7, get_byte_3 168 movgt r3, r7, get_byte_3
168USER( strgtbt r3, [r0], #1) @ May fault 169USER( T(strgtb) r3, [r0], #1) @ May fault
169 b .Lc2u_finished 170 b .Lc2u_finished
170 171
171.Lc2u_2fupi: subs r2, r2, #4 172.Lc2u_2fupi: subs r2, r2, #4
@@ -174,7 +175,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
174 mov r3, r7, pull #16 175 mov r3, r7, pull #16
175 ldr r7, [r1], #4 176 ldr r7, [r1], #4
176 orr r3, r3, r7, push #16 177 orr r3, r3, r7, push #16
177USER( strt r3, [r0], #4) @ May fault 178USER( T(str) r3, [r0], #4) @ May fault
178 mov ip, r0, lsl #32 - PAGE_SHIFT 179 mov ip, r0, lsl #32 - PAGE_SHIFT
179 rsb ip, ip, #0 180 rsb ip, ip, #0
180 movs ip, ip, lsr #32 - PAGE_SHIFT 181 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -209,18 +210,18 @@ USER( strt r3, [r0], #4) @ May fault
209 movne r3, r7, pull #16 210 movne r3, r7, pull #16
210 ldrne r7, [r1], #4 211 ldrne r7, [r1], #4
211 orrne r3, r3, r7, push #16 212 orrne r3, r3, r7, push #16
212 strnet r3, [r0], #4 @ Shouldnt fault 213 T(strne) r3, [r0], #4 @ Shouldnt fault
213 ands ip, ip, #3 214 ands ip, ip, #3
214 beq .Lc2u_2fupi 215 beq .Lc2u_2fupi
215.Lc2u_2nowords: mov r3, r7, get_byte_2 216.Lc2u_2nowords: mov r3, r7, get_byte_2
216 teq ip, #0 217 teq ip, #0
217 beq .Lc2u_finished 218 beq .Lc2u_finished
218 cmp ip, #2 219 cmp ip, #2
219USER( strbt r3, [r0], #1) @ May fault 220USER( T(strb) r3, [r0], #1) @ May fault
220 movge r3, r7, get_byte_3 221 movge r3, r7, get_byte_3
221USER( strgebt r3, [r0], #1) @ May fault 222USER( T(strgeb) r3, [r0], #1) @ May fault
222 ldrgtb r3, [r1], #0 223 ldrgtb r3, [r1], #0
223USER( strgtbt r3, [r0], #1) @ May fault 224USER( T(strgtb) r3, [r0], #1) @ May fault
224 b .Lc2u_finished 225 b .Lc2u_finished
225 226
226.Lc2u_3fupi: subs r2, r2, #4 227.Lc2u_3fupi: subs r2, r2, #4
@@ -229,7 +230,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
229 mov r3, r7, pull #24 230 mov r3, r7, pull #24
230 ldr r7, [r1], #4 231 ldr r7, [r1], #4
231 orr r3, r3, r7, push #8 232 orr r3, r3, r7, push #8
232USER( strt r3, [r0], #4) @ May fault 233USER( T(str) r3, [r0], #4) @ May fault
233 mov ip, r0, lsl #32 - PAGE_SHIFT 234 mov ip, r0, lsl #32 - PAGE_SHIFT
234 rsb ip, ip, #0 235 rsb ip, ip, #0
235 movs ip, ip, lsr #32 - PAGE_SHIFT 236 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -264,18 +265,18 @@ USER( strt r3, [r0], #4) @ May fault
264 movne r3, r7, pull #24 265 movne r3, r7, pull #24
265 ldrne r7, [r1], #4 266 ldrne r7, [r1], #4
266 orrne r3, r3, r7, push #8 267 orrne r3, r3, r7, push #8
267 strnet r3, [r0], #4 @ Shouldnt fault 268 T(strne) r3, [r0], #4 @ Shouldnt fault
268 ands ip, ip, #3 269 ands ip, ip, #3
269 beq .Lc2u_3fupi 270 beq .Lc2u_3fupi
270.Lc2u_3nowords: mov r3, r7, get_byte_3 271.Lc2u_3nowords: mov r3, r7, get_byte_3
271 teq ip, #0 272 teq ip, #0
272 beq .Lc2u_finished 273 beq .Lc2u_finished
273 cmp ip, #2 274 cmp ip, #2
274USER( strbt r3, [r0], #1) @ May fault 275USER( T(strb) r3, [r0], #1) @ May fault
275 ldrgeb r3, [r1], #1 276 ldrgeb r3, [r1], #1
276USER( strgebt r3, [r0], #1) @ May fault 277USER( T(strgeb) r3, [r0], #1) @ May fault
277 ldrgtb r3, [r1], #0 278 ldrgtb r3, [r1], #0
278USER( strgtbt r3, [r0], #1) @ May fault 279USER( T(strgtb) r3, [r0], #1) @ May fault
279 b .Lc2u_finished 280 b .Lc2u_finished
280ENDPROC(__copy_to_user) 281ENDPROC(__copy_to_user)
281 282
@@ -294,11 +295,11 @@ ENDPROC(__copy_to_user)
294.Lcfu_dest_not_aligned: 295.Lcfu_dest_not_aligned:
295 rsb ip, ip, #4 296 rsb ip, ip, #4
296 cmp ip, #2 297 cmp ip, #2
297USER( ldrbt r3, [r1], #1) @ May fault 298USER( T(ldrb) r3, [r1], #1) @ May fault
298 strb r3, [r0], #1 299 strb r3, [r0], #1
299USER( ldrgebt r3, [r1], #1) @ May fault 300USER( T(ldrgeb) r3, [r1], #1) @ May fault
300 strgeb r3, [r0], #1 301 strgeb r3, [r0], #1
301USER( ldrgtbt r3, [r1], #1) @ May fault 302USER( T(ldrgtb) r3, [r1], #1) @ May fault
302 strgtb r3, [r0], #1 303 strgtb r3, [r0], #1
303 sub r2, r2, ip 304 sub r2, r2, ip
304 b .Lcfu_dest_aligned 305 b .Lcfu_dest_aligned
@@ -321,7 +322,7 @@ ENTRY(__copy_from_user)
321.Lcfu_0fupi: subs r2, r2, #4 322.Lcfu_0fupi: subs r2, r2, #4
322 addmi ip, r2, #4 323 addmi ip, r2, #4
323 bmi .Lcfu_0nowords 324 bmi .Lcfu_0nowords
324USER( ldrt r3, [r1], #4) 325USER( T(ldr) r3, [r1], #4)
325 str r3, [r0], #4 326 str r3, [r0], #4
326 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction 327 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
327 rsb ip, ip, #0 328 rsb ip, ip, #0
@@ -350,18 +351,18 @@ USER( ldrt r3, [r1], #4)
350 ldmneia r1!, {r3 - r4} @ Shouldnt fault 351 ldmneia r1!, {r3 - r4} @ Shouldnt fault
351 stmneia r0!, {r3 - r4} 352 stmneia r0!, {r3 - r4}
352 tst ip, #4 353 tst ip, #4
353 ldrnet r3, [r1], #4 @ Shouldnt fault 354 T(ldrne) r3, [r1], #4 @ Shouldnt fault
354 strne r3, [r0], #4 355 strne r3, [r0], #4
355 ands ip, ip, #3 356 ands ip, ip, #3
356 beq .Lcfu_0fupi 357 beq .Lcfu_0fupi
357.Lcfu_0nowords: teq ip, #0 358.Lcfu_0nowords: teq ip, #0
358 beq .Lcfu_finished 359 beq .Lcfu_finished
359.Lcfu_nowords: cmp ip, #2 360.Lcfu_nowords: cmp ip, #2
360USER( ldrbt r3, [r1], #1) @ May fault 361USER( T(ldrb) r3, [r1], #1) @ May fault
361 strb r3, [r0], #1 362 strb r3, [r0], #1
362USER( ldrgebt r3, [r1], #1) @ May fault 363USER( T(ldrgeb) r3, [r1], #1) @ May fault
363 strgeb r3, [r0], #1 364 strgeb r3, [r0], #1
364USER( ldrgtbt r3, [r1], #1) @ May fault 365USER( T(ldrgtb) r3, [r1], #1) @ May fault
365 strgtb r3, [r0], #1 366 strgtb r3, [r0], #1
366 b .Lcfu_finished 367 b .Lcfu_finished
367 368
@@ -374,7 +375,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
374 375
375.Lcfu_src_not_aligned: 376.Lcfu_src_not_aligned:
376 bic r1, r1, #3 377 bic r1, r1, #3
377USER( ldrt r7, [r1], #4) @ May fault 378USER( T(ldr) r7, [r1], #4) @ May fault
378 cmp ip, #2 379 cmp ip, #2
379 bgt .Lcfu_3fupi 380 bgt .Lcfu_3fupi
380 beq .Lcfu_2fupi 381 beq .Lcfu_2fupi
@@ -382,7 +383,7 @@ USER( ldrt r7, [r1], #4) @ May fault
382 addmi ip, r2, #4 383 addmi ip, r2, #4
383 bmi .Lcfu_1nowords 384 bmi .Lcfu_1nowords
384 mov r3, r7, pull #8 385 mov r3, r7, pull #8
385USER( ldrt r7, [r1], #4) @ May fault 386USER( T(ldr) r7, [r1], #4) @ May fault
386 orr r3, r3, r7, push #24 387 orr r3, r3, r7, push #24
387 str r3, [r0], #4 388 str r3, [r0], #4
388 mov ip, r1, lsl #32 - PAGE_SHIFT 389 mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -417,7 +418,7 @@ USER( ldrt r7, [r1], #4) @ May fault
417 stmneia r0!, {r3 - r4} 418 stmneia r0!, {r3 - r4}
418 tst ip, #4 419 tst ip, #4
419 movne r3, r7, pull #8 420 movne r3, r7, pull #8
420USER( ldrnet r7, [r1], #4) @ May fault 421USER( T(ldrne) r7, [r1], #4) @ May fault
421 orrne r3, r3, r7, push #24 422 orrne r3, r3, r7, push #24
422 strne r3, [r0], #4 423 strne r3, [r0], #4
423 ands ip, ip, #3 424 ands ip, ip, #3
@@ -437,7 +438,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
437 addmi ip, r2, #4 438 addmi ip, r2, #4
438 bmi .Lcfu_2nowords 439 bmi .Lcfu_2nowords
439 mov r3, r7, pull #16 440 mov r3, r7, pull #16
440USER( ldrt r7, [r1], #4) @ May fault 441USER( T(ldr) r7, [r1], #4) @ May fault
441 orr r3, r3, r7, push #16 442 orr r3, r3, r7, push #16
442 str r3, [r0], #4 443 str r3, [r0], #4
443 mov ip, r1, lsl #32 - PAGE_SHIFT 444 mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -473,7 +474,7 @@ USER( ldrt r7, [r1], #4) @ May fault
473 stmneia r0!, {r3 - r4} 474 stmneia r0!, {r3 - r4}
474 tst ip, #4 475 tst ip, #4
475 movne r3, r7, pull #16 476 movne r3, r7, pull #16
476USER( ldrnet r7, [r1], #4) @ May fault 477USER( T(ldrne) r7, [r1], #4) @ May fault
477 orrne r3, r3, r7, push #16 478 orrne r3, r3, r7, push #16
478 strne r3, [r0], #4 479 strne r3, [r0], #4
479 ands ip, ip, #3 480 ands ip, ip, #3
@@ -485,7 +486,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
485 strb r3, [r0], #1 486 strb r3, [r0], #1
486 movge r3, r7, get_byte_3 487 movge r3, r7, get_byte_3
487 strgeb r3, [r0], #1 488 strgeb r3, [r0], #1
488USER( ldrgtbt r3, [r1], #0) @ May fault 489USER( T(ldrgtb) r3, [r1], #0) @ May fault
489 strgtb r3, [r0], #1 490 strgtb r3, [r0], #1
490 b .Lcfu_finished 491 b .Lcfu_finished
491 492
@@ -493,7 +494,7 @@ USER( ldrgtbt r3, [r1], #0) @ May fault
493 addmi ip, r2, #4 494 addmi ip, r2, #4
494 bmi .Lcfu_3nowords 495 bmi .Lcfu_3nowords
495 mov r3, r7, pull #24 496 mov r3, r7, pull #24
496USER( ldrt r7, [r1], #4) @ May fault 497USER( T(ldr) r7, [r1], #4) @ May fault
497 orr r3, r3, r7, push #8 498 orr r3, r3, r7, push #8
498 str r3, [r0], #4 499 str r3, [r0], #4
499 mov ip, r1, lsl #32 - PAGE_SHIFT 500 mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -528,7 +529,7 @@ USER( ldrt r7, [r1], #4) @ May fault
528 stmneia r0!, {r3 - r4} 529 stmneia r0!, {r3 - r4}
529 tst ip, #4 530 tst ip, #4
530 movne r3, r7, pull #24 531 movne r3, r7, pull #24
531USER( ldrnet r7, [r1], #4) @ May fault 532USER( T(ldrne) r7, [r1], #4) @ May fault
532 orrne r3, r3, r7, push #8 533 orrne r3, r3, r7, push #8
533 strne r3, [r0], #4 534 strne r3, [r0], #4
534 ands ip, ip, #3 535 ands ip, ip, #3
@@ -538,9 +539,9 @@ USER( ldrnet r7, [r1], #4) @ May fault
538 beq .Lcfu_finished 539 beq .Lcfu_finished
539 cmp ip, #2 540 cmp ip, #2
540 strb r3, [r0], #1 541 strb r3, [r0], #1
541USER( ldrgebt r3, [r1], #1) @ May fault 542USER( T(ldrgeb) r3, [r1], #1) @ May fault
542 strgeb r3, [r0], #1 543 strgeb r3, [r0], #1
543USER( ldrgtbt r3, [r1], #1) @ May fault 544USER( T(ldrgtb) r3, [r1], #1) @ May fault
544 strgtb r3, [r0], #1 545 strgtb r3, [r0], #1
545 b .Lcfu_finished 546 b .Lcfu_finished
546ENDPROC(__copy_from_user) 547ENDPROC(__copy_from_user)
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c
index 14bafc38f2dc..ad237a42d265 100644
--- a/arch/arm/mach-bcmring/clock.c
+++ b/arch/arm/mach-bcmring/clock.c
@@ -21,13 +21,12 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/clkdev.h>
24#include <mach/csp/hw_cfg.h> 25#include <mach/csp/hw_cfg.h>
25#include <mach/csp/chipcHw_def.h> 26#include <mach/csp/chipcHw_def.h>
26#include <mach/csp/chipcHw_reg.h> 27#include <mach/csp/chipcHw_reg.h>
27#include <mach/csp/chipcHw_inline.h> 28#include <mach/csp/chipcHw_inline.h>
28 29
29#include <asm/clkdev.h>
30
31#include "clock.h" 30#include "clock.h"
32 31
33#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) 32#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index b91b1b0fdff3..8fc2035759fb 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -30,10 +30,10 @@
30#include <linux/amba/bus.h> 30#include <linux/amba/bus.h>
31#include <linux/clocksource.h> 31#include <linux/clocksource.h>
32#include <linux/clockchips.h> 32#include <linux/clockchips.h>
33#include <linux/clkdev.h>
33 34
34#include <mach/csp/mm_addr.h> 35#include <mach/csp/mm_addr.h>
35#include <mach/hardware.h> 36#include <mach/hardware.h>
36#include <asm/clkdev.h>
37#include <linux/io.h> 37#include <linux/io.h>
38#include <asm/irq.h> 38#include <asm/irq.h>
39#include <asm/hardware/arm_timer.h> 39#include <asm/hardware/arm_timer.h>
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
index 9ebfcc46feb1..29b13f249aa9 100644
--- a/arch/arm/mach-cns3xxx/Kconfig
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -3,6 +3,7 @@ menu "CNS3XXX platform type"
3 3
4config MACH_CNS3420VB 4config MACH_CNS3420VB
5 bool "Support for CNS3420 Validation Board" 5 bool "Support for CNS3420 Validation Board"
6 select MIGHT_HAVE_PCI
6 help 7 help
7 Include support for the Cavium Networks CNS3420 MPCore Platform 8 Include support for the Cavium Networks CNS3420 MPCore Platform
8 Baseboard. 9 Baseboard.
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 11099980b58b..0dd22031ec62 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -68,7 +68,7 @@
68#ifndef __ASSEMBLER__ 68#ifndef __ASSEMBLER__
69 69
70#include <linux/list.h> 70#include <linux/list.h>
71#include <asm/clkdev.h> 71#include <linux/clkdev.h>
72 72
73#define PLLSTAT_GOSTAT BIT(0) 73#define PLLSTAT_GOSTAT BIT(0)
74#define PLLCMD_GOSET BIT(0) 74#define PLLCMD_GOSET BIT(0)
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index ef06c66a6f16..ca4de7105097 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -19,10 +19,10 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/clkdev.h>
22 23
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24 25
25#include <asm/clkdev.h>
26#include <asm/div64.h> 26#include <asm/div64.h>
27 27
28 28
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
index daca30b2d5b1..3938a563b280 100644
--- a/arch/arm/mach-imx/clock-imx1.c
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -22,8 +22,7 @@
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/io.h> 24#include <linux/io.h>
25 25#include <linux/clkdev.h>
26#include <asm/clkdev.h>
27 26
28#include <mach/clock.h> 27#include <mach/clock.h>
29#include <mach/hardware.h> 28#include <mach/hardware.h>
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
index cf15ea516a72..d7056559715a 100644
--- a/arch/arm/mach-imx/clock-imx21.c
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -21,11 +21,11 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/clkdev.h>
24 25
25#include <mach/clock.h> 26#include <mach/clock.h>
26#include <mach/hardware.h> 27#include <mach/hardware.h>
27#include <mach/common.h> 28#include <mach/common.h>
28#include <asm/clkdev.h>
29#include <asm/div64.h> 29#include <asm/div64.h>
30 30
31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) 31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
index 98a25bada783..ca1017b9028d 100644
--- a/arch/arm/mach-imx/clock-imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -21,8 +21,8 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/clkdev.h>
24 25
25#include <asm/clkdev.h>
26#include <asm/div64.h> 26#include <asm/div64.h>
27 27
28#include <mach/clock.h> 28#include <mach/clock.h>
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 27db275b367c..769b0f10c834 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -4,6 +4,7 @@ menu "Integrator Options"
4 4
5config ARCH_INTEGRATOR_AP 5config ARCH_INTEGRATOR_AP
6 bool "Support Integrator/AP and Integrator/PP2 platforms" 6 bool "Support Integrator/AP and Integrator/PP2 platforms"
7 select MIGHT_HAVE_PCI
7 help 8 help
8 Include support for the ARM(R) Integrator/AP and 9 Include support for the ARM(R) Integrator/AP and
9 Integrator/PP2 platforms. 10 Integrator/PP2 platforms.
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8f4fb6d638f7..b8e884b450da 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -21,9 +21,8 @@
21#include <linux/amba/bus.h> 21#include <linux/amba/bus.h>
22#include <linux/amba/serial.h> 22#include <linux/amba/serial.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clkdev.h>
24 25
25#include <asm/clkdev.h>
26#include <mach/clkdev.h>
27#include <mach/hardware.h> 26#include <mach/hardware.h>
28#include <mach/platform.h> 27#include <mach/platform.h>
29#include <asm/irq.h> 28#include <asm/irq.h>
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index fd684bf205e5..5db574f8ae3f 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -22,9 +22,8 @@
22#include <linux/amba/clcd.h> 22#include <linux/amba/clcd.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/clkdev.h>
25 26
26#include <asm/clkdev.h>
27#include <mach/clkdev.h>
28#include <asm/hardware/icst.h> 27#include <asm/hardware/icst.h>
29#include <mach/lm.h> 28#include <mach/lm.h>
30#include <mach/impd1.h> 29#include <mach/impd1.h>
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 1713ecf0c95f..85e48a5f77b9 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -21,9 +21,8 @@
21#include <linux/amba/mmci.h> 21#include <linux/amba/mmci.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/gfp.h> 23#include <linux/gfp.h>
24#include <linux/clkdev.h>
24 25
25#include <asm/clkdev.h>
26#include <mach/clkdev.h>
27#include <mach/hardware.h> 26#include <mach/hardware.h>
28#include <mach/platform.h> 27#include <mach/platform.h>
29#include <asm/irq.h> 28#include <asm/irq.h>
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index 7415e4338651..3ad455318868 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -58,13 +58,13 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
58 __dma; \ 58 __dma; \
59 }) 59 })
60 60
61#define __arch_page_to_dma(dev, page) \ 61#define __arch_pfn_to_dma(dev, pfn) \
62 ({ \ 62 ({ \
63 /* __is_lbus_virt() can never be true for RAM pages */ \ 63 /* __is_lbus_virt() can never be true for RAM pages */ \
64 (dma_addr_t)page_to_phys(page); \ 64 (dma_addr_t)__pfn_to_phys(pfn); \
65 }) 65 })
66 66
67#define __arch_dma_to_page(dev, addr) phys_to_page(addr) 67#define __arch_dma_to_pfn(dev, addr) __phys_to_pfn(addr)
68 68
69#endif /* CONFIG_ARCH_IOP13XX */ 69#endif /* CONFIG_ARCH_IOP13XX */
70#endif /* !ASSEMBLY */ 70#endif /* !ASSEMBLY */
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
index fe0c82e30b2d..f5c39a8c2b00 100644
--- a/arch/arm/mach-ks8695/Kconfig
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -4,6 +4,7 @@ menu "Kendin/Micrel KS8695 Implementations"
4 4
5config MACH_KS8695 5config MACH_KS8695
6 bool "KS8695 development board" 6 bool "KS8695 development board"
7 select MIGHT_HAVE_PCI
7 help 8 help
8 Say 'Y' here if you want your kernel to run on the original 9 Say 'Y' here if you want your kernel to run on the original
9 Kendin-Micrel KS8695 development board. 10 Kendin-Micrel KS8695 development board.
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index ffa19aae6e05..bace9a681adc 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -35,17 +35,17 @@ extern struct bus_type platform_bus_type;
35 __phys_to_virt(x) : __bus_to_virt(x)); }) 35 __phys_to_virt(x) : __bus_to_virt(x)); })
36#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \ 36#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
37 (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); }) 37 (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
38#define __arch_page_to_dma(dev, x) \ 38#define __arch_pfn_to_dma(dev, pfn) \
39 ({ dma_addr_t __dma = page_to_phys(page); \ 39 ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
40 if (!is_lbus_device(dev)) \ 40 if (!is_lbus_device(dev)) \
41 __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \ 41 __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
42 __dma; }) 42 __dma; })
43 43
44#define __arch_dma_to_page(dev, x) \ 44#define __arch_dma_to_pfn(dev, x) \
45 ({ dma_addr_t __dma = x; \ 45 ({ dma_addr_t __dma = x; \
46 if (!is_lbus_device(dev)) \ 46 if (!is_lbus_device(dev)) \
47 __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \ 47 __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \
48 phys_to_page(__dma); \ 48 __phys_to_pfn(__dma); \
49 }) 49 })
50 50
51#endif 51#endif
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index 32d63796430a..da0e6498110a 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -90,10 +90,9 @@
90#include <linux/clk.h> 90#include <linux/clk.h>
91#include <linux/amba/bus.h> 91#include <linux/amba/bus.h>
92#include <linux/amba/clcd.h> 92#include <linux/amba/clcd.h>
93#include <linux/clkdev.h>
93 94
94#include <mach/hardware.h> 95#include <mach/hardware.h>
95#include <asm/clkdev.h>
96#include <mach/clkdev.h>
97#include <mach/platform.h> 96#include <mach/platform.h>
98#include "clock.h" 97#include "clock.h"
99#include "common.h" 98#include "common.h"
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
index 016ae94691c0..9b027d7491f5 100644
--- a/arch/arm/mach-mmp/clock.h
+++ b/arch/arm/mach-mmp/clock.h
@@ -6,7 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#include <asm/clkdev.h> 9#include <linux/clkdev.h>
10 10
11struct clkops { 11struct clkops {
12 void (*enable)(struct clk *); 12 void (*enable)(struct clk *);
diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h
index 3ff7bf5e679e..a95f7b9efe31 100644
--- a/arch/arm/mach-msm/include/mach/smp.h
+++ b/arch/arm/mach-msm/include/mach/smp.h
@@ -31,9 +31,9 @@
31 31
32#include <asm/hardware/gic.h> 32#include <asm/hardware/gic.h>
33 33
34static inline void smp_cross_call(const struct cpumask *mask) 34static inline void smp_cross_call(const struct cpumask *mask, int ipi)
35{ 35{
36 gic_raise_softirq(mask, 1); 36 gic_raise_softirq(mask, ipi);
37} 37}
38 38
39#endif 39#endif
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
index 9e4a5578c2fb..00dcb08019e9 100644
--- a/arch/arm/mach-mx25/clock.c
+++ b/arch/arm/mach-mx25/clock.c
@@ -21,8 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/clkdev.h>
25#include <asm/clkdev.h>
26 25
27#include <mach/clock.h> 26#include <mach/clock.h>
28#include <mach/hardware.h> 27#include <mach/hardware.h>
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c
index 109e98f323e0..1cd8b40b7676 100644
--- a/arch/arm/mach-mx3/clock-imx31.c
+++ b/arch/arm/mach-mx3/clock-imx31.c
@@ -23,8 +23,8 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/clkdev.h>
26 27
27#include <asm/clkdev.h>
28#include <asm/div64.h> 28#include <asm/div64.h>
29 29
30#include <mach/clock.h> 30#include <mach/clock.h>
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 61e4a318980a..819dd809615a 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -21,8 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/clkdev.h>
25#include <asm/clkdev.h>
26 25
27#include <mach/clock.h> 26#include <mach/clock.h>
28#include <mach/hardware.h> 27#include <mach/hardware.h>
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index 8ac36d882927..5975edb47de8 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -14,8 +14,8 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/clkdev.h>
17 18
18#include <asm/clkdev.h>
19#include <asm/div64.h> 19#include <asm/div64.h>
20 20
21#include <mach/hardware.h> 21#include <mach/hardware.h>
diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c
index 5c85075d8a56..9fab505f1eb1 100644
--- a/arch/arm/mach-mxc91231/clock.c
+++ b/arch/arm/mach-mxc91231/clock.c
@@ -2,12 +2,12 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/io.h> 4#include <linux/io.h>
5#include <linux/clkdev.h>
5 6
6#include <mach/clock.h> 7#include <mach/clock.h>
7#include <mach/hardware.h> 8#include <mach/hardware.h>
8#include <mach/common.h> 9#include <mach/common.h>
9 10
10#include <asm/clkdev.h>
11#include <asm/bug.h> 11#include <asm/bug.h>
12#include <asm/div64.h> 12#include <asm/div64.h>
13 13
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
index 89f793adf776..48a59f24e10c 100644
--- a/arch/arm/mach-nomadik/clock.c
+++ b/arch/arm/mach-nomadik/clock.c
@@ -7,7 +7,7 @@
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/clk.h> 9#include <linux/clk.h>
10#include <asm/clkdev.h> 10#include <linux/clkdev.h>
11#include "clock.h" 11#include "clock.h"
12 12
13/* 13/*
diff --git a/arch/arm/mach-nuc93x/clock.h b/arch/arm/mach-nuc93x/clock.h
index 18e51be4816f..4de1f1da9dc5 100644
--- a/arch/arm/mach-nuc93x/clock.h
+++ b/arch/arm/mach-nuc93x/clock.h
@@ -10,7 +10,7 @@
10 * the Free Software Foundation; either version 2 of the License. 10 * the Free Software Foundation; either version 2 of the License.
11 */ 11 */
12 12
13#include <asm/clkdev.h> 13#include <linux/clkdev.h>
14 14
15void nuc93x_clk_enable(struct clk *clk, int enable); 15void nuc93x_clk_enable(struct clk *clk, int enable);
16void clks_register(struct clk_lookup *clks, size_t num); 16void clks_register(struct clk_lookup *clks, size_t num);
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index b8c7fb9d7921..84ef70476b51 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -17,9 +17,9 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/clkdev.h>
20 21
21#include <asm/mach-types.h> 22#include <asm/mach-types.h>
22#include <asm/clkdev.h>
23 23
24#include <plat/cpu.h> 24#include <plat/cpu.h>
25#include <plat/usb.h> 25#include <plat/usb.h>
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index ed8d330522f1..ebb888f59365 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -26,10 +26,10 @@
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/clkdev.h>
29 30
30#include <plat/cpu.h> 31#include <plat/cpu.h>
31#include <plat/clock.h> 32#include <plat/clock.h>
32#include <asm/clkdev.h>
33 33
34#include "clock.h" 34#include "clock.h"
35#include "prm.h" 35#include "prm.h"
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 6cee456ca542..4976b9393e49 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -17,16 +17,13 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/completion.h>
21 20
22#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
23#include <mach/omap4-common.h> 22#include <mach/omap4-common.h>
24 23
25static DECLARE_COMPLETION(cpu_killed);
26
27int platform_cpu_kill(unsigned int cpu) 24int platform_cpu_kill(unsigned int cpu)
28{ 25{
29 return wait_for_completion_timeout(&cpu_killed, 5000); 26 return 1;
30} 27}
31 28
32/* 29/*
@@ -35,15 +32,6 @@ int platform_cpu_kill(unsigned int cpu)
35 */ 32 */
36void platform_cpu_die(unsigned int cpu) 33void platform_cpu_die(unsigned int cpu)
37{ 34{
38 unsigned int this_cpu = hard_smp_processor_id();
39
40 if (cpu != this_cpu) {
41 pr_crit("platform_cpu_die running on %u, should be %u\n",
42 this_cpu, cpu);
43 BUG();
44 }
45 pr_notice("CPU%u: shutdown\n", cpu);
46 complete(&cpu_killed);
47 flush_cache_all(); 35 flush_cache_all();
48 dsb(); 36 dsb();
49 37
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 9fbac2c39104..b66cfe8bc464 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -21,7 +21,6 @@
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/localtimer.h>
25#include <asm/smp_scu.h> 24#include <asm/smp_scu.h>
26#include <mach/hardware.h> 25#include <mach/hardware.h>
27#include <mach/omap4-common.h> 26#include <mach/omap4-common.h>
@@ -29,22 +28,10 @@
29/* SCU base address */ 28/* SCU base address */
30static void __iomem *scu_base; 29static void __iomem *scu_base;
31 30
32/*
33 * Use SCU config register to count number of cores
34 */
35static inline unsigned int get_core_count(void)
36{
37 if (scu_base)
38 return scu_get_core_count(scu_base);
39 return 1;
40}
41
42static DEFINE_SPINLOCK(boot_lock); 31static DEFINE_SPINLOCK(boot_lock);
43 32
44void __cpuinit platform_secondary_init(unsigned int cpu) 33void __cpuinit platform_secondary_init(unsigned int cpu)
45{ 34{
46 trace_hardirqs_off();
47
48 /* 35 /*
49 * If any interrupts are already enabled for the primary 36 * If any interrupts are already enabled for the primary
50 * core (e.g. timer irq), then they will not have been enabled 37 * core (e.g. timer irq), then they will not have been enabled
@@ -76,7 +63,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
76 omap_modify_auxcoreboot0(0x200, 0xfffffdff); 63 omap_modify_auxcoreboot0(0x200, 0xfffffdff);
77 flush_cache_all(); 64 flush_cache_all();
78 smp_wmb(); 65 smp_wmb();
79 smp_cross_call(cpumask_of(cpu)); 66 smp_cross_call(cpumask_of(cpu), 1);
80 67
81 /* 68 /*
82 * Now the secondary core is starting up let it run its 69 * Now the secondary core is starting up let it run its
@@ -118,25 +105,9 @@ void __init smp_init_cpus(void)
118 scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256); 105 scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
119 BUG_ON(!scu_base); 106 BUG_ON(!scu_base);
120 107
121 ncores = get_core_count(); 108 ncores = scu_get_core_count(scu_base);
122
123 for (i = 0; i < ncores; i++)
124 set_cpu_possible(i, true);
125}
126
127void __init smp_prepare_cpus(unsigned int max_cpus)
128{
129 unsigned int ncores = get_core_count();
130 unsigned int cpu = smp_processor_id();
131 int i;
132 109
133 /* sanity check */ 110 /* sanity check */
134 if (ncores == 0) {
135 printk(KERN_ERR
136 "OMAP4: strange core count of 0? Default to 1\n");
137 ncores = 1;
138 }
139
140 if (ncores > NR_CPUS) { 111 if (ncores > NR_CPUS) {
141 printk(KERN_WARNING 112 printk(KERN_WARNING
142 "OMAP4: no. of cores (%d) greater than configured " 113 "OMAP4: no. of cores (%d) greater than configured "
@@ -144,13 +115,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
144 ncores, NR_CPUS); 115 ncores, NR_CPUS);
145 ncores = NR_CPUS; 116 ncores = NR_CPUS;
146 } 117 }
147 smp_store_cpu_info(cpu);
148 118
149 /* 119 for (i = 0; i < ncores; i++)
150 * are we trying to boot more cores than exist? 120 set_cpu_possible(i, true);
151 */ 121}
152 if (max_cpus > ncores) 122
153 max_cpus = ncores; 123void __init platform_smp_prepare_cpus(unsigned int max_cpus)
124{
125 int i;
154 126
155 /* 127 /*
156 * Initialise the present map, which describes the set of CPUs 128 * Initialise the present map, which describes the set of CPUs
@@ -159,18 +131,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
159 for (i = 0; i < max_cpus; i++) 131 for (i = 0; i < max_cpus; i++)
160 set_cpu_present(i, true); 132 set_cpu_present(i, true);
161 133
162 if (max_cpus > 1) { 134 /*
163 /* 135 * Initialise the SCU and wake up the secondary core using
164 * Enable the local timer or broadcast device for the 136 * wakeup_secondary().
165 * boot CPU, but only if we have more than one CPU. 137 */
166 */ 138 scu_enable(scu_base);
167 percpu_timer_setup(); 139 wakeup_secondary();
168
169 /*
170 * Initialise the SCU and wake up the secondary core using
171 * wakeup_secondary().
172 */
173 scu_enable(scu_base);
174 wakeup_secondary();
175 }
176} 140}
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
index 9d1975fa4d9f..a4a3819c96cb 100644
--- a/arch/arm/mach-pnx4008/clock.c
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -21,8 +21,7 @@
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/clkdev.h>
25#include <asm/clkdev.h>
26 25
27#include <mach/hardware.h> 26#include <mach/hardware.h>
28#include <mach/clock.h> 27#include <mach/clock.h>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index c93e73d54dd1..c98d81ff250c 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -94,6 +94,7 @@ config MACH_ARMCORE
94 select PXA27x 94 select PXA27x
95 select IWMMXT 95 select IWMMXT
96 select PXA25x 96 select PXA25x
97 select MIGHT_HAVE_PCI
97 98
98config MACH_EM_X270 99config MACH_EM_X270
99 bool "CompuLab EM-x270 platform" 100 bool "CompuLab EM-x270 platform"
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index abba0089a2ae..4e4a84be96ba 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -11,8 +11,8 @@
11#include <linux/spinlock.h> 11#include <linux/spinlock.h>
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/clkdev.h>
14 15
15#include <asm/clkdev.h>
16#include <mach/pxa2xx-regs.h> 16#include <mach/pxa2xx-regs.h>
17#include <mach/hardware.h> 17#include <mach/hardware.h>
18 18
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index d8488742b807..12cc0e87e6c4 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -1,4 +1,4 @@
1#include <asm/clkdev.h> 1#include <linux/clkdev.h>
2 2
3struct clkops { 3struct clkops {
4 void (*enable)(struct clk *); 4 void (*enable)(struct clk *);
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index aad806c5cb12..1c6602cf50e4 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -30,8 +30,8 @@
30#include <linux/ata_platform.h> 30#include <linux/ata_platform.h>
31#include <linux/amba/mmci.h> 31#include <linux/amba/mmci.h>
32#include <linux/gfp.h> 32#include <linux/gfp.h>
33#include <linux/clkdev.h>
33 34
34#include <asm/clkdev.h>
35#include <asm/system.h> 35#include <asm/system.h>
36#include <mach/hardware.h> 36#include <mach/hardware.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
@@ -47,7 +47,6 @@
47 47
48#include <asm/hardware/gic.h> 48#include <asm/hardware/gic.h>
49 49
50#include <mach/clkdev.h>
51#include <mach/platform.h> 50#include <mach/platform.h>
52#include <mach/irqs.h> 51#include <mach/irqs.h>
53#include <asm/hardware/timer-sp.h> 52#include <asm/hardware/timer-sp.h>
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index f95521a5e5ce..a87523d095e6 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -11,14 +11,11 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/completion.h>
15 14
16#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
17 16
18extern volatile int pen_release; 17extern volatile int pen_release;
19 18
20static DECLARE_COMPLETION(cpu_killed);
21
22static inline void cpu_enter_lowpower(void) 19static inline void cpu_enter_lowpower(void)
23{ 20{
24 unsigned int v; 21 unsigned int v;
@@ -34,10 +31,10 @@ static inline void cpu_enter_lowpower(void)
34 " bic %0, %0, #0x20\n" 31 " bic %0, %0, #0x20\n"
35 " mcr p15, 0, %0, c1, c0, 1\n" 32 " mcr p15, 0, %0, c1, c0, 1\n"
36 " mrc p15, 0, %0, c1, c0, 0\n" 33 " mrc p15, 0, %0, c1, c0, 0\n"
37 " bic %0, %0, #0x04\n" 34 " bic %0, %0, %2\n"
38 " mcr p15, 0, %0, c1, c0, 0\n" 35 " mcr p15, 0, %0, c1, c0, 0\n"
39 : "=&r" (v) 36 : "=&r" (v)
40 : "r" (0) 37 : "r" (0), "Ir" (CR_C)
41 : "cc"); 38 : "cc");
42} 39}
43 40
@@ -46,17 +43,17 @@ static inline void cpu_leave_lowpower(void)
46 unsigned int v; 43 unsigned int v;
47 44
48 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n" 45 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
49 " orr %0, %0, #0x04\n" 46 " orr %0, %0, %1\n"
50 " mcr p15, 0, %0, c1, c0, 0\n" 47 " mcr p15, 0, %0, c1, c0, 0\n"
51 " mrc p15, 0, %0, c1, c0, 1\n" 48 " mrc p15, 0, %0, c1, c0, 1\n"
52 " orr %0, %0, #0x20\n" 49 " orr %0, %0, #0x20\n"
53 " mcr p15, 0, %0, c1, c0, 1\n" 50 " mcr p15, 0, %0, c1, c0, 1\n"
54 : "=&r" (v) 51 : "=&r" (v)
55 : 52 : "Ir" (CR_C)
56 : "cc"); 53 : "cc");
57} 54}
58 55
59static inline void platform_do_lowpower(unsigned int cpu) 56static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
60{ 57{
61 /* 58 /*
62 * there is no power-control hardware on this platform, so all 59 * there is no power-control hardware on this platform, so all
@@ -80,22 +77,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
80 } 77 }
81 78
82 /* 79 /*
83 * getting here, means that we have come out of WFI without 80 * Getting here, means that we have come out of WFI without
84 * having been woken up - this shouldn't happen 81 * having been woken up - this shouldn't happen
85 * 82 *
86 * The trouble is, letting people know about this is not really 83 * Just note it happening - when we're woken, we can report
87 * possible, since we are currently running incoherently, and 84 * its occurrence.
88 * therefore cannot safely call printk() or anything else
89 */ 85 */
90#ifdef DEBUG 86 (*spurious)++;
91 printk("CPU%u: spurious wakeup call\n", cpu);
92#endif
93 } 87 }
94} 88}
95 89
96int platform_cpu_kill(unsigned int cpu) 90int platform_cpu_kill(unsigned int cpu)
97{ 91{
98 return wait_for_completion_timeout(&cpu_killed, 5000); 92 return 1;
99} 93}
100 94
101/* 95/*
@@ -105,30 +99,22 @@ int platform_cpu_kill(unsigned int cpu)
105 */ 99 */
106void platform_cpu_die(unsigned int cpu) 100void platform_cpu_die(unsigned int cpu)
107{ 101{
108#ifdef DEBUG 102 int spurious = 0;
109 unsigned int this_cpu = hard_smp_processor_id();
110
111 if (cpu != this_cpu) {
112 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
113 this_cpu, cpu);
114 BUG();
115 }
116#endif
117
118 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
119 complete(&cpu_killed);
120 103
121 /* 104 /*
122 * we're ready for shutdown now, so do it 105 * we're ready for shutdown now, so do it
123 */ 106 */
124 cpu_enter_lowpower(); 107 cpu_enter_lowpower();
125 platform_do_lowpower(cpu); 108 platform_do_lowpower(cpu, &spurious);
126 109
127 /* 110 /*
128 * bring this CPU back into the world of cache 111 * bring this CPU back into the world of cache
129 * coherency, and then restore interrupts 112 * coherency, and then restore interrupts
130 */ 113 */
131 cpu_leave_lowpower(); 114 cpu_leave_lowpower();
115
116 if (spurious)
117 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
132} 118}
133 119
134int platform_cpu_disable(unsigned int cpu) 120int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index d3cd265cb058..c8221b38ee7c 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -2,14 +2,13 @@
2#define ASMARM_ARCH_SMP_H 2#define ASMARM_ARCH_SMP_H
3 3
4#include <asm/hardware/gic.h> 4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6 5
7/* 6/*
8 * We use IRQ1 as the IPI 7 * We use IRQ1 as the IPI
9 */ 8 */
10static inline void smp_cross_call(const struct cpumask *mask) 9static inline void smp_cross_call(const struct cpumask *mask, int ipi)
11{ 10{
12 gic_raise_softirq(mask, 1); 11 gic_raise_softirq(mask, ipi);
13} 12}
14 13
15#endif 14#endif
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 6da8a2e53c44..a22bf67f2f78 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -19,7 +19,6 @@
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/localtimer.h>
23#include <asm/unified.h> 22#include <asm/unified.h>
24 23
25#include <mach/board-eb.h> 24#include <mach/board-eb.h>
@@ -37,6 +36,19 @@ extern void realview_secondary_startup(void);
37 */ 36 */
38volatile int __cpuinitdata pen_release = -1; 37volatile int __cpuinitdata pen_release = -1;
39 38
39/*
40 * Write pen_release in a way that is guaranteed to be visible to all
41 * observers, irrespective of whether they're taking part in coherency
42 * or not. This is necessary for the hotplug code to work reliably.
43 */
44static void write_pen_release(int val)
45{
46 pen_release = val;
47 smp_wmb();
48 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
49 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
50}
51
40static void __iomem *scu_base_addr(void) 52static void __iomem *scu_base_addr(void)
41{ 53{
42 if (machine_is_realview_eb_mp()) 54 if (machine_is_realview_eb_mp())
@@ -50,20 +62,10 @@ static void __iomem *scu_base_addr(void)
50 return (void __iomem *)0; 62 return (void __iomem *)0;
51} 63}
52 64
53static inline unsigned int get_core_count(void)
54{
55 void __iomem *scu_base = scu_base_addr();
56 if (scu_base)
57 return scu_get_core_count(scu_base);
58 return 1;
59}
60
61static DEFINE_SPINLOCK(boot_lock); 65static DEFINE_SPINLOCK(boot_lock);
62 66
63void __cpuinit platform_secondary_init(unsigned int cpu) 67void __cpuinit platform_secondary_init(unsigned int cpu)
64{ 68{
65 trace_hardirqs_off();
66
67 /* 69 /*
68 * if any interrupts are already enabled for the primary 70 * if any interrupts are already enabled for the primary
69 * core (e.g. timer irq), then they will not have been enabled 71 * core (e.g. timer irq), then they will not have been enabled
@@ -75,8 +77,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
75 * let the primary processor know we're out of the 77 * let the primary processor know we're out of the
76 * pen, then head off into the C entry point 78 * pen, then head off into the C entry point
77 */ 79 */
78 pen_release = -1; 80 write_pen_release(-1);
79 smp_wmb();
80 81
81 /* 82 /*
82 * Synchronise with the boot thread. 83 * Synchronise with the boot thread.
@@ -103,20 +104,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
103 * Note that "pen_release" is the hardware CPU ID, whereas 104 * Note that "pen_release" is the hardware CPU ID, whereas
104 * "cpu" is Linux's internal ID. 105 * "cpu" is Linux's internal ID.
105 */ 106 */
106 pen_release = cpu; 107 write_pen_release(cpu);
107 flush_cache_all();
108 108
109 /* 109 /*
110 * XXX 110 * Send the secondary CPU a soft interrupt, thereby causing
111 * 111 * the boot monitor to read the system wide flags register,
112 * This is a later addition to the booting protocol: the 112 * and branch to the address found there.
113 * bootMonitor now puts secondary cores into WFI, so
114 * poke_milo() no longer gets the cores moving; we need
115 * to send a soft interrupt to wake the secondary core.
116 * Use smp_cross_call() for this, since there's little
117 * point duplicating the code here
118 */ 113 */
119 smp_cross_call(cpumask_of(cpu)); 114 smp_cross_call(cpumask_of(cpu), 1);
120 115
121 timeout = jiffies + (1 * HZ); 116 timeout = jiffies + (1 * HZ);
122 while (time_before(jiffies, timeout)) { 117 while (time_before(jiffies, timeout)) {
@@ -136,48 +131,18 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
136 return pen_release != -1 ? -ENOSYS : 0; 131 return pen_release != -1 ? -ENOSYS : 0;
137} 132}
138 133
139static void __init poke_milo(void)
140{
141 /* nobody is to be released from the pen yet */
142 pen_release = -1;
143
144 /*
145 * Write the address of secondary startup into the system-wide flags
146 * register. The BootMonitor waits for this register to become
147 * non-zero.
148 */
149 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
150 __io_address(REALVIEW_SYS_FLAGSSET));
151
152 mb();
153}
154
155/* 134/*
156 * Initialise the CPU possible map early - this describes the CPUs 135 * Initialise the CPU possible map early - this describes the CPUs
157 * which may be present or become present in the system. 136 * which may be present or become present in the system.
158 */ 137 */
159void __init smp_init_cpus(void) 138void __init smp_init_cpus(void)
160{ 139{
161 unsigned int i, ncores = get_core_count(); 140 void __iomem *scu_base = scu_base_addr();
141 unsigned int i, ncores;
162 142
163 for (i = 0; i < ncores; i++) 143 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
164 set_cpu_possible(i, true);
165}
166
167void __init smp_prepare_cpus(unsigned int max_cpus)
168{
169 unsigned int ncores = get_core_count();
170 unsigned int cpu = smp_processor_id();
171 int i;
172 144
173 /* sanity check */ 145 /* sanity check */
174 if (ncores == 0) {
175 printk(KERN_ERR
176 "Realview: strange CM count of 0? Default to 1\n");
177
178 ncores = 1;
179 }
180
181 if (ncores > NR_CPUS) { 146 if (ncores > NR_CPUS) {
182 printk(KERN_WARNING 147 printk(KERN_WARNING
183 "Realview: no. of cores (%d) greater than configured " 148 "Realview: no. of cores (%d) greater than configured "
@@ -186,13 +151,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
186 ncores = NR_CPUS; 151 ncores = NR_CPUS;
187 } 152 }
188 153
189 smp_store_cpu_info(cpu); 154 for (i = 0; i < ncores; i++)
155 set_cpu_possible(i, true);
156}
190 157
191 /* 158void __init platform_smp_prepare_cpus(unsigned int max_cpus)
192 * are we trying to boot more cores than exist? 159{
193 */ 160 int i;
194 if (max_cpus > ncores)
195 max_cpus = ncores;
196 161
197 /* 162 /*
198 * Initialise the present map, which describes the set of CPUs 163 * Initialise the present map, which describes the set of CPUs
@@ -201,21 +166,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
201 for (i = 0; i < max_cpus; i++) 166 for (i = 0; i < max_cpus; i++)
202 set_cpu_present(i, true); 167 set_cpu_present(i, true);
203 168
169 scu_enable(scu_base_addr());
170
204 /* 171 /*
205 * Initialise the SCU if there are more than one CPU and let 172 * Write the address of secondary startup into the
206 * them know where to start. Note that, on modern versions of 173 * system-wide flags register. The BootMonitor waits
207 * MILO, the "poke" doesn't actually do anything until each 174 * until it receives a soft interrupt, and then the
208 * individual core is sent a soft interrupt to get it out of 175 * secondary CPU branches to this address.
209 * WFI
210 */ 176 */
211 if (max_cpus > 1) { 177 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
212 /* 178 __io_address(REALVIEW_SYS_FLAGSSET));
213 * Enable the local timer or broadcast device for the
214 * boot CPU, but only if we have more than one CPU.
215 */
216 percpu_timer_setup();
217
218 scu_enable(scu_base_addr());
219 poke_milo();
220 }
221} 179}
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 6983cb4d4cae..e82ab4aa7ab9 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -59,7 +59,7 @@ config MACH_JIVE
59 Say Y here if you are using the Logitech Jive. 59 Say Y here if you are using the Logitech Jive.
60 60
61config MACH_JIVE_SHOW_BOOTLOADER 61config MACH_JIVE_SHOW_BOOTLOADER
62 bool "Allow access to bootloader partitions in MTD" 62 bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
63 depends on MACH_JIVE && EXPERIMENTAL 63 depends on MACH_JIVE && EXPERIMENTAL
64 64
65config MACH_SMDK2413 65config MACH_SMDK2413
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c
index 03652c3605f6..afa5392d9fc0 100644
--- a/arch/arm/mach-s5pv310/hotplug.c
+++ b/arch/arm/mach-s5pv310/hotplug.c
@@ -13,14 +13,11 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/completion.h>
17 16
18#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
19 18
20extern volatile int pen_release; 19extern volatile int pen_release;
21 20
22static DECLARE_COMPLETION(cpu_killed);
23
24static inline void cpu_enter_lowpower(void) 21static inline void cpu_enter_lowpower(void)
25{ 22{
26 unsigned int v; 23 unsigned int v;
@@ -33,13 +30,13 @@ static inline void cpu_enter_lowpower(void)
33 * Turn off coherency 30 * Turn off coherency
34 */ 31 */
35 " mrc p15, 0, %0, c1, c0, 1\n" 32 " mrc p15, 0, %0, c1, c0, 1\n"
36 " bic %0, %0, #0x20\n" 33 " bic %0, %0, %2\n"
37 " mcr p15, 0, %0, c1, c0, 1\n" 34 " mcr p15, 0, %0, c1, c0, 1\n"
38 " mrc p15, 0, %0, c1, c0, 0\n" 35 " mrc p15, 0, %0, c1, c0, 0\n"
39 " bic %0, %0, #0x04\n" 36 " bic %0, %0, #0x04\n"
40 " mcr p15, 0, %0, c1, c0, 0\n" 37 " mcr p15, 0, %0, c1, c0, 0\n"
41 : "=&r" (v) 38 : "=&r" (v)
42 : "r" (0) 39 : "r" (0), "Ir" (CR_C)
43 : "cc"); 40 : "cc");
44} 41}
45 42
@@ -49,17 +46,17 @@ static inline void cpu_leave_lowpower(void)
49 46
50 asm volatile( 47 asm volatile(
51 "mrc p15, 0, %0, c1, c0, 0\n" 48 "mrc p15, 0, %0, c1, c0, 0\n"
52 " orr %0, %0, #0x04\n" 49 " orr %0, %0, %1\n"
53 " mcr p15, 0, %0, c1, c0, 0\n" 50 " mcr p15, 0, %0, c1, c0, 0\n"
54 " mrc p15, 0, %0, c1, c0, 1\n" 51 " mrc p15, 0, %0, c1, c0, 1\n"
55 " orr %0, %0, #0x20\n" 52 " orr %0, %0, #0x20\n"
56 " mcr p15, 0, %0, c1, c0, 1\n" 53 " mcr p15, 0, %0, c1, c0, 1\n"
57 : "=&r" (v) 54 : "=&r" (v)
58 : 55 : "Ir" (CR_C)
59 : "cc"); 56 : "cc");
60} 57}
61 58
62static inline void platform_do_lowpower(unsigned int cpu) 59static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
63{ 60{
64 /* 61 /*
65 * there is no power-control hardware on this platform, so all 62 * there is no power-control hardware on this platform, so all
@@ -83,22 +80,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
83 } 80 }
84 81
85 /* 82 /*
86 * getting here, means that we have come out of WFI without 83 * Getting here, means that we have come out of WFI without
87 * having been woken up - this shouldn't happen 84 * having been woken up - this shouldn't happen
88 * 85 *
89 * The trouble is, letting people know about this is not really 86 * Just note it happening - when we're woken, we can report
90 * possible, since we are currently running incoherently, and 87 * its occurrence.
91 * therefore cannot safely call printk() or anything else
92 */ 88 */
93#ifdef DEBUG 89 (*spurious)++;
94 printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
95#endif
96 } 90 }
97} 91}
98 92
99int platform_cpu_kill(unsigned int cpu) 93int platform_cpu_kill(unsigned int cpu)
100{ 94{
101 return wait_for_completion_timeout(&cpu_killed, 5000); 95 return 1;
102} 96}
103 97
104/* 98/*
@@ -108,30 +102,22 @@ int platform_cpu_kill(unsigned int cpu)
108 */ 102 */
109void platform_cpu_die(unsigned int cpu) 103void platform_cpu_die(unsigned int cpu)
110{ 104{
111#ifdef DEBUG 105 int spurious = 0;
112 unsigned int this_cpu = hard_smp_processor_id();
113
114 if (cpu != this_cpu) {
115 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
116 this_cpu, cpu);
117 BUG();
118 }
119#endif
120
121 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
122 complete(&cpu_killed);
123 106
124 /* 107 /*
125 * we're ready for shutdown now, so do it 108 * we're ready for shutdown now, so do it
126 */ 109 */
127 cpu_enter_lowpower(); 110 cpu_enter_lowpower();
128 platform_do_lowpower(cpu); 111 platform_do_lowpower(cpu, &spurious);
129 112
130 /* 113 /*
131 * bring this CPU back into the world of cache 114 * bring this CPU back into the world of cache
132 * coherency, and then restore interrupts 115 * coherency, and then restore interrupts
133 */ 116 */
134 cpu_leave_lowpower(); 117 cpu_leave_lowpower();
118
119 if (spurious)
120 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
135} 121}
136 122
137int platform_cpu_disable(unsigned int cpu) 123int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
index e1cc6a251c6a..393ccbd52c4a 100644
--- a/arch/arm/mach-s5pv310/include/mach/smp.h
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -7,14 +7,13 @@
7#define ASM_ARCH_SMP_H __FILE__ 7#define ASM_ARCH_SMP_H __FILE__
8 8
9#include <asm/hardware/gic.h> 9#include <asm/hardware/gic.h>
10#include <asm/smp_mpidr.h>
11 10
12/* 11/*
13 * We use IRQ1 as the IPI 12 * We use IRQ1 as the IPI
14 */ 13 */
15static inline void smp_cross_call(const struct cpumask *mask) 14static inline void smp_cross_call(const struct cpumask *mask, int ipi)
16{ 15{
17 gic_raise_softirq(mask, 1); 16 gic_raise_softirq(mask, ipi);
18} 17}
19 18
20#endif 19#endif
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c
index 15929c169f81..34093b069f67 100644
--- a/arch/arm/mach-s5pv310/platsmp.c
+++ b/arch/arm/mach-s5pv310/platsmp.c
@@ -22,7 +22,6 @@
22#include <linux/io.h> 22#include <linux/io.h>
23 23
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27#include <asm/unified.h> 26#include <asm/unified.h>
28 27
@@ -38,6 +37,19 @@ extern void s5pv310_secondary_startup(void);
38 37
39volatile int __cpuinitdata pen_release = -1; 38volatile int __cpuinitdata pen_release = -1;
40 39
40/*
41 * Write pen_release in a way that is guaranteed to be visible to all
42 * observers, irrespective of whether they're taking part in coherency
43 * or not. This is necessary for the hotplug code to work reliably.
44 */
45static void write_pen_release(int val)
46{
47 pen_release = val;
48 smp_wmb();
49 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
50 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
51}
52
41static void __iomem *scu_base_addr(void) 53static void __iomem *scu_base_addr(void)
42{ 54{
43 return (void __iomem *)(S5P_VA_SCU); 55 return (void __iomem *)(S5P_VA_SCU);
@@ -47,8 +59,6 @@ static DEFINE_SPINLOCK(boot_lock);
47 59
48void __cpuinit platform_secondary_init(unsigned int cpu) 60void __cpuinit platform_secondary_init(unsigned int cpu)
49{ 61{
50 trace_hardirqs_off();
51
52 /* 62 /*
53 * if any interrupts are already enabled for the primary 63 * if any interrupts are already enabled for the primary
54 * core (e.g. timer irq), then they will not have been enabled 64 * core (e.g. timer irq), then they will not have been enabled
@@ -60,8 +70,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
60 * let the primary processor know we're out of the 70 * let the primary processor know we're out of the
61 * pen, then head off into the C entry point 71 * pen, then head off into the C entry point
62 */ 72 */
63 pen_release = -1; 73 write_pen_release(-1);
64 smp_wmb();
65 74
66 /* 75 /*
67 * Synchronise with the boot thread. 76 * Synchronise with the boot thread.
@@ -88,16 +97,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
88 * Note that "pen_release" is the hardware CPU ID, whereas 97 * Note that "pen_release" is the hardware CPU ID, whereas
89 * "cpu" is Linux's internal ID. 98 * "cpu" is Linux's internal ID.
90 */ 99 */
91 pen_release = cpu; 100 write_pen_release(cpu);
92 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
93 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
94 101
95 /* 102 /*
96 * Send the secondary CPU a soft interrupt, thereby causing 103 * Send the secondary CPU a soft interrupt, thereby causing
97 * the boot monitor to read the system wide flags register, 104 * the boot monitor to read the system wide flags register,
98 * and branch to the address found there. 105 * and branch to the address found there.
99 */ 106 */
100 smp_cross_call(cpumask_of(cpu)); 107 smp_cross_call(cpumask_of(cpu), 1);
101 108
102 timeout = jiffies + (1 * HZ); 109 timeout = jiffies + (1 * HZ);
103 while (time_before(jiffies, timeout)) { 110 while (time_before(jiffies, timeout)) {
@@ -130,13 +137,6 @@ void __init smp_init_cpus(void)
130 ncores = scu_base ? scu_get_core_count(scu_base) : 1; 137 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
131 138
132 /* sanity check */ 139 /* sanity check */
133 if (ncores == 0) {
134 printk(KERN_ERR
135 "S5PV310: strange CM count of 0? Default to 1\n");
136
137 ncores = 1;
138 }
139
140 if (ncores > NR_CPUS) { 140 if (ncores > NR_CPUS) {
141 printk(KERN_WARNING 141 printk(KERN_WARNING
142 "S5PV310: no. of cores (%d) greater than configured " 142 "S5PV310: no. of cores (%d) greater than configured "
@@ -149,18 +149,10 @@ void __init smp_init_cpus(void)
149 set_cpu_possible(i, true); 149 set_cpu_possible(i, true);
150} 150}
151 151
152void __init smp_prepare_cpus(unsigned int max_cpus) 152void __init platform_smp_prepare_cpus(unsigned int max_cpus)
153{ 153{
154 unsigned int ncores = num_possible_cpus();
155 unsigned int cpu = smp_processor_id();
156 int i; 154 int i;
157 155
158 smp_store_cpu_info(cpu);
159
160 /* are we trying to boot more cores than exist? */
161 if (max_cpus > ncores)
162 max_cpus = ncores;
163
164 /* 156 /*
165 * Initialise the present map, which describes the set of CPUs 157 * Initialise the present map, which describes the set of CPUs
166 * actually populated at the present time. 158 * actually populated at the present time.
@@ -168,25 +160,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
168 for (i = 0; i < max_cpus; i++) 160 for (i = 0; i < max_cpus; i++)
169 set_cpu_present(i, true); 161 set_cpu_present(i, true);
170 162
163 scu_enable(scu_base_addr());
164
171 /* 165 /*
172 * Initialise the SCU if there are more than one CPU and let 166 * Write the address of secondary startup into the
173 * them know where to start. 167 * system-wide flags register. The boot monitor waits
168 * until it receives a soft interrupt, and then the
169 * secondary CPU branches to this address.
174 */ 170 */
175 if (max_cpus > 1) {
176 /*
177 * Enable the local timer or broadcast device for the
178 * boot CPU, but only if we have more than one CPU.
179 */
180 percpu_timer_setup();
181
182 scu_enable(scu_base_addr());
183
184 /*
185 * Write the address of secondary startup into the
186 * system-wide flags register. The boot monitor waits
187 * until it receives a soft interrupt, and then the
188 * secondary CPU branches to this address.
189 */
190 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); 171 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
191 }
192} 172}
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 51dcd59eda6a..632933357242 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -6,7 +6,7 @@ config ARCH_SH7367
6 bool "SH-Mobile G3 (SH7367)" 6 bool "SH-Mobile G3 (SH7367)"
7 select CPU_V6 7 select CPU_V6
8 select HAVE_CLK 8 select HAVE_CLK
9 select COMMON_CLKDEV 9 select CLKDEV_LOOKUP
10 select SH_CLK_CPG 10 select SH_CLK_CPG
11 select GENERIC_CLOCKEVENTS 11 select GENERIC_CLOCKEVENTS
12 12
@@ -14,7 +14,7 @@ config ARCH_SH7377
14 bool "SH-Mobile G4 (SH7377)" 14 bool "SH-Mobile G4 (SH7377)"
15 select CPU_V7 15 select CPU_V7
16 select HAVE_CLK 16 select HAVE_CLK
17 select COMMON_CLKDEV 17 select CLKDEV_LOOKUP
18 select SH_CLK_CPG 18 select SH_CLK_CPG
19 select GENERIC_CLOCKEVENTS 19 select GENERIC_CLOCKEVENTS
20 20
@@ -22,7 +22,7 @@ config ARCH_SH7372
22 bool "SH-Mobile AP4 (SH7372)" 22 bool "SH-Mobile AP4 (SH7372)"
23 select CPU_V7 23 select CPU_V7
24 select HAVE_CLK 24 select HAVE_CLK
25 select COMMON_CLKDEV 25 select CLKDEV_LOOKUP
26 select SH_CLK_CPG 26 select SH_CLK_CPG
27 select GENERIC_CLOCKEVENTS 27 select GENERIC_CLOCKEVENTS
28 28
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index 9f78729098f2..6b186aefcbd6 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -20,8 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/sh_clk.h> 22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
23#include <mach/common.h> 24#include <mach/common.h>
24#include <asm/clkdev.h>
25 25
26/* SH7367 registers */ 26/* SH7367 registers */
27#define RTFRQCR 0xe6150000 27#define RTFRQCR 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 3aa026069435..d98deb497c2f 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -20,8 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/sh_clk.h> 22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
23#include <mach/common.h> 24#include <mach/common.h>
24#include <asm/clkdev.h>
25 25
26/* SH7372 registers */ 26/* SH7372 registers */
27#define FRQCRA 0xe6150000 27#define FRQCRA 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index f91395aeb9ab..95942466e63f 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -20,8 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/sh_clk.h> 22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
23#include <mach/common.h> 24#include <mach/common.h>
24#include <asm/clkdev.h>
25 25
26/* SH7377 registers */ 26/* SH7377 registers */
27#define RTFRQCR 0xe6150000 27#define RTFRQCR 0xe6150000
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
index ba32a15127ab..3970a9cdce26 100644
--- a/arch/arm/mach-tcc8k/clock.c
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -12,8 +12,7 @@
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15 15#include <linux/clkdev.h>
16#include <asm/clkdev.h>
17 16
18#include <mach/clock.h> 17#include <mach/clock.h>
19#include <mach/irqs.h> 18#include <mach/irqs.h>
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index ae19f95585be..77948e0f4909 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -25,7 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/seq_file.h> 26#include <linux/seq_file.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <asm/clkdev.h> 28#include <linux/clkdev.h>
29 29
30#include "clock.h" 30#include "clock.h"
31#include "board.h" 31#include "board.h"
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 94fd859770f1..083a4cfc6cf0 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -21,7 +21,7 @@
21#define __MACH_TEGRA_CLOCK_H 21#define __MACH_TEGRA_CLOCK_H
22 22
23#include <linux/list.h> 23#include <linux/list.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25 25
26#define DIV_BUS (1 << 0) 26#define DIV_BUS (1 << 0)
27#define DIV_U71 (1 << 1) 27#define DIV_U71 (1 << 1)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 8e7f115aa21e..a5cb1ce76ff2 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -11,12 +11,9 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/completion.h>
15 14
16#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
17 16
18static DECLARE_COMPLETION(cpu_killed);
19
20static inline void cpu_enter_lowpower(void) 17static inline void cpu_enter_lowpower(void)
21{ 18{
22 unsigned int v; 19 unsigned int v;
@@ -29,13 +26,13 @@ static inline void cpu_enter_lowpower(void)
29 * Turn off coherency 26 * Turn off coherency
30 */ 27 */
31 " mrc p15, 0, %0, c1, c0, 1\n" 28 " mrc p15, 0, %0, c1, c0, 1\n"
32 " bic %0, %0, #0x20\n" 29 " bic %0, %0, %2\n"
33 " mcr p15, 0, %0, c1, c0, 1\n" 30 " mcr p15, 0, %0, c1, c0, 1\n"
34 " mrc p15, 0, %0, c1, c0, 0\n" 31 " mrc p15, 0, %0, c1, c0, 0\n"
35 " bic %0, %0, #0x04\n" 32 " bic %0, %0, #0x04\n"
36 " mcr p15, 0, %0, c1, c0, 0\n" 33 " mcr p15, 0, %0, c1, c0, 0\n"
37 : "=&r" (v) 34 : "=&r" (v)
38 : "r" (0) 35 : "r" (0), "Ir" (CR_C)
39 : "cc"); 36 : "cc");
40} 37}
41 38
@@ -45,17 +42,17 @@ static inline void cpu_leave_lowpower(void)
45 42
46 asm volatile( 43 asm volatile(
47 "mrc p15, 0, %0, c1, c0, 0\n" 44 "mrc p15, 0, %0, c1, c0, 0\n"
48 " orr %0, %0, #0x04\n" 45 " orr %0, %0, %1\n"
49 " mcr p15, 0, %0, c1, c0, 0\n" 46 " mcr p15, 0, %0, c1, c0, 0\n"
50 " mrc p15, 0, %0, c1, c0, 1\n" 47 " mrc p15, 0, %0, c1, c0, 1\n"
51 " orr %0, %0, #0x20\n" 48 " orr %0, %0, #0x20\n"
52 " mcr p15, 0, %0, c1, c0, 1\n" 49 " mcr p15, 0, %0, c1, c0, 1\n"
53 : "=&r" (v) 50 : "=&r" (v)
54 : 51 : "Ir" (CR_C)
55 : "cc"); 52 : "cc");
56} 53}
57 54
58static inline void platform_do_lowpower(unsigned int cpu) 55static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
59{ 56{
60 /* 57 /*
61 * there is no power-control hardware on this platform, so all 58 * there is no power-control hardware on this platform, so all
@@ -79,22 +76,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
79 /*}*/ 76 /*}*/
80 77
81 /* 78 /*
82 * getting here, means that we have come out of WFI without 79 * Getting here, means that we have come out of WFI without
83 * having been woken up - this shouldn't happen 80 * having been woken up - this shouldn't happen
84 * 81 *
85 * The trouble is, letting people know about this is not really 82 * Just note it happening - when we're woken, we can report
86 * possible, since we are currently running incoherently, and 83 * its occurrence.
87 * therefore cannot safely call printk() or anything else
88 */ 84 */
89#ifdef DEBUG 85 (*spurious)++;
90 printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
91#endif
92 } 86 }
93} 87}
94 88
95int platform_cpu_kill(unsigned int cpu) 89int platform_cpu_kill(unsigned int cpu)
96{ 90{
97 return wait_for_completion_timeout(&cpu_killed, 5000); 91 return 1;
98} 92}
99 93
100/* 94/*
@@ -104,30 +98,22 @@ int platform_cpu_kill(unsigned int cpu)
104 */ 98 */
105void platform_cpu_die(unsigned int cpu) 99void platform_cpu_die(unsigned int cpu)
106{ 100{
107#ifdef DEBUG 101 int spurious = 0;
108 unsigned int this_cpu = hard_smp_processor_id();
109
110 if (cpu != this_cpu) {
111 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
112 this_cpu, cpu);
113 BUG();
114 }
115#endif
116
117 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
118 complete(&cpu_killed);
119 102
120 /* 103 /*
121 * we're ready for shutdown now, so do it 104 * we're ready for shutdown now, so do it
122 */ 105 */
123 cpu_enter_lowpower(); 106 cpu_enter_lowpower();
124 platform_do_lowpower(cpu); 107 platform_do_lowpower(cpu, &spurious);
125 108
126 /* 109 /*
127 * bring this CPU back into the world of cache 110 * bring this CPU back into the world of cache
128 * coherency, and then restore interrupts 111 * coherency, and then restore interrupts
129 */ 112 */
130 cpu_leave_lowpower(); 113 cpu_leave_lowpower();
114
115 if (spurious)
116 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
131} 117}
132 118
133int platform_cpu_disable(unsigned int cpu) 119int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
index e4a34a35a544..c8221b38ee7c 100644
--- a/arch/arm/mach-tegra/include/mach/smp.h
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -2,21 +2,13 @@
2#define ASMARM_ARCH_SMP_H 2#define ASMARM_ARCH_SMP_H
3 3
4#include <asm/hardware/gic.h> 4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6 5
7/* 6/*
8 * We use IRQ1 as the IPI 7 * We use IRQ1 as the IPI
9 */ 8 */
10static inline void smp_cross_call(const struct cpumask *mask) 9static inline void smp_cross_call(const struct cpumask *mask, int ipi)
11{
12 gic_raise_softirq(mask, 1);
13}
14
15/*
16 * Do nothing on MPcore.
17 */
18static inline void smp_cross_call_done(cpumask_t callmap)
19{ 10{
11 gic_raise_softirq(mask, ipi);
20} 12}
21 13
22#endif 14#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 3b7376c4f356..ec1f68924edf 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -22,7 +22,6 @@
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27 26
28#include <mach/iomap.h> 27#include <mach/iomap.h>
@@ -41,8 +40,6 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
41 40
42void __cpuinit platform_secondary_init(unsigned int cpu) 41void __cpuinit platform_secondary_init(unsigned int cpu)
43{ 42{
44 trace_hardirqs_off();
45
46 /* 43 /*
47 * if any interrupts are already enabled for the primary 44 * if any interrupts are already enabled for the primary
48 * core (e.g. timer irq), then they will not have been enabled 45 * core (e.g. timer irq), then they will not have been enabled
@@ -117,24 +114,20 @@ void __init smp_init_cpus(void)
117{ 114{
118 unsigned int i, ncores = scu_get_core_count(scu_base); 115 unsigned int i, ncores = scu_get_core_count(scu_base);
119 116
117 if (ncores > NR_CPUS) {
118 printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
119 ncores, NR_CPUS);
120 ncores = NR_CPUS;
121 }
122
120 for (i = 0; i < ncores; i++) 123 for (i = 0; i < ncores; i++)
121 cpu_set(i, cpu_possible_map); 124 cpu_set(i, cpu_possible_map);
122} 125}
123 126
124void __init smp_prepare_cpus(unsigned int max_cpus) 127void __init platform_smp_prepare_cpus(unsigned int max_cpus)
125{ 128{
126 unsigned int ncores = scu_get_core_count(scu_base);
127 unsigned int cpu = smp_processor_id();
128 int i; 129 int i;
129 130
130 smp_store_cpu_info(cpu);
131
132 /*
133 * are we trying to boot more cores than exist?
134 */
135 if (max_cpus > ncores)
136 max_cpus = ncores;
137
138 /* 131 /*
139 * Initialise the present map, which describes the set of CPUs 132 * Initialise the present map, which describes the set of CPUs
140 * actually populated at the present time. 133 * actually populated at the present time.
@@ -142,15 +135,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
142 for (i = 0; i < max_cpus; i++) 135 for (i = 0; i < max_cpus; i++)
143 set_cpu_present(i, true); 136 set_cpu_present(i, true);
144 137
145 /* 138 scu_enable(scu_base);
146 * Initialise the SCU if there are more than one CPU and let
147 * them know where to start. Note that, on modern versions of
148 * MILO, the "poke" doesn't actually do anything until each
149 * individual core is sent a soft interrupt to get it out of
150 * WFI
151 */
152 if (max_cpus > 1) {
153 percpu_timer_setup();
154 scu_enable(scu_base);
155 }
156} 139}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ae3b308e22a4..f0dae6d8ba52 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -24,8 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/hrtimer.h> 26#include <linux/hrtimer.h>
27 27#include <linux/clkdev.h>
28#include <asm/clkdev.h>
29 28
30#include <mach/iomap.h> 29#include <mach/iomap.h>
31 30
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 7458fc6df5c6..fabcc49abe80 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -25,8 +25,8 @@
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/seq_file.h> 27#include <linux/seq_file.h>
28#include <linux/clkdev.h>
28 29
29#include <asm/clkdev.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/syscon.h> 31#include <mach/syscon.h>
32 32
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 1675047daf20..531de5c63641 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -13,8 +13,7 @@
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/io.h> 15#include <linux/io.h>
16 16#include <linux/clkdev.h>
17#include <asm/clkdev.h>
18 17
19#include <plat/mtu.h> 18#include <plat/mtu.h>
20#include <mach/hardware.h> 19#include <mach/hardware.h>
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
index a6be2cdf2b2f..64fa451edcfd 100644
--- a/arch/arm/mach-ux500/headsmp.S
+++ b/arch/arm/mach-ux500/headsmp.S
@@ -23,7 +23,6 @@ ENTRY(u8500_secondary_startup)
23 ldmia r4, {r5, r6} 23 ldmia r4, {r5, r6}
24 sub r4, r4, r5 24 sub r4, r4, r5
25 add r6, r6, r4 25 add r6, r6, r4
26 dsb
27pen: ldr r7, [r6] 26pen: ldr r7, [r6]
28 cmp r7, r0 27 cmp r7, r0
29 bne pen 28 bne pen
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index b782a03024be..dd8037ebccf8 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -11,14 +11,11 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/completion.h>
15 14
16#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
17 16
18extern volatile int pen_release; 17extern volatile int pen_release;
19 18
20static DECLARE_COMPLETION(cpu_killed);
21
22static inline void platform_do_lowpower(unsigned int cpu) 19static inline void platform_do_lowpower(unsigned int cpu)
23{ 20{
24 flush_cache_all(); 21 flush_cache_all();
@@ -38,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
38 35
39int platform_cpu_kill(unsigned int cpu) 36int platform_cpu_kill(unsigned int cpu)
40{ 37{
41 return wait_for_completion_timeout(&cpu_killed, 5000); 38 return 1;
42} 39}
43 40
44/* 41/*
@@ -48,19 +45,6 @@ int platform_cpu_kill(unsigned int cpu)
48 */ 45 */
49void platform_cpu_die(unsigned int cpu) 46void platform_cpu_die(unsigned int cpu)
50{ 47{
51#ifdef DEBUG
52 unsigned int this_cpu = hard_smp_processor_id();
53
54 if (cpu != this_cpu) {
55 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
56 this_cpu, cpu);
57 BUG();
58 }
59#endif
60
61 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
62 complete(&cpu_killed);
63
64 /* directly enter low power state, skipping secure registers */ 48 /* directly enter low power state, skipping secure registers */
65 platform_do_lowpower(cpu); 49 platform_do_lowpower(cpu);
66} 50}
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
index 197e8417375e..ca2b15b1b3b1 100644
--- a/arch/arm/mach-ux500/include/mach/smp.h
+++ b/arch/arm/mach-ux500/include/mach/smp.h
@@ -10,7 +10,6 @@
10#define ASMARM_ARCH_SMP_H 10#define ASMARM_ARCH_SMP_H
11 11
12#include <asm/hardware/gic.h> 12#include <asm/hardware/gic.h>
13#include <asm/smp_mpidr.h>
14 13
15/* This is required to wakeup the secondary core */ 14/* This is required to wakeup the secondary core */
16extern void u8500_secondary_startup(void); 15extern void u8500_secondary_startup(void);
@@ -18,8 +17,8 @@ extern void u8500_secondary_startup(void);
18/* 17/*
19 * We use IRQ1 as the IPI 18 * We use IRQ1 as the IPI
20 */ 19 */
21static inline void smp_cross_call(const struct cpumask *mask) 20static inline void smp_cross_call(const struct cpumask *mask, int ipi)
22{ 21{
23 gic_raise_softirq(mask, 1); 22 gic_raise_softirq(mask, ipi);
24} 23}
25#endif 24#endif
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index b5077b4c419f..2115a0cf07b0 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -18,7 +18,6 @@
18#include <linux/io.h> 18#include <linux/io.h>
19 19
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/localtimer.h>
22#include <asm/smp_scu.h> 21#include <asm/smp_scu.h>
23#include <mach/hardware.h> 22#include <mach/hardware.h>
24 23
@@ -28,17 +27,23 @@
28 */ 27 */
29volatile int __cpuinitdata pen_release = -1; 28volatile int __cpuinitdata pen_release = -1;
30 29
31static unsigned int __init get_core_count(void) 30/*
31 * Write pen_release in a way that is guaranteed to be visible to all
32 * observers, irrespective of whether they're taking part in coherency
33 * or not. This is necessary for the hotplug code to work reliably.
34 */
35static void write_pen_release(int val)
32{ 36{
33 return scu_get_core_count(__io_address(UX500_SCU_BASE)); 37 pen_release = val;
38 smp_wmb();
39 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
40 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
34} 41}
35 42
36static DEFINE_SPINLOCK(boot_lock); 43static DEFINE_SPINLOCK(boot_lock);
37 44
38void __cpuinit platform_secondary_init(unsigned int cpu) 45void __cpuinit platform_secondary_init(unsigned int cpu)
39{ 46{
40 trace_hardirqs_off();
41
42 /* 47 /*
43 * if any interrupts are already enabled for the primary 48 * if any interrupts are already enabled for the primary
44 * core (e.g. timer irq), then they will not have been enabled 49 * core (e.g. timer irq), then they will not have been enabled
@@ -50,7 +55,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
50 * let the primary processor know we're out of the 55 * let the primary processor know we're out of the
51 * pen, then head off into the C entry point 56 * pen, then head off into the C entry point
52 */ 57 */
53 pen_release = -1; 58 write_pen_release(-1);
54 59
55 /* 60 /*
56 * Synchronise with the boot thread. 61 * Synchronise with the boot thread.
@@ -74,11 +79,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
74 * the holding pen - release it, then wait for it to flag 79 * the holding pen - release it, then wait for it to flag
75 * that it has been released by resetting pen_release. 80 * that it has been released by resetting pen_release.
76 */ 81 */
77 pen_release = cpu; 82 write_pen_release(cpu);
78 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
79 outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
80 83
81 smp_cross_call(cpumask_of(cpu)); 84 smp_cross_call(cpumask_of(cpu), 1);
82 85
83 timeout = jiffies + (1 * HZ); 86 timeout = jiffies + (1 * HZ);
84 while (time_before(jiffies, timeout)) { 87 while (time_before(jiffies, timeout)) {
@@ -97,9 +100,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
97 100
98static void __init wakeup_secondary(void) 101static void __init wakeup_secondary(void)
99{ 102{
100 /* nobody is to be released from the pen yet */
101 pen_release = -1;
102
103 /* 103 /*
104 * write the address of secondary startup into the backup ram register 104 * write the address of secondary startup into the backup ram register
105 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the 105 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
@@ -126,40 +126,26 @@ static void __init wakeup_secondary(void)
126 */ 126 */
127void __init smp_init_cpus(void) 127void __init smp_init_cpus(void)
128{ 128{
129 unsigned int i, ncores = get_core_count(); 129 unsigned int i, ncores;
130 130
131 for (i = 0; i < ncores; i++) 131 ncores = scu_get_core_count(__io_address(UX500_SCU_BASE));
132 set_cpu_possible(i, true);
133}
134
135void __init smp_prepare_cpus(unsigned int max_cpus)
136{
137 unsigned int ncores = get_core_count();
138 unsigned int cpu = smp_processor_id();
139 int i;
140 132
141 /* sanity check */ 133 /* sanity check */
142 if (ncores == 0) { 134 if (ncores > NR_CPUS) {
143 printk(KERN_ERR
144 "U8500: strange CM count of 0? Default to 1\n");
145 ncores = 1;
146 }
147
148 if (ncores > num_possible_cpus()) {
149 printk(KERN_WARNING 135 printk(KERN_WARNING
150 "U8500: no. of cores (%d) greater than configured " 136 "U8500: no. of cores (%d) greater than configured "
151 "maximum of %d - clipping\n", 137 "maximum of %d - clipping\n",
152 ncores, num_possible_cpus()); 138 ncores, NR_CPUS);
153 ncores = num_possible_cpus(); 139 ncores = NR_CPUS;
154 } 140 }
155 141
156 smp_store_cpu_info(cpu); 142 for (i = 0; i < ncores; i++)
143 set_cpu_possible(i, true);
144}
157 145
158 /* 146void __init platform_smp_prepare_cpus(unsigned int max_cpus)
159 * are we trying to boot more cores than exist? 147{
160 */ 148 int i;
161 if (max_cpus > ncores)
162 max_cpus = ncores;
163 149
164 /* 150 /*
165 * Initialise the present map, which describes the set of CPUs 151 * Initialise the present map, which describes the set of CPUs
@@ -168,13 +154,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
168 for (i = 0; i < max_cpus; i++) 154 for (i = 0; i < max_cpus; i++)
169 set_cpu_present(i, true); 155 set_cpu_present(i, true);
170 156
171 if (max_cpus > 1) { 157 scu_enable(__io_address(UX500_SCU_BASE));
172 /* 158 wakeup_secondary();
173 * Enable the local timer or broadcast device for the
174 * boot CPU, but only if we have more than one CPU.
175 */
176 percpu_timer_setup();
177 scu_enable(__io_address(UX500_SCU_BASE));
178 wakeup_secondary();
179 }
180} 159}
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index c781f30c8368..3f7b5e9d83c5 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -4,6 +4,7 @@ menu "Versatile platform type"
4config ARCH_VERSATILE_PB 4config ARCH_VERSATILE_PB
5 bool "Support Versatile/PB platform" 5 bool "Support Versatile/PB platform"
6 select CPU_ARM926T 6 select CPU_ARM926T
7 select MIGHT_HAVE_PCI
7 default y 8 default y
8 help 9 help
9 Include support for the ARM(R) Versatile/PB platform. 10 Include support for the ARM(R) Versatile/PB platform.
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 40a024c71e4b..13a83e45a33b 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -31,8 +31,8 @@
31#include <linux/amba/pl022.h> 31#include <linux/amba/pl022.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/gfp.h> 33#include <linux/gfp.h>
34#include <linux/clkdev.h>
34 35
35#include <asm/clkdev.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/leds.h> 38#include <asm/leds.h>
@@ -46,7 +46,6 @@
46#include <asm/mach/irq.h> 46#include <asm/mach/irq.h>
47#include <asm/mach/time.h> 47#include <asm/mach/time.h>
48#include <asm/mach/map.h> 48#include <asm/mach/map.h>
49#include <mach/clkdev.h>
50#include <mach/hardware.h> 49#include <mach/hardware.h>
51#include <mach/platform.h> 50#include <mach/platform.h>
52#include <asm/hardware/timer-sp.h> 51#include <asm/hardware/timer-sp.h>
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 1b71b77ade22..2c0ac7de2814 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -5,4 +5,5 @@
5obj-y := v2m.o 5obj-y := v2m.o
6obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o 6obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o 7obj-$(CONFIG_SMP) += platsmp.o headsmp.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
8obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 9obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index cb5793ef3ee0..e628402b754c 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -8,8 +8,8 @@
8#include <linux/platform_device.h> 8#include <linux/platform_device.h>
9#include <linux/amba/bus.h> 9#include <linux/amba/bus.h>
10#include <linux/amba/clcd.h> 10#include <linux/amba/clcd.h>
11#include <linux/clkdev.h>
11 12
12#include <asm/clkdev.h>
13#include <asm/pgtable.h> 13#include <asm/pgtable.h>
14#include <asm/hardware/arm_timer.h> 14#include <asm/hardware/arm_timer.h>
15#include <asm/hardware/cache-l2x0.h> 15#include <asm/hardware/cache-l2x0.h>
@@ -18,7 +18,6 @@
18#include <asm/pmu.h> 18#include <asm/pmu.h>
19#include <asm/smp_twd.h> 19#include <asm/smp_twd.h>
20 20
21#include <mach/clkdev.h>
22#include <mach/ct-ca9x4.h> 21#include <mach/ct-ca9x4.h>
23 22
24#include <asm/hardware/timer-sp.h> 23#include <asm/hardware/timer-sp.h>
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
new file mode 100644
index 000000000000..ea4cbfb90a66
--- /dev/null
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -0,0 +1,128 @@
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/cacheflush.h>
16
17extern volatile int pen_release;
18
19static inline void cpu_enter_lowpower(void)
20{
21 unsigned int v;
22
23 flush_cache_all();
24 asm volatile(
25 "mcr p15, 0, %1, c7, c5, 0\n"
26 " mcr p15, 0, %1, c7, c10, 4\n"
27 /*
28 * Turn off coherency
29 */
30 " mrc p15, 0, %0, c1, c0, 1\n"
31 " bic %0, %0, %3\n"
32 " mcr p15, 0, %0, c1, c0, 1\n"
33 " mrc p15, 0, %0, c1, c0, 0\n"
34 " bic %0, %0, %2\n"
35 " mcr p15, 0, %0, c1, c0, 0\n"
36 : "=&r" (v)
37 : "r" (0), "Ir" (CR_C), "Ir" (0x40)
38 : "cc");
39}
40
41static inline void cpu_leave_lowpower(void)
42{
43 unsigned int v;
44
45 asm volatile(
46 "mrc p15, 0, %0, c1, c0, 0\n"
47 " orr %0, %0, %1\n"
48 " mcr p15, 0, %0, c1, c0, 0\n"
49 " mrc p15, 0, %0, c1, c0, 1\n"
50 " orr %0, %0, %2\n"
51 " mcr p15, 0, %0, c1, c0, 1\n"
52 : "=&r" (v)
53 : "Ir" (CR_C), "Ir" (0x40)
54 : "cc");
55}
56
57static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
58{
59 /*
60 * 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
62 * code will have already disabled interrupts
63 */
64 for (;;) {
65 /*
66 * here's the WFI
67 */
68 asm(".word 0xe320f003\n"
69 :
70 :
71 : "memory", "cc");
72
73 if (pen_release == cpu) {
74 /*
75 * OK, proper wakeup, we're done
76 */
77 break;
78 }
79
80 /*
81 * Getting here, means that we have come out of WFI without
82 * having been woken up - this shouldn't happen
83 *
84 * Just note it happening - when we're woken, we can report
85 * its occurrence.
86 */
87 (*spurious)++;
88 }
89}
90
91int platform_cpu_kill(unsigned int cpu)
92{
93 return 1;
94}
95
96/*
97 * platform-specific code to shutdown a CPU
98 *
99 * Called with IRQs disabled
100 */
101void platform_cpu_die(unsigned int cpu)
102{
103 int spurious = 0;
104
105 /*
106 * we're ready for shutdown now, so do it
107 */
108 cpu_enter_lowpower();
109 platform_do_lowpower(cpu, &spurious);
110
111 /*
112 * bring this CPU back into the world of cache
113 * coherency, and then restore interrupts
114 */
115 cpu_leave_lowpower();
116
117 if (spurious)
118 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
119}
120
121int platform_cpu_disable(unsigned int cpu)
122{
123 /*
124 * we don't allow CPU 0 to be shutdown (it is still too special
125 * e.g. clock tick interrupts)
126 */
127 return cpu == 0 ? -EPERM : 0;
128}
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
index 5a6da4fd247e..4c05e4a9713a 100644
--- a/arch/arm/mach-vexpress/include/mach/smp.h
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -2,13 +2,12 @@
2#define __MACH_SMP_H 2#define __MACH_SMP_H
3 3
4#include <asm/hardware/gic.h> 4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6 5
7/* 6/*
8 * We use IRQ1 as the IPI 7 * We use IRQ1 as the IPI
9 */ 8 */
10static inline void smp_cross_call(const struct cpumask *mask) 9static inline void smp_cross_call(const struct cpumask *mask, int ipi)
11{ 10{
12 gic_raise_softirq(mask, 1); 11 gic_raise_softirq(mask, ipi);
13} 12}
14#endif 13#endif
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index dfb591031d17..b1687b6abe63 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -17,7 +17,6 @@
17#include <linux/io.h> 17#include <linux/io.h>
18 18
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <asm/localtimer.h>
21#include <asm/smp_scu.h> 20#include <asm/smp_scu.h>
22#include <asm/unified.h> 21#include <asm/unified.h>
23 22
@@ -35,6 +34,19 @@ extern void vexpress_secondary_startup(void);
35 */ 34 */
36volatile int __cpuinitdata pen_release = -1; 35volatile int __cpuinitdata pen_release = -1;
37 36
37/*
38 * Write pen_release in a way that is guaranteed to be visible to all
39 * observers, irrespective of whether they're taking part in coherency
40 * or not. This is necessary for the hotplug code to work reliably.
41 */
42static void write_pen_release(int val)
43{
44 pen_release = val;
45 smp_wmb();
46 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
47 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
48}
49
38static void __iomem *scu_base_addr(void) 50static void __iomem *scu_base_addr(void)
39{ 51{
40 return MMIO_P2V(A9_MPCORE_SCU); 52 return MMIO_P2V(A9_MPCORE_SCU);
@@ -44,8 +56,6 @@ static DEFINE_SPINLOCK(boot_lock);
44 56
45void __cpuinit platform_secondary_init(unsigned int cpu) 57void __cpuinit platform_secondary_init(unsigned int cpu)
46{ 58{
47 trace_hardirqs_off();
48
49 /* 59 /*
50 * if any interrupts are already enabled for the primary 60 * if any interrupts are already enabled for the primary
51 * core (e.g. timer irq), then they will not have been enabled 61 * core (e.g. timer irq), then they will not have been enabled
@@ -57,8 +67,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
57 * let the primary processor know we're out of the 67 * let the primary processor know we're out of the
58 * pen, then head off into the C entry point 68 * pen, then head off into the C entry point
59 */ 69 */
60 pen_release = -1; 70 write_pen_release(-1);
61 smp_wmb();
62 71
63 /* 72 /*
64 * Synchronise with the boot thread. 73 * Synchronise with the boot thread.
@@ -83,16 +92,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
83 * since we haven't sent them a soft interrupt, they shouldn't 92 * since we haven't sent them a soft interrupt, they shouldn't
84 * be there. 93 * be there.
85 */ 94 */
86 pen_release = cpu; 95 write_pen_release(cpu);
87 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
88 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
89 96
90 /* 97 /*
91 * Send the secondary CPU a soft interrupt, thereby causing 98 * Send the secondary CPU a soft interrupt, thereby causing
92 * the boot monitor to read the system wide flags register, 99 * the boot monitor to read the system wide flags register,
93 * and branch to the address found there. 100 * and branch to the address found there.
94 */ 101 */
95 smp_cross_call(cpumask_of(cpu)); 102 smp_cross_call(cpumask_of(cpu), 1);
96 103
97 timeout = jiffies + (1 * HZ); 104 timeout = jiffies + (1 * HZ);
98 while (time_before(jiffies, timeout)) { 105 while (time_before(jiffies, timeout)) {
@@ -124,13 +131,6 @@ void __init smp_init_cpus(void)
124 ncores = scu_base ? scu_get_core_count(scu_base) : 1; 131 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
125 132
126 /* sanity check */ 133 /* sanity check */
127 if (ncores == 0) {
128 printk(KERN_ERR
129 "vexpress: strange CM count of 0? Default to 1\n");
130
131 ncores = 1;
132 }
133
134 if (ncores > NR_CPUS) { 134 if (ncores > NR_CPUS) {
135 printk(KERN_WARNING 135 printk(KERN_WARNING
136 "vexpress: no. of cores (%d) greater than configured " 136 "vexpress: no. of cores (%d) greater than configured "
@@ -143,20 +143,10 @@ void __init smp_init_cpus(void)
143 set_cpu_possible(i, true); 143 set_cpu_possible(i, true);
144} 144}
145 145
146void __init smp_prepare_cpus(unsigned int max_cpus) 146void __init platform_smp_prepare_cpus(unsigned int max_cpus)
147{ 147{
148 unsigned int ncores = num_possible_cpus();
149 unsigned int cpu = smp_processor_id();
150 int i; 148 int i;
151 149
152 smp_store_cpu_info(cpu);
153
154 /*
155 * are we trying to boot more cores than exist?
156 */
157 if (max_cpus > ncores)
158 max_cpus = ncores;
159
160 /* 150 /*
161 * Initialise the present map, which describes the set of CPUs 151 * Initialise the present map, which describes the set of CPUs
162 * actually populated at the present time. 152 * actually populated at the present time.
@@ -164,27 +154,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
164 for (i = 0; i < max_cpus; i++) 154 for (i = 0; i < max_cpus; i++)
165 set_cpu_present(i, true); 155 set_cpu_present(i, true);
166 156
157 scu_enable(scu_base_addr());
158
167 /* 159 /*
168 * Initialise the SCU if there are more than one CPU and let 160 * Write the address of secondary startup into the
169 * them know where to start. 161 * system-wide flags register. The boot monitor waits
162 * until it receives a soft interrupt, and then the
163 * secondary CPU branches to this address.
170 */ 164 */
171 if (max_cpus > 1) { 165 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
172 /* 166 writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
173 * Enable the local timer or broadcast device for the 167 MMIO_P2V(V2M_SYS_FLAGSSET));
174 * boot CPU, but only if we have more than one CPU.
175 */
176 percpu_timer_setup();
177
178 scu_enable(scu_base_addr());
179
180 /*
181 * Write the address of secondary startup into the
182 * system-wide flags register. The boot monitor waits
183 * until it receives a soft interrupt, and then the
184 * secondary CPU branches to this address.
185 */
186 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
187 writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
188 MMIO_P2V(V2M_SYS_FLAGSSET));
189 }
190} 168}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index de13603dc028..a9ed3428a2fa 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -11,8 +11,8 @@
11#include <linux/spinlock.h> 11#include <linux/spinlock.h>
12#include <linux/sysdev.h> 12#include <linux/sysdev.h>
13#include <linux/usb/isp1760.h> 13#include <linux/usb/isp1760.h>
14#include <linux/clkdev.h>
14 15
15#include <asm/clkdev.h>
16#include <asm/sizes.h> 16#include <asm/sizes.h>
17#include <asm/mach/flash.h> 17#include <asm/mach/flash.h>
18#include <asm/mach/map.h> 18#include <asm/mach/map.h>
@@ -20,7 +20,6 @@
20#include <asm/hardware/arm_timer.h> 20#include <asm/hardware/arm_timer.h>
21#include <asm/hardware/timer-sp.h> 21#include <asm/hardware/timer-sp.h>
22 22
23#include <mach/clkdev.h>
24#include <mach/motherboard.h> 23#include <mach/motherboard.h>
25 24
26#include <plat/sched_clock.h> 25#include <plat/sched_clock.h>
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
index c56ddab3d912..b88a1b16b2e9 100644
--- a/arch/arm/mach-w90x900/clock.h
+++ b/arch/arm/mach-w90x900/clock.h
@@ -10,7 +10,7 @@
10 * the Free Software Foundation; either version 2 of the License. 10 * the Free Software Foundation; either version 2 of the License.
11 */ 11 */
12 12
13#include <asm/clkdev.h> 13#include <linux/clkdev.h>
14 14
15void nuc900_clk_enable(struct clk *clk, int enable); 15void nuc900_clk_enable(struct clk *clk, int enable);
16void nuc900_subclk_enable(struct clk *clk, int enable); 16void nuc900_subclk_enable(struct clk *clk, int enable);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 4414a01e1e8a..8493ed04797a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -599,6 +599,14 @@ config CPU_CP15_MPU
599 help 599 help
600 Processor has the CP15 register, which has MPU related registers. 600 Processor has the CP15 register, which has MPU related registers.
601 601
602config CPU_USE_DOMAINS
603 bool
604 depends on MMU
605 default y if !CPU_32v6K
606 help
607 This option enables or disables the use of domain switching
608 via the set_fs() function.
609
602# 610#
603# CPU supports 36-bit I/O 611# CPU supports 36-bit I/O
604# 612#
@@ -628,6 +636,33 @@ config ARM_THUMBEE
628 Say Y here if you have a CPU with the ThumbEE extension and code to 636 Say Y here if you have a CPU with the ThumbEE extension and code to
629 make use of it. Say N for code that can run on CPUs without ThumbEE. 637 make use of it. Say N for code that can run on CPUs without ThumbEE.
630 638
639config SWP_EMULATE
640 bool "Emulate SWP/SWPB instructions"
641 depends on CPU_V7
642 select HAVE_PROC_CPU if PROC_FS
643 default y if SMP
644 help
645 ARMv6 architecture deprecates use of the SWP/SWPB instructions.
646 ARMv7 multiprocessing extensions introduce the ability to disable
647 these instructions, triggering an undefined instruction exception
648 when executed. Say Y here to enable software emulation of these
649 instructions for userspace (not kernel) using LDREX/STREX.
650 Also creates /proc/cpu/swp_emulation for statistics.
651
652 In some older versions of glibc [<=2.8] SWP is used during futex
653 trylock() operations with the assumption that the code will not
654 be preempted. This invalid assumption may be more likely to fail
655 with SWP emulation enabled, leading to deadlock of the user
656 application.
657
658 NOTE: when accessing uncached shared regions, LDREX/STREX rely
659 on an external transaction monitoring block called a global
660 monitor to maintain update atomicity. If your system does not
661 implement a global monitor, this option can cause programs that
662 perform SWP operations to uncached memory to deadlock.
663
664 If unsure, say Y.
665
631config CPU_BIG_ENDIAN 666config CPU_BIG_ENDIAN
632 bool "Build big-endian kernel" 667 bool "Build big-endian kernel"
633 depends on ARCH_SUPPORTS_BIG_ENDIAN 668 depends on ARCH_SUPPORTS_BIG_ENDIAN
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 809f1bf9fa29..6b48e0a3d7aa 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -312,7 +312,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
312 addr = page_address(page); 312 addr = page_address(page);
313 313
314 if (addr) 314 if (addr)
315 *handle = page_to_dma(dev, page); 315 *handle = pfn_to_dma(dev, page_to_pfn(page));
316 316
317 return addr; 317 return addr;
318} 318}
@@ -407,7 +407,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
407 if (!arch_is_coherent()) 407 if (!arch_is_coherent())
408 __dma_free_remap(cpu_addr, size); 408 __dma_free_remap(cpu_addr, size);
409 409
410 __dma_free_buffer(dma_to_page(dev, handle), size); 410 __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
411} 411}
412EXPORT_SYMBOL(dma_free_coherent); 412EXPORT_SYMBOL(dma_free_coherent);
413 413
@@ -555,17 +555,20 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
555 struct scatterlist *s; 555 struct scatterlist *s;
556 int i, j; 556 int i, j;
557 557
558 BUG_ON(!valid_dma_direction(dir));
559
558 for_each_sg(sg, s, nents, i) { 560 for_each_sg(sg, s, nents, i) {
559 s->dma_address = dma_map_page(dev, sg_page(s), s->offset, 561 s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
560 s->length, dir); 562 s->length, dir);
561 if (dma_mapping_error(dev, s->dma_address)) 563 if (dma_mapping_error(dev, s->dma_address))
562 goto bad_mapping; 564 goto bad_mapping;
563 } 565 }
566 debug_dma_map_sg(dev, sg, nents, nents, dir);
564 return nents; 567 return nents;
565 568
566 bad_mapping: 569 bad_mapping:
567 for_each_sg(sg, s, i, j) 570 for_each_sg(sg, s, i, j)
568 dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir); 571 __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
569 return 0; 572 return 0;
570} 573}
571EXPORT_SYMBOL(dma_map_sg); 574EXPORT_SYMBOL(dma_map_sg);
@@ -586,8 +589,10 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
586 struct scatterlist *s; 589 struct scatterlist *s;
587 int i; 590 int i;
588 591
592 debug_dma_unmap_sg(dev, sg, nents, dir);
593
589 for_each_sg(sg, s, nents, i) 594 for_each_sg(sg, s, nents, i)
590 dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir); 595 __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
591} 596}
592EXPORT_SYMBOL(dma_unmap_sg); 597EXPORT_SYMBOL(dma_unmap_sg);
593 598
@@ -612,6 +617,8 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
612 __dma_page_dev_to_cpu(sg_page(s), s->offset, 617 __dma_page_dev_to_cpu(sg_page(s), s->offset,
613 s->length, dir); 618 s->length, dir);
614 } 619 }
620
621 debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
615} 622}
616EXPORT_SYMBOL(dma_sync_sg_for_cpu); 623EXPORT_SYMBOL(dma_sync_sg_for_cpu);
617 624
@@ -636,5 +643,16 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
636 __dma_page_cpu_to_dev(sg_page(s), s->offset, 643 __dma_page_cpu_to_dev(sg_page(s), s->offset,
637 s->length, dir); 644 s->length, dir);
638 } 645 }
646
647 debug_dma_sync_sg_for_device(dev, sg, nents, dir);
639} 648}
640EXPORT_SYMBOL(dma_sync_sg_for_device); 649EXPORT_SYMBOL(dma_sync_sg_for_device);
650
651#define PREALLOC_DMA_DEBUG_ENTRIES 4096
652
653static int __init dma_debug_do_init(void)
654{
655 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
656 return 0;
657}
658fs_initcall(dma_debug_do_init);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 55c17a6fb22f..ab506272b2d3 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -204,12 +204,8 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
204 /* 204 /*
205 * Don't allow RAM to be mapped - this causes problems with ARMv6+ 205 * Don't allow RAM to be mapped - this causes problems with ARMv6+
206 */ 206 */
207 if (pfn_valid(pfn)) { 207 if (WARN_ON(pfn_valid(pfn)))
208 printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" 208 return NULL;
209 "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
210 "will fail in the next kernel release. Please fix your driver.\n");
211 WARN_ON(1);
212 }
213 209
214 type = get_mem_type(mtype); 210 type = get_mem_type(mtype);
215 if (!type) 211 if (!type)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 72ad3e1f56cf..79c01f540cbe 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -24,6 +24,7 @@
24#include <asm/smp_plat.h> 24#include <asm/smp_plat.h>
25#include <asm/tlb.h> 25#include <asm/tlb.h>
26#include <asm/highmem.h> 26#include <asm/highmem.h>
27#include <asm/traps.h>
27 28
28#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
29#include <asm/mach/map.h> 30#include <asm/mach/map.h>
@@ -914,12 +915,11 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
914{ 915{
915 struct map_desc map; 916 struct map_desc map;
916 unsigned long addr; 917 unsigned long addr;
917 void *vectors;
918 918
919 /* 919 /*
920 * Allocate the vector page early. 920 * Allocate the vector page early.
921 */ 921 */
922 vectors = early_alloc(PAGE_SIZE); 922 vectors_page = early_alloc(PAGE_SIZE);
923 923
924 for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) 924 for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
925 pmd_clear(pmd_off_k(addr)); 925 pmd_clear(pmd_off_k(addr));
@@ -959,7 +959,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
959 * location (0xffff0000). If we aren't using high-vectors, also 959 * location (0xffff0000). If we aren't using high-vectors, also
960 * create a mapping at the low-vectors virtual address. 960 * create a mapping at the low-vectors virtual address.
961 */ 961 */
962 map.pfn = __phys_to_pfn(virt_to_phys(vectors)); 962 map.pfn = __phys_to_pfn(virt_to_phys(vectors_page));
963 map.virtual = 0xffff0000; 963 map.virtual = 0xffff0000;
964 map.length = PAGE_SIZE; 964 map.length = PAGE_SIZE;
965 map.type = MT_HIGH_VECTORS; 965 map.type = MT_HIGH_VECTORS;
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index b795afd0a2c6..f8f777df8d72 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -109,6 +109,10 @@
109 * 110x 0 1 0 r/w r/o 109 * 110x 0 1 0 r/w r/o
110 * 11x0 0 1 0 r/w r/o 110 * 11x0 0 1 0 r/w r/o
111 * 1111 0 1 1 r/w r/w 111 * 1111 0 1 1 r/w r/w
112 *
113 * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
114 * 110x 1 1 1 r/o r/o
115 * 11x0 1 1 1 r/o r/o
112 */ 116 */
113 .macro armv6_mt_table pfx 117 .macro armv6_mt_table pfx
114\pfx\()_mt_table: 118\pfx\()_mt_table:
@@ -148,8 +152,11 @@
148 152
149 tst r1, #L_PTE_USER 153 tst r1, #L_PTE_USER
150 orrne r3, r3, #PTE_EXT_AP1 154 orrne r3, r3, #PTE_EXT_AP1
155#ifdef CONFIG_CPU_USE_DOMAINS
156 @ allow kernel read/write access to read-only user pages
151 tstne r3, #PTE_EXT_APX 157 tstne r3, #PTE_EXT_APX
152 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 158 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
159#endif
153 160
154 tst r1, #L_PTE_EXEC 161 tst r1, #L_PTE_EXEC
155 orreq r3, r3, #PTE_EXT_XN 162 orreq r3, r3, #PTE_EXT_XN
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 9b9ff5d949fd..7401f4d7e676 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -148,8 +148,11 @@ ENTRY(cpu_v7_set_pte_ext)
148 148
149 tst r1, #L_PTE_USER 149 tst r1, #L_PTE_USER
150 orrne r3, r3, #PTE_EXT_AP1 150 orrne r3, r3, #PTE_EXT_AP1
151#ifdef CONFIG_CPU_USE_DOMAINS
152 @ allow kernel read/write access to read-only user pages
151 tstne r3, #PTE_EXT_APX 153 tstne r3, #PTE_EXT_APX
152 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 154 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
155#endif
153 156
154 tst r1, #L_PTE_EXEC 157 tst r1, #L_PTE_EXEC
155 orreq r3, r3, #PTE_EXT_XN 158 orreq r3, r3, #PTE_EXT_XN
@@ -273,8 +276,6 @@ __v7_setup:
273 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) 276 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
274 ALT_UP(orr r4, r4, #TTB_FLAGS_UP) 277 ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
275 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 278 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
276 mov r10, #0x1f @ domains 0, 1 = manager
277 mcr p15, 0, r10, c3, c0, 0 @ load domain access register
278 /* 279 /*
279 * Memory region attributes with SCTLR.TRE=1 280 * Memory region attributes with SCTLR.TRE=1
280 * 281 *
@@ -313,6 +314,10 @@ __v7_setup:
313#ifdef CONFIG_CPU_ENDIAN_BE8 314#ifdef CONFIG_CPU_ENDIAN_BE8
314 orr r6, r6, #1 << 25 @ big-endian page tables 315 orr r6, r6, #1 << 25 @ big-endian page tables
315#endif 316#endif
317#ifdef CONFIG_SWP_EMULATE
318 orr r5, r5, #(1 << 10) @ set SW bit in "clear"
319 bic r6, r6, #(1 << 10) @ clear it in "mmuset"
320#endif
316 mrc p15, 0, r0, c1, c0, 0 @ read control register 321 mrc p15, 0, r0, c1, c0, 0 @ read control register
317 bic r0, r0, r5 @ clear bits them 322 bic r0, r0, r5 @ clear bits them
318 orr r0, r0, r6 @ set them 323 orr r0, r0, r6 @ set them
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 92c5bb7909f5..c9408434a855 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -11,13 +11,13 @@ choice
11 11
12config ARCH_OMAP1 12config ARCH_OMAP1
13 bool "TI OMAP1" 13 bool "TI OMAP1"
14 select COMMON_CLKDEV 14 select CLKDEV_LOOKUP
15 help 15 help
16 "Systems based on omap7xx, omap15xx or omap16xx" 16 "Systems based on omap7xx, omap15xx or omap16xx"
17 17
18config ARCH_OMAP2PLUS 18config ARCH_OMAP2PLUS
19 bool "TI OMAP2/3/4" 19 bool "TI OMAP2/3/4"
20 select COMMON_CLKDEV 20 select CLKDEV_LOOKUP
21 help 21 help
22 "Systems based on OMAP2, OMAP3 or OMAP4" 22 "Systems based on OMAP2, OMAP3 or OMAP4"
23 23
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index bb937f3fabed..4b2028ab4d2b 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -8,7 +8,7 @@
8#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H 8#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
9#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H 9#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
10 10
11#include <asm/clkdev.h> 11#include <linux/clkdev.h>
12 12
13struct omap_clk { 13struct omap_clk {
14 u16 cpu; 14 u16 cpu;
diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h
index d5306bee44b2..f8d922fb5584 100644
--- a/arch/arm/plat-omap/include/plat/memory.h
+++ b/arch/arm/plat-omap/include/plat/memory.h
@@ -61,17 +61,17 @@
61#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET) 61#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
62#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0)) 62#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
63 63
64#define __arch_page_to_dma(dev, page) \ 64#define __arch_pfn_to_dma(dev, pfn) \
65 ({ dma_addr_t __dma = page_to_phys(page); \ 65 ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
66 if (is_lbus_device(dev)) \ 66 if (is_lbus_device(dev)) \
67 __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ 67 __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
68 __dma; }) 68 __dma; })
69 69
70#define __arch_dma_to_page(dev, addr) \ 70#define __arch_dma_to_pfn(dev, addr) \
71 ({ dma_addr_t __dma = addr; \ 71 ({ dma_addr_t __dma = addr; \
72 if (is_lbus_device(dev)) \ 72 if (is_lbus_device(dev)) \
73 __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \ 73 __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \
74 phys_to_page(__dma); \ 74 __phys_to_pfn(__dma); \
75 }) 75 })
76 76
77#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \ 77#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index ecd6a488c497..7a10257909ef 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -18,7 +18,6 @@
18#define OMAP_ARCH_SMP_H 18#define OMAP_ARCH_SMP_H
19 19
20#include <asm/hardware/gic.h> 20#include <asm/hardware/gic.h>
21#include <asm/smp_mpidr.h>
22 21
23/* Needed for secondary core boot */ 22/* Needed for secondary core boot */
24extern void omap_secondary_startup(void); 23extern void omap_secondary_startup(void);
@@ -29,9 +28,9 @@ extern u32 omap_read_auxcoreboot0(void);
29/* 28/*
30 * We use Soft IRQ1 as the IPI 29 * We use Soft IRQ1 as the IPI
31 */ 30 */
32static inline void smp_cross_call(const struct cpumask *mask) 31static inline void smp_cross_call(const struct cpumask *mask, int ipi)
33{ 32{
34 gic_raise_softirq(mask, 1); 33 gic_raise_softirq(mask, ipi);
35} 34}
36 35
37#endif 36#endif
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 298bafc0a52f..2572260f990f 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -15,7 +15,7 @@
15#define __PLAT_CLOCK_H 15#define __PLAT_CLOCK_H
16 16
17#include <linux/list.h> 17#include <linux/list.h>
18#include <asm/clkdev.h> 18#include <linux/clkdev.h>
19#include <linux/types.h> 19#include <linux/types.h>
20 20
21/* clk structure flags */ 21/* clk structure flags */
diff --git a/arch/arm/plat-stmp3xxx/clock.c b/arch/arm/plat-stmp3xxx/clock.c
index e593a2a801c6..2e712e17ce72 100644
--- a/arch/arm/plat-stmp3xxx/clock.c
+++ b/arch/arm/plat-stmp3xxx/clock.c
@@ -25,9 +25,9 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/clkdev.h>
28 29
29#include <asm/mach-types.h> 30#include <asm/mach-types.h>
30#include <asm/clkdev.h>
31#include <mach/platform.h> 31#include <mach/platform.h>
32#include <mach/regs-clkctrl.h> 32#include <mach/regs-clkctrl.h>
33 33
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 8063a322c790..0797cb528b46 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -10,9 +10,12 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/cpu.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/notifier.h>
14#include <linux/signal.h> 16#include <linux/signal.h>
15#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/smp.h>
16#include <linux/init.h> 19#include <linux/init.h>
17 20
18#include <asm/cputype.h> 21#include <asm/cputype.h>
@@ -484,7 +487,24 @@ void vfp_flush_hwstate(struct thread_info *thread)
484 put_cpu(); 487 put_cpu();
485} 488}
486 489
487#include <linux/smp.h> 490/*
491 * VFP hardware can lose all context when a CPU goes offline.
492 * Safely clear our held state when a CPU has been killed, and
493 * re-enable access to VFP when the CPU comes back online.
494 *
495 * Both CPU_DYING and CPU_STARTING are called on the CPU which
496 * is being offlined/onlined.
497 */
498static int vfp_hotplug(struct notifier_block *b, unsigned long action,
499 void *hcpu)
500{
501 if (action == CPU_DYING || action == CPU_DYING_FROZEN) {
502 unsigned int cpu = (long)hcpu;
503 last_VFP_context[cpu] = NULL;
504 } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
505 vfp_enable(NULL);
506 return NOTIFY_OK;
507}
488 508
489/* 509/*
490 * VFP support code initialisation. 510 * VFP support code initialisation.
@@ -514,6 +534,8 @@ static int __init vfp_init(void)
514 else if (vfpsid & FPSID_NODOUBLE) { 534 else if (vfpsid & FPSID_NODOUBLE) {
515 printk("no double precision support\n"); 535 printk("no double precision support\n");
516 } else { 536 } else {
537 hotcpu_notifier(vfp_hotplug, 0);
538
517 smp_call_function(vfp_enable, NULL, 1); 539 smp_call_function(vfp_enable, NULL, 1);
518 540
519 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ 541 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 2e9d78d21fd3..25cf0b34dffd 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,7 +1,7 @@
1config SUPERH 1config SUPERH
2 def_bool y 2 def_bool y
3 select EMBEDDED 3 select EMBEDDED
4 select HAVE_CLK 4 select CLKDEV_LOOKUP
5 select HAVE_IDE if HAS_IOPORT 5 select HAVE_IDE if HAS_IOPORT
6 select HAVE_MEMBLOCK 6 select HAVE_MEMBLOCK
7 select HAVE_OPROFILE 7 select HAVE_OPROFILE
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index a5ecfbacaf36..87618c91d178 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -24,10 +24,10 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/usb/r8a66597.h> 25#include <linux/usb/r8a66597.h>
26#include <linux/usb/m66592.h> 26#include <linux/usb/m66592.h>
27#include <linux/clkdev.h>
27#include <net/ax88796.h> 28#include <net/ax88796.h>
28#include <asm/machvec.h> 29#include <asm/machvec.h>
29#include <mach/highlander.h> 30#include <mach/highlander.h>
30#include <asm/clkdev.h>
31#include <asm/clock.h> 31#include <asm/clock.h>
32#include <asm/heartbeat.h> 32#include <asm/heartbeat.h>
33#include <asm/io.h> 33#include <asm/io.h>
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
index 5645f358128b..6ba91868201c 100644
--- a/arch/sh/include/asm/clkdev.h
+++ b/arch/sh/include/asm/clkdev.h
@@ -1,9 +1,5 @@
1/* 1/*
2 * arch/sh/include/asm/clkdev.h 2 * Copyright (C) 2010 Paul Mundt <lethal@linux-sh.org>
3 *
4 * Cloned from arch/arm/include/asm/clkdev.h:
5 *
6 * Copyright (C) 2008 Russell King.
7 * 3 *
8 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
@@ -11,25 +7,25 @@
11 * 7 *
12 * Helper for the clk API to assist looking up a struct clk. 8 * Helper for the clk API to assist looking up a struct clk.
13 */ 9 */
14#ifndef __ASM_CLKDEV_H
15#define __ASM_CLKDEV_H
16 10
17struct clk; 11#ifndef __CLKDEV__H_
12#define __CLKDEV__H_
18 13
19struct clk_lookup { 14#include <linux/bootmem.h>
20 struct list_head node; 15#include <linux/mm.h>
21 const char *dev_id; 16#include <linux/slab.h>
22 const char *con_id;
23 struct clk *clk;
24};
25 17
26struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 18#include <asm/clock.h>
27 const char *dev_fmt, ...);
28 19
29void clkdev_add(struct clk_lookup *cl); 20static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
30void clkdev_drop(struct clk_lookup *cl); 21{
22 if (!slab_is_available())
23 return alloc_bootmem_low_pages(size);
24 else
25 return kzalloc(size, GFP_KERNEL);
26}
31 27
32void clkdev_add_table(struct clk_lookup *, size_t); 28#define __clk_put(clk)
33int clk_add_alias(const char *, const char *, char *, struct device *); 29#define __clk_get(clk) ({ 1; })
34 30
35#endif 31#endif /* __CLKDEV_H__ */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 8eed6a485446..cf6522179523 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -11,7 +11,7 @@ endif
11 11
12CFLAGS_REMOVE_return_address.o = -pg 12CFLAGS_REMOVE_return_address.o = -pg
13 13
14obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \ 14obj-y := debugtraps.o dma-nommu.o dumpstack.o \
15 idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \ 15 idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \
16 machvec.o nmi_debug.o process.o \ 16 machvec.o nmi_debug.o process.o \
17 process_$(BITS).o ptrace.o ptrace_$(BITS).o \ 17 process_$(BITS).o ptrace.o ptrace_$(BITS).o \
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
deleted file mode 100644
index 1f800ef4a735..000000000000
--- a/arch/sh/kernel/clkdev.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * arch/sh/kernel/clkdev.c
3 *
4 * Cloned from arch/arm/common/clkdev.c:
5 *
6 * Copyright (C) 2008 Russell King.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Helper for the clk API to assist looking up a struct clk.
13 */
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/device.h>
17#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/err.h>
20#include <linux/string.h>
21#include <linux/mutex.h>
22#include <linux/clk.h>
23#include <linux/slab.h>
24#include <linux/bootmem.h>
25#include <linux/mm.h>
26#include <asm/clock.h>
27#include <asm/clkdev.h>
28
29static LIST_HEAD(clocks);
30static DEFINE_MUTEX(clocks_mutex);
31
32/*
33 * Find the correct struct clk for the device and connection ID.
34 * We do slightly fuzzy matching here:
35 * An entry with a NULL ID is assumed to be a wildcard.
36 * If an entry has a device ID, it must match
37 * If an entry has a connection ID, it must match
38 * Then we take the most specific entry - with the following
39 * order of precedence: dev+con > dev only > con only.
40 */
41static struct clk *clk_find(const char *dev_id, const char *con_id)
42{
43 struct clk_lookup *p;
44 struct clk *clk = NULL;
45 int match, best = 0;
46
47 list_for_each_entry(p, &clocks, node) {
48 match = 0;
49 if (p->dev_id) {
50 if (!dev_id || strcmp(p->dev_id, dev_id))
51 continue;
52 match += 2;
53 }
54 if (p->con_id) {
55 if (!con_id || strcmp(p->con_id, con_id))
56 continue;
57 match += 1;
58 }
59 if (match == 0)
60 continue;
61
62 if (match > best) {
63 clk = p->clk;
64 best = match;
65 }
66 }
67 return clk;
68}
69
70struct clk *clk_get_sys(const char *dev_id, const char *con_id)
71{
72 struct clk *clk;
73
74 mutex_lock(&clocks_mutex);
75 clk = clk_find(dev_id, con_id);
76 mutex_unlock(&clocks_mutex);
77
78 return clk ? clk : ERR_PTR(-ENOENT);
79}
80EXPORT_SYMBOL(clk_get_sys);
81
82void clkdev_add(struct clk_lookup *cl)
83{
84 mutex_lock(&clocks_mutex);
85 list_add_tail(&cl->node, &clocks);
86 mutex_unlock(&clocks_mutex);
87}
88EXPORT_SYMBOL(clkdev_add);
89
90void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
91{
92 mutex_lock(&clocks_mutex);
93 while (num--) {
94 list_add_tail(&cl->node, &clocks);
95 cl++;
96 }
97 mutex_unlock(&clocks_mutex);
98}
99
100#define MAX_DEV_ID 20
101#define MAX_CON_ID 16
102
103struct clk_lookup_alloc {
104 struct clk_lookup cl;
105 char dev_id[MAX_DEV_ID];
106 char con_id[MAX_CON_ID];
107};
108
109struct clk_lookup * __init_refok
110clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
111{
112 struct clk_lookup_alloc *cla;
113
114 if (!slab_is_available())
115 cla = alloc_bootmem_low_pages(sizeof(*cla));
116 else
117 cla = kzalloc(sizeof(*cla), GFP_KERNEL);
118
119 if (!cla)
120 return NULL;
121
122 cla->cl.clk = clk;
123 if (con_id) {
124 strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
125 cla->cl.con_id = cla->con_id;
126 }
127
128 if (dev_fmt) {
129 va_list ap;
130
131 va_start(ap, dev_fmt);
132 vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
133 cla->cl.dev_id = cla->dev_id;
134 va_end(ap);
135 }
136
137 return &cla->cl;
138}
139EXPORT_SYMBOL(clkdev_alloc);
140
141int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
142 struct device *dev)
143{
144 struct clk *r = clk_get(dev, id);
145 struct clk_lookup *l;
146
147 if (IS_ERR(r))
148 return PTR_ERR(r);
149
150 l = clkdev_alloc(r, alias, alias_dev_name);
151 clk_put(r);
152 if (!l)
153 return -ENODEV;
154 clkdev_add(l);
155 return 0;
156}
157EXPORT_SYMBOL(clk_add_alias);
158
159/*
160 * clkdev_drop - remove a clock dynamically allocated
161 */
162void clkdev_drop(struct clk_lookup *cl)
163{
164 struct clk_lookup_alloc *cla = container_of(cl, struct clk_lookup_alloc, cl);
165
166 mutex_lock(&clocks_mutex);
167 list_del(&cl->node);
168 mutex_unlock(&clocks_mutex);
169 kfree(cla);
170}
171EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index e2f63d68da51..dd0e0f211359 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -2,7 +2,7 @@
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <linux/io.h> 4#include <linux/io.h>
5#include <asm/clkdev.h> 5#include <linux/clkdev.h>
6#include <asm/clock.h> 6#include <asm/clock.h>
7 7
8static struct clk master_clk = { 8static struct clk master_clk = {
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 50f887dda565..4187cf4fe185 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -48,20 +48,4 @@ int __init clk_init(void)
48 return ret; 48 return ret;
49} 49}
50 50
51/*
52 * Returns a clock. Note that we first try to use device id on the bus
53 * and clock name. If this fails, we try to use clock name only.
54 */
55struct clk *clk_get(struct device *dev, const char *con_id)
56{
57 const char *dev_id = dev ? dev_name(dev) : NULL;
58
59 return clk_get_sys(dev_id, con_id);
60}
61EXPORT_SYMBOL_GPL(clk_get);
62
63void clk_put(struct clk *clk)
64{
65}
66EXPORT_SYMBOL_GPL(clk_put);
67 51
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index 6282a839e08e..3f6f8e98635c 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/clkdev.h> 16#include <linux/clkdev.h>
17#include <asm/clock.h> 17#include <asm/clock.h>
18#include <asm/freq.h> 18#include <asm/freq.h>
19 19
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 71291ae201b9..93c646072c1b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25#include <asm/clock.h> 25#include <asm/clock.h>
26 26
27/* SH7343 registers */ 27/* SH7343 registers */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 7ce5bbcd4084..049dc0628ccc 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25#include <asm/clock.h> 25#include <asm/clock.h>
26 26
27/* SH7366 registers */ 27/* SH7366 registers */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 2030f3d9fac7..9d23a36f0647 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25#include <asm/clock.h> 25#include <asm/clock.h>
26#include <asm/hwblk.h> 26#include <asm/hwblk.h>
27#include <cpu/sh7722.h> 27#include <cpu/sh7722.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index d3938f0d3702..55493cd5bd8f 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -22,7 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <asm/clkdev.h> 25#include <linux/clkdev.h>
26#include <asm/clock.h> 26#include <asm/clock.h>
27#include <asm/hwblk.h> 27#include <asm/hwblk.h>
28#include <cpu/sh7723.h> 28#include <cpu/sh7723.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 271c0b325a9a..d08fa953c88b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -22,7 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <asm/clkdev.h> 25#include <linux/clkdev.h>
26#include <asm/clock.h> 26#include <asm/clock.h>
27#include <asm/hwblk.h> 27#include <asm/hwblk.h>
28#include <cpu/sh7724.h> 28#include <cpu/sh7724.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index ce39a2ae8c6c..e073e3eb4c3d 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <asm/clkdev.h> 15#include <linux/clkdev.h>
16#include <asm/clock.h> 16#include <asm/clock.h>
17#include <asm/freq.h> 17#include <asm/freq.h>
18 18
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
index 1f1df48008cd..599630fc4d3b 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/clkdev.h> 16#include <linux/clkdev.h>
17#include <asm/clock.h> 17#include <asm/clock.h>
18#include <asm/freq.h> 18#include <asm/freq.h>
19#include <asm/io.h> 19#include <asm/io.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
index 62d706350060..8894926479a6 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <asm/clkdev.h> 15#include <linux/clkdev.h>
16#include <asm/clock.h> 16#include <asm/clock.h>
17#include <asm/freq.h> 17#include <asm/freq.h>
18#include <asm/io.h> 18#include <asm/io.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index c3e458aaa2b7..2d960247f3eb 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -14,7 +14,7 @@
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/cpufreq.h> 16#include <linux/cpufreq.h>
17#include <asm/clkdev.h> 17#include <linux/clkdev.h>
18#include <asm/clock.h> 18#include <asm/clock.h>
19#include <asm/freq.h> 19#include <asm/freq.h>
20#include <cpu/sh7785.h> 20#include <cpu/sh7785.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index 597c9fbe49c6..42e403be9076 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/clkdev.h> 16#include <linux/clkdev.h>
17#include <asm/clock.h> 17#include <asm/clock.h>
18#include <asm/freq.h> 18#include <asm/freq.h>
19 19
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 4f70df6b6169..1afdb93b8ccb 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -14,7 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <asm/clkdev.h> 17#include <linux/clkdev.h>
18#include <asm/clock.h> 18#include <asm/clock.h>
19#include <asm/freq.h> 19#include <asm/freq.h>
20 20
diff --git a/drivers/Kconfig b/drivers/Kconfig
index a2b902f4d437..3d93b3a3d630 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -111,4 +111,6 @@ source "drivers/xen/Kconfig"
111source "drivers/staging/Kconfig" 111source "drivers/staging/Kconfig"
112 112
113source "drivers/platform/Kconfig" 113source "drivers/platform/Kconfig"
114
115source "drivers/clk/Kconfig"
114endmenu 116endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index f3ebb30f1b7f..bf15ce7493d2 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -115,3 +115,5 @@ obj-$(CONFIG_VLYNQ) += vlynq/
115obj-$(CONFIG_STAGING) += staging/ 115obj-$(CONFIG_STAGING) += staging/
116obj-y += platform/ 116obj-y += platform/
117obj-y += ieee802154/ 117obj-y += ieee802154/
118#common clk code
119obj-y += clk/
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 2737b9752205..e7df019d29d4 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -147,6 +147,39 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
147 clk_put(pclk); 147 clk_put(pclk);
148} 148}
149 149
150static int amba_get_enable_vcore(struct amba_device *pcdev)
151{
152 struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
153 int ret;
154
155 pcdev->vcore = vcore;
156
157 if (IS_ERR(vcore)) {
158 /* It is OK not to supply a vcore regulator */
159 if (PTR_ERR(vcore) == -ENODEV)
160 return 0;
161 return PTR_ERR(vcore);
162 }
163
164 ret = regulator_enable(vcore);
165 if (ret) {
166 regulator_put(vcore);
167 pcdev->vcore = ERR_PTR(-ENODEV);
168 }
169
170 return ret;
171}
172
173static void amba_put_disable_vcore(struct amba_device *pcdev)
174{
175 struct regulator *vcore = pcdev->vcore;
176
177 if (!IS_ERR(vcore)) {
178 regulator_disable(vcore);
179 regulator_put(vcore);
180 }
181}
182
150/* 183/*
151 * These are the device model conversion veneers; they convert the 184 * These are the device model conversion veneers; they convert the
152 * device model structures to our more specific structures. 185 * device model structures to our more specific structures.
@@ -159,6 +192,10 @@ static int amba_probe(struct device *dev)
159 int ret; 192 int ret;
160 193
161 do { 194 do {
195 ret = amba_get_enable_vcore(pcdev);
196 if (ret)
197 break;
198
162 ret = amba_get_enable_pclk(pcdev); 199 ret = amba_get_enable_pclk(pcdev);
163 if (ret) 200 if (ret)
164 break; 201 break;
@@ -168,6 +205,7 @@ static int amba_probe(struct device *dev)
168 break; 205 break;
169 206
170 amba_put_disable_pclk(pcdev); 207 amba_put_disable_pclk(pcdev);
208 amba_put_disable_vcore(pcdev);
171 } while (0); 209 } while (0);
172 210
173 return ret; 211 return ret;
@@ -180,6 +218,7 @@ static int amba_remove(struct device *dev)
180 int ret = drv->remove(pcdev); 218 int ret = drv->remove(pcdev);
181 219
182 amba_put_disable_pclk(pcdev); 220 amba_put_disable_pclk(pcdev);
221 amba_put_disable_vcore(pcdev);
183 222
184 return ret; 223 return ret;
185} 224}
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
new file mode 100644
index 000000000000..4168c8896e16
--- /dev/null
+++ b/drivers/clk/Kconfig
@@ -0,0 +1,4 @@
1
2config CLKDEV_LOOKUP
3 bool
4 select HAVE_CLK
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
new file mode 100644
index 000000000000..07613fa172c9
--- /dev/null
+++ b/drivers/clk/Makefile
@@ -0,0 +1,2 @@
1
2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
diff --git a/arch/arm/common/clkdev.c b/drivers/clk/clkdev.c
index e2b2bb66e094..0fc0a79852de 100644
--- a/arch/arm/common/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/common/clkdev.c 2 * drivers/clk/clkdev.c
3 * 3 *
4 * Copyright (C) 2008 Russell King. 4 * Copyright (C) 2008 Russell King.
5 * 5 *
@@ -18,10 +18,7 @@
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/clk.h> 20#include <linux/clk.h>
21#include <linux/slab.h> 21#include <linux/clkdev.h>
22
23#include <asm/clkdev.h>
24#include <mach/clkdev.h>
25 22
26static LIST_HEAD(clocks); 23static LIST_HEAD(clocks);
27static DEFINE_MUTEX(clocks_mutex); 24static DEFINE_MUTEX(clocks_mutex);
@@ -120,12 +117,12 @@ struct clk_lookup_alloc {
120 char con_id[MAX_CON_ID]; 117 char con_id[MAX_CON_ID];
121}; 118};
122 119
123struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 120struct clk_lookup * __init_refok
124 const char *dev_fmt, ...) 121clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
125{ 122{
126 struct clk_lookup_alloc *cla; 123 struct clk_lookup_alloc *cla;
127 124
128 cla = kzalloc(sizeof(*cla), GFP_KERNEL); 125 cla = __clkdev_alloc(sizeof(*cla));
129 if (!cla) 126 if (!cla)
130 return NULL; 127 return NULL;
131 128
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index c6454cca0447..9e7f259346e1 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -18,6 +18,7 @@
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/resource.h> 20#include <linux/resource.h>
21#include <linux/regulator/consumer.h>
21 22
22#define AMBA_NR_IRQS 2 23#define AMBA_NR_IRQS 2
23#define AMBA_CID 0xb105f00d 24#define AMBA_CID 0xb105f00d
@@ -28,6 +29,7 @@ struct amba_device {
28 struct device dev; 29 struct device dev;
29 struct resource res; 30 struct resource res;
30 struct clk *pclk; 31 struct clk *pclk;
32 struct regulator *vcore;
31 u64 dma_mask; 33 u64 dma_mask;
32 unsigned int periphid; 34 unsigned int periphid;
33 unsigned int irq[AMBA_NR_IRQS]; 35 unsigned int irq[AMBA_NR_IRQS];
@@ -71,6 +73,12 @@ void amba_release_regions(struct amba_device *);
71#define amba_pclk_disable(d) \ 73#define amba_pclk_disable(d) \
72 do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0) 74 do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0)
73 75
76#define amba_vcore_enable(d) \
77 (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore))
78
79#define amba_vcore_disable(d) \
80 do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0)
81
74/* Some drivers don't use the struct amba_device */ 82/* Some drivers don't use the struct amba_device */
75#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff) 83#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
76#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f) 84#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)
diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h
new file mode 100644
index 000000000000..457bcb0a310a
--- /dev/null
+++ b/include/linux/clkdev.h
@@ -0,0 +1,36 @@
1/*
2 * include/linux/clkdev.h
3 *
4 * Copyright (C) 2008 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Helper for the clk API to assist looking up a struct clk.
11 */
12#ifndef __CLKDEV_H
13#define __CLKDEV_H
14
15#include <asm/clkdev.h>
16
17struct clk;
18struct device;
19
20struct clk_lookup {
21 struct list_head node;
22 const char *dev_id;
23 const char *con_id;
24 struct clk *clk;
25};
26
27struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
28 const char *dev_fmt, ...);
29
30void clkdev_add(struct clk_lookup *cl);
31void clkdev_drop(struct clk_lookup *cl);
32
33void clkdev_add_table(struct clk_lookup *, size_t);
34int clk_add_alias(const char *, const char *, char *, struct device *);
35
36#endif