Commit 4073723a authored by Russell King's avatar Russell King

Merge branch 'misc' into devel

Conflicts:
	arch/arm/Kconfig
	arch/arm/common/Makefile
	arch/arm/kernel/Makefile
	arch/arm/kernel/smp.c
parents 58daf18c 4ec3eb13
...@@ -34,3 +34,5 @@ memory.txt ...@@ -34,3 +34,5 @@ memory.txt
- description of the virtual memory layout - description of the virtual memory layout
nwfpe/ nwfpe/
- NWFPE floating point emulator documentation - NWFPE floating point emulator documentation
swp_emulation
- SWP/SWPB emulation handler/logging description
Software emulation of deprecated SWP instruction (CONFIG_SWP_EMULATE)
---------------------------------------------------------------------
ARMv6 architecture deprecates use of the SWP/SWPB instructions, and recommeds
moving to the load-locked/store-conditional instructions LDREX and STREX.
ARMv7 multiprocessing extensions introduce the ability to disable these
instructions, triggering an undefined instruction exception when executed.
Trapped instructions are emulated using an LDREX/STREX or LDREXB/STREXB
sequence. If a memory access fault (an abort) occurs, a segmentation fault is
signalled to the triggering process.
/proc/cpu/swp_emulation holds some statistics/information, including the PID of
the last process to trigger the emulation to be invocated. For example:
---
Emulated SWP: 12
Emulated SWPB: 0
Aborted SWP{B}: 1
Last process: 314
---
NOTE: when accessing uncached shared regions, LDREX/STREX rely on an external
transaction monitoring block called a global monitor to maintain update
atomicity. If your system does not implement a global monitor, this option can
cause programs that perform SWP operations to uncached memory to deadlock, as
the STREX operation will always fail.
...@@ -2,6 +2,7 @@ config ARM ...@@ -2,6 +2,7 @@ config ARM
bool bool
default y default y
select HAVE_AOUT select HAVE_AOUT
select HAVE_DMA_API_DEBUG
select HAVE_IDE select HAVE_IDE
select HAVE_MEMBLOCK select HAVE_MEMBLOCK
select RTC_LIB select RTC_LIB
...@@ -36,6 +37,9 @@ config ARM ...@@ -36,6 +37,9 @@ config ARM
config HAVE_PWM config HAVE_PWM
bool bool
config MIGHT_HAVE_PCI
bool
config SYS_SUPPORTS_APM_EMULATION config SYS_SUPPORTS_APM_EMULATION
bool bool
...@@ -226,7 +230,7 @@ config ARCH_INTEGRATOR ...@@ -226,7 +230,7 @@ config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family" bool "ARM Ltd. Integrator family"
select ARM_AMBA select ARM_AMBA
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
select COMMON_CLKDEV select CLKDEV_LOOKUP
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE select PLAT_VERSATILE
...@@ -236,7 +240,7 @@ config ARCH_INTEGRATOR ...@@ -236,7 +240,7 @@ config ARCH_INTEGRATOR
config ARCH_REALVIEW config ARCH_REALVIEW
bool "ARM Ltd. RealView family" bool "ARM Ltd. RealView family"
select ARM_AMBA select ARM_AMBA
select COMMON_CLKDEV select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
...@@ -251,7 +255,7 @@ config ARCH_VERSATILE ...@@ -251,7 +255,7 @@ config ARCH_VERSATILE
bool "ARM Ltd. Versatile family" bool "ARM Ltd. Versatile family"
select ARM_AMBA select ARM_AMBA
select ARM_VIC select ARM_VIC
select COMMON_CLKDEV select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
select ICST select ICST
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
...@@ -266,7 +270,7 @@ config ARCH_VEXPRESS ...@@ -266,7 +270,7 @@ config ARCH_VEXPRESS
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA select ARM_AMBA
select ARM_TIMER_SP804 select ARM_TIMER_SP804
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_CLK select HAVE_CLK
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
...@@ -288,7 +292,7 @@ config ARCH_BCMRING ...@@ -288,7 +292,7 @@ config ARCH_BCMRING
depends on MMU depends on MMU
select CPU_V6 select CPU_V6
select ARM_AMBA select ARM_AMBA
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
help help
...@@ -306,6 +310,7 @@ config ARCH_CNS3XXX ...@@ -306,6 +310,7 @@ config ARCH_CNS3XXX
select CPU_V6 select CPU_V6
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARM_GIC select ARM_GIC
select MIGHT_HAVE_PCI
select PCI_DOMAINS if PCI select PCI_DOMAINS if PCI
help help
Support for Cavium Networks CNS3XXX platform. Support for Cavium Networks CNS3XXX platform.
...@@ -335,7 +340,7 @@ config ARCH_EP93XX ...@@ -335,7 +340,7 @@ config ARCH_EP93XX
select CPU_ARM920T select CPU_ARM920T
select ARM_AMBA select ARM_AMBA
select ARM_VIC select ARM_VIC
select COMMON_CLKDEV select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_USES_GETTIMEOFFSET select ARCH_USES_GETTIMEOFFSET
...@@ -355,14 +360,14 @@ config ARCH_MXC ...@@ -355,14 +360,14 @@ config ARCH_MXC
bool "Freescale MXC/iMX-based" bool "Freescale MXC/iMX-based"
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select COMMON_CLKDEV select CLKDEV_LOOKUP
help help
Support for Freescale MXC/iMX-based family of processors Support for Freescale MXC/iMX-based family of processors
config ARCH_STMP3XXX config ARCH_STMP3XXX
bool "Freescale STMP3xxx" bool "Freescale STMP3xxx"
select CPU_ARM926T select CPU_ARM926T
select COMMON_CLKDEV select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select USB_ARCH_HAS_EHCI select USB_ARCH_HAS_EHCI
...@@ -442,6 +447,7 @@ config ARCH_IXP4XX ...@@ -442,6 +447,7 @@ config ARCH_IXP4XX
select GENERIC_GPIO select GENERIC_GPIO
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
select MIGHT_HAVE_PCI
select DMABOUNCE if PCI select DMABOUNCE if PCI
help help
Support for Intel's IXP4XX (XScale) family of processors. Support for Intel's IXP4XX (XScale) family of processors.
...@@ -481,7 +487,7 @@ config ARCH_LPC32XX ...@@ -481,7 +487,7 @@ config ARCH_LPC32XX
select HAVE_IDE select HAVE_IDE
select ARM_AMBA select ARM_AMBA
select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_OHCI
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_TIME select GENERIC_TIME
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
help help
...@@ -515,7 +521,7 @@ config ARCH_MMP ...@@ -515,7 +521,7 @@ config ARCH_MMP
bool "Marvell PXA168/910/MMP2" bool "Marvell PXA168/910/MMP2"
depends on MMU depends on MMU
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
select TICK_ONESHOT select TICK_ONESHOT
...@@ -549,7 +555,7 @@ config ARCH_W90X900 ...@@ -549,7 +555,7 @@ config ARCH_W90X900
bool "Nuvoton W90X900 CPU" bool "Nuvoton W90X900 CPU"
select CPU_ARM926T select CPU_ARM926T
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
help help
Support for Nuvoton (Winbond logic dept.) ARM9 processor, Support for Nuvoton (Winbond logic dept.) ARM9 processor,
...@@ -563,19 +569,19 @@ config ARCH_W90X900 ...@@ -563,19 +569,19 @@ config ARCH_W90X900
config ARCH_NUC93X config ARCH_NUC93X
bool "Nuvoton NUC93X CPU" bool "Nuvoton NUC93X CPU"
select CPU_ARM926T select CPU_ARM926T
select COMMON_CLKDEV select CLKDEV_LOOKUP
help help
Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
low-power and high performance MPEG-4/JPEG multimedia controller chip. low-power and high performance MPEG-4/JPEG multimedia controller chip.
config ARCH_TEGRA config ARCH_TEGRA
bool "NVIDIA Tegra" bool "NVIDIA Tegra"
select CLKDEV_LOOKUP
select GENERIC_TIME select GENERIC_TIME
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_GPIO select GENERIC_GPIO
select HAVE_CLK select HAVE_CLK
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
select COMMON_CLKDEV
select ARCH_HAS_BARRIERS if CACHE_L2X0 select ARCH_HAS_BARRIERS if CACHE_L2X0
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
help help
...@@ -585,7 +591,7 @@ config ARCH_TEGRA ...@@ -585,7 +591,7 @@ config ARCH_TEGRA
config ARCH_PNX4008 config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile" bool "Philips Nexperia PNX4008 Mobile"
select CPU_ARM926T select CPU_ARM926T
select COMMON_CLKDEV select CLKDEV_LOOKUP
select ARCH_USES_GETTIMEOFFSET select ARCH_USES_GETTIMEOFFSET
help help
This enables support for Philips PNX4008 mobile platform. This enables support for Philips PNX4008 mobile platform.
...@@ -595,7 +601,7 @@ config ARCH_PXA ...@@ -595,7 +601,7 @@ config ARCH_PXA
depends on MMU depends on MMU
select ARCH_MTD_XIP select ARCH_MTD_XIP
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
select COMMON_CLKDEV select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_SCHED_CLOCK select HAVE_SCHED_CLOCK
...@@ -774,7 +780,7 @@ config ARCH_TCC_926 ...@@ -774,7 +780,7 @@ config ARCH_TCC_926
bool "Telechips TCC ARM926-based systems" bool "Telechips TCC ARM926-based systems"
select CPU_ARM926T select CPU_ARM926T
select HAVE_CLK select HAVE_CLK
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
help help
Support for Telechips TCC ARM926-based systems. Support for Telechips TCC ARM926-based systems.
...@@ -799,7 +805,7 @@ config ARCH_U300 ...@@ -799,7 +805,7 @@ config ARCH_U300
select ARM_AMBA select ARM_AMBA
select ARM_VIC select ARM_VIC
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_GPIO select GENERIC_GPIO
help help
Support for ST-Ericsson U300 series mobile platforms. Support for ST-Ericsson U300 series mobile platforms.
...@@ -809,7 +815,7 @@ config ARCH_U8500 ...@@ -809,7 +815,7 @@ config ARCH_U8500
select CPU_V7 select CPU_V7
select ARM_AMBA select ARM_AMBA
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select COMMON_CLKDEV select CLKDEV_LOOKUP
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
help help
Support for ST-Ericsson's Ux500 architecture Support for ST-Ericsson's Ux500 architecture
...@@ -819,7 +825,7 @@ config ARCH_NOMADIK ...@@ -819,7 +825,7 @@ config ARCH_NOMADIK
select ARM_AMBA select ARM_AMBA
select ARM_VIC select ARM_VIC
select CPU_ARM926T select CPU_ARM926T
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
help help
...@@ -831,7 +837,7 @@ config ARCH_DAVINCI ...@@ -831,7 +837,7 @@ config ARCH_DAVINCI
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ZONE_DMA select ZONE_DMA
select HAVE_IDE select HAVE_IDE
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_ALLOCATOR select GENERIC_ALLOCATOR
select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_HAS_HOLES_MEMORYMODEL
help help
...@@ -852,7 +858,7 @@ config PLAT_SPEAR ...@@ -852,7 +858,7 @@ config PLAT_SPEAR
bool "ST SPEAr" bool "ST SPEAr"
select ARM_AMBA select ARM_AMBA
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select COMMON_CLKDEV select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_CLK select HAVE_CLK
help help
...@@ -1034,6 +1040,11 @@ config CPU_HAS_PMU ...@@ -1034,6 +1040,11 @@ config CPU_HAS_PMU
default y default y
bool bool
config MULTI_IRQ_HANDLER
bool
help
Allow each machine to specify it's own IRQ handler at run time.
if !MMU if !MMU
source "arch/arm/Kconfig-nommu" source "arch/arm/Kconfig-nommu"
endif endif
...@@ -1181,7 +1192,7 @@ config ISA_DMA_API ...@@ -1181,7 +1192,7 @@ config ISA_DMA_API
bool bool
config PCI config PCI
bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX || SA1100_NANOENGINE bool "PCI support" if MIGHT_HAVE_PCI
help help
Find out whether you have a PCI motherboard. PCI is the name of a Find out whether you have a PCI motherboard. PCI is the name of a
bus system, i.e. the way the CPU talks to the other stuff inside bus system, i.e. the way the CPU talks to the other stuff inside
...@@ -1253,7 +1264,7 @@ config SMP ...@@ -1253,7 +1264,7 @@ config SMP
config SMP_ON_UP config SMP_ON_UP
bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)" bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
depends on EXPERIMENTAL depends on EXPERIMENTAL
depends on SMP && !XIP && !THUMB2_KERNEL depends on SMP && !XIP
default y default y
help help
SMP kernels contain instructions which fail on non-SMP processors. SMP kernels contain instructions which fail on non-SMP processors.
...@@ -1272,6 +1283,7 @@ config HAVE_ARM_SCU ...@@ -1272,6 +1283,7 @@ config HAVE_ARM_SCU
config HAVE_ARM_TWD config HAVE_ARM_TWD
bool bool
depends on SMP depends on SMP
select TICK_ONESHOT
help help
This options enables support for the ARM timer and watchdog unit This options enables support for the ARM timer and watchdog unit
...@@ -1335,7 +1347,7 @@ config HZ ...@@ -1335,7 +1347,7 @@ config HZ
default 100 default 100
config THUMB2_KERNEL config THUMB2_KERNEL
bool "Compile the kernel in Thumb-2 mode" bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
select AEABI select AEABI
select ARM_ASM_UNIFIED select ARM_ASM_UNIFIED
...@@ -1549,6 +1561,7 @@ config SECCOMP ...@@ -1549,6 +1561,7 @@ config SECCOMP
config CC_STACKPROTECTOR config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
depends on EXPERIMENTAL
help help
This option turns on the -fstack-protector GCC feature. This This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on feature puts, at the beginning of functions, a canary value on
...@@ -1745,7 +1758,7 @@ config CPU_FREQ_S3C ...@@ -1745,7 +1758,7 @@ config CPU_FREQ_S3C
Internal configuration node for common cpufreq on Samsung SoC Internal configuration node for common cpufreq on Samsung SoC
config CPU_FREQ_S3C24XX config CPU_FREQ_S3C24XX
bool "CPUfreq driver for Samsung S3C24XX series CPUs" bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
select CPU_FREQ_S3C select CPU_FREQ_S3C
help help
...@@ -1757,7 +1770,7 @@ config CPU_FREQ_S3C24XX ...@@ -1757,7 +1770,7 @@ config CPU_FREQ_S3C24XX
If in doubt, say N. If in doubt, say N.
config CPU_FREQ_S3C24XX_PLL config CPU_FREQ_S3C24XX_PLL
bool "Support CPUfreq changing of PLL frequency" bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
depends on CPU_FREQ_S3C24XX && EXPERIMENTAL depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
help help
Compile in support for changing the PLL frequency from the Compile in support for changing the PLL frequency from the
......
...@@ -31,7 +31,7 @@ config FRAME_POINTER ...@@ -31,7 +31,7 @@ config FRAME_POINTER
reported is severely limited. reported is severely limited.
config ARM_UNWIND config ARM_UNWIND
bool "Enable stack unwinding support" bool "Enable stack unwinding support (EXPERIMENTAL)"
depends on AEABI && EXPERIMENTAL depends on AEABI && EXPERIMENTAL
default y default y
help help
......
...@@ -37,7 +37,3 @@ config SHARP_PARAM ...@@ -37,7 +37,3 @@ config SHARP_PARAM
config SHARP_SCOOP config SHARP_SCOOP
bool bool
config COMMON_CLKDEV
bool
select HAVE_CLK
...@@ -328,7 +328,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, ...@@ -328,7 +328,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
* substitute the safe buffer for the unsafe one. * substitute the safe buffer for the unsafe one.
* (basically move the buffer from an unsafe area to a safe one) * (basically move the buffer from an unsafe area to a safe one)
*/ */
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 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,7 +338,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
return map_single(dev, ptr, size, dir); return map_single(dev, ptr, size, dir);
} }
EXPORT_SYMBOL(dma_map_single); EXPORT_SYMBOL(__dma_map_single);
/* /*
* see if a mapped address was really a "safe" buffer and if so, copy * see if a mapped address was really a "safe" buffer and if so, copy
...@@ -346,7 +346,7 @@ EXPORT_SYMBOL(dma_map_single); ...@@ -346,7 +346,7 @@ EXPORT_SYMBOL(dma_map_single);
* the safe buffer. (basically return things back to the way they * the safe buffer. (basically return things back to the way they
* should be) * should be)
*/ */
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 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,9 +354,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
unmap_single(dev, dma_addr, size, dir); unmap_single(dev, dma_addr, size, dir);
} }
EXPORT_SYMBOL(dma_unmap_single); EXPORT_SYMBOL(__dma_unmap_single);
dma_addr_t dma_map_page(struct device *dev, struct page *page, dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir) unsigned long offset, size_t size, enum dma_data_direction dir)
{ {
dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n", 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,7 +372,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
return map_single(dev, page_address(page) + offset, size, dir); return map_single(dev, page_address(page) + offset, size, dir);
} }
EXPORT_SYMBOL(dma_map_page); EXPORT_SYMBOL(__dma_map_page);
/* /*
* see if a mapped address was really a "safe" buffer and if so, copy * see if a mapped address was really a "safe" buffer and if so, copy
...@@ -380,7 +380,7 @@ EXPORT_SYMBOL(dma_map_page); ...@@ -380,7 +380,7 @@ EXPORT_SYMBOL(dma_map_page);
* the safe buffer. (basically return things back to the way they * the safe buffer. (basically return things back to the way they
* should be) * should be)
*/ */
void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir) enum dma_data_direction dir)
{ {
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 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,7 +388,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
unmap_single(dev, dma_addr, size, dir); unmap_single(dev, dma_addr, size, dir);
} }
EXPORT_SYMBOL(dma_unmap_page); EXPORT_SYMBOL(__dma_unmap_page);
int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
unsigned long off, size_t sz, enum dma_data_direction dir) unsigned long off, size_t sz, enum dma_data_direction dir)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#endif #endif
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/domain.h>
/* /*
* Endian independent macros for shifting bytes within registers. * Endian independent macros for shifting bytes within registers.
...@@ -157,16 +158,24 @@ ...@@ -157,16 +158,24 @@
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define ALT_SMP(instr...) \ #define ALT_SMP(instr...) \
9998: instr 9998: instr
/*
* Note: if you get assembler errors from ALT_UP() when building with
* CONFIG_THUMB2_KERNEL, you almost certainly need to use
* ALT_SMP( W(instr) ... )
*/
#define ALT_UP(instr...) \ #define ALT_UP(instr...) \
.pushsection ".alt.smp.init", "a" ;\ .pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\ .long 9998b ;\
instr ;\ 9997: instr ;\
.if . - 9997b != 4 ;\
.error "ALT_UP() content must assemble to exactly 4 bytes";\
.endif ;\
.popsection .popsection
#define ALT_UP_B(label) \ #define ALT_UP_B(label) \
.equ up_b_offset, label - 9998b ;\ .equ up_b_offset, label - 9998b ;\
.pushsection ".alt.smp.init", "a" ;\ .pushsection ".alt.smp.init", "a" ;\
.long 9998b ;\ .long 9998b ;\
b . + up_b_offset ;\ W(b) . + up_b_offset ;\
.popsection .popsection
#else #else
#define ALT_SMP(instr...) #define ALT_SMP(instr...)
...@@ -177,16 +186,24 @@ ...@@ -177,16 +186,24 @@
/* /*
* SMP data memory barrier * SMP data memory barrier
*/ */
.macro smp_dmb .macro smp_dmb mode
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#if __LINUX_ARM_ARCH__ >= 7 #if __LINUX_ARM_ARCH__ >= 7
.ifeqs "\mode","arm"
ALT_SMP(dmb) ALT_SMP(dmb)
.else
ALT_SMP(W(dmb))
.endif
#elif __LINUX_ARM_ARCH__ == 6 #elif __LINUX_ARM_ARCH__ == 6
ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
#else #else
#error Incompatible SMP platform #error Incompatible SMP platform
#endif #endif
.ifeqs "\mode","arm"
ALT_UP(nop) ALT_UP(nop)
.else
ALT_UP(W(nop))
.endif
#endif #endif
.endm .endm
...@@ -206,12 +223,12 @@ ...@@ -206,12 +223,12 @@
*/ */
#ifdef CONFIG_THUMB2_KERNEL #ifdef CONFIG_THUMB2_KERNEL
.macro usraccoff, instr, reg, ptr, inc, off, cond, abort .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()
9999: 9999:
.if \inc == 1 .if \inc == 1
\instr\cond\()bt \reg, [\ptr, #\off] \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
.elseif \inc == 4 .elseif \inc == 4
\instr\cond\()t \reg, [\ptr, #\off] \instr\cond\()\t\().w \reg, [\ptr, #\off]
.else .else
.error "Unsupported inc macro argument" .error "Unsupported inc macro argument"
.endif .endif
...@@ -246,13 +263,13 @@ ...@@ -246,13 +263,13 @@
#else /* !CONFIG_THUMB2_KERNEL */ #else /* !CONFIG_THUMB2_KERNEL */
.macro usracc, instr, reg, ptr, inc, cond, rept, abort .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()
.rept \rept .rept \rept
9999: 9999:
.if \inc == 1 .if \inc == 1
\instr\cond\()bt \reg, [\ptr], #\inc \instr\cond\()b\()\t \reg, [\ptr], #\inc
.elseif \inc == 4 .elseif \inc == 4
\instr\cond\()t \reg, [\ptr], #\inc \instr\cond\()\t \reg, [\ptr], #\inc
.else .else
.error "Unsupported inc macro argument" .error "Unsupported inc macro argument"
.endif .endif
......
...@@ -23,4 +23,6 @@ ...@@ -23,4 +23,6 @@
#define ARCH_SLAB_MINALIGN 8 #define ARCH_SLAB_MINALIGN 8
#endif #endif
#define __read_mostly __attribute__((__section__(".data..read_mostly")))
#endif #endif
...@@ -12,23 +12,13 @@ ...@@ -12,23 +12,13 @@
#ifndef __ASM_CLKDEV_H #ifndef __ASM_CLKDEV_H
#define __ASM_CLKDEV_H #define __ASM_CLKDEV_H
struct clk; #include <linux/slab.h>
struct device;
struct clk_lookup { #include <mach/clkdev.h>
struct list_head node;
const char *dev_id;
const char *con_id;
struct clk *clk;
};
struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
const char *dev_fmt, ...); {
return kzalloc(size, GFP_KERNEL);
void clkdev_add(struct clk_lookup *cl); }
void clkdev_drop(struct clk_lookup *cl);
void clkdev_add_table(struct clk_lookup *, size_t);
int clk_add_alias(const char *, const char *, char *, struct device *);
#endif #endif
...@@ -5,24 +5,29 @@ ...@@ -5,24 +5,29 @@
#include <linux/mm_types.h> #include <linux/mm_types.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/dma-debug.h>
#include <asm-generic/dma-coherent.h> #include <asm-generic/dma-coherent.h>
#include <asm/memory.h> #include <asm/memory.h>
#ifdef __arch_page_to_dma
#error Please update to __arch_pfn_to_dma
#endif
/* /*
* page_to_dma/dma_to_virt/virt_to_dma are architecture private functions * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
* used internally by the DMA-mapping API to provide DMA addresses. They * functions used internally by the DMA-mapping API to provide DMA
* must not be used by drivers. * addresses. They must not be used by drivers.
*/ */
#ifndef __arch_page_to_dma #ifndef __arch_pfn_to_dma
static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
{ {
return (dma_addr_t)__pfn_to_bus(page_to_pfn(page)); return (dma_addr_t)__pfn_to_bus(pfn);
} }
static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
{ {
return pfn_to_page(__bus_to_pfn(addr)); return __bus_to_pfn(addr);
} }
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) static 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,14 +40,14 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
} }
#else #else
static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
{ {
return __arch_page_to_dma(dev, page); return __arch_pfn_to_dma(dev, pfn);
} }
static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
{ {
return __arch_dma_to_page(dev, addr); return __arch_dma_to_pfn(dev, addr);
} }
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) static 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,13 +298,13 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
/* /*
* The DMA API, implemented by dmabounce.c. See below for descriptions. * The DMA API, implemented by dmabounce.c. See below for descriptions.
*/ */
extern dma_addr_t dma_map_single(struct device *, void *, size_t, extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
enum dma_data_direction); enum dma_data_direction);
extern void dma_unmap_single(struct device *, dma_addr_t, size_t, extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
enum dma_data_direction); enum dma_data_direction);
extern dma_addr_t dma_map_page(struct device *, struct page *, extern dma_addr_t __dma_map_page(struct device *, struct page *,
unsigned long, size_t, enum dma_data_direction); unsigned long, size_t, enum dma_data_direction);
extern void dma_unmap_page(struct device *, dma_addr_t, size_t, extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
enum dma_data_direction); enum dma_data_direction);
/* /*
...@@ -323,6 +328,34 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, ...@@ -323,6 +328,34 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
} }
static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
size_t size, enum dma_data_direction dir)
{
__dma_single_cpu_to_dev(cpu_addr, size, dir);
return virt_to_dma(dev, cpu_addr);
}
static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir)
{
__dma_page_cpu_to_dev(page, offset, size, dir);
return pfn_to_dma(dev, page_to_pfn(page)) + offset;
}
static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
__dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
}
static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
{
__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
handle & ~PAGE_MASK, size, dir);
}
#endif /* CONFIG_DMABOUNCE */
/** /**
* dma_map_single - map a single buffer for streaming DMA * dma_map_single - map a single buffer for streaming DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @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, ...@@ -340,11 +373,16 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
size_t size, enum dma_data_direction dir) size_t size, enum dma_data_direction dir)
{ {
dma_addr_t addr;
BUG_ON(!valid_dma_direction(dir)); BUG_ON(!valid_dma_direction(dir));
__dma_single_cpu_to_dev(cpu_addr, size, dir); addr = __dma_map_single(dev, cpu_addr, size, dir);
debug_dma_map_page(dev, virt_to_page(cpu_addr),
(unsigned long)cpu_addr & ~PAGE_MASK, size,
dir, addr, true);
return virt_to_dma(dev, cpu_addr); return addr;
} }
/** /**
...@@ -364,11 +402,14 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, ...@@ -364,11 +402,14 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir) unsigned long offset, size_t size, enum dma_data_direction dir)
{ {
dma_addr_t addr;
BUG_ON(!valid_dma_direction(dir)); BUG_ON(!valid_dma_direction(dir));
__dma_page_cpu_to_dev(page, offset, size, dir); addr = __dma_map_page(dev, page, offset, size, dir);
debug_dma_map_page(dev, page, offset, size, dir, addr, false);
return page_to_dma(dev, page) + offset; return addr;
} }
/** /**
...@@ -388,7 +429,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, ...@@ -388,7 +429,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir) size_t size, enum dma_data_direction dir)
{ {
__dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); debug_dma_unmap_page(dev, handle, size, dir, true);
__dma_unmap_single(dev, handle, size, dir);
} }
/** /**
...@@ -408,10 +450,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, ...@@ -408,10 +450,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir) size_t size, enum dma_data_direction dir)
{ {
__dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK, debug_dma_unmap_page(dev, handle, size, dir, false);
size, dir); __dma_unmap_page(dev, handle, size, dir);
} }
#endif /* CONFIG_DMABOUNCE */
/** /**
* dma_sync_single_range_for_cpu * dma_sync_single_range_for_cpu
...@@ -437,6 +478,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, ...@@ -437,6 +478,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
{ {
BUG_ON(!valid_dma_direction(dir)); BUG_ON(!valid_dma_direction(dir));
debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
return; return;
...@@ -449,6 +492,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, ...@@ -449,6 +492,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
{ {
BUG_ON(!valid_dma_direction(dir)); BUG_ON(!valid_dma_direction(dir));
debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
return; return;
......
...@@ -45,13 +45,17 @@ ...@@ -45,13 +45,17 @@
*/ */
#define DOMAIN_NOACCESS 0 #define DOMAIN_NOACCESS 0
#define DOMAIN_CLIENT 1 #define DOMAIN_CLIENT 1
#ifdef CONFIG_CPU_USE_DOMAINS
#define DOMAIN_MANAGER 3 #define DOMAIN_MANAGER 3
#else
#define DOMAIN_MANAGER 1
#endif
#define domain_val(dom,type) ((type) << (2*(dom))) #define domain_val(dom,type) ((type) << (2*(dom)))
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#ifdef CONFIG_MMU #ifdef CONFIG_CPU_USE_DOMAINS
#define set_domain(x) \ #define set_domain(x) \
do { \ do { \
__asm__ __volatile__( \ __asm__ __volatile__( \
...@@ -74,5 +78,28 @@ ...@@ -74,5 +78,28 @@
#define modify_domain(dom,type) do { } while (0) #define modify_domain(dom,type) do { } while (0)
#endif #endif
/*
* Generate the T (user) versions of the LDR/STR and related
* instructions (inline assembly)
*/
#ifdef CONFIG_CPU_USE_DOMAINS
#define T(instr) #instr "t"
#else
#define T(instr) #instr
#endif #endif
#endif /* !__ASSEMBLY__ */
#else /* __ASSEMBLY__ */
/*
* Generate the T (user) versions of the LDR/STR and related
* instructions
*/
#ifdef CONFIG_CPU_USE_DOMAINS
#define T(instr) instr ## t
#else
#define T(instr) instr
#endif
#endif /* __ASSEMBLY__ */
#endif /* !__ASM_PROC_DOMAIN_H */
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro arch_irq_handler_default
get_irqnr_preamble r5, lr
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrne lr, BSYM(1b)
bne asm_do_IRQ
#ifdef CONFIG_SMP
/*
* XXX
*
* this macro assumes that irqstat (r6) and base (r5) are
* preserved from get_irqnr_and_base above
*/
ALT_SMP(test_for_ipi r0, r6, r5, lr)
ALT_UP_B(9997f)
movne r1, sp
adrne lr, BSYM(1b)
bne do_IPI
#ifdef CONFIG_LOCAL_TIMERS
test_for_ltirq r0, r6, r5, lr
movne r0, sp
adrne lr, BSYM(1b)
bne do_local_timer
#endif
#endif
9997:
.endm
.macro arch_irq_handler, symbol_name
.align 5
.global \symbol_name
\symbol_name:
mov r4, lr
arch_irq_handler_default
mov pc, r4
.endm
...@@ -13,12 +13,13 @@ ...@@ -13,12 +13,13 @@
#include <linux/preempt.h> #include <linux/preempt.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/domain.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: ldrt %1, [%2]\n" \ "1: " T(ldr) " %1, [%2]\n" \
" " insn "\n" \ " " insn "\n" \
"2: strt %0, [%2]\n" \ "2: " T(str) " %0, [%2]\n" \
" mov %0, #0\n" \ " mov %0, #0\n" \
"3:\n" \ "3:\n" \
" .pushsection __ex_table,\"a\"\n" \ " .pushsection __ex_table,\"a\"\n" \
...@@ -97,10 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) ...@@ -97,10 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
pagefault_disable(); /* implies preempt_disable() */ pagefault_disable(); /* implies preempt_disable() */
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
"1: ldrt %0, [%3]\n" "1: " T(ldr) " %0, [%3]\n"
" teq %0, %1\n" " teq %0, %1\n"
" it eq @ explicit IT needed for the 2b label\n" " it eq @ explicit IT needed for the 2b label\n"
"2: streqt %2, [%3]\n" "2: " T(streq) " %2, [%3]\n"
"3:\n" "3:\n"
" .pushsection __ex_table,\"a\"\n" " .pushsection __ex_table,\"a\"\n"
" .align 3\n" " .align 3\n"
......
...@@ -5,13 +5,31 @@ ...@@ -5,13 +5,31 @@
#include <linux/threads.h> #include <linux/threads.h>
#include <asm/irq.h> #include <asm/irq.h>
#define NR_IPI 5
typedef struct { typedef struct {
unsigned int __softirq_pending; unsigned int __softirq_pending;
#ifdef CONFIG_LOCAL_TIMERS
unsigned int local_timer_irqs; unsigned int local_timer_irqs;
#endif
#ifdef CONFIG_SMP
unsigned int ipi_irqs[NR_IPI];
#endif
} ____cacheline_aligned irq_cpustat_t; } ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++
#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member)
#ifdef CONFIG_SMP
u64 smp_irq_stat_cpu(unsigned int cpu);
#else
#define smp_irq_stat_cpu(cpu) 0
#endif
#define arch_irq_stat_cpu smp_irq_stat_cpu
#if NR_IRQS > 512 #if NR_IRQS > 512
#define HARDIRQ_BITS 10 #define HARDIRQ_BITS 10
#elif NR_IRQS > 256 #elif NR_IRQS > 256
......
...@@ -30,7 +30,6 @@ asmlinkage void do_local_timer(struct pt_regs *); ...@@ -30,7 +30,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
#include "smp_twd.h" #include "smp_twd.h"
#define local_timer_ack() twd_timer_ack() #define local_timer_ack() twd_timer_ack()
#define local_timer_stop() twd_timer_stop()
#else #else
...@@ -40,11 +39,6 @@ asmlinkage void do_local_timer(struct pt_regs *); ...@@ -40,11 +39,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
*/ */
int local_timer_ack(void); int local_timer_ack(void);
/*
* Stop a local timer interrupt.
*/
void local_timer_stop(void);
#endif #endif
/* /*
...@@ -52,12 +46,6 @@ void local_timer_stop(void); ...@@ -52,12 +46,6 @@ void local_timer_stop(void);
*/ */
void local_timer_setup(struct clock_event_device *); void local_timer_setup(struct clock_event_device *);
#else
static inline void local_timer_stop(void)
{
}
#endif #endif
#endif #endif
...@@ -37,11 +37,20 @@ struct machine_desc { ...@@ -37,11 +37,20 @@ struct machine_desc {
struct meminfo *); struct meminfo *);
void (*reserve)(void);/* reserve mem blocks */ void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */ void (*map_io)(void);/* IO mapping function */
void (*init_early)(void);
void (*init_irq)(void); void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */ struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void); void (*init_machine)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
void (*handle_irq)(struct pt_regs *);
#endif
}; };
/*
* Current machine - only accessible during boot.
*/
extern struct machine_desc *machine_desc;
/* /*
* Set of macros to define architecture features. This is built into * Set of macros to define architecture features. This is built into
* a table by the linker. * a table by the linker.
......
...@@ -17,10 +17,12 @@ struct seq_file; ...@@ -17,10 +17,12 @@ struct seq_file;
/* /*
* This is internal. Do not use it. * This is internal. Do not use it.
*/ */
extern unsigned int arch_nr_irqs;
extern void (*init_arch_irq)(void);
extern void init_FIQ(void); extern void init_FIQ(void);
extern int show_fiq_list(struct seq_file *, void *); extern int show_fiq_list(struct seq_file *, int);
#ifdef CONFIG_MULTI_IRQ_HANDLER
extern void (*handle_arch_irq)(struct pt_regs *);
#endif
/* /*
* This is for easy migration, but should be changed in the source * This is for easy migration, but should be changed in the source
......
...@@ -43,7 +43,6 @@ struct sys_timer { ...@@ -43,7 +43,6 @@ struct sys_timer {
#endif #endif
}; };
extern struct sys_timer *system_timer;
extern void timer_tick(void); extern void timer_tick(void);
#endif #endif
...@@ -33,27 +33,23 @@ struct seq_file; ...@@ -33,27 +33,23 @@ struct seq_file;
/* /*
* generate IPI list text * generate IPI list text
*/ */
extern void show_ipi_list(struct seq_file *p); extern void show_ipi_list(struct seq_file *, int);
/* /*
* Called from assembly code, this handles an IPI. * Called from assembly code, this handles an IPI.
*/ */
asmlinkage void do_IPI(struct pt_regs *regs); asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
/* /*
* Setup the set of possible CPUs (via set_cpu_possible) * Setup the set of possible CPUs (via set_cpu_possible)
*/ */
extern void smp_init_cpus(void); extern void smp_init_cpus(void);
/*
* Move global data into per-processor storage.
*/
extern void smp_store_cpu_info(unsigned int cpuid);
/* /*
* Raise an IPI cross call on CPUs in callmap. * Raise an IPI cross call on CPUs in callmap.
*/ */
extern void smp_cross_call(const struct cpumask *mask); extern void smp_cross_call(const struct cpumask *mask, int ipi);
/* /*
* Boot a secondary CPU, and assign it the specified idle task. * Boot a secondary CPU, and assign it the specified idle task.
...@@ -72,6 +68,11 @@ asmlinkage void secondary_start_kernel(void); ...@@ -72,6 +68,11 @@ asmlinkage void secondary_start_kernel(void);
*/ */
extern void platform_secondary_init(unsigned int cpu); extern void platform_secondary_init(unsigned int cpu);
/*
* Initialize cpu_possible map, and enable coherency
*/
extern void platform_smp_prepare_cpus(unsigned int);
/* /*
* Initial data for bringing up a secondary CPU. * Initial data for bringing up a secondary CPU.
*/ */
...@@ -97,6 +98,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); ...@@ -97,6 +98,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
/* /*
* show local interrupt info * show local interrupt info
*/ */
extern void show_local_irqs(struct seq_file *); extern void show_local_irqs(struct seq_file *, int);
#endif /* ifndef __ASM_ARM_SMP_H */ #endif /* ifndef __ASM_ARM_SMP_H */
#ifndef ASMARM_SMP_MIDR_H
#define ASMARM_SMP_MIDR_H
#define hard_smp_processor_id() \
({ \
unsigned int cpunum; \
__asm__("\n" \
"1: mrc p15, 0, %0, c0, c0, 5\n" \
" .pushsection \".alt.smp.init\", \"a\"\n"\
" .long 1b\n" \
" mov %0, #0\n" \
" .popsection" \
: "=r" (cpunum)); \
cpunum &= 0x0F; \
})
#endif
...@@ -22,7 +22,6 @@ struct clock_event_device; ...@@ -22,7 +22,6 @@ struct clock_event_device;
extern void __iomem *twd_base; extern void __iomem *twd_base;
void twd_timer_stop(void);
int twd_timer_ack(void); int twd_timer_ack(void);
void twd_timer_setup(struct clock_event_device *); void twd_timer_setup(struct clock_event_device *);
......
...@@ -124,6 +124,13 @@ extern unsigned int user_debug; ...@@ -124,6 +124,13 @@ extern unsigned int user_debug;
#define vectors_high() (0) #define vectors_high() (0)
#endif #endif
#if __LINUX_ARM_ARCH__ >= 7 || \
(__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
#define sev() __asm__ __volatile__ ("sev" : : : "memory")
#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
#endif
#if __LINUX_ARM_ARCH__ >= 7 #if __LINUX_ARM_ARCH__ >= 7
#define isb() __asm__ __volatile__ ("isb" : : : "memory") #define isb() __asm__ __volatile__ ("isb" : : : "memory")
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") #define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
......
...@@ -46,4 +46,6 @@ static inline int in_exception_text(unsigned long ptr) ...@@ -46,4 +46,6 @@ static inline int in_exception_text(unsigned long ptr)
extern void __init early_trap_init(void); extern void __init early_trap_init(void);
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
extern void *vectors_page;
#endif #endif
...@@ -227,7 +227,7 @@ do { \ ...@@ -227,7 +227,7 @@ do { \
#define __get_user_asm_byte(x,addr,err) \ #define __get_user_asm_byte(x,addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: ldrbt %1,[%2]\n" \ "1: " T(ldrb) " %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
" .pushsection .fixup,\"ax\"\n" \ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
...@@ -263,7 +263,7 @@ do { \ ...@@ -263,7 +263,7 @@ do { \
#define __get_user_asm_word(x,addr,err) \ #define __get_user_asm_word(x,addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: ldrt %1,[%2]\n" \ "1: " T(ldr) " %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
" .pushsection .fixup,\"ax\"\n" \ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
...@@ -308,7 +308,7 @@ do { \ ...@@ -308,7 +308,7 @@ do { \
#define __put_user_asm_byte(x,__pu_addr,err) \ #define __put_user_asm_byte(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strbt %1,[%2]\n" \ "1: " T(strb) " %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
" .pushsection .fixup,\"ax\"\n" \ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
...@@ -341,7 +341,7 @@ do { \ ...@@ -341,7 +341,7 @@ do { \
#define __put_user_asm_word(x,__pu_addr,err) \ #define __put_user_asm_word(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strt %1,[%2]\n" \ "1: " T(str) " %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
" .pushsection .fixup,\"ax\"\n" \ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
...@@ -366,10 +366,10 @@ do { \ ...@@ -366,10 +366,10 @@ do { \
#define __put_user_asm_dword(x,__pu_addr,err) \ #define __put_user_asm_dword(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \ ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \
ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \ ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \
THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \ THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \
THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \ THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \
"3:\n" \ "3:\n" \
" .pushsection .fixup,\"ax\"\n" \ " .pushsection .fixup,\"ax\"\n" \
" .align 2\n" \ " .align 2\n" \
......
...@@ -30,7 +30,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o ...@@ -30,7 +30,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o obj-$(CONFIG_PCI) += bios32.o isa.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
...@@ -44,6 +44,8 @@ obj-$(CONFIG_KGDB) += kgdb.o ...@@ -44,6 +44,8 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o obj-$(CONFIG_HAVE_TCM) += tcm.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
......
...@@ -25,42 +25,22 @@ ...@@ -25,42 +25,22 @@
#include <asm/tls.h> #include <asm/tls.h>
#include "entry-header.S" #include "entry-header.S"
#include <asm/entry-macro-multi.S>
/* /*
* Interrupt handling. Preserves r7, r8, r9 * Interrupt handling. Preserves r7, r8, r9
*/ */
.macro irq_handler .macro irq_handler
get_irqnr_preamble r5, lr #ifdef CONFIG_MULTI_IRQ_HANDLER
1: get_irqnr_and_base r0, r6, r5, lr ldr r5, =handle_arch_irq
movne r1, sp mov r0, sp
@ ldr r5, [r5]
@ routine called with r0 = irq number, r1 = struct pt_regs * adr lr, BSYM(9997f)
@ teq r5, #0
adrne lr, BSYM(1b) movne pc, r5
bne asm_do_IRQ
#ifdef CONFIG_SMP
/*
* XXX
*
* this macro assumes that irqstat (r6) and base (r5) are
* preserved from get_irqnr_and_base above
*/
ALT_SMP(test_for_ipi r0, r6, r5, lr)
ALT_UP_B(9997f)
movne r0, sp
adrne lr, BSYM(1b)
bne do_IPI
#ifdef CONFIG_LOCAL_TIMERS
test_for_ltirq r0, r6, r5, lr
movne r0, sp
adrne lr, BSYM(1b)
bne do_local_timer
#endif #endif
arch_irq_handler_default
9997: 9997:
#endif
.endm .endm
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
...@@ -735,7 +715,7 @@ ENTRY(__switch_to) ...@@ -735,7 +715,7 @@ ENTRY(__switch_to)
THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
THUMB( str sp, [ip], #4 ) THUMB( str sp, [ip], #4 )
THUMB( str lr, [ip], #4 ) THUMB( str lr, [ip], #4 )
#ifdef CONFIG_MMU #ifdef CONFIG_CPU_USE_DOMAINS
ldr r6, [r2, #TI_CPU_DOMAIN] ldr r6, [r2, #TI_CPU_DOMAIN]
#endif #endif
set_tls r3, r4, r5 set_tls r3, r4, r5
...@@ -744,7 +724,7 @@ ENTRY(__switch_to) ...@@ -744,7 +724,7 @@ ENTRY(__switch_to)
ldr r8, =__stack_chk_guard ldr r8, =__stack_chk_guard
ldr r7, [r7, #TSK_STACK_CANARY] ldr r7, [r7, #TSK_STACK_CANARY]
#endif #endif
#ifdef CONFIG_MMU #ifdef CONFIG_CPU_USE_DOMAINS
mcr p15, 0, r6, c3, c0, 0 @ Set domain register mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif #endif
mov r5, r0 mov r5, r0
...@@ -842,7 +822,7 @@ __kuser_helper_start: ...@@ -842,7 +822,7 @@ __kuser_helper_start:
*/ */
__kuser_memory_barrier: @ 0xffff0fa0 __kuser_memory_barrier: @ 0xffff0fa0
smp_dmb smp_dmb arm
usr_ret lr usr_ret lr
.align 5 .align 5
...@@ -959,7 +939,7 @@ kuser_cmpxchg_fixup: ...@@ -959,7 +939,7 @@ kuser_cmpxchg_fixup:
#else #else
smp_dmb smp_dmb arm
1: ldrex r3, [r2] 1: ldrex r3, [r2]
subs r3, r3, r0 subs r3, r3, r0
strexeq r3, r1, [r2] strexeq r3, r1, [r2]
...@@ -1245,3 +1225,9 @@ cr_alignment: ...@@ -1245,3 +1225,9 @@ cr_alignment:
.space 4 .space 4
cr_no_alignment: cr_no_alignment:
.space 4 .space 4
#ifdef CONFIG_MULTI_IRQ_HANDLER
.globl handle_arch_irq
handle_arch_irq:
.space 4
#endif
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <asm/fiq.h> #include <asm/fiq.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/traps.h>
static unsigned long no_fiq_insn; static unsigned long no_fiq_insn;
...@@ -67,17 +68,22 @@ static struct fiq_handler default_owner = { ...@@ -67,17 +68,22 @@ static struct fiq_handler default_owner = {
static struct fiq_handler *current_fiq = &default_owner; static struct fiq_handler *current_fiq = &default_owner;
int show_fiq_list(struct seq_file *p, void *v) int show_fiq_list(struct seq_file *p, int prec)
{ {
if (current_fiq != &default_owner) if (current_fiq != &default_owner)
seq_printf(p, "FIQ: %s\n", current_fiq->name); seq_printf(p, "%*s: %s\n", prec, "FIQ",
current_fiq->name);
return 0; return 0;
} }
void set_fiq_handler(void *start, unsigned int length) void set_fiq_handler(void *start, unsigned int length)
{ {
#if defined(CONFIG_CPU_USE_DOMAINS)
memcpy((void *)0xffff001c, start, length); memcpy((void *)0xffff001c, start, length);
#else
memcpy(vectors_page + 0x1c, start, length);
#endif
flush_icache_range(0xffff001c, 0xffff001c + length); flush_icache_range(0xffff001c, 0xffff001c + length);
if (!vectors_high()) if (!vectors_high())
flush_icache_range(0x1c, 0x1c + length); flush_icache_range(0x1c, 0x1c + length);
......
...@@ -91,6 +91,11 @@ ENTRY(stext) ...@@ -91,6 +91,11 @@ ENTRY(stext)
movs r8, r5 @ invalid machine (r5=0)? movs r8, r5 @ invalid machine (r5=0)?
THUMB( it eq ) @ force fixup-able long branch encoding THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_a @ yes, error 'a' beq __error_a @ yes, error 'a'
/*
* r1 = machine no, r2 = atags,
* r8 = machinfo, r9 = cpuid, r10 = procinfo
*/
bl __vet_atags bl __vet_atags
#ifdef CONFIG_SMP_ON_UP #ifdef CONFIG_SMP_ON_UP
bl __fixup_smp bl __fixup_smp
...@@ -387,19 +392,19 @@ ENDPROC(__turn_mmu_on) ...@@ -387,19 +392,19 @@ ENDPROC(__turn_mmu_on)
#ifdef CONFIG_SMP_ON_UP #ifdef CONFIG_SMP_ON_UP
__fixup_smp: __fixup_smp:
mov r7, #0x00070000 mov r4, #0x00070000
orr r6, r7, #0xff000000 @ mask 0xff070000 orr r3, r4, #0xff000000 @ mask 0xff070000
orr r7, r7, #0x41000000 @ val 0x41070000 orr r4, r4, #0x41000000 @ val 0x41070000
and r0, r9, r6 and r0, r9, r3
teq r0, r7 @ ARM CPU and ARMv6/v7? teq r0, r4 @ ARM CPU and ARMv6/v7?
bne __fixup_smp_on_up @ no, assume UP bne __fixup_smp_on_up @ no, assume UP
orr r6, r6, #0x0000ff00 orr r3, r3, #0x0000ff00
orr r6, r6, #0x000000f0 @ mask 0xff07fff0 orr r3, r3, #0x000000f0 @ mask 0xff07fff0
orr r7, r7, #0x0000b000 orr r4, r4, #0x0000b000
orr r7, r7, #0x00000020 @ val 0x4107b020 orr r4, r4, #0x00000020 @ val 0x4107b020
and r0, r9, r6 and r0, r9, r3
teq r0, r7 @ ARM 11MPCore? teq r0, r4 @ ARM 11MPCore?
moveq pc, lr @ yes, assume SMP moveq pc, lr @ yes, assume SMP
mrc p15, 0, r0, c0, c0, 5 @ read MPIDR mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
...@@ -408,15 +413,22 @@ __fixup_smp: ...@@ -408,15 +413,22 @@ __fixup_smp:
__fixup_smp_on_up: __fixup_smp_on_up:
adr r0, 1f adr r0, 1f
ldmia r0, {r3, r6, r7} ldmia r0, {r3 - r5}
sub r3, r0, r3 sub r3, r0, r3
add r6, r6, r3 add r4, r4, r3
add r7, r7, r3 add r5, r5, r3
2: cmp r6, r7 2: cmp r4, r5
ldmia r6!, {r0, r4} movhs pc, lr
strlo r4, [r0, r3] ldmia r4!, {r0, r6}
blo 2b ARM( str r6, [r0, r3] )
mov pc, lr THUMB( add r0, r0, r3 )
#ifdef __ARMEB__
THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
#endif
THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
THUMB( strh r6, [r0] )
b 2b
ENDPROC(__fixup_smp) ENDPROC(__fixup_smp)
.align .align
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
...@@ -48,8 +49,6 @@ ...@@ -48,8 +49,6 @@
#define irq_finish(irq) do { } while (0) #define irq_finish(irq) do { } while (0)
#endif #endif
unsigned int arch_nr_irqs;
void (*init_arch_irq)(void) __initdata = NULL;
unsigned long irq_err_count; unsigned long irq_err_count;
int show_interrupts(struct seq_file *p, void *v) int show_interrupts(struct seq_file *p, void *v)
...@@ -58,11 +57,20 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -58,11 +57,20 @@ int show_interrupts(struct seq_file *p, void *v)
struct irq_desc *desc; struct irq_desc *desc;
struct irqaction * action; struct irqaction * action;
unsigned long flags; unsigned long flags;
int prec, n;
for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
n *= 10;
#ifdef CONFIG_SMP
if (prec < 4)
prec = 4;
#endif
if (i == 0) { if (i == 0) {
char cpuname[12]; char cpuname[12];
seq_printf(p, " "); seq_printf(p, "%*s ", prec, "");
for_each_present_cpu(cpu) { for_each_present_cpu(cpu) {
sprintf(cpuname, "CPU%d", cpu); sprintf(cpuname, "CPU%d", cpu);
seq_printf(p, " %10s", cpuname); seq_printf(p, " %10s", cpuname);
...@@ -77,7 +85,7 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -77,7 +85,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (!action) if (!action)
goto unlock; goto unlock;
seq_printf(p, "%3d: ", i); seq_printf(p, "%*d: ", prec, i);
for_each_present_cpu(cpu) for_each_present_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
seq_printf(p, " %10s", desc->chip->name ? : "-"); seq_printf(p, " %10s", desc->chip->name ? : "-");
...@@ -90,13 +98,15 @@ int show_interrupts(struct seq_file *p, void *v) ...@@ -90,13 +98,15 @@ int show_interrupts(struct seq_file *p, void *v)
raw_spin_unlock_irqrestore(&desc->lock, flags); raw_spin_unlock_irqrestore(&desc->lock, flags);
} else if (i == nr_irqs) { } else if (i == nr_irqs) {
#ifdef CONFIG_FIQ #ifdef CONFIG_FIQ
show_fiq_list(p, v); show_fiq_list(p, prec);
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
show_ipi_list(p); show_ipi_list(p, prec);
show_local_irqs(p); #endif
#ifdef CONFIG_LOCAL_TIMERS
show_local_irqs(p, prec);
#endif #endif
seq_printf(p, "Err: %10lu\n", irq_err_count); seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
} }
return 0; return 0;
} }
...@@ -156,13 +166,13 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) ...@@ -156,13 +166,13 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
void __init init_IRQ(void) void __init init_IRQ(void)
{ {
init_arch_irq(); machine_desc->init_irq();
} }
#ifdef CONFIG_SPARSE_IRQ #ifdef CONFIG_SPARSE_IRQ
int __init arch_probe_nr_irqs(void) int __init arch_probe_nr_irqs(void)
{ {
nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS; nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
return nr_irqs; return nr_irqs;
} }
#endif #endif
......
...@@ -75,9 +75,9 @@ extern void reboot_setup(char *str); ...@@ -75,9 +75,9 @@ extern void reboot_setup(char *str);
unsigned int processor_id; unsigned int processor_id;
EXPORT_SYMBOL(processor_id); EXPORT_SYMBOL(processor_id);
unsigned int __machine_arch_type; unsigned int __machine_arch_type __read_mostly;
EXPORT_SYMBOL(__machine_arch_type); EXPORT_SYMBOL(__machine_arch_type);
unsigned int cacheid; unsigned int cacheid __read_mostly;
EXPORT_SYMBOL(cacheid); EXPORT_SYMBOL(cacheid);
unsigned int __atags_pointer __initdata; unsigned int __atags_pointer __initdata;
...@@ -91,24 +91,24 @@ EXPORT_SYMBOL(system_serial_low); ...@@ -91,24 +91,24 @@ EXPORT_SYMBOL(system_serial_low);
unsigned int system_serial_high; unsigned int system_serial_high;
EXPORT_SYMBOL(system_serial_high); EXPORT_SYMBOL(system_serial_high);
unsigned int elf_hwcap; unsigned int elf_hwcap __read_mostly;
EXPORT_SYMBOL(elf_hwcap); EXPORT_SYMBOL(elf_hwcap);
#ifdef MULTI_CPU #ifdef MULTI_CPU
struct processor processor; struct processor processor __read_mostly;
#endif #endif
#ifdef MULTI_TLB #ifdef MULTI_TLB
struct cpu_tlb_fns cpu_tlb; struct cpu_tlb_fns cpu_tlb __read_mostly;
#endif #endif
#ifdef MULTI_USER #ifdef MULTI_USER
struct cpu_user_fns cpu_user; struct cpu_user_fns cpu_user __read_mostly;
#endif #endif
#ifdef MULTI_CACHE #ifdef MULTI_CACHE
struct cpu_cache_fns cpu_cache; struct cpu_cache_fns cpu_cache __read_mostly;
#endif #endif
#ifdef CONFIG_OUTER_CACHE #ifdef CONFIG_OUTER_CACHE
struct outer_cache_fns outer_cache; struct outer_cache_fns outer_cache __read_mostly;
EXPORT_SYMBOL(outer_cache); EXPORT_SYMBOL(outer_cache);
#endif #endif
...@@ -126,6 +126,7 @@ EXPORT_SYMBOL(elf_platform); ...@@ -126,6 +126,7 @@ EXPORT_SYMBOL(elf_platform);
static const char *cpu_name; static const char *cpu_name;
static const char *machine_name; static const char *machine_name;
static char __initdata cmd_line[COMMAND_LINE_SIZE]; static char __initdata cmd_line[COMMAND_LINE_SIZE];
struct machine_desc *machine_desc __initdata;
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
...@@ -708,13 +709,11 @@ static struct init_tags { ...@@ -708,13 +709,11 @@ static struct init_tags {
{ 0, ATAG_NONE } { 0, ATAG_NONE }
}; };
static void (*init_machine)(void) __initdata;
static int __init customize_machine(void) static int __init customize_machine(void)
{ {
/* customizes platform devices, or adds new ones */ /* customizes platform devices, or adds new ones */
if (init_machine) if (machine_desc->init_machine)
init_machine(); machine_desc->init_machine();
return 0; return 0;
} }
arch_initcall(customize_machine); arch_initcall(customize_machine);
...@@ -809,6 +808,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -809,6 +808,7 @@ void __init setup_arch(char **cmdline_p)
setup_processor(); setup_processor();
mdesc = setup_machine(machine_arch_type); mdesc = setup_machine(machine_arch_type);
machine_desc = mdesc;
machine_name = mdesc->name; machine_name = mdesc->name;
if (mdesc->soft_reboot) if (mdesc->soft_reboot)
...@@ -868,13 +868,9 @@ void __init setup_arch(char **cmdline_p) ...@@ -868,13 +868,9 @@ void __init setup_arch(char **cmdline_p)
cpu_init(); cpu_init();
tcm_init(); tcm_init();
/* #ifdef CONFIG_MULTI_IRQ_HANDLER
* Set up various architecture-specific pointers handle_arch_irq = mdesc->handle_irq;
*/ #endif
arch_nr_irqs = mdesc->nr_irqs;
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT #ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE) #if defined(CONFIG_VGA_CONSOLE)
...@@ -884,6 +880,9 @@ void __init setup_arch(char **cmdline_p) ...@@ -884,6 +880,9 @@ void __init setup_arch(char **cmdline_p)
#endif #endif
#endif #endif
early_trap_init(); early_trap_init();
if (mdesc->init_early)
mdesc->init_early();
} }
......
This diff is collapsed.
/*
* linux/arch/arm/kernel/smp_tlb.c
*
* Copyright (C) 2002 ARM Limited, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/preempt.h>
#include <linux/smp.h>
#include <asm/smp_plat.h>
#include <asm/tlbflush.h>
static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
const struct cpumask *mask)
{
preempt_disable();
smp_call_function_many(mask, func, info, wait);
if (cpumask_test_cpu(smp_processor_id(), mask))
func(info);
preempt_enable();
}
/**********************************************************************/
/*
* TLB operations
*/
struct tlb_args {
struct vm_area_struct *ta_vma;
unsigned long ta_start;
unsigned long ta_end;
};
static inline void ipi_flush_tlb_all(void *ignored)
{
local_flush_tlb_all();
}
static inline void ipi_flush_tlb_mm(void *arg)
{
struct mm_struct *mm = (struct mm_struct *)arg;
local_flush_tlb_mm(mm);
}
static inline void ipi_flush_tlb_page(void *arg)
{
struct tlb_args *ta = (struct tlb_args *)arg;
local_flush_tlb_page(ta->ta_vma, ta->ta_start);
}
static inline void ipi_flush_tlb_kernel_page(void *arg)
{
struct tlb_args *ta = (struct tlb_args *)arg;
local_flush_tlb_kernel_page(ta->ta_start);
}
static inline void ipi_flush_tlb_range(void *arg)
{
struct tlb_args *ta = (struct tlb_args *)arg;
local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
}
static inline void ipi_flush_tlb_kernel_range(void *arg)
{
struct tlb_args *ta = (struct tlb_args *)arg;
local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
}
void flush_tlb_all(void)
{
if (tlb_ops_need_broadcast())
on_each_cpu(ipi_flush_tlb_all, NULL, 1);
else
local_flush_tlb_all();
}
void flush_tlb_mm(struct mm_struct *mm)
{
if (tlb_ops_need_broadcast())
on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
else
local_flush_tlb_mm(mm);
}
void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
{
if (tlb_ops_need_broadcast()) {
struct tlb_args ta;
ta.ta_vma = vma;
ta.ta_start = uaddr;
on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
} else
local_flush_tlb_page(vma, uaddr);
}
void flush_tlb_kernel_page(unsigned long kaddr)
{
if (tlb_ops_need_broadcast()) {
struct tlb_args ta;
ta.ta_start = kaddr;
on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
} else
local_flush_tlb_kernel_page(kaddr);
}
void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
if (tlb_ops_need_broadcast()) {
struct tlb_args ta;
ta.ta_vma = vma;
ta.ta_start = start;
ta.ta_end = end;
on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
} else
local_flush_tlb_range(vma, start, end);
}
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
if (tlb_ops_need_broadcast()) {
struct tlb_args ta;
ta.ta_start = start;
ta.ta_end = end;
on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
} else
local_flush_tlb_kernel_range(start, end);
}
...@@ -145,13 +145,3 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) ...@@ -145,13 +145,3 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clockevents_register_device(clk); clockevents_register_device(clk);
} }
#ifdef CONFIG_HOTPLUG_CPU
/*
* take a local timer down
*/
void twd_timer_stop(void)
{
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
}
#endif
/*
* linux/arch/arm/kernel/swp_emulate.c
*
* Copyright (C) 2009 ARM Limited
* __user_* functions adapted from include/asm/uaccess.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Implements emulation of the SWP/SWPB instructions using load-exclusive and
* store-exclusive for processors that have them disabled (or future ones that
* might not implement them).
*
* Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
* Where: Rt = destination
* Rt2 = source
* Rn = address
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/perf_event.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
/*
* Error-checking SWP macros implemented using ldrex{b}/strex{b}
*/
#define __user_swpX_asm(data, addr, res, temp, B) \
__asm__ __volatile__( \
" mov %2, %1\n" \
"0: ldrex"B" %1, [%3]\n" \
"1: strex"B" %0, %2, [%3]\n" \
" cmp %0, #0\n" \
" movne %0, %4\n" \
"2:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
"3: mov %0, %5\n" \
" b 2b\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 0b, 3b\n" \
" .long 1b, 3b\n" \
" .previous" \
: "=&r" (res), "+r" (data), "=&r" (temp) \
: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
: "cc", "memory")
#define __user_swp_asm(data, addr, res, temp) \
__user_swpX_asm(data, addr, res, temp, "")
#define __user_swpb_asm(data, addr, res, temp) \
__user_swpX_asm(data, addr, res, temp, "b")
/*
* Macros/defines for extracting register numbers from instruction.
*/
#define EXTRACT_REG_NUM(instruction, offset) \
(((instruction) & (0xf << (offset))) >> (offset))
#define RN_OFFSET 16
#define RT_OFFSET 12
#define RT2_OFFSET 0
/*
* Bit 22 of the instruction encoding distinguishes between
* the SWP and SWPB variants (bit set means SWPB).
*/
#define TYPE_SWPB (1 << 22)
static unsigned long swpcounter;
static unsigned long swpbcounter;
static unsigned long abtcounter;
static pid_t previous_pid;
#ifdef CONFIG_PROC_FS
static int proc_read_status(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
char *p = page;
int len;
p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
if (previous_pid != 0)
p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
len = (p - page) - off;
if (len < 0)
len = 0;
*eof = (len <= count) ? 1 : 0;
*start = page + off;
return len;
}
#endif
/*
* Set up process info to signal segmentation fault - called on access error.
*/
static void set_segfault(struct pt_regs *regs, unsigned long addr)
{
siginfo_t info;
if (find_vma(current->mm, addr) == NULL)
info.si_code = SEGV_MAPERR;
else
info.si_code = SEGV_ACCERR;
info.si_signo = SIGSEGV;
info.si_errno = 0;
info.si_addr = (void *) instruction_pointer(regs);
pr_debug("SWP{B} emulation: access caused memory abort!\n");
arm_notify_die("Illegal memory access", regs, &info, 0, 0);
abtcounter++;
}
static int emulate_swpX(unsigned int address, unsigned int *data,
unsigned int type)
{
unsigned int res = 0;
if ((type != TYPE_SWPB) && (address & 0x3)) {
/* SWP to unaligned address not permitted */
pr_debug("SWP instruction on unaligned pointer!\n");
return -EFAULT;
}
while (1) {
unsigned long temp;
/*
* Barrier required between accessing protected resource and
* releasing a lock for it. Legacy code might not have done
* this, and we cannot determine that this is not the case
* being emulated, so insert always.
*/
smp_mb();
if (type == TYPE_SWPB)
__user_swpb_asm(*data, address, res, temp);
else
__user_swp_asm(*data, address, res, temp);
if (likely(res != -EAGAIN) || signal_pending(current))
break;
cond_resched();
}
if (res == 0) {
/*
* Barrier also required between aquiring a lock for a
* protected resource and accessing the resource. Inserted for
* same reason as above.
*/
smp_mb();
if (type == TYPE_SWPB)
swpbcounter++;
else
swpcounter++;
}
return res;
}
/*
* swp_handler logs the id of calling process, dissects the instruction, sanity
* checks the memory location, calls emulate_swpX for the actual operation and
* deals with fixup/error handling before returning
*/
static int swp_handler(struct pt_regs *regs, unsigned int instr)
{
unsigned int address, destreg, data, type;
unsigned int res = 0;
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, regs->ARM_pc);
if (current->pid != previous_pid) {
pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
current->comm, (unsigned long)current->pid);
previous_pid = current->pid;
}
address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
data = regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
type = instr & TYPE_SWPB;
pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n",
EXTRACT_REG_NUM(instr, RN_OFFSET), address,
destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
/* Check access in reasonable access range for both SWP and SWPB */
if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
pr_debug("SWP{B} emulation: access to %p not allowed!\n",
(void *)address);
res = -EFAULT;
} else {
res = emulate_swpX(address, &data, type);
}
if (res == 0) {
/*
* On successful emulation, revert the adjustment to the PC
* made in kernel/traps.c in order to resume execution at the
* instruction following the SWP{B}.
*/
regs->ARM_pc += 4;
regs->uregs[destreg] = data;
} else if (res == -EFAULT) {
/*
* Memory errors do not mean emulation failed.
* Set up signal info to return SEGV, then return OK
*/
set_segfault(regs, address);
}
return 0;
}
/*
* Only emulate SWP/SWPB executed in ARM state/User mode.
* The kernel must be SWP free and SWP{B} does not exist in Thumb/ThumbEE.
*/
static struct undef_hook swp_hook = {
.instr_mask = 0x0fb00ff0,
.instr_val = 0x01000090,
.cpsr_mask = MODE_MASK | PSR_T_BIT | PSR_J_BIT,
.cpsr_val = USR_MODE,
.fn = swp_handler
};
/*
* Register handler and create status file in /proc/cpu
* Invoked as late_initcall, since not needed before init spawned.
*/
static int __init swp_emulation_init(void)
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *res;
res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
if (!res)
return -ENOMEM;
res->read_proc = proc_read_status;
#endif /* CONFIG_PROC_FS */
printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
register_undef_hook(&swp_hook);
return 0;
}
late_initcall(swp_emulation_init);
...@@ -30,12 +30,13 @@ ...@@ -30,12 +30,13 @@
#include <asm/leds.h> #include <asm/leds.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/stacktrace.h> #include <asm/stacktrace.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
/* /*
* Our system timer. * Our system timer.
*/ */
struct sys_timer *system_timer; static struct sys_timer *system_timer;
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
/* this needs a better home */ /* this needs a better home */
...@@ -160,6 +161,7 @@ device_initcall(timer_init_sysfs); ...@@ -160,6 +161,7 @@ device_initcall(timer_init_sysfs);
void __init time_init(void) void __init time_init(void)
{ {
system_timer = machine_desc->timer;
system_timer->init(); system_timer->init();
} }
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
void *vectors_page;
#ifdef CONFIG_DEBUG_USER #ifdef CONFIG_DEBUG_USER
unsigned int user_debug; unsigned int user_debug;
...@@ -756,7 +758,11 @@ static void __init kuser_get_tls_init(unsigned long vectors) ...@@ -756,7 +758,11 @@ static void __init kuser_get_tls_init(unsigned long vectors)
void __init early_trap_init(void) void __init early_trap_init(void)
{ {
#if defined(CONFIG_CPU_USE_DOMAINS)
unsigned long vectors = CONFIG_VECTORS_BASE; unsigned long vectors = CONFIG_VECTORS_BASE;
#else
unsigned long vectors = (unsigned long)vectors_page;
#endif
extern char __stubs_start[], __stubs_end[]; extern char __stubs_start[], __stubs_end[];
extern char __vectors_start[], __vectors_end[]; extern char __vectors_start[], __vectors_end[];
extern char __kuser_helper_start[], __kuser_helper_end[]; extern char __kuser_helper_start[], __kuser_helper_end[];
...@@ -780,10 +786,10 @@ void __init early_trap_init(void) ...@@ -780,10 +786,10 @@ void __init early_trap_init(void)
* Copy signal return handlers into the vector page, and * Copy signal return handlers into the vector page, and
* set sigreturn to be a pointer to these. * set sigreturn to be a pointer to these.
*/ */
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
sizeof(sigreturn_codes)); sigreturn_codes, sizeof(sigreturn_codes));
memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
sizeof(syscall_restart_code)); syscall_restart_code, sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE); flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT); modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
......
...@@ -168,6 +168,7 @@ SECTIONS ...@@ -168,6 +168,7 @@ SECTIONS
NOSAVE_DATA NOSAVE_DATA
CACHELINE_ALIGNED_DATA(32) CACHELINE_ALIGNED_DATA(32)
READ_MOSTLY_DATA(32)
/* /*
* The exception fixup table (might need resorting at runtime) * The exception fixup table (might need resorting at runtime)
......
...@@ -28,20 +28,21 @@ ...@@ -28,20 +28,21 @@
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/domain.h>
ENTRY(__get_user_1) ENTRY(__get_user_1)
1: ldrbt r2, [r0] 1: T(ldrb) r2, [r0]
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
ENDPROC(__get_user_1) ENDPROC(__get_user_1)
ENTRY(__get_user_2) ENTRY(__get_user_2)
#ifdef CONFIG_THUMB2_KERNEL #ifdef CONFIG_THUMB2_KERNEL
2: ldrbt r2, [r0] 2: T(ldrb) r2, [r0]
3: ldrbt r3, [r0, #1] 3: T(ldrb) r3, [r0, #1]
#else #else
2: ldrbt r2, [r0], #1 2: T(ldrb) r2, [r0], #1
3: ldrbt r3, [r0] 3: T(ldrb) r3, [r0]
#endif #endif
#ifndef __ARMEB__ #ifndef __ARMEB__
orr r2, r2, r3, lsl #8 orr r2, r2, r3, lsl #8
...@@ -53,7 +54,7 @@ ENTRY(__get_user_2) ...@@ -53,7 +54,7 @@ ENTRY(__get_user_2)
ENDPROC(__get_user_2) ENDPROC(__get_user_2)
ENTRY(__get_user_4) ENTRY(__get_user_4)
4: ldrt r2, [r0] 4: T(ldr) r2, [r0]
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
ENDPROC(__get_user_4) ENDPROC(__get_user_4)
......
...@@ -28,9 +28,10 @@ ...@@ -28,9 +28,10 @@
*/ */
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/domain.h>
ENTRY(__put_user_1) ENTRY(__put_user_1)
1: strbt r2, [r0] 1: T(strb) r2, [r0]
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
ENDPROC(__put_user_1) ENDPROC(__put_user_1)
...@@ -39,19 +40,19 @@ ENTRY(__put_user_2) ...@@ -39,19 +40,19 @@ ENTRY(__put_user_2)
mov ip, r2, lsr #8 mov ip, r2, lsr #8
#ifdef CONFIG_THUMB2_KERNEL #ifdef CONFIG_THUMB2_KERNEL
#ifndef __ARMEB__ #ifndef __ARMEB__
2: strbt r2, [r0] 2: T(strb) r2, [r0]
3: strbt ip, [r0, #1] 3: T(strb) ip, [r0, #1]
#else #else
2: strbt ip, [r0] 2: T(strb) ip, [r0]
3: strbt r2, [r0, #1] 3: T(strb) r2, [r0, #1]
#endif #endif
#else /* !CONFIG_THUMB2_KERNEL */ #else /* !CONFIG_THUMB2_KERNEL */
#ifndef __ARMEB__ #ifndef __ARMEB__
2: strbt r2, [r0], #1 2: T(strb) r2, [r0], #1
3: strbt ip, [r0] 3: T(strb) ip, [r0]
#else #else
2: strbt ip, [r0], #1 2: T(strb) ip, [r0], #1
3: strbt r2, [r0] 3: T(strb) r2, [r0]
#endif #endif
#endif /* CONFIG_THUMB2_KERNEL */ #endif /* CONFIG_THUMB2_KERNEL */
mov r0, #0 mov r0, #0
...@@ -59,18 +60,18 @@ ENTRY(__put_user_2) ...@@ -59,18 +60,18 @@ ENTRY(__put_user_2)
ENDPROC(__put_user_2) ENDPROC(__put_user_2)
ENTRY(__put_user_4) ENTRY(__put_user_4)
4: strt r2, [r0] 4: T(str) r2, [r0]
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
ENDPROC(__put_user_4) ENDPROC(__put_user_4)
ENTRY(__put_user_8) ENTRY(__put_user_8)
#ifdef CONFIG_THUMB2_KERNEL #ifdef CONFIG_THUMB2_KERNEL
5: strt r2, [r0] 5: T(str) r2, [r0]
6: strt r3, [r0, #4] 6: T(str) r3, [r0, #4]
#else #else
5: strt r2, [r0], #4 5: T(str) r2, [r0], #4
6: strt r3, [r0] 6: T(str) r3, [r0]
#endif #endif
mov r0, #0 mov r0, #0
mov pc, lr mov pc, lr
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/domain.h>
.text .text
...@@ -31,11 +32,11 @@ ...@@ -31,11 +32,11 @@
rsb ip, ip, #4 rsb ip, ip, #4
cmp ip, #2 cmp ip, #2
ldrb r3, [r1], #1 ldrb r3, [r1], #1
USER( strbt r3, [r0], #1) @ May fault USER( T(strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1 ldrgeb r3, [r1], #1
USER( strgebt r3, [r0], #1) @ May fault USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1 ldrgtb r3, [r1], #1
USER( strgtbt r3, [r0], #1) @ May fault USER( T(strgtb) r3, [r0], #1) @ May fault
sub r2, r2, ip sub r2, r2, ip
b .Lc2u_dest_aligned b .Lc2u_dest_aligned
...@@ -58,7 +59,7 @@ ENTRY(__copy_to_user) ...@@ -58,7 +59,7 @@ ENTRY(__copy_to_user)
addmi ip, r2, #4 addmi ip, r2, #4
bmi .Lc2u_0nowords bmi .Lc2u_0nowords
ldr r3, [r1], #4 ldr r3, [r1], #4
USER( strt r3, [r0], #4) @ May fault USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0 rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT movs ip, ip, lsr #32 - PAGE_SHIFT
...@@ -87,18 +88,18 @@ USER( strt r3, [r0], #4) @ May fault ...@@ -87,18 +88,18 @@ USER( strt r3, [r0], #4) @ May fault
stmneia r0!, {r3 - r4} @ Shouldnt fault stmneia r0!, {r3 - r4} @ Shouldnt fault
tst ip, #4 tst ip, #4
ldrne r3, [r1], #4 ldrne r3, [r1], #4
strnet r3, [r0], #4 @ Shouldnt fault T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3 ands ip, ip, #3
beq .Lc2u_0fupi beq .Lc2u_0fupi
.Lc2u_0nowords: teq ip, #0 .Lc2u_0nowords: teq ip, #0
beq .Lc2u_finished beq .Lc2u_finished
.Lc2u_nowords: cmp ip, #2 .Lc2u_nowords: cmp ip, #2
ldrb r3, [r1], #1 ldrb r3, [r1], #1
USER( strbt r3, [r0], #1) @ May fault USER( T(strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1 ldrgeb r3, [r1], #1
USER( strgebt r3, [r0], #1) @ May fault USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #1 ldrgtb r3, [r1], #1
USER( strgtbt r3, [r0], #1) @ May fault USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished b .Lc2u_finished
.Lc2u_not_enough: .Lc2u_not_enough:
...@@ -119,7 +120,7 @@ USER( strgtbt r3, [r0], #1) @ May fault ...@@ -119,7 +120,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
mov r3, r7, pull #8 mov r3, r7, pull #8
ldr r7, [r1], #4 ldr r7, [r1], #4
orr r3, r3, r7, push #24 orr r3, r3, r7, push #24
USER( strt r3, [r0], #4) @ May fault USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0 rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT movs ip, ip, lsr #32 - PAGE_SHIFT
...@@ -154,18 +155,18 @@ USER( strt r3, [r0], #4) @ May fault ...@@ -154,18 +155,18 @@ USER( strt r3, [r0], #4) @ May fault
movne r3, r7, pull #8 movne r3, r7, pull #8
ldrne r7, [r1], #4 ldrne r7, [r1], #4
orrne r3, r3, r7, push #24 orrne r3, r3, r7, push #24
strnet r3, [r0], #4 @ Shouldnt fault T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3 ands ip, ip, #3
beq .Lc2u_1fupi beq .Lc2u_1fupi
.Lc2u_1nowords: mov r3, r7, get_byte_1 .Lc2u_1nowords: mov r3, r7, get_byte_1
teq ip, #0 teq ip, #0
beq .Lc2u_finished beq .Lc2u_finished
cmp ip, #2 cmp ip, #2
USER( strbt r3, [r0], #1) @ May fault USER( T(strb) r3, [r0], #1) @ May fault
movge r3, r7, get_byte_2 movge r3, r7, get_byte_2
USER( strgebt r3, [r0], #1) @ May fault USER( T(strgeb) r3, [r0], #1) @ May fault
movgt r3, r7, get_byte_3 movgt r3, r7, get_byte_3
USER( strgtbt r3, [r0], #1) @ May fault USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished b .Lc2u_finished
.Lc2u_2fupi: subs r2, r2, #4 .Lc2u_2fupi: subs r2, r2, #4
...@@ -174,7 +175,7 @@ USER( strgtbt r3, [r0], #1) @ May fault ...@@ -174,7 +175,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
mov r3, r7, pull #16 mov r3, r7, pull #16
ldr r7, [r1], #4 ldr r7, [r1], #4
orr r3, r3, r7, push #16 orr r3, r3, r7, push #16
USER( strt r3, [r0], #4) @ May fault USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0 rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT movs ip, ip, lsr #32 - PAGE_SHIFT
...@@ -209,18 +210,18 @@ USER( strt r3, [r0], #4) @ May fault ...@@ -209,18 +210,18 @@ USER( strt r3, [r0], #4) @ May fault
movne r3, r7, pull #16 movne r3, r7, pull #16
ldrne r7, [r1], #4 ldrne r7, [r1], #4
orrne r3, r3, r7, push #16 orrne r3, r3, r7, push #16
strnet r3, [r0], #4 @ Shouldnt fault T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3 ands ip, ip, #3
beq .Lc2u_2fupi beq .Lc2u_2fupi
.Lc2u_2nowords: mov r3, r7, get_byte_2 .Lc2u_2nowords: mov r3, r7, get_byte_2
teq ip, #0 teq ip, #0
beq .Lc2u_finished beq .Lc2u_finished
cmp ip, #2 cmp ip, #2
USER( strbt r3, [r0], #1) @ May fault USER( T(strb) r3, [r0], #1) @ May fault
movge r3, r7, get_byte_3 movge r3, r7, get_byte_3
USER( strgebt r3, [r0], #1) @ May fault USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0 ldrgtb r3, [r1], #0
USER( strgtbt r3, [r0], #1) @ May fault USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished b .Lc2u_finished
.Lc2u_3fupi: subs r2, r2, #4 .Lc2u_3fupi: subs r2, r2, #4
...@@ -229,7 +230,7 @@ USER( strgtbt r3, [r0], #1) @ May fault ...@@ -229,7 +230,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
mov r3, r7, pull #24 mov r3, r7, pull #24
ldr r7, [r1], #4 ldr r7, [r1], #4
orr r3, r3, r7, push #8 orr r3, r3, r7, push #8
USER( strt r3, [r0], #4) @ May fault USER( T(str) r3, [r0], #4) @ May fault
mov ip, r0, lsl #32 - PAGE_SHIFT mov ip, r0, lsl #32 - PAGE_SHIFT
rsb ip, ip, #0 rsb ip, ip, #0
movs ip, ip, lsr #32 - PAGE_SHIFT movs ip, ip, lsr #32 - PAGE_SHIFT
...@@ -264,18 +265,18 @@ USER( strt r3, [r0], #4) @ May fault ...@@ -264,18 +265,18 @@ USER( strt r3, [r0], #4) @ May fault
movne r3, r7, pull #24 movne r3, r7, pull #24
ldrne r7, [r1], #4 ldrne r7, [r1], #4
orrne r3, r3, r7, push #8 orrne r3, r3, r7, push #8
strnet r3, [r0], #4 @ Shouldnt fault T(strne) r3, [r0], #4 @ Shouldnt fault
ands ip, ip, #3 ands ip, ip, #3
beq .Lc2u_3fupi beq .Lc2u_3fupi
.Lc2u_3nowords: mov r3, r7, get_byte_3 .Lc2u_3nowords: mov r3, r7, get_byte_3
teq ip, #0 teq ip, #0
beq .Lc2u_finished beq .Lc2u_finished
cmp ip, #2 cmp ip, #2
USER( strbt r3, [r0], #1) @ May fault USER( T(strb) r3, [r0], #1) @ May fault
ldrgeb r3, [r1], #1 ldrgeb r3, [r1], #1
USER( strgebt r3, [r0], #1) @ May fault USER( T(strgeb) r3, [r0], #1) @ May fault
ldrgtb r3, [r1], #0 ldrgtb r3, [r1], #0
USER( strgtbt r3, [r0], #1) @ May fault USER( T(strgtb) r3, [r0], #1) @ May fault
b .Lc2u_finished b .Lc2u_finished
ENDPROC(__copy_to_user) ENDPROC(__copy_to_user)
...@@ -294,11 +295,11 @@ ENDPROC(__copy_to_user) ...@@ -294,11 +295,11 @@ ENDPROC(__copy_to_user)
.Lcfu_dest_not_aligned: .Lcfu_dest_not_aligned:
rsb ip, ip, #4 rsb ip, ip, #4
cmp ip, #2 cmp ip, #2
USER( ldrbt r3, [r1], #1) @ May fault USER( T(ldrb) r3, [r1], #1) @ May fault
strb r3, [r0], #1 strb r3, [r0], #1
USER( ldrgebt r3, [r1], #1) @ May fault USER( T(ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1 strgeb r3, [r0], #1
USER( ldrgtbt r3, [r1], #1) @ May fault USER( T(ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1 strgtb r3, [r0], #1
sub r2, r2, ip sub r2, r2, ip
b .Lcfu_dest_aligned b .Lcfu_dest_aligned
...@@ -321,7 +322,7 @@ ENTRY(__copy_from_user) ...@@ -321,7 +322,7 @@ ENTRY(__copy_from_user)
.Lcfu_0fupi: subs r2, r2, #4 .Lcfu_0fupi: subs r2, r2, #4
addmi ip, r2, #4 addmi ip, r2, #4
bmi .Lcfu_0nowords bmi .Lcfu_0nowords
USER( ldrt r3, [r1], #4) USER( T(ldr) r3, [r1], #4)
str r3, [r0], #4 str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
rsb ip, ip, #0 rsb ip, ip, #0
...@@ -350,18 +351,18 @@ USER( ldrt r3, [r1], #4) ...@@ -350,18 +351,18 @@ USER( ldrt r3, [r1], #4)
ldmneia r1!, {r3 - r4} @ Shouldnt fault ldmneia r1!, {r3 - r4} @ Shouldnt fault
stmneia r0!, {r3 - r4} stmneia r0!, {r3 - r4}
tst ip, #4 tst ip, #4
ldrnet r3, [r1], #4 @ Shouldnt fault T(ldrne) r3, [r1], #4 @ Shouldnt fault
strne r3, [r0], #4 strne r3, [r0], #4
ands ip, ip, #3 ands ip, ip, #3
beq .Lcfu_0fupi beq .Lcfu_0fupi
.Lcfu_0nowords: teq ip, #0 .Lcfu_0nowords: teq ip, #0
beq .Lcfu_finished beq .Lcfu_finished
.Lcfu_nowords: cmp ip, #2 .Lcfu_nowords: cmp ip, #2
USER( ldrbt r3, [r1], #1) @ May fault USER( T(ldrb) r3, [r1], #1) @ May fault
strb r3, [r0], #1 strb r3, [r0], #1
USER( ldrgebt r3, [r1], #1) @ May fault USER( T(ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1 strgeb r3, [r0], #1
USER( ldrgtbt r3, [r1], #1) @ May fault USER( T(ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1 strgtb r3, [r0], #1
b .Lcfu_finished b .Lcfu_finished
...@@ -374,7 +375,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault ...@@ -374,7 +375,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
.Lcfu_src_not_aligned: .Lcfu_src_not_aligned:
bic r1, r1, #3 bic r1, r1, #3
USER( ldrt r7, [r1], #4) @ May fault USER( T(ldr) r7, [r1], #4) @ May fault
cmp ip, #2 cmp ip, #2
bgt .Lcfu_3fupi bgt .Lcfu_3fupi
beq .Lcfu_2fupi beq .Lcfu_2fupi
...@@ -382,7 +383,7 @@ USER( ldrt r7, [r1], #4) @ May fault ...@@ -382,7 +383,7 @@ USER( ldrt r7, [r1], #4) @ May fault
addmi ip, r2, #4 addmi ip, r2, #4
bmi .Lcfu_1nowords bmi .Lcfu_1nowords
mov r3, r7, pull #8 mov r3, r7, pull #8
USER( ldrt r7, [r1], #4) @ May fault USER( T(ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #24 orr r3, r3, r7, push #24
str r3, [r0], #4 str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT mov ip, r1, lsl #32 - PAGE_SHIFT
...@@ -417,7 +418,7 @@ USER( ldrt r7, [r1], #4) @ May fault ...@@ -417,7 +418,7 @@ USER( ldrt r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4} stmneia r0!, {r3 - r4}
tst ip, #4 tst ip, #4
movne r3, r7, pull #8 movne r3, r7, pull #8
USER( ldrnet r7, [r1], #4) @ May fault USER( T(ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #24 orrne r3, r3, r7, push #24
strne r3, [r0], #4 strne r3, [r0], #4
ands ip, ip, #3 ands ip, ip, #3
...@@ -437,7 +438,7 @@ USER( ldrnet r7, [r1], #4) @ May fault ...@@ -437,7 +438,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
addmi ip, r2, #4 addmi ip, r2, #4
bmi .Lcfu_2nowords bmi .Lcfu_2nowords
mov r3, r7, pull #16 mov r3, r7, pull #16
USER( ldrt r7, [r1], #4) @ May fault USER( T(ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #16 orr r3, r3, r7, push #16
str r3, [r0], #4 str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT mov ip, r1, lsl #32 - PAGE_SHIFT
...@@ -473,7 +474,7 @@ USER( ldrt r7, [r1], #4) @ May fault ...@@ -473,7 +474,7 @@ USER( ldrt r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4} stmneia r0!, {r3 - r4}
tst ip, #4 tst ip, #4
movne r3, r7, pull #16 movne r3, r7, pull #16
USER( ldrnet r7, [r1], #4) @ May fault USER( T(ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #16 orrne r3, r3, r7, push #16
strne r3, [r0], #4 strne r3, [r0], #4
ands ip, ip, #3 ands ip, ip, #3
...@@ -485,7 +486,7 @@ USER( ldrnet r7, [r1], #4) @ May fault ...@@ -485,7 +486,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
strb r3, [r0], #1 strb r3, [r0], #1
movge r3, r7, get_byte_3 movge r3, r7, get_byte_3
strgeb r3, [r0], #1 strgeb r3, [r0], #1
USER( ldrgtbt r3, [r1], #0) @ May fault USER( T(ldrgtb) r3, [r1], #0) @ May fault
strgtb r3, [r0], #1 strgtb r3, [r0], #1
b .Lcfu_finished b .Lcfu_finished
...@@ -493,7 +494,7 @@ USER( ldrgtbt r3, [r1], #0) @ May fault ...@@ -493,7 +494,7 @@ USER( ldrgtbt r3, [r1], #0) @ May fault
addmi ip, r2, #4 addmi ip, r2, #4
bmi .Lcfu_3nowords bmi .Lcfu_3nowords
mov r3, r7, pull #24 mov r3, r7, pull #24
USER( ldrt r7, [r1], #4) @ May fault USER( T(ldr) r7, [r1], #4) @ May fault
orr r3, r3, r7, push #8 orr r3, r3, r7, push #8
str r3, [r0], #4 str r3, [r0], #4
mov ip, r1, lsl #32 - PAGE_SHIFT mov ip, r1, lsl #32 - PAGE_SHIFT
...@@ -528,7 +529,7 @@ USER( ldrt r7, [r1], #4) @ May fault ...@@ -528,7 +529,7 @@ USER( ldrt r7, [r1], #4) @ May fault
stmneia r0!, {r3 - r4} stmneia r0!, {r3 - r4}
tst ip, #4 tst ip, #4
movne r3, r7, pull #24 movne r3, r7, pull #24
USER( ldrnet r7, [r1], #4) @ May fault USER( T(ldrne) r7, [r1], #4) @ May fault
orrne r3, r3, r7, push #8 orrne r3, r3, r7, push #8
strne r3, [r0], #4 strne r3, [r0], #4
ands ip, ip, #3 ands ip, ip, #3
...@@ -538,9 +539,9 @@ USER( ldrnet r7, [r1], #4) @ May fault ...@@ -538,9 +539,9 @@ USER( ldrnet r7, [r1], #4) @ May fault
beq .Lcfu_finished beq .Lcfu_finished
cmp ip, #2 cmp ip, #2
strb r3, [r0], #1 strb r3, [r0], #1
USER( ldrgebt r3, [r1], #1) @ May fault USER( T(ldrgeb) r3, [r1], #1) @ May fault
strgeb r3, [r0], #1 strgeb r3, [r0], #1
USER( ldrgtbt r3, [r1], #1) @ May fault USER( T(ldrgtb) r3, [r1], #1) @ May fault
strgtb r3, [r0], #1 strgtb r3, [r0], #1
b .Lcfu_finished b .Lcfu_finished
ENDPROC(__copy_from_user) ENDPROC(__copy_from_user)
......
...@@ -21,13 +21,12 @@ ...@@ -21,13 +21,12 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/clkdev.h>
#include <mach/csp/hw_cfg.h> #include <mach/csp/hw_cfg.h>
#include <mach/csp/chipcHw_def.h> #include <mach/csp/chipcHw_def.h>
#include <mach/csp/chipcHw_reg.h> #include <mach/csp/chipcHw_reg.h>
#include <mach/csp/chipcHw_inline.h> #include <mach/csp/chipcHw_inline.h>
#include <asm/clkdev.h>
#include "clock.h" #include "clock.h"
#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
......
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/clkdev.h>
#include <mach/csp/mm_addr.h> #include <mach/csp/mm_addr.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/clkdev.h>
#include <linux/io.h> #include <linux/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware/arm_timer.h> #include <asm/hardware/arm_timer.h>
......
...@@ -3,6 +3,7 @@ menu "CNS3XXX platform type" ...@@ -3,6 +3,7 @@ menu "CNS3XXX platform type"
config MACH_CNS3420VB config MACH_CNS3420VB
bool "Support for CNS3420 Validation Board" bool "Support for CNS3420 Validation Board"
select MIGHT_HAVE_PCI
help help
Include support for the Cavium Networks CNS3420 MPCore Platform Include support for the Cavium Networks CNS3420 MPCore Platform
Baseboard. Baseboard.
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#include <linux/list.h> #include <linux/list.h>
#include <asm/clkdev.h> #include <linux/clkdev.h>
#define PLLSTAT_GOSTAT BIT(0) #define PLLSTAT_GOSTAT BIT(0)
#define PLLCMD_GOSET BIT(0) #define PLLCMD_GOSET BIT(0)
......
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/clkdev.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/common.h> #include <mach/common.h>
#include <asm/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) #define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/clock.h> #include <mach/clock.h>
......
...@@ -4,6 +4,7 @@ menu "Integrator Options" ...@@ -4,6 +4,7 @@ menu "Integrator Options"
config ARCH_INTEGRATOR_AP config ARCH_INTEGRATOR_AP
bool "Support Integrator/AP and Integrator/PP2 platforms" bool "Support Integrator/AP and Integrator/PP2 platforms"
select MIGHT_HAVE_PCI
help help
Include support for the ARM(R) Integrator/AP and Include support for the ARM(R) Integrator/AP and
Integrator/PP2 platforms. Integrator/PP2 platforms.
......
...@@ -21,9 +21,8 @@ ...@@ -21,9 +21,8 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/amba/serial.h> #include <linux/amba/serial.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <asm/irq.h> #include <asm/irq.h>
......
...@@ -22,9 +22,8 @@ ...@@ -22,9 +22,8 @@
#include <linux/amba/clcd.h> #include <linux/amba/clcd.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <asm/hardware/icst.h> #include <asm/hardware/icst.h>
#include <mach/lm.h> #include <mach/lm.h>
#include <mach/impd1.h> #include <mach/impd1.h>
......
...@@ -21,9 +21,8 @@ ...@@ -21,9 +21,8 @@
#include <linux/amba/mmci.h> #include <linux/amba/mmci.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <asm/irq.h> #include <asm/irq.h>
......
...@@ -58,13 +58,13 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x) ...@@ -58,13 +58,13 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
__dma; \ __dma; \
}) })
#define __arch_page_to_dma(dev, page) \ #define __arch_pfn_to_dma(dev, pfn) \
({ \ ({ \
/* __is_lbus_virt() can never be true for RAM pages */ \ /* __is_lbus_virt() can never be true for RAM pages */ \
(dma_addr_t)page_to_phys(page); \ (dma_addr_t)__pfn_to_phys(pfn); \
}) })
#define __arch_dma_to_page(dev, addr) phys_to_page(addr) #define __arch_dma_to_pfn(dev, addr) __phys_to_pfn(addr)
#endif /* CONFIG_ARCH_IOP13XX */ #endif /* CONFIG_ARCH_IOP13XX */
#endif /* !ASSEMBLY */ #endif /* !ASSEMBLY */
......
...@@ -4,6 +4,7 @@ menu "Kendin/Micrel KS8695 Implementations" ...@@ -4,6 +4,7 @@ menu "Kendin/Micrel KS8695 Implementations"
config MACH_KS8695 config MACH_KS8695
bool "KS8695 development board" bool "KS8695 development board"
select MIGHT_HAVE_PCI
help help
Say 'Y' here if you want your kernel to run on the original Say 'Y' here if you want your kernel to run on the original
Kendin-Micrel KS8695 development board. Kendin-Micrel KS8695 development board.
......
...@@ -35,17 +35,17 @@ extern struct bus_type platform_bus_type; ...@@ -35,17 +35,17 @@ extern struct bus_type platform_bus_type;
__phys_to_virt(x) : __bus_to_virt(x)); }) __phys_to_virt(x) : __bus_to_virt(x)); })
#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \ #define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
(dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); }) (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
#define __arch_page_to_dma(dev, x) \ #define __arch_pfn_to_dma(dev, pfn) \
({ dma_addr_t __dma = page_to_phys(page); \ ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
if (!is_lbus_device(dev)) \ if (!is_lbus_device(dev)) \
__dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \ __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
__dma; }) __dma; })
#define __arch_dma_to_page(dev, x) \ #define __arch_dma_to_pfn(dev, x) \
({ dma_addr_t __dma = x; \ ({ dma_addr_t __dma = x; \
if (!is_lbus_device(dev)) \ if (!is_lbus_device(dev)) \
__dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \ __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \
phys_to_page(__dma); \ __phys_to_pfn(__dma); \
}) })
#endif #endif
......
...@@ -90,10 +90,9 @@ ...@@ -90,10 +90,9 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/amba/clcd.h> #include <linux/amba/clcd.h>
#include <linux/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/clkdev.h>
#include <mach/clkdev.h>
#include <mach/platform.h> #include <mach/platform.h>
#include "clock.h" #include "clock.h"
#include "common.h" #include "common.h"
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <asm/clkdev.h> #include <linux/clkdev.h>
struct clkops { struct clkops {
void (*enable)(struct clk *); void (*enable)(struct clk *);
......
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
static inline void smp_cross_call(const struct cpumask *mask) static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{ {
gic_raise_softirq(mask, 1); gic_raise_softirq(mask, ipi);
} }
#endif #endif
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/clock.h> #include <mach/clock.h>
......
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/common.h> #include <mach/common.h>
#include <asm/clkdev.h>
#include <asm/bug.h> #include <asm/bug.h>
#include <asm/div64.h> #include <asm/div64.h>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <asm/clkdev.h> #include <linux/clkdev.h>
#include "clock.h" #include "clock.h"
/* /*
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* the Free Software Foundation; either version 2 of the License. * the Free Software Foundation; either version 2 of the License.
*/ */
#include <asm/clkdev.h> #include <linux/clkdev.h>
void nuc93x_clk_enable(struct clk *clk, int enable); void nuc93x_clk_enable(struct clk *clk, int enable);
void clks_register(struct clk_lookup *clks, size_t num); void clks_register(struct clk_lookup *clks, size_t num);
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/clkdev.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/usb.h> #include <plat/usb.h>
......
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/clkdev.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <asm/clkdev.h>
#include "clock.h" #include "clock.h"
#include "prm.h" #include "prm.h"
......
...@@ -17,16 +17,13 @@ ...@@ -17,16 +17,13 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/completion.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <mach/omap4-common.h> #include <mach/omap4-common.h>
static DECLARE_COMPLETION(cpu_killed);
int platform_cpu_kill(unsigned int cpu) int platform_cpu_kill(unsigned int cpu)
{ {
return wait_for_completion_timeout(&cpu_killed, 5000); return 1;
} }
/* /*
...@@ -35,15 +32,6 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -35,15 +32,6 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
unsigned int this_cpu = hard_smp_processor_id();
if (cpu != this_cpu) {
pr_crit("platform_cpu_die running on %u, should be %u\n",
this_cpu, cpu);
BUG();
}
pr_notice("CPU%u: shutdown\n", cpu);
complete(&cpu_killed);
flush_cache_all(); flush_cache_all();
dsb(); dsb();
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/omap4-common.h> #include <mach/omap4-common.h>
...@@ -29,22 +28,10 @@ ...@@ -29,22 +28,10 @@
/* SCU base address */ /* SCU base address */
static void __iomem *scu_base; static void __iomem *scu_base;
/*
* Use SCU config register to count number of cores
*/
static inline unsigned int get_core_count(void)
{
if (scu_base)
return scu_get_core_count(scu_base);
return 1;
}
static DEFINE_SPINLOCK(boot_lock); static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu) void __cpuinit platform_secondary_init(unsigned int cpu)
{ {
trace_hardirqs_off();
/* /*
* If any interrupts are already enabled for the primary * If any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled * 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,7 +63,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
omap_modify_auxcoreboot0(0x200, 0xfffffdff); omap_modify_auxcoreboot0(0x200, 0xfffffdff);
flush_cache_all(); flush_cache_all();
smp_wmb(); smp_wmb();
smp_cross_call(cpumask_of(cpu)); smp_cross_call(cpumask_of(cpu), 1);
/* /*
* Now the secondary core is starting up let it run its * Now the secondary core is starting up let it run its
...@@ -118,25 +105,9 @@ void __init smp_init_cpus(void) ...@@ -118,25 +105,9 @@ void __init smp_init_cpus(void)
scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256); scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
BUG_ON(!scu_base); BUG_ON(!scu_base);
ncores = get_core_count(); ncores = scu_get_core_count(scu_base);
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
}
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int ncores = get_core_count();
unsigned int cpu = smp_processor_id();
int i;
/* sanity check */ /* sanity check */
if (ncores == 0) {
printk(KERN_ERR
"OMAP4: strange core count of 0? Default to 1\n");
ncores = 1;
}
if (ncores > NR_CPUS) { if (ncores > NR_CPUS) {
printk(KERN_WARNING printk(KERN_WARNING
"OMAP4: no. of cores (%d) greater than configured " "OMAP4: no. of cores (%d) greater than configured "
...@@ -144,13 +115,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -144,13 +115,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
ncores, NR_CPUS); ncores, NR_CPUS);
ncores = NR_CPUS; ncores = NR_CPUS;
} }
smp_store_cpu_info(cpu);
/* for (i = 0; i < ncores; i++)
* are we trying to boot more cores than exist? set_cpu_possible(i, true);
*/ }
if (max_cpus > ncores)
max_cpus = ncores; void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{
int i;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
...@@ -159,18 +131,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -159,18 +131,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
if (max_cpus > 1) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
/* /*
* Initialise the SCU and wake up the secondary core using * Initialise the SCU and wake up the secondary core using
* wakeup_secondary(). * wakeup_secondary().
*/ */
scu_enable(scu_base); scu_enable(scu_base);
wakeup_secondary(); wakeup_secondary();
}
} }
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/clock.h> #include <mach/clock.h>
......
...@@ -94,6 +94,7 @@ config MACH_ARMCORE ...@@ -94,6 +94,7 @@ config MACH_ARMCORE
select PXA27x select PXA27x
select IWMMXT select IWMMXT
select PXA25x select PXA25x
select MIGHT_HAVE_PCI
config MACH_EM_X270 config MACH_EM_X270
bool "CompuLab EM-x270 platform" bool "CompuLab EM-x270 platform"
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/pxa2xx-regs.h> #include <mach/pxa2xx-regs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
#include <asm/clkdev.h> #include <linux/clkdev.h>
struct clkops { struct clkops {
void (*enable)(struct clk *); void (*enable)(struct clk *);
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include <linux/ata_platform.h> #include <linux/ata_platform.h>
#include <linux/amba/mmci.h> #include <linux/amba/mmci.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <asm/system.h> #include <asm/system.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <mach/clkdev.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <mach/irqs.h> #include <mach/irqs.h>
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
......
...@@ -11,14 +11,11 @@ ...@@ -11,14 +11,11 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/completion.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
extern volatile int pen_release; extern volatile int pen_release;
static DECLARE_COMPLETION(cpu_killed);
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -34,10 +31,10 @@ static inline void cpu_enter_lowpower(void) ...@@ -34,10 +31,10 @@ static inline void cpu_enter_lowpower(void)
" bic %0, %0, #0x20\n" " bic %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n" " mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n" " mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n" " bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 0\n" " mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v) : "=&r" (v)
: "r" (0) : "r" (0), "Ir" (CR_C)
: "cc"); : "cc");
} }
...@@ -46,17 +43,17 @@ static inline void cpu_leave_lowpower(void) ...@@ -46,17 +43,17 @@ static inline void cpu_leave_lowpower(void)
unsigned int v; unsigned int v;
asm volatile( "mrc p15, 0, %0, c1, c0, 0\n" asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
" orr %0, %0, #0x04\n" " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n" " mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n" " mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n" " orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n" " mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v) : "=&r" (v)
: : "Ir" (CR_C)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{ {
/* /*
* there is no power-control hardware on this platform, so all * 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,22 +77,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
} }
/* /*
* getting here, means that we have come out of WFI without * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen * having been woken up - this shouldn't happen
* *
* The trouble is, letting people know about this is not really * Just note it happening - when we're woken, we can report
* possible, since we are currently running incoherently, and * its occurrence.
* therefore cannot safely call printk() or anything else
*/ */
#ifdef DEBUG (*spurious)++;
printk("CPU%u: spurious wakeup call\n", cpu);
#endif
} }
} }
int platform_cpu_kill(unsigned int cpu) int platform_cpu_kill(unsigned int cpu)
{ {
return wait_for_completion_timeout(&cpu_killed, 5000); return 1;
} }
/* /*
...@@ -105,30 +99,22 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -105,30 +99,22 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
#ifdef DEBUG int spurious = 0;
unsigned int this_cpu = hard_smp_processor_id();
if (cpu != this_cpu) {
printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
this_cpu, cpu);
BUG();
}
#endif
printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
complete(&cpu_killed);
/* /*
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu); platform_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
* coherency, and then restore interrupts * coherency, and then restore interrupts
*/ */
cpu_leave_lowpower(); cpu_leave_lowpower();
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
} }
int platform_cpu_disable(unsigned int cpu) int platform_cpu_disable(unsigned int cpu)
......
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
#define ASMARM_ARCH_SMP_H #define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/smp_mpidr.h>
/* /*
* We use IRQ1 as the IPI * We use IRQ1 as the IPI
*/ */
static inline void smp_cross_call(const struct cpumask *mask) static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{ {
gic_raise_softirq(mask, 1); gic_raise_softirq(mask, ipi);
} }
#endif #endif
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/localtimer.h>
#include <asm/unified.h> #include <asm/unified.h>
#include <mach/board-eb.h> #include <mach/board-eb.h>
...@@ -37,6 +36,19 @@ extern void realview_secondary_startup(void); ...@@ -37,6 +36,19 @@ extern void realview_secondary_startup(void);
*/ */
volatile int __cpuinitdata pen_release = -1; volatile int __cpuinitdata pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static void __iomem *scu_base_addr(void) static void __iomem *scu_base_addr(void)
{ {
if (machine_is_realview_eb_mp()) if (machine_is_realview_eb_mp())
...@@ -50,20 +62,10 @@ static void __iomem *scu_base_addr(void) ...@@ -50,20 +62,10 @@ static void __iomem *scu_base_addr(void)
return (void __iomem *)0; return (void __iomem *)0;
} }
static inline unsigned int get_core_count(void)
{
void __iomem *scu_base = scu_base_addr();
if (scu_base)
return scu_get_core_count(scu_base);
return 1;
}
static DEFINE_SPINLOCK(boot_lock); static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu) void __cpuinit platform_secondary_init(unsigned int cpu)
{ {
trace_hardirqs_off();
/* /*
* if any interrupts are already enabled for the primary * if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled * 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,8 +77,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
* let the primary processor know we're out of the * let the primary processor know we're out of the
* pen, then head off into the C entry point * pen, then head off into the C entry point
*/ */
pen_release = -1; write_pen_release(-1);
smp_wmb();
/* /*
* Synchronise with the boot thread. * Synchronise with the boot thread.
...@@ -103,20 +104,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -103,20 +104,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Note that "pen_release" is the hardware CPU ID, whereas * Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID. * "cpu" is Linux's internal ID.
*/ */
pen_release = cpu; write_pen_release(cpu);
flush_cache_all();
/* /*
* XXX * Send the secondary CPU a soft interrupt, thereby causing
* * the boot monitor to read the system wide flags register,
* This is a later addition to the booting protocol: the * and branch to the address found there.
* bootMonitor now puts secondary cores into WFI, so
* poke_milo() no longer gets the cores moving; we need
* to send a soft interrupt to wake the secondary core.
* Use smp_cross_call() for this, since there's little
* point duplicating the code here
*/ */
smp_cross_call(cpumask_of(cpu)); smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ); timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
...@@ -136,48 +131,18 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -136,48 +131,18 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
return pen_release != -1 ? -ENOSYS : 0; return pen_release != -1 ? -ENOSYS : 0;
} }
static void __init poke_milo(void)
{
/* nobody is to be released from the pen yet */
pen_release = -1;
/*
* Write the address of secondary startup into the system-wide flags
* register. The BootMonitor waits for this register to become
* non-zero.
*/
__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
__io_address(REALVIEW_SYS_FLAGSSET));
mb();
}
/* /*
* Initialise the CPU possible map early - this describes the CPUs * Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system. * which may be present or become present in the system.
*/ */
void __init smp_init_cpus(void) void __init smp_init_cpus(void)
{ {
unsigned int i, ncores = get_core_count(); void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores;
for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
}
void __init smp_prepare_cpus(unsigned int max_cpus) ncores = scu_base ? scu_get_core_count(scu_base) : 1;
{
unsigned int ncores = get_core_count();
unsigned int cpu = smp_processor_id();
int i;
/* sanity check */ /* sanity check */
if (ncores == 0) {
printk(KERN_ERR
"Realview: strange CM count of 0? Default to 1\n");
ncores = 1;
}
if (ncores > NR_CPUS) { if (ncores > NR_CPUS) {
printk(KERN_WARNING printk(KERN_WARNING
"Realview: no. of cores (%d) greater than configured " "Realview: no. of cores (%d) greater than configured "
...@@ -186,13 +151,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -186,13 +151,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
ncores = NR_CPUS; ncores = NR_CPUS;
} }
smp_store_cpu_info(cpu); for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
}
/* void __init platform_smp_prepare_cpus(unsigned int max_cpus)
* are we trying to boot more cores than exist? {
*/ int i;
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
...@@ -201,21 +166,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -201,21 +166,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
scu_enable(scu_base_addr());
/* /*
* Initialise the SCU if there are more than one CPU and let * Write the address of secondary startup into the
* them know where to start. Note that, on modern versions of * system-wide flags register. The BootMonitor waits
* MILO, the "poke" doesn't actually do anything until each * until it receives a soft interrupt, and then the
* individual core is sent a soft interrupt to get it out of * secondary CPU branches to this address.
* WFI
*/
if (max_cpus > 1) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/ */
percpu_timer_setup(); __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
__io_address(REALVIEW_SYS_FLAGSSET));
scu_enable(scu_base_addr());
poke_milo();
}
} }
...@@ -59,7 +59,7 @@ config MACH_JIVE ...@@ -59,7 +59,7 @@ config MACH_JIVE
Say Y here if you are using the Logitech Jive. Say Y here if you are using the Logitech Jive.
config MACH_JIVE_SHOW_BOOTLOADER config MACH_JIVE_SHOW_BOOTLOADER
bool "Allow access to bootloader partitions in MTD" bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
depends on MACH_JIVE && EXPERIMENTAL depends on MACH_JIVE && EXPERIMENTAL
config MACH_SMDK2413 config MACH_SMDK2413
......
...@@ -13,14 +13,11 @@ ...@@ -13,14 +13,11 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/completion.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
extern volatile int pen_release; extern volatile int pen_release;
static DECLARE_COMPLETION(cpu_killed);
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -33,13 +30,13 @@ static inline void cpu_enter_lowpower(void) ...@@ -33,13 +30,13 @@ static inline void cpu_enter_lowpower(void)
* Turn off coherency * Turn off coherency
*/ */
" mrc p15, 0, %0, c1, c0, 1\n" " mrc p15, 0, %0, c1, c0, 1\n"
" bic %0, %0, #0x20\n" " bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 1\n" " mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n" " mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n" " bic %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n" " mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v) : "=&r" (v)
: "r" (0) : "r" (0), "Ir" (CR_C)
: "cc"); : "cc");
} }
...@@ -49,17 +46,17 @@ static inline void cpu_leave_lowpower(void) ...@@ -49,17 +46,17 @@ static inline void cpu_leave_lowpower(void)
asm volatile( asm volatile(
"mrc p15, 0, %0, c1, c0, 0\n" "mrc p15, 0, %0, c1, c0, 0\n"
" orr %0, %0, #0x04\n" " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n" " mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n" " mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n" " orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n" " mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v) : "=&r" (v)
: : "Ir" (CR_C)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{ {
/* /*
* there is no power-control hardware on this platform, so all * 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,22 +80,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
} }
/* /*
* getting here, means that we have come out of WFI without * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen * having been woken up - this shouldn't happen
* *
* The trouble is, letting people know about this is not really * Just note it happening - when we're woken, we can report
* possible, since we are currently running incoherently, and * its occurrence.
* therefore cannot safely call printk() or anything else
*/ */
#ifdef DEBUG (*spurious)++;
printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
#endif
} }
} }
int platform_cpu_kill(unsigned int cpu) int platform_cpu_kill(unsigned int cpu)
{ {
return wait_for_completion_timeout(&cpu_killed, 5000); return 1;
} }
/* /*
...@@ -108,30 +102,22 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -108,30 +102,22 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
#ifdef DEBUG int spurious = 0;
unsigned int this_cpu = hard_smp_processor_id();
if (cpu != this_cpu) {
printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
this_cpu, cpu);
BUG();
}
#endif
printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
complete(&cpu_killed);
/* /*
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu); platform_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
* coherency, and then restore interrupts * coherency, and then restore interrupts
*/ */
cpu_leave_lowpower(); cpu_leave_lowpower();
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
} }
int platform_cpu_disable(unsigned int cpu) int platform_cpu_disable(unsigned int cpu)
......
...@@ -7,14 +7,13 @@ ...@@ -7,14 +7,13 @@
#define ASM_ARCH_SMP_H __FILE__ #define ASM_ARCH_SMP_H __FILE__
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/smp_mpidr.h>
/* /*
* We use IRQ1 as the IPI * We use IRQ1 as the IPI
*/ */
static inline void smp_cross_call(const struct cpumask *mask) static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{ {
gic_raise_softirq(mask, 1); gic_raise_softirq(mask, ipi);
} }
#endif #endif
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/unified.h> #include <asm/unified.h>
...@@ -38,6 +37,19 @@ extern void s5pv310_secondary_startup(void); ...@@ -38,6 +37,19 @@ extern void s5pv310_secondary_startup(void);
volatile int __cpuinitdata pen_release = -1; volatile int __cpuinitdata pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void write_pen_release(int val)
{
pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
}
static void __iomem *scu_base_addr(void) static void __iomem *scu_base_addr(void)
{ {
return (void __iomem *)(S5P_VA_SCU); return (void __iomem *)(S5P_VA_SCU);
...@@ -47,8 +59,6 @@ static DEFINE_SPINLOCK(boot_lock); ...@@ -47,8 +59,6 @@ static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu) void __cpuinit platform_secondary_init(unsigned int cpu)
{ {
trace_hardirqs_off();
/* /*
* if any interrupts are already enabled for the primary * if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled * 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,8 +70,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
* let the primary processor know we're out of the * let the primary processor know we're out of the
* pen, then head off into the C entry point * pen, then head off into the C entry point
*/ */
pen_release = -1; write_pen_release(-1);
smp_wmb();
/* /*
* Synchronise with the boot thread. * Synchronise with the boot thread.
...@@ -88,16 +97,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -88,16 +97,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* Note that "pen_release" is the hardware CPU ID, whereas * Note that "pen_release" is the hardware CPU ID, whereas
* "cpu" is Linux's internal ID. * "cpu" is Linux's internal ID.
*/ */
pen_release = cpu; write_pen_release(cpu);
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
/* /*
* Send the secondary CPU a soft interrupt, thereby causing * Send the secondary CPU a soft interrupt, thereby causing
* the boot monitor to read the system wide flags register, * the boot monitor to read the system wide flags register,
* and branch to the address found there. * and branch to the address found there.
*/ */
smp_cross_call(cpumask_of(cpu)); smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ); timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
...@@ -130,13 +137,6 @@ void __init smp_init_cpus(void) ...@@ -130,13 +137,6 @@ void __init smp_init_cpus(void)
ncores = scu_base ? scu_get_core_count(scu_base) : 1; ncores = scu_base ? scu_get_core_count(scu_base) : 1;
/* sanity check */ /* sanity check */
if (ncores == 0) {
printk(KERN_ERR
"S5PV310: strange CM count of 0? Default to 1\n");
ncores = 1;
}
if (ncores > NR_CPUS) { if (ncores > NR_CPUS) {
printk(KERN_WARNING printk(KERN_WARNING
"S5PV310: no. of cores (%d) greater than configured " "S5PV310: no. of cores (%d) greater than configured "
...@@ -149,18 +149,10 @@ void __init smp_init_cpus(void) ...@@ -149,18 +149,10 @@ void __init smp_init_cpus(void)
set_cpu_possible(i, true); set_cpu_possible(i, true);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = num_possible_cpus();
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/* are we trying to boot more cores than exist? */
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -168,17 +160,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -168,17 +160,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
/*
* Initialise the SCU if there are more than one CPU and let
* them know where to start.
*/
if (max_cpus > 1) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
scu_enable(scu_base_addr()); scu_enable(scu_base_addr());
/* /*
...@@ -188,5 +169,4 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -188,5 +169,4 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
* secondary CPU branches to this address. * secondary CPU branches to this address.
*/ */
__raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
}
} }
...@@ -6,7 +6,7 @@ config ARCH_SH7367 ...@@ -6,7 +6,7 @@ config ARCH_SH7367
bool "SH-Mobile G3 (SH7367)" bool "SH-Mobile G3 (SH7367)"
select CPU_V6 select CPU_V6
select HAVE_CLK select HAVE_CLK
select COMMON_CLKDEV select CLKDEV_LOOKUP
select SH_CLK_CPG select SH_CLK_CPG
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
...@@ -14,7 +14,7 @@ config ARCH_SH7377 ...@@ -14,7 +14,7 @@ config ARCH_SH7377
bool "SH-Mobile G4 (SH7377)" bool "SH-Mobile G4 (SH7377)"
select CPU_V7 select CPU_V7
select HAVE_CLK select HAVE_CLK
select COMMON_CLKDEV select CLKDEV_LOOKUP
select SH_CLK_CPG select SH_CLK_CPG
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
...@@ -22,7 +22,7 @@ config ARCH_SH7372 ...@@ -22,7 +22,7 @@ config ARCH_SH7372
bool "SH-Mobile AP4 (SH7372)" bool "SH-Mobile AP4 (SH7372)"
select CPU_V7 select CPU_V7
select HAVE_CLK select HAVE_CLK
select COMMON_CLKDEV select CLKDEV_LOOKUP
select SH_CLK_CPG select SH_CLK_CPG
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/sh_clk.h> #include <linux/sh_clk.h>
#include <linux/clkdev.h>
#include <mach/common.h> #include <mach/common.h>
#include <asm/clkdev.h>
/* SH7367 registers */ /* SH7367 registers */
#define RTFRQCR 0xe6150000 #define RTFRQCR 0xe6150000
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/sh_clk.h> #include <linux/sh_clk.h>
#include <linux/clkdev.h>
#include <mach/common.h> #include <mach/common.h>
#include <asm/clkdev.h>
/* SH7372 registers */ /* SH7372 registers */
#define FRQCRA 0xe6150000 #define FRQCRA 0xe6150000
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/sh_clk.h> #include <linux/sh_clk.h>
#include <linux/clkdev.h>
#include <mach/common.h> #include <mach/common.h>
#include <asm/clkdev.h>
/* SH7377 registers */ /* SH7377 registers */
#define RTFRQCR 0xe6150000 #define RTFRQCR 0xe6150000
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/irqs.h> #include <mach/irqs.h>
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <asm/clkdev.h> #include <linux/clkdev.h>
#include "clock.h" #include "clock.h"
#include "board.h" #include "board.h"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define __MACH_TEGRA_CLOCK_H #define __MACH_TEGRA_CLOCK_H
#include <linux/list.h> #include <linux/list.h>
#include <asm/clkdev.h> #include <linux/clkdev.h>
#define DIV_BUS (1 << 0) #define DIV_BUS (1 << 0)
#define DIV_U71 (1 << 1) #define DIV_U71 (1 << 1)
......
...@@ -11,12 +11,9 @@ ...@@ -11,12 +11,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/completion.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
static DECLARE_COMPLETION(cpu_killed);
static inline void cpu_enter_lowpower(void) static inline void cpu_enter_lowpower(void)
{ {
unsigned int v; unsigned int v;
...@@ -29,13 +26,13 @@ static inline void cpu_enter_lowpower(void) ...@@ -29,13 +26,13 @@ static inline void cpu_enter_lowpower(void)
* Turn off coherency * Turn off coherency
*/ */
" mrc p15, 0, %0, c1, c0, 1\n" " mrc p15, 0, %0, c1, c0, 1\n"
" bic %0, %0, #0x20\n" " bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 1\n" " mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n" " mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n" " bic %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n" " mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v) : "=&r" (v)
: "r" (0) : "r" (0), "Ir" (CR_C)
: "cc"); : "cc");
} }
...@@ -45,17 +42,17 @@ static inline void cpu_leave_lowpower(void) ...@@ -45,17 +42,17 @@ static inline void cpu_leave_lowpower(void)
asm volatile( asm volatile(
"mrc p15, 0, %0, c1, c0, 0\n" "mrc p15, 0, %0, c1, c0, 0\n"
" orr %0, %0, #0x04\n" " orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n" " mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n" " mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n" " orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n" " mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v) : "=&r" (v)
: : "Ir" (CR_C)
: "cc"); : "cc");
} }
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{ {
/* /*
* there is no power-control hardware on this platform, so all * 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,22 +76,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
/*}*/ /*}*/
/* /*
* getting here, means that we have come out of WFI without * Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen * having been woken up - this shouldn't happen
* *
* The trouble is, letting people know about this is not really * Just note it happening - when we're woken, we can report
* possible, since we are currently running incoherently, and * its occurrence.
* therefore cannot safely call printk() or anything else
*/ */
#ifdef DEBUG (*spurious)++;
printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
#endif
} }
} }
int platform_cpu_kill(unsigned int cpu) int platform_cpu_kill(unsigned int cpu)
{ {
return wait_for_completion_timeout(&cpu_killed, 5000); return 1;
} }
/* /*
...@@ -104,30 +98,22 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -104,30 +98,22 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
#ifdef DEBUG int spurious = 0;
unsigned int this_cpu = hard_smp_processor_id();
if (cpu != this_cpu) {
printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
this_cpu, cpu);
BUG();
}
#endif
printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
complete(&cpu_killed);
/* /*
* we're ready for shutdown now, so do it * we're ready for shutdown now, so do it
*/ */
cpu_enter_lowpower(); cpu_enter_lowpower();
platform_do_lowpower(cpu); platform_do_lowpower(cpu, &spurious);
/* /*
* bring this CPU back into the world of cache * bring this CPU back into the world of cache
* coherency, and then restore interrupts * coherency, and then restore interrupts
*/ */
cpu_leave_lowpower(); cpu_leave_lowpower();
if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
} }
int platform_cpu_disable(unsigned int cpu) int platform_cpu_disable(unsigned int cpu)
......
...@@ -2,21 +2,13 @@ ...@@ -2,21 +2,13 @@
#define ASMARM_ARCH_SMP_H #define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/smp_mpidr.h>
/* /*
* We use IRQ1 as the IPI * We use IRQ1 as the IPI
*/ */
static inline void smp_cross_call(const struct cpumask *mask) static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{
gic_raise_softirq(mask, 1);
}
/*
* Do nothing on MPcore.
*/
static inline void smp_cross_call_done(cpumask_t callmap)
{ {
gic_raise_softirq(mask, ipi);
} }
#endif #endif
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/iomap.h> #include <mach/iomap.h>
...@@ -41,8 +40,6 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); ...@@ -41,8 +40,6 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
void __cpuinit platform_secondary_init(unsigned int cpu) void __cpuinit platform_secondary_init(unsigned int cpu)
{ {
trace_hardirqs_off();
/* /*
* if any interrupts are already enabled for the primary * if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled * core (e.g. timer irq), then they will not have been enabled
...@@ -117,24 +114,20 @@ void __init smp_init_cpus(void) ...@@ -117,24 +114,20 @@ void __init smp_init_cpus(void)
{ {
unsigned int i, ncores = scu_get_core_count(scu_base); unsigned int i, ncores = scu_get_core_count(scu_base);
if (ncores > NR_CPUS) {
printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
ncores, NR_CPUS);
ncores = NR_CPUS;
}
for (i = 0; i < ncores; i++) for (i = 0; i < ncores; i++)
cpu_set(i, cpu_possible_map); cpu_set(i, cpu_possible_map);
} }
void __init smp_prepare_cpus(unsigned int max_cpus) void __init platform_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = scu_get_core_count(scu_base);
unsigned int cpu = smp_processor_id();
int i; int i;
smp_store_cpu_info(cpu);
/*
* are we trying to boot more cores than exist?
*/
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
* actually populated at the present time. * actually populated at the present time.
...@@ -142,15 +135,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -142,15 +135,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
/*
* Initialise the SCU if there are more than one CPU and let
* them know where to start. Note that, on modern versions of
* MILO, the "poke" doesn't actually do anything until each
* individual core is sent a soft interrupt to get it out of
* WFI
*/
if (max_cpus > 1) {
percpu_timer_setup();
scu_enable(scu_base); scu_enable(scu_base);
}
} }
...@@ -24,8 +24,7 @@ ...@@ -24,8 +24,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/iomap.h> #include <mach/iomap.h>
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/syscon.h> #include <mach/syscon.h>
......
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <plat/mtu.h> #include <plat/mtu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -23,7 +23,6 @@ ENTRY(u8500_secondary_startup) ...@@ -23,7 +23,6 @@ ENTRY(u8500_secondary_startup)
ldmia r4, {r5, r6} ldmia r4, {r5, r6}
sub r4, r4, r5 sub r4, r4, r5
add r6, r6, r4 add r6, r6, r4
dsb
pen: ldr r7, [r6] pen: ldr r7, [r6]
cmp r7, r0 cmp r7, r0
bne pen bne pen
......
...@@ -11,14 +11,11 @@ ...@@ -11,14 +11,11 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/completion.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
extern volatile int pen_release; extern volatile int pen_release;
static DECLARE_COMPLETION(cpu_killed);
static inline void platform_do_lowpower(unsigned int cpu) static inline void platform_do_lowpower(unsigned int cpu)
{ {
flush_cache_all(); flush_cache_all();
...@@ -38,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu) ...@@ -38,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
int platform_cpu_kill(unsigned int cpu) int platform_cpu_kill(unsigned int cpu)
{ {
return wait_for_completion_timeout(&cpu_killed, 5000); return 1;
} }
/* /*
...@@ -48,19 +45,6 @@ int platform_cpu_kill(unsigned int cpu) ...@@ -48,19 +45,6 @@ int platform_cpu_kill(unsigned int cpu)
*/ */
void platform_cpu_die(unsigned int cpu) void platform_cpu_die(unsigned int cpu)
{ {
#ifdef DEBUG
unsigned int this_cpu = hard_smp_processor_id();
if (cpu != this_cpu) {
printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
this_cpu, cpu);
BUG();
}
#endif
printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
complete(&cpu_killed);
/* directly enter low power state, skipping secure registers */ /* directly enter low power state, skipping secure registers */
platform_do_lowpower(cpu); platform_do_lowpower(cpu);
} }
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#define ASMARM_ARCH_SMP_H #define ASMARM_ARCH_SMP_H
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/smp_mpidr.h>
/* This is required to wakeup the secondary core */ /* This is required to wakeup the secondary core */
extern void u8500_secondary_startup(void); extern void u8500_secondary_startup(void);
...@@ -18,8 +17,8 @@ extern void u8500_secondary_startup(void); ...@@ -18,8 +17,8 @@ extern void u8500_secondary_startup(void);
/* /*
* We use IRQ1 as the IPI * We use IRQ1 as the IPI
*/ */
static inline void smp_cross_call(const struct cpumask *mask) static inline void smp_cross_call(const struct cpumask *mask, int ipi)
{ {
gic_raise_softirq(mask, 1); gic_raise_softirq(mask, ipi);
} }
#endif #endif
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/localtimer.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -28,17 +27,23 @@ ...@@ -28,17 +27,23 @@
*/ */
volatile int __cpuinitdata pen_release = -1; volatile int __cpuinitdata pen_release = -1;
static unsigned int __init get_core_count(void) /*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably.
*/
static void write_pen_release(int val)
{ {
return scu_get_core_count(__io_address(UX500_SCU_BASE)); pen_release = val;
smp_wmb();
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
} }
static DEFINE_SPINLOCK(boot_lock); static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu) void __cpuinit platform_secondary_init(unsigned int cpu)
{ {
trace_hardirqs_off();
/* /*
* if any interrupts are already enabled for the primary * if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled * 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,7 +55,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
* let the primary processor know we're out of the * let the primary processor know we're out of the
* pen, then head off into the C entry point * pen, then head off into the C entry point
*/ */
pen_release = -1; write_pen_release(-1);
/* /*
* Synchronise with the boot thread. * Synchronise with the boot thread.
...@@ -74,11 +79,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -74,11 +79,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* the holding pen - release it, then wait for it to flag * the holding pen - release it, then wait for it to flag
* that it has been released by resetting pen_release. * that it has been released by resetting pen_release.
*/ */
pen_release = cpu; write_pen_release(cpu);
__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
smp_cross_call(cpumask_of(cpu)); smp_cross_call(cpumask_of(cpu), 1);
timeout = jiffies + (1 * HZ); timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) { while (time_before(jiffies, timeout)) {
...@@ -97,9 +100,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) ...@@ -97,9 +100,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
static void __init wakeup_secondary(void) static void __init wakeup_secondary(void)
{ {
/* nobody is to be released from the pen yet */
pen_release = -1;
/* /*
* write the address of secondary startup into the backup ram register * write the address of secondary startup into the backup ram register
* at offset 0x1FF4, then write the magic number 0xA1FEED01 to the * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
...@@ -126,40 +126,26 @@ static void __init wakeup_secondary(void) ...@@ -126,40 +126,26 @@ static void __init wakeup_secondary(void)
*/ */
void __init smp_init_cpus(void) void __init smp_init_cpus(void)
{ {
unsigned int i, ncores = get_core_count(); unsigned int i, ncores;
for (i = 0; i < ncores; i++) ncores = scu_get_core_count(__io_address(UX500_SCU_BASE));
set_cpu_possible(i, true);
}
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int ncores = get_core_count();
unsigned int cpu = smp_processor_id();
int i;
/* sanity check */ /* sanity check */
if (ncores == 0) { if (ncores > NR_CPUS) {
printk(KERN_ERR
"U8500: strange CM count of 0? Default to 1\n");
ncores = 1;
}
if (ncores > num_possible_cpus()) {
printk(KERN_WARNING printk(KERN_WARNING
"U8500: no. of cores (%d) greater than configured " "U8500: no. of cores (%d) greater than configured "
"maximum of %d - clipping\n", "maximum of %d - clipping\n",
ncores, num_possible_cpus()); ncores, NR_CPUS);
ncores = num_possible_cpus(); ncores = NR_CPUS;
} }
smp_store_cpu_info(cpu); for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);
}
/* void __init platform_smp_prepare_cpus(unsigned int max_cpus)
* are we trying to boot more cores than exist? {
*/ int i;
if (max_cpus > ncores)
max_cpus = ncores;
/* /*
* Initialise the present map, which describes the set of CPUs * Initialise the present map, which describes the set of CPUs
...@@ -168,13 +154,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -168,13 +154,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++) for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true); set_cpu_present(i, true);
if (max_cpus > 1) {
/*
* Enable the local timer or broadcast device for the
* boot CPU, but only if we have more than one CPU.
*/
percpu_timer_setup();
scu_enable(__io_address(UX500_SCU_BASE)); scu_enable(__io_address(UX500_SCU_BASE));
wakeup_secondary(); wakeup_secondary();
}
} }
...@@ -4,6 +4,7 @@ menu "Versatile platform type" ...@@ -4,6 +4,7 @@ menu "Versatile platform type"
config ARCH_VERSATILE_PB config ARCH_VERSATILE_PB
bool "Support Versatile/PB platform" bool "Support Versatile/PB platform"
select CPU_ARM926T select CPU_ARM926T
select MIGHT_HAVE_PCI
default y default y
help help
Include support for the ARM(R) Versatile/PB platform. Include support for the ARM(R) Versatile/PB platform.
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#include <linux/amba/pl022.h> #include <linux/amba/pl022.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/clkdev.h>
#include <asm/clkdev.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/leds.h> #include <asm/leds.h>
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <mach/clkdev.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/platform.h> #include <mach/platform.h>
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment