summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig10
-rw-r--r--arch/arm/Makefile5
-rw-r--r--arch/arm/boot/Makefile12
-rw-r--r--arch/arm/boot/compressed/head.S14
-rw-r--r--arch/arm/boot/dts/Makefile56
-rw-r--r--arch/arm/boot/dts/animeo_ip.dts178
-rw-r--r--arch/arm/boot/dts/at91rm9200.dtsi349
-rw-r--r--arch/arm/boot/dts/at91rm9200ek.dts79
-rw-r--r--arch/arm/boot/dts/at91sam9260.dtsi295
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi299
-rw-r--r--arch/arm/boot/dts/at91sam9263ek.dts29
-rw-r--r--arch/arm/boot/dts/at91sam9g15.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g15ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_2mmc.dts26
-rw-r--r--arch/arm/boot/dts/at91sam9g20ek_common.dtsi30
-rw-r--r--arch/arm/boot/dts/at91sam9g25.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g25ek.dts49
-rw-r--r--arch/arm/boot/dts/at91sam9g35.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9g35ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi301
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts48
-rw-r--r--arch/arm/boot/dts/at91sam9n12.dtsi225
-rw-r--r--arch/arm/boot/dts/at91sam9n12ek.dts22
-rw-r--r--arch/arm/boot/dts/at91sam9x25.dtsi49
-rw-r--r--arch/arm/boot/dts/at91sam9x25ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9x35.dtsi28
-rw-r--r--arch/arm/boot/dts/at91sam9x35ek.dts16
-rw-r--r--arch/arm/boot/dts/at91sam9x5.dtsi270
-rw-r--r--arch/arm/boot/dts/at91sam9x5ek.dtsi101
-rw-r--r--arch/arm/boot/dts/dbx5x0.dtsi14
-rw-r--r--arch/arm/boot/dts/imx28.dtsi1
-rw-r--r--arch/arm/boot/dts/pm9g45.dts165
-rw-r--r--arch/arm/boot/dts/snowball.dts31
-rw-r--r--arch/arm/boot/dts/spear1310-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear1310.dtsi27
-rw-r--r--arch/arm/boot/dts/spear1340-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear1340.dtsi26
-rw-r--r--arch/arm/boot/dts/spear310.dtsi22
-rw-r--r--arch/arm/boot/dts/spear320-evb.dts4
-rw-r--r--arch/arm/boot/dts/spear320.dtsi23
-rw-r--r--arch/arm/boot/dts/tegra20-seaboard.dts4
-rw-r--r--arch/arm/common/gic.c45
-rw-r--r--arch/arm/common/timer-sp.c2
-rw-r--r--arch/arm/common/vic.c19
-rw-r--r--arch/arm/configs/afeb9260_defconfig2
-rw-r--r--arch/arm/configs/at91_dt_defconfig1
-rw-r--r--arch/arm/configs/at91sam9260_defconfig2
-rw-r--r--arch/arm/configs/at91sam9261_defconfig2
-rw-r--r--arch/arm/configs/at91sam9263_defconfig2
-rw-r--r--arch/arm/configs/at91sam9g20_defconfig2
-rw-r--r--arch/arm/configs/corgi_defconfig2
-rw-r--r--arch/arm/configs/davinci_all_defconfig2
-rw-r--r--arch/arm/configs/h7202_defconfig3
-rw-r--r--arch/arm/configs/magician_defconfig2
-rw-r--r--arch/arm/configs/mini2440_defconfig2
-rw-r--r--arch/arm/configs/omap1_defconfig3
-rw-r--r--arch/arm/configs/prima2_defconfig1
-rw-r--r--arch/arm/configs/spitz_defconfig2
-rw-r--r--arch/arm/configs/stamp9g20_defconfig2
-rw-r--r--arch/arm/configs/u8500_defconfig2
-rw-r--r--arch/arm/configs/viper_defconfig2
-rw-r--r--arch/arm/configs/zeus_defconfig2
-rw-r--r--arch/arm/include/asm/Kbuild2
-rw-r--r--arch/arm/include/asm/assembler.h8
-rw-r--r--arch/arm/include/asm/cpu.h1
-rw-r--r--arch/arm/include/asm/cputype.h13
-rw-r--r--arch/arm/include/asm/cti.h20
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h5
-rw-r--r--arch/arm/include/asm/hardware/sp810.h2
-rw-r--r--arch/arm/include/asm/hardware/vic.h2
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h8
-rw-r--r--arch/arm/include/asm/io.h2
-rw-r--r--arch/arm/include/asm/mach/serial_at91.h33
-rw-r--r--arch/arm/include/asm/mach/serial_sa1100.h31
-rw-r--r--arch/arm/include/asm/mach/udc_pxa2xx.h26
-rw-r--r--arch/arm/include/asm/mmu.h13
-rw-r--r--arch/arm/include/asm/mmu_context.h88
-rw-r--r--arch/arm/include/asm/percpu.h45
-rw-r--r--arch/arm/include/asm/perf_event.h7
-rw-r--r--arch/arm/include/asm/pgtable-2level.h2
-rw-r--r--arch/arm/include/asm/pgtable-3level.h4
-rw-r--r--arch/arm/include/asm/pgtable.h10
-rw-r--r--arch/arm/include/asm/pmu.h28
-rw-r--r--arch/arm/include/asm/prom.h4
-rw-r--r--arch/arm/include/asm/smp.h1
-rw-r--r--arch/arm/include/asm/smp_plat.h17
-rw-r--r--arch/arm/include/asm/syscall.h9
-rw-r--r--arch/arm/include/asm/thread_info.h7
-rw-r--r--arch/arm/kernel/devtree.c104
-rw-r--r--arch/arm/kernel/entry-common.S16
-rw-r--r--arch/arm/kernel/head-nommu.S2
-rw-r--r--arch/arm/kernel/hw_breakpoint.c154
-rw-r--r--arch/arm/kernel/perf_event.c85
-rw-r--r--arch/arm/kernel/perf_event_cpu.c74
-rw-r--r--arch/arm/kernel/perf_event_v6.c126
-rw-r--r--arch/arm/kernel/perf_event_v7.c246
-rw-r--r--arch/arm/kernel/perf_event_xscale.c157
-rw-r--r--arch/arm/kernel/process.c4
-rw-r--r--arch/arm/kernel/ptrace.c43
-rw-r--r--arch/arm/kernel/setup.c84
-rw-r--r--arch/arm/kernel/smp.c12
-rw-r--r--arch/arm/kernel/smp_twd.c54
-rw-r--r--arch/arm/kernel/topology.c42
-rw-r--r--arch/arm/kernel/vmlinux.lds.S19
-rw-r--r--arch/arm/mach-at91/Kconfig9
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/at91rm9200.c22
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c63
-rw-r--r--arch/arm/mach-at91/at91sam9260.c8
-rw-r--r--arch/arm/mach-at91/at91sam9261.c4
-rw-r--r--arch/arm/mach-at91/at91sam9263.c11
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c12
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c16
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c4
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c21
-rw-r--r--arch/arm/mach-at91/board-dt.c2
-rw-r--r--arch/arm/mach-at91/board-rm9200-dt.c57
-rw-r--r--arch/arm/mach-at91/generic.h1
-rw-r--r--arch/arm/mach-at91/gpio.c190
-rw-r--r--arch/arm/mach-at91/include/mach/board.h10
-rw-r--r--arch/arm/mach-at91/setup.c20
-rw-r--r--arch/arm/mach-at91/soc.h12
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c53
-rw-r--r--arch/arm/mach-davinci/dm644x.c3
-rw-r--r--arch/arm/mach-dove/include/mach/pm.h2
-rw-r--r--arch/arm/mach-dove/irq.c14
-rw-r--r--arch/arm/mach-exynos/dma.c3
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h1
-rw-r--r--arch/arm/mach-integrator/impd1.c76
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/udc.h2
-rw-r--r--arch/arm/mach-kirkwood/pcie.c11
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c3
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c2
-rw-r--r--arch/arm/mach-nomadik/i2c-8815nhk.c3
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c5
-rw-r--r--arch/arm/mach-omap2/board-overo.c1
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c34
-rw-r--r--arch/arm/mach-omap2/drm.c7
-rw-r--r--arch/arm/mach-omap2/pmu.c2
-rw-r--r--arch/arm/mach-omap2/twl-common.c1
-rw-r--r--arch/arm/mach-pxa/include/mach/udc.h2
-rw-r--r--arch/arm/mach-realview/realview_eb.c1
-rw-r--r--arch/arm/mach-sa1100/assabet.c2
-rw-r--r--arch/arm/mach-sa1100/badge4.c2
-rw-r--r--arch/arm/mach-sa1100/cerf.c2
-rw-r--r--arch/arm/mach-sa1100/collie.c2
-rw-r--r--arch/arm/mach-sa1100/h3xxx.c2
-rw-r--r--arch/arm/mach-sa1100/hackkit.c2
-rw-r--r--arch/arm/mach-sa1100/jornada720.c2
-rw-r--r--arch/arm/mach-sa1100/lart.c2
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c2
-rw-r--r--arch/arm/mach-sa1100/neponset.c2
-rw-r--r--arch/arm/mach-sa1100/pleb.c2
-rw-r--r--arch/arm/mach-sa1100/shannon.c2
-rw-r--r--arch/arm/mach-sa1100/simpad.c2
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c2
-rw-r--r--arch/arm/mach-u300/core.c5
-rw-r--r--arch/arm/mach-u300/include/mach/irqs.h126
-rw-r--r--arch/arm/mach-ux500/board-mop500-audio.c3
-rw-r--r--arch/arm/mach-ux500/board-mop500-pins.c3
-rw-r--r--arch/arm/mach-ux500/board-mop500.c66
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c12
-rw-r--r--arch/arm/mach-ux500/devices-common.c3
-rw-r--r--arch/arm/mach-ux500/devices-common.h8
-rw-r--r--arch/arm/mach-vexpress/v2m.c2
-rw-r--r--arch/arm/mm/cache-aurora-l2.h55
-rw-r--r--arch/arm/mm/cache-l2x0.c278
-rw-r--r--arch/arm/mm/context.c207
-rw-r--r--arch/arm/mm/idmap.c14
-rw-r--r--arch/arm/mm/ioremap.c16
-rw-r--r--arch/arm/mm/mmap.c134
-rw-r--r--arch/arm/mm/mmu.c2
-rw-r--r--arch/arm/mm/proc-macros.S4
-rw-r--r--arch/arm/mm/proc-v6.S2
-rw-r--r--arch/arm/mm/proc-v7-2level.S10
-rw-r--r--arch/arm/mm/proc-v7-3level.S5
-rw-r--r--arch/arm/mm/proc-v7.S2
-rw-r--r--arch/arm/net/bpf_jit_32.c6
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio-nomadik.h102
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h173
-rw-r--r--arch/arm/plat-omap/i2c.c21
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h55
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h9
-rw-r--r--arch/arm/plat-s3c24xx/dma.c9
-rw-r--r--arch/arm/plat-spear/Kconfig1
186 files changed, 4634 insertions, 2077 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ade7e924bef5..825066e29c38 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,8 +5,9 @@ config ARM
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_WANT_IPC_PARSE_VERSION
+ select BUILDTIME_EXTABLE_SORT if MMU
select CPU_PM if (SUSPEND || CPU_IDLE)
- select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
+ select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU
select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GENERIC_IRQ_PROBE
@@ -21,6 +22,7 @@ config ARM
select HAVE_AOUT
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
+ select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_BPF_JIT
select HAVE_C_RECORDMCOUNT
@@ -330,6 +332,8 @@ config ARCH_AT91
select IRQ_DOMAIN
select NEED_MACH_GPIO_H
select NEED_MACH_IO_H if PCCARD
+ select PINCTRL
+ select PINCTRL_AT91 if USE_OF
help
This enables support for systems based on Atmel
AT91RM9200 and AT91SAM9* processors.
@@ -364,6 +368,7 @@ config ARCH_CNS3XXX
config ARCH_CLPS711X
bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
+ select ARCH_REQUIRE_GPIOLIB
select ARCH_USES_GETTIMEOFFSET
select CLKDEV_LOOKUP
select COMMON_CLK
@@ -547,6 +552,7 @@ config ARCH_KIRKWOOD
select CPU_FEROCEON
select GENERIC_CLOCKEVENTS
select PCI
+ select PCI_QUIRKS
select PLAT_ORION_LEGACY
help
Support for the following Marvell Kirkwood series SoCs:
@@ -586,6 +592,7 @@ config ARCH_MMP
select GPIO_PXA
select IRQ_DOMAIN
select NEED_MACH_GPIO_H
+ select PINCTRL
select PLAT_PXA
select SPARSE_IRQ
help
@@ -904,6 +911,7 @@ config ARCH_NOMADIK
config PLAT_SPEAR
bool "ST SPEAr"
+ select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select CLKDEV_LOOKUP
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 5f914fca911b..45096a1ee0a0 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -32,6 +32,7 @@ KBUILD_DEFCONFIG := versatile_defconfig
# defines filename extension depending memory management type.
ifeq ($(CONFIG_MMU),)
MMUEXT := -nommu
+KBUILD_CFLAGS += $(call cc-option,-mno-unaligned-access)
endif
ifeq ($(CONFIG_FRAME_POINTER),y)
@@ -292,10 +293,10 @@ zinstall uinstall install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
%.dtb: scripts
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
dtbs: scripts
- $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) dtbs
# We use MRPROPER_FILES and CLEAN_FILES now
archclean:
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 9137df539b61..abfce280f57b 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -15,8 +15,6 @@ ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
endif
-include $(srctree)/arch/arm/boot/dts/Makefile
-
# Note: the following conditions must always be true:
# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
# PARAMS_PHYS must be within 4MB of ZRELADDR
@@ -59,16 +57,6 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
endif
-targets += $(dtb-y)
-
-# Rule to build device tree blobs
-$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call if_changed_dep,dtc)
-
-$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
-
-clean-files := *.dtb
-
ifneq ($(LOADADDR),)
UIMAGE_LOADADDR=$(LOADADDR)
else
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 90275f036cd1..49ca86e37b8d 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -652,6 +652,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
mov pc, lr
ENDPROC(__setup_mmu)
+@ Enable unaligned access on v6, to allow better code generation
+@ for the decompressor C code:
+__armv6_mmu_cache_on:
+ mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
+ bic r0, r0, #2 @ A (no unaligned access fault)
+ orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
+ mcr p15, 0, r0, c1, c0, 0 @ write SCTLR
+ b __armv4_mmu_cache_on
+
__arm926ejs_mmu_cache_on:
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
mov r0, #4 @ put dcache in WT mode
@@ -694,6 +703,9 @@ __armv7_mmu_cache_on:
bic r0, r0, #1 << 28 @ clear SCTLR.TRE
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
orr r0, r0, #0x003c @ write buffer
+ bic r0, r0, #2 @ A (no unaligned access fault)
+ orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
+ @ (needed for ARM1176)
#ifdef CONFIG_MMU
#ifdef CONFIG_CPU_ENDIAN_BE8
orr r0, r0, #1 << 25 @ big-endian page tables
@@ -914,7 +926,7 @@ proc_types:
.word 0x0007b000 @ ARMv6
.word 0x000ff000
- W(b) __armv4_mmu_cache_on
+ W(b) __armv6_mmu_cache_on
W(b) __armv4_mmu_cache_off
W(b) __armv6_mmu_cache_flush
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f37cf9fa5fa0..262493752234 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1,21 +1,37 @@
ifeq ($(CONFIG_OF),y)
-dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb \
- at91sam9263ek.dtb \
- at91sam9g20ek_2mmc.dtb \
- at91sam9g20ek.dtb \
- at91sam9g25ek.dtb \
- at91sam9m10g45ek.dtb \
- at91sam9n12ek.dtb \
- ethernut5.dtb \
- evk-pro3.dtb \
- kizbox.dtb \
- tny_a9260.dtb \
- tny_a9263.dtb \
- tny_a9g20.dtb \
- usb_a9260.dtb \
- usb_a9263.dtb \
- usb_a9g20.dtb
+# Keep at91 dtb files sorted alphabetically for each SoC
+# rm9200
+dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb
+# sam9260
+dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb
+dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb
+dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb
+dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb
+dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb
+# sam9263
+dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9263.dtb
+# sam9g20
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek_2mmc.dtb
+dtb-$(CONFIG_ARCH_AT91) += kizbox.dtb
+dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb
+dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb
+# sam9g45
+dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb
+# sam9n12
+dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb
+# sam9x5
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
+dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
+
dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
dove-cubox.dtb \
@@ -104,4 +120,12 @@ dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
wm8505-ref.dtb \
wm8650-mid.dtb
+targets += dtbs
endif
+
+# *.dtb used to be generated in the directory above. Clean out the
+# old build results so people don't accidentally use them.
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+ $(Q)rm -f $(obj)/../*.dtb
+
+clean-files := *.dtb
diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts
new file mode 100644
index 000000000000..74d92cd29d87
--- /dev/null
+++ b/arch/arm/boot/dts/animeo_ip.dts
@@ -0,0 +1,178 @@
+/*
+ * animeo_ip.dts - Device Tree file for Somfy Animeo IP Boards
+ *
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 only.
+ */
+
+/dts-v1/;
+/include/ "at91sam9260.dtsi"
+
+/ {
+ model = "Somfy Animeo IP";
+ compatible = "somfy,animeo-ip", "atmel,at91sam9260", "atmel,at91sam9";
+
+ aliases {
+ serial0 = &usart1;
+ serial1 = &usart2;
+ serial2 = &usart0;
+ serial3 = &dbgu;
+ serial4 = &usart3;
+ serial5 = &uart0;
+ serial6 = &uart1;
+ };
+
+ chosen {
+ linux,stdout-path = &usart2;
+ };
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ usart0: serial@fffb0000 {
+ pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ usart1: serial@fffb4000 {
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+ };
+
+ usart2: serial@fffb8000 {
+ pinctrl-0 = <&pinctrl_usart2>;
+ status = "okay";
+ };
+
+ macb0: ethernet@fffc4000 {
+ pinctrl-0 = <&pinctrl_macb_rmii &pinctrl_macb_rmii_mii>;
+ phy-mode = "mii";
+ status = "okay";
+ };
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <&pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ };
+ };
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x8000>;
+ };
+
+ barebox@8000 {
+ label = "barebox";
+ reg = <0x8000 0x40000>;
+ };
+
+ bareboxenv@48000 {
+ label = "bareboxenv";
+ reg = <0x48000 0x8000>;
+ };
+
+ user_block@0x50000 {
+ label = "user_block";
+ reg = <0x50000 0xb0000>;
+ };
+
+ kernel@100000 {
+ label = "kernel";
+ reg = <0x100000 0x1b0000>;
+ };
+
+ root@2b0000 {
+ label = "root";
+ reg = <0x2b0000 0x1D50000>;
+ };
+ };
+
+ usb0: ohci@00500000 {
+ num-ports = <2>;
+ atmel,vbus-gpio = <&pioB 15 1>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ power_green {
+ label = "power_green";
+ gpios = <&pioC 17 0>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ power_red {
+ label = "power_red";
+ gpios = <&pioA 2 0>;
+ };
+
+ tx_green {
+ label = "tx_green";
+ gpios = <&pioC 19 0>;
+ };
+
+ tx_red {
+ label = "tx_red";
+ gpios = <&pioC 18 0>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ keyswitch_in {
+ label = "keyswitch_in";
+ gpios = <&pioB 1 0>;
+ linux,code = <28>;
+ gpio-key,wakeup;
+ };
+
+ error_in {
+ label = "error_in";
+ gpios = <&pioB 2 0>;
+ linux,code = <29>;
+ gpio-key,wakeup;
+ };
+
+ btn {
+ label = "btn";
+ gpios = <&pioC 23 0>;
+ linux,code = <31>;
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
new file mode 100644
index 000000000000..e154f242c680
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -0,0 +1,349 @@
+/*
+ * at91rm9200.dtsi - Device Tree Include file for AT91RM9200 family SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>,
+ * 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Based on at91sam9260.dtsi
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Atmel AT91RM9200 family SoC";
+ compatible = "atmel,at91rm9200";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ gpio0 = &pioA;
+ gpio1 = &pioB;
+ gpio2 = &pioC;
+ gpio3 = &pioD;
+ tcb0 = &tcb0;
+ tcb1 = &tcb1;
+ };
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm920t";
+ };
+ };
+
+ memory {
+ reg = <0x20000000 0x04000000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <3>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ reg = <0xfffff000 0x200>;
+ atmel,external-irqs = <25 26 27 28 29 30 31>;
+ };
+
+ ramc0: ramc@ffffff00 {
+ compatible = "atmel,at91rm9200-sdramc";
+ reg = <0xffffff00 0x100>;
+ };
+
+ pmc: pmc@fffffc00 {
+ compatible = "atmel,at91rm9200-pmc";
+ reg = <0xfffffc00 0x100>;
+ };
+
+ st: timer@fffffd00 {
+ compatible = "atmel,at91rm9200-st";
+ reg = <0xfffffd00 0x100>;
+ interrupts = <1 4 7>;
+ };
+
+ tcb0: timer@fffa0000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa0000 0x100>;
+ interrupts = <17 4 0 18 4 0 19 4 0>;
+ };
+
+ tcb1: timer@fffa4000 {
+ compatible = "atmel,at91rm9200-tcb";
+ reg = <0xfffa4000 0x100>;
+ interrupts = <20 4 0 21 4 0 22 4 0>;
+ };
+
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffffffff /* pioA */
+ 0xffffffff 0x083fffff /* pioB */
+ 0xffff3fff 0x00000000 /* pioC */
+ 0x03ff87ff 0x0fffff80 /* pioD */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <0 30 0x1 0x0 /* PA30 periph A */
+ 0 31 0x1 0x1>; /* PA31 periph with pullup */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <0 17 0x1 0x0 /* PA17 periph A */
+ 0 18 0x1 0x0>; /* PA18 periph A */
+ };
+
+ pinctrl_uart0_rts: uart0_rts-0 {
+ atmel,pins =
+ <0 20 0x1 0x0>; /* PA20 periph A */
+ };
+
+ pinctrl_uart0_cts: uart0_cts-0 {
+ atmel,pins =
+ <0 21 0x1 0x0>; /* PA21 periph A */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <1 20 0x1 0x1 /* PB20 periph A with pullup */
+ 1 21 0x1 0x0>; /* PB21 periph A */
+ };
+
+ pinctrl_uart1_rts: uart1_rts-0 {
+ atmel,pins =
+ <1 24 0x1 0x0>; /* PB24 periph A */
+ };
+
+ pinctrl_uart1_cts: uart1_cts-0 {
+ atmel,pins =
+ <1 26 0x1 0x0>; /* PB26 periph A */
+ };
+
+ pinctrl_uart1_dtr_dsr: uart1_dtr_dsr-0 {
+ atmel,pins =
+ <1 19 0x1 0x0 /* PB19 periph A */
+ 1 25 0x1 0x0>; /* PB25 periph A */
+ };
+
+ pinctrl_uart1_dcd: uart1_dcd-0 {
+ atmel,pins =
+ <1 23 0x1 0x0>; /* PB23 periph A */
+ };
+
+ pinctrl_uart1_ri: uart1_ri-0 {
+ atmel,pins =
+ <1 18 0x1 0x0>; /* PB18 periph A */
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2: uart2-0 {
+ atmel,pins =
+ <0 22 0x1 0x0 /* PA22 periph A */
+ 0 23 0x1 0x1>; /* PA23 periph A with pullup */
+ };
+
+ pinctrl_uart2_rts: uart2_rts-0 {
+ atmel,pins =
+ <0 30 0x2 0x0>; /* PA30 periph B */
+ };
+
+ pinctrl_uart2_cts: uart2_cts-0 {
+ atmel,pins =
+ <0 31 0x2 0x0>; /* PA31 periph B */
+ };
+ };
+
+ uart3 {
+ pinctrl_uart3: uart3-0 {
+ atmel,pins =
+ <0 5 0x2 0x1 /* PA5 periph B with pullup */
+ 0 6 0x2 0x0>; /* PA6 periph B */
+ };
+
+ pinctrl_uart3_rts: uart3_rts-0 {
+ atmel,pins =
+ <1 0 0x2 0x0>; /* PB0 periph B */
+ };
+
+ pinctrl_uart3_cts: uart3_cts-0 {
+ atmel,pins =
+ <1 1 0x2 0x0>; /* PB1 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <2 2 0x0 0x1 /* PC2 gpio RDY pin pull_up */
+ 1 1 0x0 0x1>; /* PB1 gpio CD pin pull_up */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
+ status = "disabled";
+ };
+
+ usart0: serial@fffc0000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc0000 0x200>;
+ interrupts = <6 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ status = "disabled";
+ };
+
+ usart1: serial@fffc4000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc4000 0x200>;
+ interrupts = <7 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "disabled";
+ };
+
+ usart2: serial@fffc8000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffc8000 0x200>;
+ interrupts = <8 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "disabled";
+ };
+
+ usart3: serial@fffcc000 {
+ compatible = "atmel,at91rm9200-usart";
+ reg = <0xfffcc000 0x200>;
+ interrupts = <23 4 5>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "disabled";
+ };
+
+ usb1: gadget@fffb0000 {
+ compatible = "atmel,at91rm9200-udc";
+ reg = <0xfffb0000 0x4000>;
+ interrupts = <11 4 2>;
+ status = "disabled";
+ };
+ };
+
+ nand0: nand@40000000 {
+ compatible = "atmel,at91rm9200-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x40000000 0x10000000>;
+ atmel,nand-addr-offset = <21>;
+ atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
+ nand-ecc-mode = "soft";
+ gpios = <&pioC 2 0
+ 0
+ &pioB 1 0
+ >;
+ status = "disabled";
+ };
+
+ usb0: ohci@00300000 {
+ compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+ reg = <0x00300000 0x100000>;
+ interrupts = <23 4 2>;
+ status = "disabled";
+ };
+ };
+
+ i2c@0 {
+ compatible = "i2c-gpio";
+ gpios = <&pioA 23 0 /* sda */
+ &pioA 24 0 /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ i2c-gpio,delay-us = <2>; /* ~100 kHz */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts
new file mode 100644
index 000000000000..8aa48931e0a2
--- /dev/null
+++ b/arch/arm/boot/dts/at91rm9200ek.dts
@@ -0,0 +1,79 @@
+/*
+ * at91rm9200ek.dts - Device Tree file for Atmel AT91RM9200 evaluation kit
+ *
+ * Copyright (C) 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 only
+ */
+/dts-v1/;
+/include/ "at91rm9200.dtsi"
+
+/ {
+ model = "Atmel AT91RM9200 evaluation kit";
+ compatible = "atmel,at91rm9200ek", "atmel,at91rm9200";
+
+ memory {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <18432000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart1: serial@fffc4000 {
+ pinctrl-0 =
+ <&pinctrl_uart1
+ &pinctrl_uart1_rts
+ &pinctrl_uart1_cts
+ &pinctrl_uart1_dtr_dsr
+ &pinctrl_uart1_dcd
+ &pinctrl_uart1_ri>;
+ status = "okay";
+ };
+
+ usb1: gadget@fffb0000 {
+ atmel,vbus-gpio = <&pioD 4 0>;
+ status = "okay";
+ };
+ };
+
+ usb0: ohci@00300000 {
+ num-ports = <2>;
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds2 {
+ label = "green";
+ gpios = <&pioB 0 0x1>;
+ linux,default-trigger = "mmc0";
+ };
+
+ ds4 {
+ label = "yellow";
+ gpios = <&pioB 1 0x1>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ ds6 {
+ label = "red";
+ gpios = <&pioB 2 0x1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index d410581a5a85..b1d3fab60e0a 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -21,8 +21,8 @@
serial2 = &usart1;
serial3 = &usart2;
serial4 = &usart3;
- serial5 = &usart4;
- serial6 = &usart5;
+ serial5 = &uart0;
+ serial6 = &uart1;
gpio0 = &pioA;
gpio1 = &pioB;
gpio2 = &pioC;
@@ -98,40 +98,250 @@
interrupts = <26 4 0 27 4 0 28 4 0>;
};
- pioA: gpio@fffff400 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x600>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc00c3b /* pioA */
+ 0xffffffff 0x7fff3ccf /* pioB */
+ 0xffffffff 0x007fffff /* pioC */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <1 14 0x1 0x0 /* PB14 periph A */
+ 1 15 0x1 0x1>; /* PB15 periph with pullup */
+ };
+ };
- pioB: gpio@fffff600 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <1 4 0x1 0x0 /* PB4 periph A */
+ 1 5 0x1 0x0>; /* PB5 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <1 26 0x1 0x0>; /* PB26 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <1 27 0x1 0x0>; /* PB27 periph A */
+ };
+
+ pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 {
+ atmel,pins =
+ <1 24 0x1 0x0 /* PB24 periph A */
+ 1 22 0x1 0x0>; /* PB22 periph A */
+ };
+
+ pinctrl_usart0_dcd: usart0_dcd-0 {
+ atmel,pins =
+ <1 23 0x1 0x0>; /* PB23 periph A */
+ };
+
+ pinctrl_usart0_ri: usart0_ri-0 {
+ atmel,pins =
+ <1 25 0x1 0x0>; /* PB25 periph A */
+ };
+ };
- pioC: gpio@fffff800 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <2 6 0x1 0x1 /* PB6 periph A with pullup */
+ 2 7 0x1 0x0>; /* PB7 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <1 28 0x1 0x0>; /* PB28 periph A */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <1 29 0x1 0x0>; /* PB29 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <1 8 0x1 0x1 /* PB8 periph A with pullup */
+ 1 9 0x1 0x0>; /* PB9 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <0 4 0x1 0x0>; /* PA4 periph A */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <0 5 0x1 0x0>; /* PA5 periph A */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <2 10 0x1 0x1 /* PB10 periph A with pullup */
+ 2 11 0x1 0x0>; /* PB11 periph A */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <3 8 0x2 0x0>; /* PB8 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <3 10 0x2 0x0>; /* PB10 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <0 31 0x2 0x1 /* PA31 periph B with pullup */
+ 0 30 0x2 0x0>; /* PA30 periph B */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <2 12 0x1 0x1 /* PB12 periph A with pullup */
+ 2 13 0x1 0x0>; /* PB13 periph A */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <2 13 0x0 0x1 /* PC13 gpio RDY pin pull_up */
+ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <0 12 0x1 0x0 /* PA12 periph A */
+ 0 13 0x1 0x0 /* PA13 periph A */
+ 0 14 0x1 0x0 /* PA14 periph A */
+ 0 15 0x1 0x0 /* PA15 periph A */
+ 0 16 0x1 0x0 /* PA16 periph A */
+ 0 17 0x1 0x0 /* PA17 periph A */
+ 0 18 0x1 0x0 /* PA18 periph A */
+ 0 19 0x1 0x0 /* PA19 periph A */
+ 0 20 0x1 0x0 /* PA20 periph A */
+ 0 21 0x1 0x0>; /* PA21 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <0 22 0x2 0x0 /* PA22 periph B */
+ 0 23 0x2 0x0 /* PA23 periph B */
+ 0 24 0x2 0x0 /* PA24 periph B */
+ 0 25 0x2 0x0 /* PA25 periph B */
+ 0 26 0x2 0x0 /* PA26 periph B */
+ 0 27 0x2 0x0 /* PA27 periph B */
+ 0 28 0x2 0x0 /* PA28 periph B */
+ 0 29 0x2 0x0>; /* PA29 periph B */
+ };
+
+ pinctrl_macb_rmii_mii_alt: macb_rmii_mii-1 {
+ atmel,pins =
+ <0 10 0x2 0x0 /* PA10 periph B */
+ 0 11 0x2 0x0 /* PA11 periph B */
+ 0 24 0x2 0x0 /* PA24 periph B */
+ 0 25 0x2 0x0 /* PA25 periph B */
+ 0 26 0x2 0x0 /* PA26 periph B */
+ 0 27 0x2 0x0 /* PA27 periph B */
+ 0 28 0x2 0x0 /* PA28 periph B */
+ 0 29 0x2 0x0>; /* PA29 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <0 8 0x1 0x0>; /* PA8 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 6 0x1 0x1>; /* PA6 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 9 0x1 0x1 /* PA9 periph A with pullup */
+ 0 10 0x1 0x1 /* PA10 periph A with pullup */
+ 0 11 0x1 0x1>; /* PA11 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <0 1 0x2 0x1 /* PA1 periph B with pullup */
+ 0 0 0x2 0x1>; /* PA0 periph B with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <0 5 0x2 0x1 /* PA5 periph B with pullup */
+ 0 4 0x2 0x1 /* PA4 periph B with pullup */
+ 0 3 0x2 0x1>; /* PA3 periph B with pullup */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -141,6 +351,8 @@
interrupts = <6 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -150,6 +362,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -159,6 +373,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -168,24 +384,30 @@
interrupts = <23 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
status = "disabled";
};
- usart4: serial@fffd4000 {
+ uart0: serial@fffd4000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd4000 0x200>;
interrupts = <24 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
status = "disabled";
};
- usart5: serial@fffd8000 {
+ uart1: serial@fffd8000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd8000 0x200>;
interrupts = <25 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
status = "disabled";
};
@@ -193,6 +415,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffc4000 0x100>;
interrupts = <21 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
status = "disabled";
};
@@ -212,6 +436,15 @@
status = "disabled";
};
+ mmc0: mmc@fffa8000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffa8000 0x600>;
+ interrupts = <9 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
adc0: adc@fffe0000 {
compatible = "atmel,at91sam9260-adc";
reg = <0xfffe0000 0x100>;
@@ -257,6 +490,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioC 13 0
&pioC 14 0
0
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 3e6e5c1abbf3..66106eecf1ed 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -89,60 +89,243 @@
reg = <0xfffffd10 0x10>;
};
- pioA: gpio@fffff200 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff200 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
- pioB: gpio@fffff400 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ atmel,mux-mask = <
+ /* A B */
+ 0xfffffffb 0xffffe07f /* pioA */
+ 0x0007ffff 0x39072fff /* pioB */
+ 0xffffffff 0x3ffffff8 /* pioC */
+ 0xfffffbff 0xffffffff /* pioD */
+ 0xffe00fff 0xfbfcff00 /* pioE */
+ >;
- pioC: gpio@fffff600 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <2 30 0x1 0x0 /* PC30 periph A */
+ 2 31 0x1 0x1>; /* PC31 periph with pullup */
+ };
+ };
- pioD: gpio@fffff800 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <0 26 0x1 0x1 /* PA26 periph A with pullup */
+ 0 27 0x1 0x0>; /* PA27 periph A */
+ };
- pioE: gpio@fffffa00 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <0 28 0x1 0x0>; /* PA28 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <0 29 0x1 0x0>; /* PA29 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <3 0 0x1 0x1 /* PD0 periph A with pullup */
+ 3 1 0x1 0x0>; /* PD1 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <3 7 0x2 0x0>; /* PD7 periph B */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <3 8 0x2 0x0>; /* PD8 periph B */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <3 2 0x1 0x1 /* PD2 periph A with pullup */
+ 3 3 0x1 0x0>; /* PD3 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <3 5 0x2 0x0>; /* PD5 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <4 6 0x2 0x0>; /* PD6 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <0 22 0x0 0x1 /* PA22 gpio RDY pin pull_up*/
+ 3 15 0x0 0x1>; /* PD15 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <2 25 0x2 0x0 /* PC25 periph B */
+ 4 21 0x1 0x0 /* PE21 periph A */
+ 4 23 0x1 0x0 /* PE23 periph A */
+ 4 24 0x1 0x0 /* PE24 periph A */
+ 4 25 0x1 0x0 /* PE25 periph A */
+ 4 26 0x1 0x0 /* PE26 periph A */
+ 4 27 0x1 0x0 /* PE27 periph A */
+ 4 28 0x1 0x0 /* PE28 periph A */
+ 4 29 0x1 0x0 /* PE29 periph A */
+ 4 30 0x1 0x0>; /* PE30 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <2 20 0x2 0x0 /* PC20 periph B */
+ 2 21 0x2 0x0 /* PC21 periph B */
+ 2 22 0x2 0x0 /* PC22 periph B */
+ 2 23 0x2 0x0 /* PC23 periph B */
+ 2 24 0x2 0x0 /* PC24 periph B */
+ 2 25 0x2 0x0 /* PC25 periph B */
+ 2 27 0x2 0x0 /* PC27 periph B */
+ 4 22 0x2 0x0>; /* PE22 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_clk: mmc0_clk-0 {
+ atmel,pins =
+ <0 12 0x1 0x0>; /* PA12 periph A */
+ };
+
+ pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <0 1 0x1 0x1 /* PA1 periph A with pullup */
+ 0 0 0x1 0x1>; /* PA0 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 3 0x1 0x1 /* PA3 periph A with pullup */
+ 0 4 0x1 0x1 /* PA4 periph A with pullup */
+ 0 5 0x1 0x1>; /* PA5 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <0 16 0x1 0x1 /* PA16 periph A with pullup */
+ 0 17 0x1 0x1>; /* PA17 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 {
+ atmel,pins =
+ <0 18 0x1 0x1 /* PA18 periph A with pullup */
+ 0 19 0x1 0x1 /* PA19 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA20 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_clk: mmc1_clk-0 {
+ atmel,pins =
+ <0 6 0x1 0x0>; /* PA6 periph A */
+ };
+
+ pinctrl_mmc1_slot0_cmd_dat0: mmc1_slot0_cmd_dat0-0 {
+ atmel,pins =
+ <0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 8 0x1 0x1>; /* PA8 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 9 0x1 0x1 /* PA9 periph A with pullup */
+ 0 10 0x1 0x1 /* PA10 periph A with pullup */
+ 0 11 0x1 0x1>; /* PA11 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot1_cmd_dat0: mmc1_slot1_cmd_dat0-0 {
+ atmel,pins =
+ <0 21 0x1 0x1 /* PA21 periph A with pullup */
+ 0 22 0x1 0x1>; /* PA22 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot1_dat1_3: mmc1_slot1_dat1_3-0 {
+ atmel,pins =
+ <0 23 0x1 0x1 /* PA23 periph A with pullup */
+ 0 24 0x1 0x1 /* PA24 periph A with pullup */
+ 0 25 0x1 0x1>; /* PA25 periph A with pullup */
+ };
+ };
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -152,6 +335,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -161,6 +346,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -170,6 +357,8 @@
interrupts = <9 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -177,6 +366,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffbc000 0x100>;
interrupts = <21 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
status = "disabled";
};
@@ -195,6 +386,24 @@
#size-cells = <0>;
status = "disabled";
};
+
+ mmc0: mmc@fff80000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff80000 0x600>;
+ interrupts = <10 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@fff84000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff84000 0x600>;
+ interrupts = <11 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
@@ -206,6 +415,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioA 22 0
&pioD 15 0
0
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts
index f86ac4b609fc..1eb08728f527 100644
--- a/arch/arm/boot/dts/at91sam9263ek.dts
+++ b/arch/arm/boot/dts/at91sam9263ek.dts
@@ -38,6 +38,10 @@
};
usart0: serial@fff8c000 {
+ pinctrl-0 = <
+ &pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts>;
status = "okay";
};
@@ -50,6 +54,31 @@
atmel,vbus-gpio = <&pioA 25 0>;
status = "okay";
};
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 18 0>;
+ wp-gpios = <&pioE 19 0>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <5 18 0x0 0x5 /* PE18 gpio CD pin pull up and deglitch */
+ 5 19 0x0 0x1>; /* PE19 gpio WP pin pull up */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g15.dtsi b/arch/arm/boot/dts/at91sam9g15.dtsi
new file mode 100644
index 000000000000..fbe7a7089c2a
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g15.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g15.dtsi - Device Tree Include file for AT91SAM9G15 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G15 SoC";
+ compatible = "atmel, at91sam9g15, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0x00000000 /* pioA */
+ 0x00040000 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g15ek.dts b/arch/arm/boot/dts/at91sam9g15ek.dts
new file mode 100644
index 000000000000..86dd3f6d938f
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g15ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9g15ek.dts - Device Tree file for AT91SAM9G15-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9g15.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25-EK";
+ compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
index f1b2e148ac8c..66467b113126 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
+++ b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts
@@ -12,6 +12,32 @@
model = "Atmel at91sam9g20ek 2 mmc";
compatible = "atmel,at91sam9g20ek_2mmc", "atmel,at91sam9g20", "atmel,at91sam9";
+ ahb {
+ apb{
+ mmc0: mmc@fffa8000 {
+ /* clk already mux wuth slot0 */
+ pinctrl-0 = <
+ &pinctrl_board_mmc0_slot0
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioC 2 0>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0_slot0 {
+ pinctrl_board_mmc0_slot0: mmc0_slot0-board {
+ atmel,pins =
+ <2 2 0x0 0x5>; /* PC2 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+ };
+ };
+
leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index e6391a4e6649..32a500a0e481 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -35,6 +35,13 @@
};
usart0: serial@fffb0000 {
+ pinctrl-0 =
+ <&pinctrl_usart0
+ &pinctrl_usart0_rts
+ &pinctrl_usart0_cts
+ &pinctrl_usart0_dtr_dsr
+ &pinctrl_usart0_dcd
+ &pinctrl_usart0_ri>;
status = "okay";
};
@@ -51,6 +58,29 @@
atmel,vbus-gpio = <&pioC 5 0>;
status = "okay";
};
+
+ mmc0: mmc@fffa8000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0_slot1
+ &pinctrl_mmc0_clk
+ &pinctrl_mmc0_slot1_cmd_dat0
+ &pinctrl_mmc0_slot1_dat1_3>;
+ status = "okay";
+ slot@1 {
+ reg = <1>;
+ bus-width = <4>;
+ cd-gpios = <&pioC 9 0>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0_slot1 {
+ pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ atmel,pins =
+ <2 9 0x0 0x5>; /* PC9 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi
new file mode 100644
index 000000000000..05a718fb83c4
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g25.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g25.dtsi - Device Tree Include file for AT91SAM9G25 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25 SoC";
+ compatible = "atmel, at91sam9g25, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0xc000001c /* pioA */
+ 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */
+ 0x80000000 0x07c0ffff 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
index 877c08f06763..c5ab16fba059 100644
--- a/arch/arm/boot/dts/at91sam9g25ek.dts
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -7,55 +7,10 @@
* Licensed under GPLv2 or later.
*/
/dts-v1/;
-/include/ "at91sam9x5.dtsi"
-/include/ "at91sam9x5cm.dtsi"
+/include/ "at91sam9g25.dtsi"
+/include/ "at91sam9x5ek.dtsi"
/ {
model = "Atmel AT91SAM9G25-EK";
compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
-
- chosen {
- bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
- };
-
- ahb {
- apb {
- dbgu: serial@fffff200 {
- status = "okay";
- };
-
- usart0: serial@f801c000 {
- status = "okay";
- };
-
- macb0: ethernet@f802c000 {
- phy-mode = "rmii";
- status = "okay";
- };
-
- i2c0: i2c@f8010000 {
- status = "okay";
- };
-
- i2c1: i2c@f8014000 {
- status = "okay";
- };
-
- i2c2: i2c@f8018000 {
- status = "okay";
- };
- };
-
- usb0: ohci@00600000 {
- status = "okay";
- num-ports = <2>;
- atmel,vbus-gpio = <&pioD 19 1
- &pioD 20 1
- >;
- };
-
- usb1: ehci@00700000 {
- status = "okay";
- };
- };
};
diff --git a/arch/arm/boot/dts/at91sam9g35.dtsi b/arch/arm/boot/dts/at91sam9g35.dtsi
new file mode 100644
index 000000000000..f9d14a722794
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g35.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9g35.dtsi - Device Tree Include file for AT91SAM9G35 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G35 SoC";
+ compatible = "atmel, at91sam9g35, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe0399f 0xc000000c /* pioA */
+ 0x000406ff 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g35ek.dts b/arch/arm/boot/dts/at91sam9g35ek.dts
new file mode 100644
index 000000000000..95944bdd798d
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g35ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9g35ek.dts - Device Tree file for AT91SAM9G35-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9g35.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G35-EK";
+ compatible = "atmel,at91sam9g35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 3add030d61f8..0741caeeced1 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -108,60 +108,243 @@
interrupts = <21 4 0>;
};
- pioA: gpio@fffff200 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff200 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff200 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff200 0xfffff200 0xa00>;
+
+ atmel,mux-mask = <
+ /* A B */
+ 0xffffffff 0xffc003ff /* pioA */
+ 0xffffffff 0x800f8f00 /* pioB */
+ 0xffffffff 0x00000e00 /* pioC */
+ 0xffffffff 0xff0c1381 /* pioD */
+ 0xffffffff 0x81ffff81 /* pioE */
+ >;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <1 12 0x1 0x0 /* PB12 periph A */
+ 1 13 0x1 0x0>; /* PB13 periph A */
+ };
+ };
- pioB: gpio@fffff400 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <1 19 0x1 0x1 /* PB19 periph A with pullup */
+ 1 18 0x1 0x0>; /* PB18 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <1 17 0x2 0x0>; /* PB17 periph B */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <1 15 0x2 0x0>; /* PB15 periph B */
+ };
+ };
- pioC: gpio@fffff600 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <4 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ uart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <1 4 0x1 0x1 /* PB4 periph A with pullup */
+ 1 5 0x1 0x0>; /* PB5 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <3 16 0x1 0x0>; /* PD16 periph A */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <3 17 0x1 0x0>; /* PD17 periph A */
+ };
+ };
- pioD: gpio@fffff800 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <5 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <1 6 0x1 0x1 /* PB6 periph A with pullup */
+ 1 7 0x1 0x0>; /* PB7 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <2 9 0x2 0x0>; /* PC9 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <2 11 0x2 0x0>; /* PC11 periph B */
+ };
+ };
- pioE: gpio@fffffa00 {
- compatible = "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <5 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <1 8 0x1 0x1 /* PB9 periph A with pullup */
+ 1 9 0x1 0x0>; /* PB8 periph A */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <0 23 0x2 0x0>; /* PA23 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <0 24 0x2 0x0>; /* PA24 periph B */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <2 8 0x0 0x1 /* PC8 gpio RDY pin pull_up*/
+ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ macb {
+ pinctrl_macb_rmii: macb_rmii-0 {
+ atmel,pins =
+ <0 10 0x1 0x0 /* PA10 periph A */
+ 0 11 0x1 0x0 /* PA11 periph A */
+ 0 12 0x1 0x0 /* PA12 periph A */
+ 0 13 0x1 0x0 /* PA13 periph A */
+ 0 14 0x1 0x0 /* PA14 periph A */
+ 0 15 0x1 0x0 /* PA15 periph A */
+ 0 16 0x1 0x0 /* PA16 periph A */
+ 0 17 0x1 0x0 /* PA17 periph A */
+ 0 18 0x1 0x0 /* PA18 periph A */
+ 0 19 0x1 0x0>; /* PA19 periph A */
+ };
+
+ pinctrl_macb_rmii_mii: macb_rmii_mii-0 {
+ atmel,pins =
+ <0 6 0x2 0x0 /* PA6 periph B */
+ 0 7 0x2 0x0 /* PA7 periph B */
+ 0 8 0x2 0x0 /* PA8 periph B */
+ 0 9 0x2 0x0 /* PA9 periph B */
+ 0 27 0x2 0x0 /* PA27 periph B */
+ 0 28 0x2 0x0 /* PA28 periph B */
+ 0 29 0x2 0x0 /* PA29 periph B */
+ 0 30 0x2 0x0>; /* PA30 periph B */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 0 0x1 0x0 /* PA0 periph A */
+ 0 1 0x1 0x1 /* PA1 periph A with pullup */
+ 0 2 0x1 0x1>; /* PA2 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 3 0x1 0x1 /* PA3 periph A with pullup */
+ 0 4 0x1 0x1 /* PA4 periph A with pullup */
+ 0 5 0x1 0x1>; /* PA5 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
+ atmel,pins =
+ <0 6 0x1 0x1 /* PA6 periph A with pullup */
+ 0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 8 0x1 0x1 /* PA8 periph A with pullup */
+ 0 9 0x1 0x1>; /* PA9 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 31 0x1 0x0 /* PA31 periph A */
+ 0 22 0x1 0x1 /* PA22 periph A with pullup */
+ 0 23 0x1 0x1>; /* PA23 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 24 0x1 0x1 /* PA24 periph A with pullup */
+ 0 25 0x1 0x1 /* PA25 periph A with pullup */
+ 0 26 0x1 0x1>; /* PA26 periph A with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat4_7: mmc1_slot0_dat4_7-0 {
+ atmel,pins =
+ <0 27 0x1 0x1 /* PA27 periph A with pullup */
+ 0 28 0x1 0x1 /* PA28 periph A with pullup */
+ 0 29 0x1 0x1 /* PA29 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA30 periph A with pullup */
+ };
+ };
+
+ pioA: gpio@fffff200 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff200 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff400 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff600 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <4 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffff800 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <5 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioE: gpio@fffffa00 {
+ compatible = "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <5 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -171,6 +354,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -180,6 +365,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -189,6 +376,8 @@
interrupts = <9 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -198,6 +387,8 @@
interrupts = <10 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
status = "disabled";
};
@@ -205,6 +396,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xfffbc000 0x100>;
interrupts = <25 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb_rmii>;
status = "disabled";
};
@@ -262,6 +455,24 @@
trigger-value = <0x6>;
};
};
+
+ mmc0: mmc@fff80000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfff80000 0x600>;
+ interrupts = <11 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ mmc1: mmc@fffd0000 {
+ compatible = "atmel,hsmci";
+ reg = <0xfffd0000 0x600>;
+ interrupts = <29 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
nand0: nand@40000000 {
@@ -273,6 +484,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioC 8 0
&pioC 14 0
0
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index 15e1dd43f625..20c31913c270 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -39,6 +39,10 @@
};
usart1: serial@fff90000 {
+ pinctrl-0 =
+ <&pinctrl_usart1
+ &pinctrl_usart1_rts
+ &pinctrl_usart1_cts>;
status = "okay";
};
@@ -54,6 +58,50 @@
i2c1: i2c@fff88000 {
status = "okay";
};
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 10 0>;
+ };
+ };
+
+ mmc1: mmc@fffd0000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc1
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 11 0>;
+ wp-gpios = <&pioD 29 0>;
+ };
+ };
+
+ pinctrl@fffff200 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <3 10 0x0 0x5>; /* PD10 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ mmc1 {
+ pinctrl_board_mmc1: mmc1-board {
+ atmel,pins =
+ <3 11 0x0 0x5 /* PD11 gpio CD pin pull up and deglitch */
+ 3 29 0x0 0x1>; /* PD29 gpio WP pin pull up */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 82508d68aa7e..e9efb34f4379 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -84,6 +84,15 @@
reg = <0xfffffe10 0x10>;
};
+ mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
tcb0: timer@f8008000 {
compatible = "atmel,at91sam9x5-tcb";
reg = <0xf8008000 0x100>;
@@ -102,50 +111,186 @@
interrupts = <20 4 0>;
};
- pioA: gpio@fffff400 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
- pioB: gpio@fffff600 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe07983 0x00000000 /* pioA */
+ 0x00040000 0x00047e0f 0x00000000 /* pioB */
+ 0xfdffffff 0x07c00000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
- pioC: gpio@fffff800 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <0 9 0x1 0x0 /* PA9 periph A */
+ 0 10 0x1 0x1>; /* PA10 periph with pullup */
+ };
+ };
- pioD: gpio@fffffa00 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <0 1 0x1 0x1 /* PA1 periph A with pullup */
+ 0 0 0x1 0x0>; /* PA0 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <0 2 0x1 0x0>; /* PA2 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <0 3 0x1 0x0>; /* PA3 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <0 6 0x1 0x1 /* PA6 periph A with pullup */
+ 0 5 0x1 0x0>; /* PA5 periph A */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <0 8 0x1 0x1 /* PA8 periph A with pullup */
+ 0 7 0x1 0x0>; /* PA7 periph A */
+ };
+
+ pinctrl_usart2_rts: usart2_rts-0 {
+ atmel,pins =
+ <1 0 0x2 0x0>; /* PB0 periph B */
+ };
+
+ pinctrl_usart2_cts: usart2_cts-0 {
+ atmel,pins =
+ <1 1 0x2 0x0>; /* PB1 periph B */
+ };
+ };
+
+ usart3 {
+ pinctrl_usart3: usart3-0 {
+ atmel,pins =
+ <2 23 0x2 0x1 /* PC23 periph B with pullup */
+ 2 22 0x2 0x0>; /* PC22 periph B */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <2 24 0x2 0x0>; /* PC24 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <2 25 0x2 0x0>; /* PC25 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <2 9 0x3 0x1 /* PC9 periph C with pullup */
+ 2 8 0x3 0x0>; /* PC8 periph C */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <2 16 0x3 0x1 /* PC17 periph C with pullup */
+ 2 17 0x3 0x0>; /* PC16 periph C */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <3 5 0x0 0x1 /* PD5 gpio RDY pin pull_up*/
+ 3 4 0x0 0x1>; /* PD4 gpio enable pin pull_up */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 17 0x1 0x0 /* PA17 periph A */
+ 0 16 0x1 0x1 /* PA16 periph A with pullup */
+ 0 15 0x1 0x1>; /* PA15 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 18 0x1 0x1 /* PA18 periph A with pullup */
+ 0 19 0x1 0x1 /* PA19 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA20 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 {
+ atmel,pins =
+ <0 11 0x2 0x1 /* PA11 periph B with pullup */
+ 0 12 0x2 0x1 /* PA12 periph B with pullup */
+ 0 13 0x2 0x1 /* PA13 periph B with pullup */
+ 0 14 0x2 0x1>; /* PA14 periph B with pullup */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -155,6 +300,8 @@
interrupts = <5 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -164,6 +311,8 @@
interrupts = <6 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -173,6 +322,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -182,6 +333,8 @@
interrupts = <8 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart3>;
status = "disabled";
};
@@ -215,6 +368,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioD 5 0
&pioD 4 0
0
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index 912b2c283d6f..0376bf4fd66b 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -45,6 +45,28 @@
i2c1: i2c@f8014000 {
status = "okay";
};
+
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioA 7 0>;
+ };
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <0 7 0x0 0x5>; /* PA7 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
};
nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9x25.dtsi b/arch/arm/boot/dts/at91sam9x25.dtsi
new file mode 100644
index 000000000000..54eb33ba6d22
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x25.dtsi
@@ -0,0 +1,49 @@
+/*
+ * at91sam9x25.dtsi - Device Tree Include file for AT91SAM9X25 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X25 SoC";
+ compatible = "atmel, at91sam9x25, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe03fff 0xc000001c /* pioA */
+ 0x0007ffff 0x00047e3f 0x00000000 /* pioB */
+ 0x80000000 0xfffd0000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+
+ macb1 {
+ pinctrl_macb1_rmii: macb1_rmii-0 {
+ atmel,pins =
+ <2 16 0x2 0x0 /* PC16 periph B */
+ 2 18 0x2 0x0 /* PC18 periph B */
+ 2 19 0x2 0x0 /* PC19 periph B */
+ 2 20 0x2 0x0 /* PC20 periph B */
+ 2 21 0x2 0x0 /* PC21 periph B */
+ 2 27 0x2 0x0 /* PC27 periph B */
+ 2 28 0x2 0x0 /* PC28 periph B */
+ 2 29 0x2 0x0 /* PC29 periph B */
+ 2 30 0x2 0x0 /* PC30 periph B */
+ 2 31 0x2 0x0>; /* PC31 periph B */
+ };
+ };
+ };
+
+ macb1: ethernet@f8030000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb1_rmii>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x25ek.dts b/arch/arm/boot/dts/at91sam9x25ek.dts
new file mode 100644
index 000000000000..af907eaa1f25
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x25ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9x25ek.dts - Device Tree file for AT91SAM9X25-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9x25.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G25-EK";
+ compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9x35.dtsi b/arch/arm/boot/dts/at91sam9x35.dtsi
new file mode 100644
index 000000000000..fb102d6126ce
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x35.dtsi
@@ -0,0 +1,28 @@
+/*
+ * at91sam9x35.dtsi - Device Tree Include file for AT91SAM9X35 SoC
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+
+/include/ "at91sam9x5.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X35 SoC";
+ compatible = "atmel, at91sam9x35, atmel,at91sam9x5";
+
+ ahb {
+ apb {
+ pinctrl@fffff400 {
+ atmel,mux-mask = <
+ /* A B C */
+ 0xffffffff 0xffe03fff 0xc000000c /* pioA */
+ 0x000406ff 0x00047e3f 0x00000000 /* pioB */
+ 0xfdffffff 0x00000000 0xb83fffff /* pioC */
+ 0x003fffff 0x003f8000 0x00000000 /* pioD */
+ >;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9x35ek.dts b/arch/arm/boot/dts/at91sam9x35ek.dts
new file mode 100644
index 000000000000..5ccb607b5414
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x35ek.dts
@@ -0,0 +1,16 @@
+/*
+ * at91sam9x35ek.dts - Device Tree file for AT91SAM9X35-EK board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9x35.dtsi"
+/include/ "at91sam9x5ek.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X35-EK";
+ compatible = "atmel,at91sam9x35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 03fc136421c5..7ee49e8daf98 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -111,50 +111,244 @@
interrupts = <21 4 0>;
};
- pioA: gpio@fffff400 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff400 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
+ pinctrl@fffff400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+ ranges = <0xfffff400 0xfffff400 0x800>;
+
+ /* shared pinctrl settings */
+ dbgu {
+ pinctrl_dbgu: dbgu-0 {
+ atmel,pins =
+ <0 9 0x1 0x0 /* PA9 periph A */
+ 0 10 0x1 0x1>; /* PA10 periph A with pullup */
+ };
+ };
- pioB: gpio@fffff600 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff600 0x100>;
- interrupts = <2 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ usart0 {
+ pinctrl_usart0: usart0-0 {
+ atmel,pins =
+ <0 0 0x1 0x1 /* PA0 periph A with pullup */
+ 0 1 0x1 0x0>; /* PA1 periph A */
+ };
+
+ pinctrl_usart0_rts: usart0_rts-0 {
+ atmel,pins =
+ <0 2 0x1 0x0>; /* PA2 periph A */
+ };
+
+ pinctrl_usart0_cts: usart0_cts-0 {
+ atmel,pins =
+ <0 3 0x1 0x0>; /* PA3 periph A */
+ };
+ };
+
+ usart1 {
+ pinctrl_usart1: usart1-0 {
+ atmel,pins =
+ <0 5 0x1 0x1 /* PA5 periph A with pullup */
+ 0 6 0x1 0x0>; /* PA6 periph A */
+ };
+
+ pinctrl_usart1_rts: usart1_rts-0 {
+ atmel,pins =
+ <3 27 0x3 0x0>; /* PC27 periph C */
+ };
+
+ pinctrl_usart1_cts: usart1_cts-0 {
+ atmel,pins =
+ <3 28 0x3 0x0>; /* PC28 periph C */
+ };
+ };
+
+ usart2 {
+ pinctrl_usart2: usart2-0 {
+ atmel,pins =
+ <0 7 0x1 0x1 /* PA7 periph A with pullup */
+ 0 8 0x1 0x0>; /* PA8 periph A */
+ };
+
+ pinctrl_uart2_rts: uart2_rts-0 {
+ atmel,pins =
+ <0 0 0x2 0x0>; /* PB0 periph B */
+ };
+
+ pinctrl_uart2_cts: uart2_cts-0 {
+ atmel,pins =
+ <0 1 0x2 0x0>; /* PB1 periph B */
+ };
+ };
+
+ usart3 {
+ pinctrl_uart3: usart3-0 {
+ atmel,pins =
+ <3 23 0x2 0x1 /* PC22 periph B with pullup */
+ 3 23 0x2 0x0>; /* PC23 periph B */
+ };
+
+ pinctrl_usart3_rts: usart3_rts-0 {
+ atmel,pins =
+ <3 24 0x2 0x0>; /* PC24 periph B */
+ };
+
+ pinctrl_usart3_cts: usart3_cts-0 {
+ atmel,pins =
+ <3 25 0x2 0x0>; /* PC25 periph B */
+ };
+ };
+
+ uart0 {
+ pinctrl_uart0: uart0-0 {
+ atmel,pins =
+ <3 8 0x3 0x0 /* PC8 periph C */
+ 3 9 0x3 0x1>; /* PC9 periph C with pullup */
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1: uart1-0 {
+ atmel,pins =
+ <3 16 0x3 0x0 /* PC16 periph C */
+ 3 17 0x3 0x1>; /* PC17 periph C with pullup */
+ };
+ };
+
+ nand {
+ pinctrl_nand: nand-0 {
+ atmel,pins =
+ <3 4 0x0 0x1 /* PD5 gpio RDY pin pull_up */
+ 3 5 0x0 0x1>; /* PD4 gpio enable pin pull_up */
+ };
+ };
+
+ macb0 {
+ pinctrl_macb0_rmii: macb0_rmii-0 {
+ atmel,pins =
+ <1 0 0x1 0x0 /* PB0 periph A */
+ 1 1 0x1 0x0 /* PB1 periph A */
+ 1 2 0x1 0x0 /* PB2 periph A */
+ 1 3 0x1 0x0 /* PB3 periph A */
+ 1 4 0x1 0x0 /* PB4 periph A */
+ 1 5 0x1 0x0 /* PB5 periph A */
+ 1 6 0x1 0x0 /* PB6 periph A */
+ 1 7 0x1 0x0 /* PB7 periph A */
+ 1 9 0x1 0x0 /* PB9 periph A */
+ 1 10 0x1 0x0>; /* PB10 periph A */
+ };
+
+ pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 {
+ atmel,pins =
+ <1 8 0x1 0x0 /* PA8 periph A */
+ 1 11 0x1 0x0 /* PA11 periph A */
+ 1 12 0x1 0x0 /* PA12 periph A */
+ 1 13 0x1 0x0 /* PA13 periph A */
+ 1 14 0x1 0x0 /* PA14 periph A */
+ 1 15 0x1 0x0 /* PA15 periph A */
+ 1 16 0x1 0x0 /* PA16 periph A */
+ 1 17 0x1 0x0>; /* PA17 periph A */
+ };
+ };
+
+ mmc0 {
+ pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 17 0x1 0x0 /* PA17 periph A */
+ 0 16 0x1 0x1 /* PA16 periph A with pullup */
+ 0 15 0x1 0x1>; /* PA15 periph A with pullup */
+ };
+
+ pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 18 0x1 0x1 /* PA18 periph A with pullup */
+ 0 19 0x1 0x1 /* PA19 periph A with pullup */
+ 0 20 0x1 0x1>; /* PA20 periph A with pullup */
+ };
+ };
+
+ mmc1 {
+ pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 {
+ atmel,pins =
+ <0 13 0x2 0x0 /* PA13 periph B */
+ 0 12 0x2 0x1 /* PA12 periph B with pullup */
+ 0 11 0x2 0x1>; /* PA11 periph B with pullup */
+ };
+
+ pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 {
+ atmel,pins =
+ <0 2 0x2 0x1 /* PA2 periph B with pullup */
+ 0 3 0x2 0x1 /* PA3 periph B with pullup */
+ 0 4 0x2 0x1>; /* PA4 periph B with pullup */
+ };
+ };
+
+ pioA: gpio@fffff400 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff400 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioB: gpio@fffff600 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff600 0x200>;
+ interrupts = <2 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-lines = <19>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioC: gpio@fffff800 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffff800 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pioD: gpio@fffffa00 {
+ compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+ reg = <0xfffffa00 0x200>;
+ interrupts = <3 4 1>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #gpio-lines = <22>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
};
- pioC: gpio@fffff800 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffff800 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ mmc0: mmc@f0008000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf0008000 0x600>;
+ interrupts = <12 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
};
- pioD: gpio@fffffa00 {
- compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
- reg = <0xfffffa00 0x100>;
- interrupts = <3 4 1>;
- #gpio-cells = <2>;
- gpio-controller;
- interrupt-controller;
- #interrupt-cells = <2>;
+ mmc1: mmc@f000c000 {
+ compatible = "atmel,hsmci";
+ reg = <0xf000c000 0x600>;
+ interrupts = <26 4 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
};
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
interrupts = <1 4 7>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_dbgu>;
status = "disabled";
};
@@ -164,6 +358,8 @@
interrupts = <5 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart0>;
status = "disabled";
};
@@ -173,6 +369,8 @@
interrupts = <6 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1>;
status = "disabled";
};
@@ -182,6 +380,8 @@
interrupts = <7 4 5>;
atmel,use-dma-rx;
atmel,use-dma-tx;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2>;
status = "disabled";
};
@@ -189,6 +389,8 @@
compatible = "cdns,at32ap7000-macb", "cdns,macb";
reg = <0xf802c000 0x100>;
interrupts = <24 4 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_macb0_rmii>;
status = "disabled";
};
@@ -273,6 +475,8 @@
>;
atmel,nand-addr-offset = <21>;
atmel,nand-cmd-offset = <22>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand>;
gpios = <&pioD 5 0
&pioD 4 0
0
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi
new file mode 100644
index 000000000000..8a7cf1d9cf5d
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi
@@ -0,0 +1,101 @@
+/*
+ * at91sam9x5ek.dtsi - Device Tree file for AT91SAM9x5CM Base board
+ *
+ * Copyright (C) 2012 Atmel,
+ * 2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/include/ "at91sam9x5cm.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9X5-EK";
+ compatible = "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc@f0008000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc0
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 15 0>;
+ };
+ };
+
+ mmc1: mmc@f000c000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc1
+ &pinctrl_mmc1_slot0_clk_cmd_dat0
+ &pinctrl_mmc1_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 14 0>;
+ };
+ };
+
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+
+ usart0: serial@f801c000 {
+ status = "okay";
+ };
+
+ macb0: ethernet@f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ i2c0: i2c@f8010000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@f8014000 {
+ status = "okay";
+ };
+
+ i2c2: i2c@f8018000 {
+ status = "okay";
+ };
+
+ pinctrl@fffff400 {
+ mmc0 {
+ pinctrl_board_mmc0: mmc0-board {
+ atmel,pins =
+ <3 15 0x0 0x5>; /* PD15 gpio CD pin pull up and deglitch */
+ };
+ };
+
+ mmc1 {
+ pinctrl_board_mmc1: mmc1-board {
+ atmel,pins =
+ <3 14 0x0 0x5>; /* PD14 gpio CD pin pull up and deglitch */
+ };
+ };
+ };
+ };
+
+ usb0: ohci@00600000 {
+ status = "okay";
+ num-ports = <2>;
+ atmel,vbus-gpio = <&pioD 19 1
+ &pioD 20 1
+ >;
+ };
+
+ usb1: ehci@00700000 {
+ status = "okay";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 4b0e0ca08f40..731086b2fca2 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -203,6 +203,14 @@
reg = <0x80157450 0xC>;
};
+ thermal@801573c0 {
+ compatible = "stericsson,db8500-thermal";
+ reg = <0x801573c0 0x40>;
+ interrupts = <21 0x4>, <22 0x4>;
+ interrupt-names = "IRQ_HOTMON_LOW", "IRQ_HOTMON_HIGH";
+ status = "disabled";
+ };
+
db8500-prcmu-regulators {
compatible = "stericsson,db8500-prcmu-regulator";
@@ -660,5 +668,11 @@
ranges = <0 0x50000000 0x4000000>;
status = "disabled";
};
+
+ cpufreq-cooling {
+ compatible = "stericsson,db8500-cpufreq-cooling";
+ status = "disabled";
+ };
+
};
};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 55c57ea6169e..b4587b27ae42 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -799,6 +799,7 @@
compatible = "fsl,imx28-auart", "fsl,imx23-auart";
reg = <0x8006a000 0x2000>;
interrupts = <112 70 71>;
+ fsl,auart-dma-channel = <8 9>;
clocks = <&clks 45>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/pm9g45.dts b/arch/arm/boot/dts/pm9g45.dts
new file mode 100644
index 000000000000..387fedb58988
--- /dev/null
+++ b/arch/arm/boot/dts/pm9g45.dts
@@ -0,0 +1,165 @@
+/*
+ * pm9g45.dts - Device Tree file for Ronetix pm9g45 board
+ *
+ * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+/include/ "at91sam9g45.dtsi"
+
+/ {
+ model = "Ronetix pm9g45";
+ compatible = "ronetix,pm9g45", "atmel,at91sam9g45", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x70000000 0x8000000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ main_clock: clock@0 {
+ compatible = "atmel,osc", "fixed-clock";
+ clock-frequency = <12000000>;
+ };
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ pinctrl@fffff200 {
+
+ board {
+ pinctrl_board_nand: nand0-board {
+ atmel,pins =
+ <3 3 0x0 0x1 /* PD3 gpio RDY pin pull_up*/
+ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */
+ };
+ };
+
+ mmc {
+ pinctrl_board_mmc: mmc0-board {
+ atmel,pins =
+ <3 6 0x0 0x5>; /* PD6 gpio CD pin pull_up and deglitch */
+ };
+ };
+ };
+
+ mmc0: mmc@fff80000 {
+ pinctrl-0 = <
+ &pinctrl_board_mmc
+ &pinctrl_mmc0_slot0_clk_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
+ status = "okay";
+ slot@0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioD 6 0>;
+ };
+ };
+
+ macb0: ethernet@fffbc000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ };
+
+ nand0: nand@40000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "soft";
+ nand-on-flash-bbt;
+ pinctrl-0 = <&pinctrl_board_nand>;
+
+ gpios = <&pioD 3 0
+ &pioC 14 0
+ 0
+ >;
+
+ status = "okay";
+
+ at91bootstrap@0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x20000>;
+ };
+
+ barebox@20000 {
+ label = "barebox";
+ reg = <0x20000 0x40000>;
+ };
+
+ bareboxenv@60000 {
+ label = "bareboxenv";
+ reg = <0x60000 0x1A0000>;
+ };
+
+ kernel@200000 {
+ label = "bareboxenv2";
+ reg = <0x200000 0x300000>;
+ };
+
+ kernel@500000 {
+ label = "root";
+ reg = <0x500000 0x400000>;
+ };
+
+ data@900000 {
+ label = "data";
+ reg = <0x900000 0x8340000>;
+ };
+ };
+
+ usb0: ohci@00700000 {
+ status = "okay";
+ num-ports = <2>;
+ };
+
+ usb1: ehci@00800000 {
+ status = "okay";
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led0 {
+ label = "led0";
+ gpios = <&pioD 0 1>;
+ linux,default-trigger = "nand-disk";
+ };
+
+ led1 {
+ label = "led1";
+ gpios = <&pioD 31 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ right {
+ label = "SW4";
+ gpios = <&pioE 7 1>;
+ linux,code = <106>;
+ };
+
+ up {
+ label = "SW3";
+ gpios = <&pioE 8 1>;
+ linux,code = <103>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/snowball.dts b/arch/arm/boot/dts/snowball.dts
index 702c0baa6004..c6f85f0bc531 100644
--- a/arch/arm/boot/dts/snowball.dts
+++ b/arch/arm/boot/dts/snowball.dts
@@ -99,6 +99,33 @@
status = "okay";
};
+ prcmu@80157000 {
+ thermal@801573c0 {
+ num-trips = <4>;
+
+ trip0-temp = <70000>;
+ trip0-type = "active";
+ trip0-cdev-num = <1>;
+ trip0-cdev-name0 = "thermal-cpufreq-0";
+
+ trip1-temp = <75000>;
+ trip1-type = "active";
+ trip1-cdev-num = <1>;
+ trip1-cdev-name0 = "thermal-cpufreq-0";
+
+ trip2-temp = <80000>;
+ trip2-type = "active";
+ trip2-cdev-num = <1>;
+ trip2-cdev-name0 = "thermal-cpufreq-0";
+
+ trip3-temp = <85000>;
+ trip3-type = "critical";
+ trip3-cdev-num = <0>;
+
+ status = "okay";
+ };
+ };
+
external-bus@50000000 {
status = "okay";
@@ -183,5 +210,9 @@
reg = <0x33>;
};
};
+
+ cpufreq-cooling {
+ status = "okay";
+ };
};
};
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
index dd4358bc26e2..2e4c5727468e 100644
--- a/arch/arm/boot/dts/spear1310-evb.dts
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -181,6 +181,10 @@
status = "okay";
};
+ gpio@d8400000 {
+ status = "okay";
+ };
+
i2c0: i2c@e0280000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 419ea7413d23..7cd25eb4f8e0 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -70,6 +70,12 @@
status = "disabled";
};
+ pinmux: pinmux@e0700000 {
+ compatible = "st,spear1310-pinmux";
+ reg = <0xe0700000 0x1000>;
+ #gpio-range-cells = <2>;
+ };
+
spi1: spi@5d400000 {
compatible = "arm,pl022", "arm,primecell";
reg = <0x5d400000 0x1000>;
@@ -179,6 +185,27 @@
thermal@e07008c4 {
st,thermal-flags = <0x7000>;
};
+
+ gpiopinctrl: gpio@d8400000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xd8400000 0x1000>;
+ interrupts = <0 100 0x4>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 246>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <246>;
+ st-plgpio,enb-reg = <0xd0>;
+ st-plgpio,wdata-reg = <0x90>;
+ st-plgpio,dir-reg = <0xb0>;
+ st-plgpio,ie-reg = <0x30>;
+ st-plgpio,rdata-reg = <0x70>;
+ st-plgpio,mis-reg = <0x10>;
+ st-plgpio,eit-reg = <0x50>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
index c9a54e06fb68..045f7123ffac 100644
--- a/arch/arm/boot/dts/spear1340-evb.dts
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -193,6 +193,10 @@
status = "okay";
};
+ gpio@e2800000 {
+ status = "okay";
+ };
+
i2c0: i2c@e0280000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index d71fe2a68f09..6c09eb0a1b2b 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -24,6 +24,12 @@
status = "disabled";
};
+ pinmux: pinmux@e0700000 {
+ compatible = "st,spear1340-pinmux";
+ reg = <0xe0700000 0x1000>;
+ #gpio-range-cells = <2>;
+ };
+
spi1: spi@5d400000 {
compatible = "arm,pl022", "arm,primecell";
reg = <0x5d400000 0x1000>;
@@ -51,6 +57,26 @@
thermal@e07008c4 {
st,thermal-flags = <0x2a00>;
};
+
+ gpiopinctrl: gpio@e2800000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xe2800000 0x1000>;
+ interrupts = <0 107 0x4>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 252>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <250>;
+ st-plgpio,wdata-reg = <0x40>;
+ st-plgpio,dir-reg = <0x00>;
+ st-plgpio,ie-reg = <0x80>;
+ st-plgpio,rdata-reg = <0x20>;
+ st-plgpio,mis-reg = <0xa0>;
+ st-plgpio,eit-reg = <0x60>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi
index 62fc4fb3e5f9..930303e48df9 100644
--- a/arch/arm/boot/dts/spear310.dtsi
+++ b/arch/arm/boot/dts/spear310.dtsi
@@ -22,9 +22,10 @@
0xb0000000 0xb0000000 0x10000000
0xd0000000 0xd0000000 0x30000000>;
- pinmux@b4000000 {
+ pinmux: pinmux@b4000000 {
compatible = "st,spear310-pinmux";
reg = <0xb4000000 0x1000>;
+ #gpio-range-cells = <2>;
};
fsmc: flash@44000000 {
@@ -75,6 +76,25 @@
reg = <0xb2200000 0x1000>;
status = "disabled";
};
+
+ gpiopinctrl: gpio@b4000000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xb4000000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 102>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <102>;
+ st-plgpio,enb-reg = <0x10>;
+ st-plgpio,wdata-reg = <0x20>;
+ st-plgpio,dir-reg = <0x30>;
+ st-plgpio,ie-reg = <0x50>;
+ st-plgpio,rdata-reg = <0x40>;
+ st-plgpio,mis-reg = <0x60>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index 082328bd64ab..ad4bfc68ee05 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -164,6 +164,10 @@
status = "okay";
};
+ gpio@b3000000 {
+ status = "okay";
+ };
+
i2c0: i2c@d0180000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi
index 1f49d69595a0..67d7ada71275 100644
--- a/arch/arm/boot/dts/spear320.dtsi
+++ b/arch/arm/boot/dts/spear320.dtsi
@@ -21,9 +21,10 @@
ranges = <0x40000000 0x40000000 0x80000000
0xd0000000 0xd0000000 0x30000000>;
- pinmux@b3000000 {
+ pinmux: pinmux@b3000000 {
compatible = "st,spear320-pinmux";
reg = <0xb3000000 0x1000>;
+ #gpio-range-cells = <2>;
};
clcd@90000000 {
@@ -90,6 +91,26 @@
reg = <0xa4000000 0x1000>;
status = "disabled";
};
+
+ gpiopinctrl: gpio@b3000000 {
+ compatible = "st,spear-plgpio";
+ reg = <0xb3000000 0x1000>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinmux 0 102>;
+ status = "disabled";
+
+ st-plgpio,ngpio = <102>;
+ st-plgpio,enb-reg = <0x24>;
+ st-plgpio,wdata-reg = <0x34>;
+ st-plgpio,dir-reg = <0x44>;
+ st-plgpio,ie-reg = <0x64>;
+ st-plgpio,rdata-reg = <0x54>;
+ st-plgpio,mis-reg = <0x84>;
+ st-plgpio,eit-reg = <0x94>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index f0ba901676ac..a20d4ff3fb3c 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -523,12 +523,12 @@
};
temperature-sensor@4c {
- compatible = "nct1008";
+ compatible = "onnn,nct1008";
reg = <0x4c>;
};
magnetometer@c {
- compatible = "ak8975";
+ compatible = "ak,ak8975";
reg = <0xc>;
interrupt-parent = <&gpio>;
interrupts = <109 0x04>; /* gpio PN5 */
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index aa5269984187..36ae03a3f5d1 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -70,6 +70,14 @@ struct gic_chip_data {
static DEFINE_RAW_SPINLOCK(irq_controller_lock);
/*
+ * The GIC mapping of CPU interfaces does not necessarily match
+ * the logical CPU numbering. Let's use a mapping as returned
+ * by the GIC itself.
+ */
+#define NR_GIC_CPU_IF 8
+static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
+
+/*
* Supported arch specific GIC irq extension.
* Default make them NULL.
*/
@@ -238,11 +246,11 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
u32 val, mask, bit;
- if (cpu >= 8 || cpu >= nr_cpu_ids)
+ if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids)
return -EINVAL;
mask = 0xff << shift;
- bit = 1 << (cpu_logical_map(cpu) + shift);
+ bit = gic_cpu_map[cpu] << shift;
raw_spin_lock(&irq_controller_lock);
val = readl_relaxed(reg) & ~mask;
@@ -349,11 +357,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
u32 cpumask;
unsigned int gic_irqs = gic->gic_irqs;
void __iomem *base = gic_data_dist_base(gic);
- u32 cpu = cpu_logical_map(smp_processor_id());
-
- cpumask = 1 << cpu;
- cpumask |= cpumask << 8;
- cpumask |= cpumask << 16;
writel_relaxed(0, base + GIC_DIST_CTRL);
@@ -366,6 +369,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
/*
* Set all global interrupts to this CPU only.
*/
+ cpumask = readl_relaxed(base + GIC_DIST_TARGET + 0);
for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
@@ -389,9 +393,25 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
void __iomem *dist_base = gic_data_dist_base(gic);
void __iomem *base = gic_data_cpu_base(gic);
+ unsigned int cpu_mask, cpu = smp_processor_id();
int i;
/*
+ * Get what the GIC says our CPU mask is.
+ */
+ BUG_ON(cpu >= NR_GIC_CPU_IF);
+ cpu_mask = readl_relaxed(dist_base + GIC_DIST_TARGET + 0);
+ gic_cpu_map[cpu] = cpu_mask;
+
+ /*
+ * Clear our mask from the other map entries in case they're
+ * still undefined.
+ */
+ for (i = 0; i < NR_GIC_CPU_IF; i++)
+ if (i != cpu)
+ gic_cpu_map[i] &= ~cpu_mask;
+
+ /*
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
*/
@@ -646,7 +666,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
{
irq_hw_number_t hwirq_base;
struct gic_chip_data *gic;
- int gic_irqs, irq_base;
+ int gic_irqs, irq_base, i;
BUG_ON(gic_nr >= MAX_GIC_NR);
@@ -683,6 +703,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
}
/*
+ * Initialize the CPU interface map to all CPUs.
+ * It will be refined as each CPU probes its ID.
+ */
+ for (i = 0; i < NR_GIC_CPU_IF; i++)
+ gic_cpu_map[i] = 0xff;
+
+ /*
* For primary GICs, skip over SGIs.
* For secondary GICs, skip over PPIs, too.
*/
@@ -737,7 +764,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
/* Convert our logical CPU mask into a physical one. */
for_each_cpu(cpu, mask)
- map |= 1 << cpu_logical_map(cpu);
+ map |= gic_cpu_map[cpu];
/*
* Ensure that stores to Normal memory are visible to the
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index df13a3ffff35..9d2d3ba339ff 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = {
.set_mode = sp804_set_mode,
.set_next_event = sp804_set_next_event,
.rating = 300,
- .cpumask = cpu_all_mask,
};
static struct irqaction sp804_timer_irq = {
@@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
evt->name = name;
evt->irq = irq;
+ evt->cpumask = cpu_possible_mask;
setup_irq(irq, &sp804_timer_irq);
clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index e0d538803cc3..e4df17ca90c7 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -218,7 +218,7 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
v->resume_sources = resume_sources;
v->irq = irq;
vic_id++;
- v->domain = irq_domain_add_legacy(node, fls(valid_sources), irq, 0,
+ v->domain = irq_domain_add_simple(node, fls(valid_sources), irq,
&vic_irqdomain_ops, v);
}
@@ -350,7 +350,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
vic_register(base, irq_start, vic_sources, 0, node);
}
-void __init __vic_init(void __iomem *base, unsigned int irq_start,
+void __init __vic_init(void __iomem *base, int irq_start,
u32 vic_sources, u32 resume_sources,
struct device_node *node)
{
@@ -407,7 +407,6 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
int __init vic_of_init(struct device_node *node, struct device_node *parent)
{
void __iomem *regs;
- int irq_base;
if (WARN(parent, "non-root VICs are not supported"))
return -EINVAL;
@@ -416,18 +415,12 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
if (WARN_ON(!regs))
return -EIO;
- irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
- if (WARN_ON(irq_base < 0))
- goto out_unmap;
-
- __vic_init(regs, irq_base, ~0, ~0, node);
+ /*
+ * Passing -1 as first IRQ makes the simple domain allocate descriptors
+ */
+ __vic_init(regs, -1, ~0, ~0, node);
return 0;
-
- out_unmap:
- iounmap(regs);
-
- return -EIO;
}
#endif /* CONFIG OF */
diff --git a/arch/arm/configs/afeb9260_defconfig b/arch/arm/configs/afeb9260_defconfig
index c285a9d777d9..a8dbc1e05253 100644
--- a/arch/arm/configs/afeb9260_defconfig
+++ b/arch/arm/configs/afeb9260_defconfig
@@ -79,7 +79,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DEBUG=y
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index 67bc571ed0c3..b175577d7abb 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -111,6 +111,7 @@ CONFIG_I2C=y
CONFIG_I2C_GPIO=y
CONFIG_SPI=y
CONFIG_SPI_ATMEL=y
+CONFIG_PINCTRL_AT91=y
# CONFIG_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_AT91SAM9X_WATCHDOG=y
diff --git a/arch/arm/configs/at91sam9260_defconfig b/arch/arm/configs/at91sam9260_defconfig
index 505b3765f87e..0ea5d2c97fc4 100644
--- a/arch/arm/configs/at91sam9260_defconfig
+++ b/arch/arm/configs/at91sam9260_defconfig
@@ -75,7 +75,7 @@ CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_AT91SAM9=y
diff --git a/arch/arm/configs/at91sam9261_defconfig b/arch/arm/configs/at91sam9261_defconfig
index 1e8712ef062e..c87beb973b37 100644
--- a/arch/arm/configs/at91sam9261_defconfig
+++ b/arch/arm/configs/at91sam9261_defconfig
@@ -125,7 +125,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=m
diff --git a/arch/arm/configs/at91sam9263_defconfig b/arch/arm/configs/at91sam9263_defconfig
index d2050cada82d..c5212f43eee6 100644
--- a/arch/arm/configs/at91sam9263_defconfig
+++ b/arch/arm/configs/at91sam9263_defconfig
@@ -133,7 +133,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_SDIO_UART=m
diff --git a/arch/arm/configs/at91sam9g20_defconfig b/arch/arm/configs/at91sam9g20_defconfig
index e1b0e80b54a5..3b1881033ad8 100644
--- a/arch/arm/configs/at91sam9g20_defconfig
+++ b/arch/arm/configs/at91sam9g20_defconfig
@@ -96,7 +96,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=m
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 4b8a25d9e686..1fd1d1de3220 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -218,7 +218,7 @@ CONFIG_USB_GADGET=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_PXA=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 67b5abb6f857..4ea7c95719d2 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -144,7 +144,7 @@ CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_USB_CDC_COMPOSITE=m
diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig
index 69405a762423..e16d3f372e2a 100644
--- a/arch/arm/configs/h7202_defconfig
+++ b/arch/arm/configs/h7202_defconfig
@@ -34,8 +34,7 @@ CONFIG_FB_MODE_HELPERS=y
CONFIG_USB_GADGET=m
CONFIG_USB_ZERO=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_FILE_STORAGE_TEST=y
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_EXT2_FS=y
CONFIG_TMPFS=y
diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
index a691ef4c6008..557dd291288b 100644
--- a/arch/arm/configs/magician_defconfig
+++ b/arch/arm/configs/magician_defconfig
@@ -136,7 +136,7 @@ CONFIG_USB_PXA27X=y
CONFIG_USB_ETH=m
# CONFIG_USB_ETH_RNDIS is not set
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_USB_GPIO_VBUS=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
index 00630e6af45c..a07948a87caa 100644
--- a/arch/arm/configs/mini2440_defconfig
+++ b/arch/arm/configs/mini2440_defconfig
@@ -240,7 +240,7 @@ CONFIG_USB_GADGET_S3C2410=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_CDC_COMPOSITE=m
CONFIG_MMC=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index dde2a1af7b39..42eab9a2a0fd 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -214,8 +214,7 @@ CONFIG_USB_TEST=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETH=m
# CONFIG_USB_ETH_RNDIS is not set
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_FILE_STORAGE_TEST=y
+CONFIG_USB_MASS_STORAGE=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig
index 807d4e2acb17..6a936c7c078a 100644
--- a/arch/arm/configs/prima2_defconfig
+++ b/arch/arm/configs/prima2_defconfig
@@ -37,7 +37,6 @@ CONFIG_SPI_SIRF=y
CONFIG_SPI_SPIDEV=y
# CONFIG_HWMON is not set
CONFIG_USB_GADGET=y
-CONFIG_USB_FILE_STORAGE=m
CONFIG_USB_MASS_STORAGE=m
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index df77931a4326..2e0419d1b964 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -214,7 +214,7 @@ CONFIG_USB_GADGET_DUMMY_HCD=y
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_PXA=y
diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig
index 52f1488591c7..b845f5519bcc 100644
--- a/arch/arm/configs/stamp9g20_defconfig
+++ b/arch/arm/configs/stamp9g20_defconfig
@@ -97,7 +97,7 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=m
CONFIG_USB_ZERO=m
CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=y
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index da6845493caa..250625d5223f 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -69,6 +69,8 @@ CONFIG_GPIO_TC3589X=y
CONFIG_POWER_SUPPLY=y
CONFIG_AB8500_BM=y
CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
CONFIG_MFD_STMPE=y
CONFIG_MFD_TC3589X=y
CONFIG_AB5500_CORE=y
diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
index 1d01ddd33122..d36e0d3c86ec 100644
--- a/arch/arm/configs/viper_defconfig
+++ b/arch/arm/configs/viper_defconfig
@@ -139,7 +139,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
CONFIG_USB_GADGET=m
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig
index 547a3c1e59db..731d4f985310 100644
--- a/arch/arm/configs/zeus_defconfig
+++ b/arch/arm/configs/zeus_defconfig
@@ -143,7 +143,7 @@ CONFIG_USB_GADGET=m
CONFIG_USB_PXA27X=y
CONFIG_USB_ETH=m
CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_USB_G_SERIAL=m
CONFIG_USB_G_PRINTER=m
CONFIG_MMC=y
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index f70ae175a3d6..d3db39860b9c 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -16,7 +16,6 @@ generic-y += local64.h
generic-y += msgbuf.h
generic-y += param.h
generic-y += parport.h
-generic-y += percpu.h
generic-y += poll.h
generic-y += resource.h
generic-y += sections.h
@@ -31,5 +30,6 @@ generic-y += sockios.h
generic-y += termbits.h
generic-y += termios.h
generic-y += timex.h
+generic-y += trace_clock.h
generic-y += types.h
generic-y += unaligned.h
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 2ef95813fce0..eb87200aa4b5 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -250,6 +250,7 @@
* Beware, it also clobers LR.
*/
.macro safe_svcmode_maskall reg:req
+#if __LINUX_ARM_ARCH__ >= 6
mrs \reg , cpsr
mov lr , \reg
and lr , lr , #MODE_MASK
@@ -266,6 +267,13 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
__ERET
1: msr cpsr_c, \reg
2:
+#else
+/*
+ * workaround for possibly broken pre-v6 hardware
+ * (akita, Sharp Zaurus C-1000, PXA270-based)
+ */
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, \reg
+#endif
.endm
/*
diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h
index d797223b39d5..2744f0602550 100644
--- a/arch/arm/include/asm/cpu.h
+++ b/arch/arm/include/asm/cpu.h
@@ -15,6 +15,7 @@
struct cpuinfo_arm {
struct cpu cpu;
+ u32 cpuid;
#ifdef CONFIG_SMP
unsigned int loops_per_jiffy;
#endif
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index cb47d28cbe1f..a59dcb5ab5fc 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -25,6 +25,19 @@
#define CPUID_EXT_ISAR4 "c2, 4"
#define CPUID_EXT_ISAR5 "c2, 5"
+#define MPIDR_SMP_BITMASK (0x3 << 30)
+#define MPIDR_SMP_VALUE (0x2 << 30)
+
+#define MPIDR_MT_BITMASK (0x1 << 24)
+
+#define MPIDR_HWID_BITMASK 0xFFFFFF
+
+#define MPIDR_LEVEL_BITS 8
+#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
+
+#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
+ ((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
+
extern unsigned int processor_id;
#ifdef CONFIG_CPU_CP15
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h
index a0ada3ea4358..f2e5cad3f306 100644
--- a/arch/arm/include/asm/cti.h
+++ b/arch/arm/include/asm/cti.h
@@ -146,15 +146,7 @@ static inline void cti_irq_ack(struct cti *cti)
*/
static inline void cti_unlock(struct cti *cti)
{
- void __iomem *base = cti->base;
- unsigned long val;
-
- val = __raw_readl(base + LOCKSTATUS);
-
- if (val & 1) {
- val = LOCKCODE;
- __raw_writel(val, base + LOCKACCESS);
- }
+ __raw_writel(LOCKCODE, cti->base + LOCKACCESS);
}
/**
@@ -166,14 +158,6 @@ static inline void cti_unlock(struct cti *cti)
*/
static inline void cti_lock(struct cti *cti)
{
- void __iomem *base = cti->base;
- unsigned long val;
-
- val = __raw_readl(base + LOCKSTATUS);
-
- if (!(val & 1)) {
- val = ~LOCKCODE;
- __raw_writel(val, base + LOCKACCESS);
- }
+ __raw_writel(~LOCKCODE, cti->base + LOCKACCESS);
}
#endif
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index c4c87bc12231..3b2c40b5bfa2 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -102,6 +102,10 @@
#define L2X0_ADDR_FILTER_EN 1
+#define L2X0_CTRL_EN 1
+
+#define L2X0_WAY_SIZE_SHIFT 3
+
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
@@ -126,6 +130,7 @@ struct l2x0_regs {
unsigned long filter_end;
unsigned long prefetch_ctrl;
unsigned long pwr_ctrl;
+ unsigned long ctrl;
};
extern struct l2x0_regs l2x0_saved_regs;
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
index 6b9b077d86b3..afd7e916472f 100644
--- a/arch/arm/include/asm/hardware/sp810.h
+++ b/arch/arm/include/asm/hardware/sp810.h
@@ -56,6 +56,8 @@
#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
+#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2))
+
static inline void sysctl_soft_reset(void __iomem *base)
{
/* switch to slow mode */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index e14af1a1a320..2bebad36fc83 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -47,7 +47,7 @@
struct device_node;
struct pt_regs;
-void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
+void __vic_init(void __iomem *base, int irq_start, u32 vic_sources,
u32 resume_sources, struct device_node *node);
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
int vic_of_init(struct device_node *node, struct device_node *parent);
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index c190bc992f0e..01169dd723f1 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -98,12 +98,12 @@ static inline void decode_ctrl_reg(u32 reg,
#define ARM_BASE_WCR 112
/* Accessor macros for the debug registers. */
-#define ARM_DBG_READ(M, OP2, VAL) do {\
- asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\
+#define ARM_DBG_READ(N, M, OP2, VAL) do {\
+ asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\
} while (0)
-#define ARM_DBG_WRITE(M, OP2, VAL) do {\
- asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\
+#define ARM_DBG_WRITE(N, M, OP2, VAL) do {\
+ asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
} while (0)
struct notifier_block;
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 42f042ee4ada..652b56086de7 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -374,7 +374,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
#ifdef CONFIG_MMU
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
-extern int valid_phys_addr_range(unsigned long addr, size_t size);
+extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
extern int devmem_is_allowed(unsigned long pfn);
#endif
diff --git a/arch/arm/include/asm/mach/serial_at91.h b/arch/arm/include/asm/mach/serial_at91.h
deleted file mode 100644
index ea6d063923b8..000000000000
--- a/arch/arm/include/asm/mach/serial_at91.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/include/asm/mach/serial_at91.h
- *
- * Based on serial_sa1100.h by Nicolas Pitre
- *
- * Copyright (C) 2002 ATMEL Rousset
- *
- * Low level machine dependent UART functions.
- */
-
-struct uart_port;
-
-/*
- * This is a temporary structure for registering these
- * functions; it is intended to be discarded after boot.
- */
-struct atmel_port_fns {
- void (*set_mctrl)(struct uart_port *, u_int);
- u_int (*get_mctrl)(struct uart_port *);
- void (*enable_ms)(struct uart_port *);
- void (*pm)(struct uart_port *, u_int, u_int);
- int (*set_wake)(struct uart_port *, u_int);
- int (*open)(struct uart_port *);
- void (*close)(struct uart_port *);
-};
-
-#if defined(CONFIG_SERIAL_ATMEL)
-void atmel_register_uart_fns(struct atmel_port_fns *fns);
-#else
-#define atmel_register_uart_fns(fns) do { } while (0)
-#endif
-
-
diff --git a/arch/arm/include/asm/mach/serial_sa1100.h b/arch/arm/include/asm/mach/serial_sa1100.h
deleted file mode 100644
index d09064bf95a0..000000000000
--- a/arch/arm/include/asm/mach/serial_sa1100.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/include/asm/mach/serial_sa1100.h
- *
- * Author: Nicolas Pitre
- *
- * Moved and changed lots, Russell King
- *
- * Low level machine dependent UART functions.
- */
-
-struct uart_port;
-struct uart_info;
-
-/*
- * This is a temporary structure for registering these
- * functions; it is intended to be discarded after boot.
- */
-struct sa1100_port_fns {
- void (*set_mctrl)(struct uart_port *, u_int);
- u_int (*get_mctrl)(struct uart_port *);
- void (*pm)(struct uart_port *, u_int, u_int);
- int (*set_wake)(struct uart_port *, u_int);
-};
-
-#ifdef CONFIG_SERIAL_SA1100
-void sa1100_register_uart_fns(struct sa1100_port_fns *fns);
-void sa1100_register_uart(int idx, int port);
-#else
-#define sa1100_register_uart_fns(fns) do { } while (0)
-#define sa1100_register_uart(idx,port) do { } while (0)
-#endif
diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h
deleted file mode 100644
index ea297ac70bc6..000000000000
--- a/arch/arm/include/asm/mach/udc_pxa2xx.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/include/asm/mach/udc_pxa2xx.h
- *
- * This supports machine-specific differences in how the PXA2xx
- * USB Device Controller (UDC) is wired.
- *
- * It is set in linux/arch/arm/mach-pxa/<machine>.c or in
- * linux/arch/mach-ixp4xx/<machine>.c and used in
- * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c
- */
-
-struct pxa2xx_udc_mach_info {
- int (*udc_is_connected)(void); /* do we see host? */
- void (*udc_command)(int cmd);
-#define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */
-#define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */
-
- /* Boards following the design guidelines in the developer's manual,
- * with on-chip GPIOs not Lubbock's weird hardware, can have a sane
- * VBUS IRQ and omit the methods above. Store the GPIO number
- * here. Note that sometimes the signals go through inverters...
- */
- bool gpio_pullup_inverted;
- int gpio_pullup; /* high == pullup activated */
-};
-
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 14965658a923..9f77e7804f3b 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -5,18 +5,15 @@
typedef struct {
#ifdef CONFIG_CPU_HAS_ASID
- unsigned int id;
- raw_spinlock_t id_lock;
+ u64 id;
#endif
- unsigned int kvm_seq;
+ unsigned int vmalloc_seq;
} mm_context_t;
#ifdef CONFIG_CPU_HAS_ASID
-#define ASID(mm) ((mm)->context.id & 255)
-
-/* init_mm.context.id_lock should be initialized. */
-#define INIT_MM_CONTEXT(name) \
- .context.id_lock = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock),
+#define ASID_BITS 8
+#define ASID_MASK ((~0ULL) << ASID_BITS)
+#define ASID(mm) ((mm)->context.id & ~ASID_MASK)
#else
#define ASID(mm) (0)
#endif
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 0306bc642c0d..e1f644bc7cc5 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -20,88 +20,12 @@
#include <asm/proc-fns.h>
#include <asm-generic/mm_hooks.h>
-void __check_kvm_seq(struct mm_struct *mm);
+void __check_vmalloc_seq(struct mm_struct *mm);
#ifdef CONFIG_CPU_HAS_ASID
-/*
- * On ARMv6, we have the following structure in the Context ID:
- *
- * 31 7 0
- * +-------------------------+-----------+
- * | process ID | ASID |
- * +-------------------------+-----------+
- * | context ID |
- * +-------------------------------------+
- *
- * The ASID is used to tag entries in the CPU caches and TLBs.
- * The context ID is used by debuggers and trace logic, and
- * should be unique within all running processes.
- */
-#define ASID_BITS 8
-#define ASID_MASK ((~0) << ASID_BITS)
-#define ASID_FIRST_VERSION (1 << ASID_BITS)
-
-extern unsigned int cpu_last_asid;
-
-void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
-void __new_context(struct mm_struct *mm);
-void cpu_set_reserved_ttbr0(void);
-
-static inline void switch_new_context(struct mm_struct *mm)
-{
- unsigned long flags;
-
- __new_context(mm);
-
- local_irq_save(flags);
- cpu_switch_mm(mm->pgd, mm);
- local_irq_restore(flags);
-}
-
-static inline void check_and_switch_context(struct mm_struct *mm,
- struct task_struct *tsk)
-{
- if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
- __check_kvm_seq(mm);
-
- /*
- * Required during context switch to avoid speculative page table
- * walking with the wrong TTBR.
- */
- cpu_set_reserved_ttbr0();
-
- if (!((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
- /*
- * The ASID is from the current generation, just switch to the
- * new pgd. This condition is only true for calls from
- * context_switch() and interrupts are already disabled.
- */
- cpu_switch_mm(mm->pgd, mm);
- else if (irqs_disabled())
- /*
- * Defer the new ASID allocation until after the context
- * switch critical region since __new_context() cannot be
- * called with interrupts disabled (it sends IPIs).
- */
- set_ti_thread_flag(task_thread_info(tsk), TIF_SWITCH_MM);
- else
- /*
- * That is a direct call to switch_mm() or activate_mm() with
- * interrupts enabled and a new context.
- */
- switch_new_context(mm);
-}
-
-#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0)
-
-#define finish_arch_post_lock_switch \
- finish_arch_post_lock_switch
-static inline void finish_arch_post_lock_switch(void)
-{
- if (test_and_clear_thread_flag(TIF_SWITCH_MM))
- switch_new_context(current->mm);
-}
+void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
+#define init_new_context(tsk,mm) ({ mm->context.id = 0; })
#else /* !CONFIG_CPU_HAS_ASID */
@@ -110,8 +34,8 @@ static inline void finish_arch_post_lock_switch(void)
static inline void check_and_switch_context(struct mm_struct *mm,
struct task_struct *tsk)
{
- if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
- __check_kvm_seq(mm);
+ if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
+ __check_vmalloc_seq(mm);
if (irqs_disabled())
/*
@@ -143,6 +67,7 @@ static inline void finish_arch_post_lock_switch(void)
#endif /* CONFIG_CPU_HAS_ASID */
#define destroy_context(mm) do { } while(0)
+#define activate_mm(prev,next) switch_mm(prev, next, NULL)
/*
* This is called when "tsk" is about to enter lazy TLB mode.
@@ -186,6 +111,5 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
}
#define deactivate_mm(tsk,mm) do { } while (0)
-#define activate_mm(prev,next) switch_mm(prev, next, NULL)
#endif
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
new file mode 100644
index 000000000000..968c0a14e0a3
--- /dev/null
+++ b/arch/arm/include/asm/percpu.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _ASM_ARM_PERCPU_H_
+#define _ASM_ARM_PERCPU_H_
+
+/*
+ * Same as asm-generic/percpu.h, except that we store the per cpu offset
+ * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
+ */
+#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6)
+static inline void set_my_cpu_offset(unsigned long off)
+{
+ /* Set TPIDRPRW */
+ asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
+}
+
+static inline unsigned long __my_cpu_offset(void)
+{
+ unsigned long off;
+ /* Read TPIDRPRW */
+ asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : : "memory");
+ return off;
+}
+#define __my_cpu_offset __my_cpu_offset()
+#else
+#define set_my_cpu_offset(x) do {} while(0)
+
+#endif /* CONFIG_SMP */
+
+#include <asm-generic/percpu.h>
+
+#endif /* _ASM_ARM_PERCPU_H_ */
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index 625cd621a436..755877527cf9 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -21,4 +21,11 @@
#define C(_x) PERF_COUNT_HW_CACHE_##_x
#define CACHE_OP_UNSUPPORTED 0xFFFF
+#ifdef CONFIG_HW_PERF_EVENTS
+struct pt_regs;
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+#define perf_misc_flags(regs) perf_misc_flags(regs)
+#endif
+
#endif /* __ARM_PERF_EVENT_H__ */
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index 2317a71c8f8e..f97ee02386ee 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -115,6 +115,7 @@
* The PTE table pointer refers to the hardware entries; the "Linux"
* entries are stored 1024 bytes below.
*/
+#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
@@ -123,6 +124,7 @@
#define L_PTE_USER (_AT(pteval_t, 1) << 8)
#define L_PTE_XN (_AT(pteval_t, 1) << 9)
#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
+#define L_PTE_NONE (_AT(pteval_t, 1) << 11)
/*
* These are the memory types, defined to be compatible with
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index b24903549d1c..a3f37929940a 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -67,7 +67,8 @@
* These bits overlap with the hardware bits but the naming is preserved for
* consistency with the classic page table format.
*/
-#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */
+#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
+#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Present */
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
#define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */
@@ -76,6 +77,7 @@
#define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */
#define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */
+#define L_PTE_NONE (_AT(pteval_t, 1) << 57) /* PROT_NONE */
/*
* To be used in assembly code with the upper page attributes.
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 08c12312a1f9..9c82f988c0e3 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -73,7 +73,7 @@ extern pgprot_t pgprot_kernel;
#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
-#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
+#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY | L_PTE_NONE)
#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
@@ -83,7 +83,7 @@ extern pgprot_t pgprot_kernel;
#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
#define PAGE_KERNEL_EXEC pgprot_kernel
-#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN | L_PTE_NONE)
#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
@@ -203,9 +203,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
#define pte_special(pte) (0)
-#define pte_present_user(pte) \
- ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
- (L_PTE_PRESENT | L_PTE_USER))
+#define pte_present_user(pte) (pte_present(pte) && (pte_val(pte) & L_PTE_USER))
#if __LINUX_ARM_ARCH__ < 6
static inline void __sync_icache_dcache(pte_t pteval)
@@ -242,7 +240,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
+ const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER | L_PTE_NONE;
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
return pte;
}
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index a26170dce02e..f24edad26c70 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -67,19 +67,19 @@ struct arm_pmu {
cpumask_t active_irqs;
char *name;
irqreturn_t (*handle_irq)(int irq_num, void *dev);
- void (*enable)(struct hw_perf_event *evt, int idx);
- void (*disable)(struct hw_perf_event *evt, int idx);
+ void (*enable)(struct perf_event *event);
+ void (*disable)(struct perf_event *event);
int (*get_event_idx)(struct pmu_hw_events *hw_events,
- struct hw_perf_event *hwc);
+ struct perf_event *event);
int (*set_event_filter)(struct hw_perf_event *evt,
struct perf_event_attr *attr);
- u32 (*read_counter)(int idx);
- void (*write_counter)(int idx, u32 val);
- void (*start)(void);
- void (*stop)(void);
+ u32 (*read_counter)(struct perf_event *event);
+ void (*write_counter)(struct perf_event *event, u32 val);
+ void (*start)(struct arm_pmu *);
+ void (*stop)(struct arm_pmu *);
void (*reset)(void *);
- int (*request_irq)(irq_handler_t handler);
- void (*free_irq)(void);
+ int (*request_irq)(struct arm_pmu *, irq_handler_t handler);
+ void (*free_irq)(struct arm_pmu *);
int (*map_event)(struct perf_event *event);
int num_events;
atomic_t active_events;
@@ -93,15 +93,11 @@ struct arm_pmu {
extern const struct dev_pm_ops armpmu_dev_pm_ops;
-int armpmu_register(struct arm_pmu *armpmu, char *name, int type);
+int armpmu_register(struct arm_pmu *armpmu, int type);
-u64 armpmu_event_update(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx);
+u64 armpmu_event_update(struct perf_event *event);
-int armpmu_event_set_period(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx);
+int armpmu_event_set_period(struct perf_event *event);
int armpmu_map_event(struct perf_event *event,
const unsigned (*event_map)[PERF_COUNT_HW_MAX],
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
index aeae9c609df4..a219227c3e43 100644
--- a/arch/arm/include/asm/prom.h
+++ b/arch/arm/include/asm/prom.h
@@ -11,10 +11,13 @@
#ifndef __ASMARM_PROM_H
#define __ASMARM_PROM_H
+#define HAVE_ARCH_DEVTREE_FIXUPS
+
#ifdef CONFIG_OF
extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
extern void arm_dt_memblock_reserve(void);
+extern void __init arm_dt_init_cpu_maps(void);
#else /* CONFIG_OF */
@@ -24,6 +27,7 @@ static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
}
static inline void arm_dt_memblock_reserve(void) { }
+static inline void arm_dt_init_cpu_maps(void) { }
#endif /* CONFIG_OF */
#endif /* ASMARM_PROM_H */
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 2e3be16c6766..d3a22bebe6ce 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -79,6 +79,7 @@ extern void cpu_die(void);
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
struct smp_operations {
#ifdef CONFIG_SMP
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
index 558d6c80aca9..aaa61b6f50ff 100644
--- a/arch/arm/include/asm/smp_plat.h
+++ b/arch/arm/include/asm/smp_plat.h
@@ -5,6 +5,9 @@
#ifndef __ASMARM_SMP_PLAT_H
#define __ASMARM_SMP_PLAT_H
+#include <linux/cpumask.h>
+#include <linux/err.h>
+
#include <asm/cputype.h>
/*
@@ -48,5 +51,19 @@ static inline int cache_ops_need_broadcast(void)
*/
extern int __cpu_logical_map[];
#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+/*
+ * Retrieve logical cpu index corresponding to a given MPIDR[23:0]
+ * - mpidr: MPIDR[23:0] to be used for the look-up
+ *
+ * Returns the cpu logical index or -EINVAL on look-up error
+ */
+static inline int get_logical_index(u32 mpidr)
+{
+ int cpu;
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+ if (cpu_logical_map(cpu) == mpidr)
+ return cpu;
+ return -EINVAL;
+}
#endif
diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
index 9fdded6b1089..f1d96d4e8092 100644
--- a/arch/arm/include/asm/syscall.h
+++ b/arch/arm/include/asm/syscall.h
@@ -7,6 +7,8 @@
#ifndef _ASM_ARM_SYSCALL_H
#define _ASM_ARM_SYSCALL_H
+#include <linux/audit.h> /* for AUDIT_ARCH_* */
+#include <linux/elf.h> /* for ELF_EM */
#include <linux/err.h>
#include <linux/sched.h>
@@ -95,4 +97,11 @@ static inline void syscall_set_arguments(struct task_struct *task,
memcpy(&regs->ARM_r0 + i, args, n * sizeof(args[0]));
}
+static inline int syscall_get_arch(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /* ARM tasks don't change audit architectures on the fly. */
+ return AUDIT_ARCH_ARM;
+}
+
#endif /* _ASM_ARM_SYSCALL_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 8477b4c1d39f..cddda1f41f0f 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -151,10 +151,10 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_SYSCALL_TRACE 8
#define TIF_SYSCALL_AUDIT 9
#define TIF_SYSCALL_TRACEPOINT 10
+#define TIF_SECCOMP 11 /* seccomp syscall filtering active */
#define TIF_USING_IWMMXT 17
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 20
-#define TIF_SECCOMP 21
#define TIF_SWITCH_MM 22 /* deferred switch_mm */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -163,11 +163,12 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
+#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
/* Checks for any syscall work in entry-common.S */
-#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
+#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
/*
* Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index bee7f9d47f02..70f1bdeb241b 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -19,8 +19,10 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
+#include <asm/cputype.h>
#include <asm/setup.h>
#include <asm/page.h>
+#include <asm/smp_plat.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
@@ -61,6 +63,108 @@ void __init arm_dt_memblock_reserve(void)
}
}
+/*
+ * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
+ * and builds the cpu logical map array containing MPIDR values related to
+ * logical cpus
+ *
+ * Updates the cpu possible mask with the number of parsed cpu nodes
+ */
+void __init arm_dt_init_cpu_maps(void)
+{
+ /*
+ * Temp logical map is initialized with UINT_MAX values that are
+ * considered invalid logical map entries since the logical map must
+ * contain a list of MPIDR[23:0] values where MPIDR[31:24] must
+ * read as 0.
+ */
+ struct device_node *cpu, *cpus;
+ u32 i, j, cpuidx = 1;
+ u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
+
+ u32 tmp_map[NR_CPUS] = { [0 ... NR_CPUS-1] = UINT_MAX };
+ bool bootcpu_valid = false;
+ cpus = of_find_node_by_path("/cpus");
+
+ if (!cpus)
+ return;
+
+ for_each_child_of_node(cpus, cpu) {
+ u32 hwid;
+
+ pr_debug(" * %s...\n", cpu->full_name);
+ /*
+ * A device tree containing CPU nodes with missing "reg"
+ * properties is considered invalid to build the
+ * cpu_logical_map.
+ */
+ if (of_property_read_u32(cpu, "reg", &hwid)) {
+ pr_debug(" * %s missing reg property\n",
+ cpu->full_name);
+ return;
+ }
+
+ /*
+ * 8 MSBs must be set to 0 in the DT since the reg property
+ * defines the MPIDR[23:0].
+ */
+ if (hwid & ~MPIDR_HWID_BITMASK)
+ return;
+
+ /*
+ * Duplicate MPIDRs are a recipe for disaster.
+ * Scan all initialized entries and check for
+ * duplicates. If any is found just bail out.
+ * temp values were initialized to UINT_MAX
+ * to avoid matching valid MPIDR[23:0] values.
+ */
+ for (j = 0; j < cpuidx; j++)
+ if (WARN(tmp_map[j] == hwid, "Duplicate /cpu reg "
+ "properties in the DT\n"))
+ return;
+
+ /*
+ * Build a stashed array of MPIDR values. Numbering scheme
+ * requires that if detected the boot CPU must be assigned
+ * logical id 0. Other CPUs get sequential indexes starting
+ * from 1. If a CPU node with a reg property matching the
+ * boot CPU MPIDR is detected, this is recorded so that the
+ * logical map built from DT is validated and can be used
+ * to override the map created in smp_setup_processor_id().
+ */
+ if (hwid == mpidr) {
+ i = 0;
+ bootcpu_valid = true;
+ } else {
+ i = cpuidx++;
+ }
+
+ if (WARN(cpuidx > nr_cpu_ids, "DT /cpu %u nodes greater than "
+ "max cores %u, capping them\n",
+ cpuidx, nr_cpu_ids)) {
+ cpuidx = nr_cpu_ids;
+ break;
+ }
+
+ tmp_map[i] = hwid;
+ }
+
+ if (WARN(!bootcpu_valid, "DT missing boot CPU MPIDR[23:0], "
+ "fall back to default cpu_logical_map\n"))
+ return;
+
+ /*
+ * Since the boot CPU node contains proper data, and all nodes have
+ * a reg property, the DT CPU list can be considered valid and the
+ * logical map created in smp_setup_processor_id() can be overridden
+ */
+ for (i = 0; i < cpuidx; i++) {
+ set_cpu_possible(i, true);
+ cpu_logical_map(i) = tmp_map[i];
+ pr_debug("cpu logical map 0x%x\n", cpu_logical_map(i));
+ }
+}
+
/**
* setup_machine_fdt - Machine setup when an dtb was passed to the kernel
* @dt_phys: physical address of dt blob
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 34711757ba59..804153c0a9cf 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -417,16 +417,6 @@ local_restart:
ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args
-#ifdef CONFIG_SECCOMP
- tst r10, #_TIF_SECCOMP
- beq 1f
- mov r0, scno
- bl __secure_computing
- add r0, sp, #S_R0 + S_OFF @ pointer to regs
- ldmia r0, {r0 - r3} @ have to reload r0 - r3
-1:
-#endif
-
tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?
bne __sys_trace
@@ -458,11 +448,13 @@ __sys_trace:
ldmccia r1, {r0 - r6} @ have to reload r0 - r6
stmccia sp, {r4, r5} @ and update the stack args
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
- b 2b
+ cmp scno, #-1 @ skip the syscall?
+ bne 2b
+ add sp, sp, #S_OFF @ restore stack
+ b ret_slow_syscall
__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
- mov r1, scno
mov r0, sp
bl syscall_trace_exit
b ret_slow_syscall
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 278cfc144f44..2c228a07e58c 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -68,7 +68,7 @@ __after_proc_init:
* CP15 system control register value returned in r0 from
* the CPU init function.
*/
-#ifdef CONFIG_ALIGNMENT_TRAP
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
orr r0, r0, #CR_A
#else
bic r0, r0, #CR_A
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 281bf3301241..5ff2e77782b1 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -52,14 +52,14 @@ static u8 debug_arch;
/* Maximum supported watchpoint length. */
static u8 max_watchpoint_len;
-#define READ_WB_REG_CASE(OP2, M, VAL) \
- case ((OP2 << 4) + M): \
- ARM_DBG_READ(c ## M, OP2, VAL); \
+#define READ_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_READ(c0, c ## M, OP2, VAL); \
break
-#define WRITE_WB_REG_CASE(OP2, M, VAL) \
- case ((OP2 << 4) + M): \
- ARM_DBG_WRITE(c ## M, OP2, VAL);\
+#define WRITE_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_WRITE(c0, c ## M, OP2, VAL); \
break
#define GEN_READ_WB_REG_CASES(OP2, VAL) \
@@ -136,12 +136,12 @@ static u8 get_debug_arch(void)
/* Do we implement the extended CPUID interface? */
if (((read_cpuid_id() >> 16) & 0xf) != 0xf) {
- pr_warning("CPUID feature registers not supported. "
- "Assuming v6 debug is present.\n");
+ pr_warn_once("CPUID feature registers not supported. "
+ "Assuming v6 debug is present.\n");
return ARM_DEBUG_ARCH_V6;
}
- ARM_DBG_READ(c0, 0, didr);
+ ARM_DBG_READ(c0, c0, 0, didr);
return (didr >> 16) & 0xf;
}
@@ -169,7 +169,7 @@ static int debug_exception_updates_fsr(void)
static int get_num_wrp_resources(void)
{
u32 didr;
- ARM_DBG_READ(c0, 0, didr);
+ ARM_DBG_READ(c0, c0, 0, didr);
return ((didr >> 28) & 0xf) + 1;
}
@@ -177,7 +177,7 @@ static int get_num_wrp_resources(void)
static int get_num_brp_resources(void)
{
u32 didr;
- ARM_DBG_READ(c0, 0, didr);
+ ARM_DBG_READ(c0, c0, 0, didr);
return ((didr >> 24) & 0xf) + 1;
}
@@ -228,19 +228,17 @@ static int get_num_brps(void)
* be put into halting debug mode at any time by an external debugger
* but there is nothing we can do to prevent that.
*/
-static int enable_monitor_mode(void)
+static int monitor_mode_enabled(void)
{
u32 dscr;
- int ret = 0;
-
- ARM_DBG_READ(c1, 0, dscr);
+ ARM_DBG_READ(c0, c1, 0, dscr);
+ return !!(dscr & ARM_DSCR_MDBGEN);
+}
- /* Ensure that halting mode is disabled. */
- if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
- "halting debug mode enabled. Unable to access hardware resources.\n")) {
- ret = -EPERM;
- goto out;
- }
+static int enable_monitor_mode(void)
+{
+ u32 dscr;
+ ARM_DBG_READ(c0, c1, 0, dscr);
/* If monitor mode is already enabled, just return. */
if (dscr & ARM_DSCR_MDBGEN)
@@ -250,24 +248,27 @@ static int enable_monitor_mode(void)
switch (get_debug_arch()) {
case ARM_DEBUG_ARCH_V6:
case ARM_DEBUG_ARCH_V6_1:
- ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
+ ARM_DBG_WRITE(c0, c1, 0, (dscr | ARM_DSCR_MDBGEN));
break;
case ARM_DEBUG_ARCH_V7_ECP14:
case ARM_DEBUG_ARCH_V7_1:
- ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
+ ARM_DBG_WRITE(c0, c2, 2, (dscr | ARM_DSCR_MDBGEN));
+ isb();
break;
default:
- ret = -ENODEV;
- goto out;
+ return -ENODEV;
}
/* Check that the write made it through. */
- ARM_DBG_READ(c1, 0, dscr);
- if (!(dscr & ARM_DSCR_MDBGEN))
- ret = -EPERM;
+ ARM_DBG_READ(c0, c1, 0, dscr);
+ if (!(dscr & ARM_DSCR_MDBGEN)) {
+ pr_warn_once("Failed to enable monitor mode on CPU %d.\n",
+ smp_processor_id());
+ return -EPERM;
+ }
out:
- return ret;
+ return 0;
}
int hw_breakpoint_slots(int type)
@@ -328,14 +329,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
{
struct arch_hw_breakpoint *info = counter_arch_bp(bp);
struct perf_event **slot, **slots;
- int i, max_slots, ctrl_base, val_base, ret = 0;
+ int i, max_slots, ctrl_base, val_base;
u32 addr, ctrl;
- /* Ensure that we are in monitor mode and halting mode is disabled. */
- ret = enable_monitor_mode();
- if (ret)
- goto out;
-
addr = info->address;
ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
@@ -362,9 +358,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
}
}
- if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
- ret = -EBUSY;
- goto out;
+ if (i == max_slots) {
+ pr_warning("Can't find any breakpoint slot\n");
+ return -EBUSY;
}
/* Override the breakpoint data with the step data. */
@@ -383,9 +379,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
/* Setup the control register. */
write_wb_reg(ctrl_base + i, ctrl);
-
-out:
- return ret;
+ return 0;
}
void arch_uninstall_hw_breakpoint(struct perf_event *bp)
@@ -416,8 +410,10 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
}
}
- if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
+ if (i == max_slots) {
+ pr_warning("Can't find any breakpoint slot\n");
return;
+ }
/* Ensure that we disable the mismatch breakpoint. */
if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE &&
@@ -596,6 +592,10 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
int ret = 0;
u32 offset, alignment_mask = 0x3;
+ /* Ensure that we are in monitor debug mode. */
+ if (!monitor_mode_enabled())
+ return -ENODEV;
+
/* Build the arch_hw_breakpoint. */
ret = arch_build_bp_info(bp);
if (ret)
@@ -858,7 +858,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
local_irq_enable();
/* We only handle watchpoints and hardware breakpoints. */
- ARM_DBG_READ(c1, 0, dscr);
+ ARM_DBG_READ(c0, c1, 0, dscr);
/* Perform perf callbacks. */
switch (ARM_DSCR_MOE(dscr)) {
@@ -906,7 +906,7 @@ static struct undef_hook debug_reg_hook = {
static void reset_ctrl_regs(void *unused)
{
int i, raw_num_brps, err = 0, cpu = smp_processor_id();
- u32 dbg_power;
+ u32 val;
/*
* v7 debug contains save and restore registers so that debug state
@@ -919,23 +919,30 @@ static void reset_ctrl_regs(void *unused)
switch (debug_arch) {
case ARM_DEBUG_ARCH_V6:
case ARM_DEBUG_ARCH_V6_1:
- /* ARMv6 cores just need to reset the registers. */
- goto reset_regs;
+ /* ARMv6 cores clear the registers out of reset. */
+ goto out_mdbgen;
case ARM_DEBUG_ARCH_V7_ECP14:
/*
* Ensure sticky power-down is clear (i.e. debug logic is
* powered up).
*/
- asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power));
- if ((dbg_power & 0x1) == 0)
+ ARM_DBG_READ(c1, c5, 4, val);
+ if ((val & 0x1) == 0)
err = -EPERM;
+
+ /*
+ * Check whether we implement OS save and restore.
+ */
+ ARM_DBG_READ(c1, c1, 4, val);
+ if ((val & 0x9) == 0)
+ goto clear_vcr;
break;
case ARM_DEBUG_ARCH_V7_1:
/*
* Ensure the OS double lock is clear.
*/
- asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power));
- if ((dbg_power & 0x1) == 1)
+ ARM_DBG_READ(c1, c3, 4, val);
+ if ((val & 0x1) == 1)
err = -EPERM;
break;
}
@@ -947,24 +954,29 @@ static void reset_ctrl_regs(void *unused)
}
/*
- * Unconditionally clear the lock by writing a value
+ * Unconditionally clear the OS lock by writing a value
* other than 0xC5ACCE55 to the access register.
*/
- asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
+ ARM_DBG_WRITE(c1, c0, 4, 0);
isb();
/*
* Clear any configured vector-catch events before
* enabling monitor mode.
*/
- asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
+clear_vcr:
+ ARM_DBG_WRITE(c0, c7, 0, 0);
isb();
-reset_regs:
- if (enable_monitor_mode())
+ if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
+ pr_warning("CPU %d failed to disable vector catch\n", cpu);
return;
+ }
- /* We must also reset any reserved registers. */
+ /*
+ * The control/value register pairs are UNKNOWN out of reset so
+ * clear them to avoid spurious debug events.
+ */
raw_num_brps = get_num_brp_resources();
for (i = 0; i < raw_num_brps; ++i) {
write_wb_reg(ARM_BASE_BCR + i, 0UL);
@@ -975,6 +987,19 @@ reset_regs:
write_wb_reg(ARM_BASE_WCR + i, 0UL);
write_wb_reg(ARM_BASE_WVR + i, 0UL);
}
+
+ if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) {
+ pr_warning("CPU %d failed to clear debug register pairs\n", cpu);
+ return;
+ }
+
+ /*
+ * Have a crack at enabling monitor mode. We don't actually need
+ * it yet, but reporting an error early is useful if it fails.
+ */
+out_mdbgen:
+ if (enable_monitor_mode())
+ cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu));
}
static int __cpuinit dbg_reset_notify(struct notifier_block *self,
@@ -992,8 +1017,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
static int __init arch_hw_breakpoint_init(void)
{
- u32 dscr;
-
debug_arch = get_debug_arch();
if (!debug_arch_supported()) {
@@ -1028,17 +1051,10 @@ static int __init arch_hw_breakpoint_init(void)
core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " :
"", core_num_wrps);
- ARM_DBG_READ(c1, 0, dscr);
- if (dscr & ARM_DSCR_HDBGEN) {
- max_watchpoint_len = 4;
- pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
- max_watchpoint_len);
- } else {
- /* Work out the maximum supported watchpoint length. */
- max_watchpoint_len = get_max_wp_len();
- pr_info("maximum watchpoint size is %u bytes.\n",
- max_watchpoint_len);
- }
+ /* Work out the maximum supported watchpoint length. */
+ max_watchpoint_len = get_max_wp_len();
+ pr_info("maximum watchpoint size is %u bytes.\n",
+ max_watchpoint_len);
/* Register debug fault handler. */
hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 53c0304b734a..f9e8657dd241 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -86,12 +86,10 @@ armpmu_map_event(struct perf_event *event,
return -ENOENT;
}
-int
-armpmu_event_set_period(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx)
+int armpmu_event_set_period(struct perf_event *event)
{
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
s64 left = local64_read(&hwc->period_left);
s64 period = hwc->sample_period;
int ret = 0;
@@ -119,24 +117,22 @@ armpmu_event_set_period(struct perf_event *event,
local64_set(&hwc->prev_count, (u64)-left);
- armpmu->write_counter(idx, (u64)(-left) & 0xffffffff);
+ armpmu->write_counter(event, (u64)(-left) & 0xffffffff);
perf_event_update_userpage(event);
return ret;
}
-u64
-armpmu_event_update(struct perf_event *event,
- struct hw_perf_event *hwc,
- int idx)
+u64 armpmu_event_update(struct perf_event *event)
{
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
u64 delta, prev_raw_count, new_raw_count;
again:
prev_raw_count = local64_read(&hwc->prev_count);
- new_raw_count = armpmu->read_counter(idx);
+ new_raw_count = armpmu->read_counter(event);
if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
new_raw_count) != prev_raw_count)
@@ -159,7 +155,7 @@ armpmu_read(struct perf_event *event)
if (hwc->idx < 0)
return;
- armpmu_event_update(event, hwc, hwc->idx);
+ armpmu_event_update(event);
}
static void
@@ -173,14 +169,13 @@ armpmu_stop(struct perf_event *event, int flags)
* PERF_EF_UPDATE, see comments in armpmu_start().
*/
if (!(hwc->state & PERF_HES_STOPPED)) {
- armpmu->disable(hwc, hwc->idx);
- armpmu_event_update(event, hwc, hwc->idx);
+ armpmu->disable(event);
+ armpmu_event_update(event);
hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
}
}
-static void
-armpmu_start(struct perf_event *event, int flags)
+static void armpmu_start(struct perf_event *event, int flags)
{
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
struct hw_perf_event *hwc = &event->hw;
@@ -200,8 +195,8 @@ armpmu_start(struct perf_event *event, int flags)
* get an interrupt too soon or *way* too late if the overflow has
* happened since disabling.
*/
- armpmu_event_set_period(event, hwc, hwc->idx);
- armpmu->enable(hwc, hwc->idx);
+ armpmu_event_set_period(event);
+ armpmu->enable(event);
}
static void
@@ -233,7 +228,7 @@ armpmu_add(struct perf_event *event, int flags)
perf_pmu_disable(event->pmu);
/* If we don't have a space for the counter then finish early. */
- idx = armpmu->get_event_idx(hw_events, hwc);
+ idx = armpmu->get_event_idx(hw_events, event);
if (idx < 0) {
err = idx;
goto out;
@@ -244,7 +239,7 @@ armpmu_add(struct perf_event *event, int flags)
* sure it is disabled.
*/
event->hw.idx = idx;
- armpmu->disable(hwc, idx);
+ armpmu->disable(event);
hw_events->events[idx] = event;
hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
@@ -264,13 +259,12 @@ validate_event(struct pmu_hw_events *hw_events,
struct perf_event *event)
{
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
- struct hw_perf_event fake_event = event->hw;
struct pmu *leader_pmu = event->group_leader->pmu;
if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
return 1;
- return armpmu->get_event_idx(hw_events, &fake_event) >= 0;
+ return armpmu->get_event_idx(hw_events, event) >= 0;
}
static int
@@ -316,7 +310,7 @@ static irqreturn_t armpmu_dispatch_irq(int irq, void *dev)
static void
armpmu_release_hardware(struct arm_pmu *armpmu)
{
- armpmu->free_irq();
+ armpmu->free_irq(armpmu);
pm_runtime_put_sync(&armpmu->plat_device->dev);
}
@@ -330,7 +324,7 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
return -ENODEV;
pm_runtime_get_sync(&pmu_device->dev);
- err = armpmu->request_irq(armpmu_dispatch_irq);
+ err = armpmu->request_irq(armpmu, armpmu_dispatch_irq);
if (err) {
armpmu_release_hardware(armpmu);
return err;
@@ -465,13 +459,13 @@ static void armpmu_enable(struct pmu *pmu)
int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
if (enabled)
- armpmu->start();
+ armpmu->start(armpmu);
}
static void armpmu_disable(struct pmu *pmu)
{
struct arm_pmu *armpmu = to_arm_pmu(pmu);
- armpmu->stop();
+ armpmu->stop(armpmu);
}
#ifdef CONFIG_PM_RUNTIME
@@ -517,12 +511,13 @@ static void __init armpmu_init(struct arm_pmu *armpmu)
};
}
-int armpmu_register(struct arm_pmu *armpmu, char *name, int type)
+int armpmu_register(struct arm_pmu *armpmu, int type)
{
armpmu_init(armpmu);
+ pm_runtime_enable(&armpmu->plat_device->dev);
pr_info("enabled with %s PMU driver, %d counters available\n",
armpmu->name, armpmu->num_events);
- return perf_pmu_register(&armpmu->pmu, name, type);
+ return perf_pmu_register(&armpmu->pmu, armpmu->name, type);
}
/*
@@ -576,6 +571,10 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
struct frame_tail __user *tail;
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* We don't support guest os callchain now */
+ return;
+ }
tail = (struct frame_tail __user *)regs->ARM_fp - 1;
@@ -603,9 +602,41 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
{
struct stackframe fr;
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ /* We don't support guest os callchain now */
+ return;
+ }
+
fr.fp = regs->ARM_fp;
fr.sp = regs->ARM_sp;
fr.lr = regs->ARM_lr;
fr.pc = regs->ARM_pc;
walk_stackframe(&fr, callchain_trace, entry);
}
+
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+ return perf_guest_cbs->get_guest_ip();
+
+ return instruction_pointer(regs);
+}
+
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+ int misc = 0;
+
+ if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ if (perf_guest_cbs->is_user_mode())
+ misc |= PERF_RECORD_MISC_GUEST_USER;
+ else
+ misc |= PERF_RECORD_MISC_GUEST_KERNEL;
+ } else {
+ if (user_mode(regs))
+ misc |= PERF_RECORD_MISC_USER;
+ else
+ misc |= PERF_RECORD_MISC_KERNEL;
+ }
+
+ return misc;
+}
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 8d7d8d4de9d6..9a4f6307a016 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/cputype.h>
@@ -45,7 +46,7 @@ const char *perf_pmu_name(void)
if (!cpu_pmu)
return NULL;
- return cpu_pmu->pmu.name;
+ return cpu_pmu->name;
}
EXPORT_SYMBOL_GPL(perf_pmu_name);
@@ -70,7 +71,7 @@ static struct pmu_hw_events *cpu_pmu_get_cpu_events(void)
return &__get_cpu_var(cpu_hw_events);
}
-static void cpu_pmu_free_irq(void)
+static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu)
{
int i, irq, irqs;
struct platform_device *pmu_device = cpu_pmu->plat_device;
@@ -86,7 +87,7 @@ static void cpu_pmu_free_irq(void)
}
}
-static int cpu_pmu_request_irq(irq_handler_t handler)
+static int cpu_pmu_request_irq(struct arm_pmu *cpu_pmu, irq_handler_t handler)
{
int i, err, irq, irqs;
struct platform_device *pmu_device = cpu_pmu->plat_device;
@@ -147,7 +148,7 @@ static void __devinit cpu_pmu_init(struct arm_pmu *cpu_pmu)
/* Ensure the PMU has sane values out of reset. */
if (cpu_pmu && cpu_pmu->reset)
- on_each_cpu(cpu_pmu->reset, NULL, 1);
+ on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
}
/*
@@ -163,7 +164,9 @@ static int __cpuinit cpu_pmu_notify(struct notifier_block *b,
return NOTIFY_DONE;
if (cpu_pmu && cpu_pmu->reset)
- cpu_pmu->reset(NULL);
+ cpu_pmu->reset(cpu_pmu);
+ else
+ return NOTIFY_DONE;
return NOTIFY_OK;
}
@@ -195,13 +198,13 @@ static struct platform_device_id __devinitdata cpu_pmu_plat_device_ids[] = {
/*
* CPU PMU identification and probing.
*/
-static struct arm_pmu *__devinit probe_current_pmu(void)
+static int __devinit probe_current_pmu(struct arm_pmu *pmu)
{
- struct arm_pmu *pmu = NULL;
int cpu = get_cpu();
unsigned long cpuid = read_cpuid_id();
unsigned long implementor = (cpuid & 0xFF000000) >> 24;
unsigned long part_number = (cpuid & 0xFFF0);
+ int ret = -ENODEV;
pr_info("probing PMU on CPU %d\n", cpu);
@@ -211,25 +214,25 @@ static struct arm_pmu *__devinit probe_current_pmu(void)
case 0xB360: /* ARM1136 */
case 0xB560: /* ARM1156 */
case 0xB760: /* ARM1176 */
- pmu = armv6pmu_init();
+ ret = armv6pmu_init(pmu);
break;
case 0xB020: /* ARM11mpcore */
- pmu = armv6mpcore_pmu_init();
+ ret = armv6mpcore_pmu_init(pmu);
break;
case 0xC080: /* Cortex-A8 */
- pmu = armv7_a8_pmu_init();
+ ret = armv7_a8_pmu_init(pmu);
break;
case 0xC090: /* Cortex-A9 */
- pmu = armv7_a9_pmu_init();
+ ret = armv7_a9_pmu_init(pmu);
break;
case 0xC050: /* Cortex-A5 */
- pmu = armv7_a5_pmu_init();
+ ret = armv7_a5_pmu_init(pmu);
break;
case 0xC0F0: /* Cortex-A15 */
- pmu = armv7_a15_pmu_init();
+ ret = armv7_a15_pmu_init(pmu);
break;
case 0xC070: /* Cortex-A7 */
- pmu = armv7_a7_pmu_init();
+ ret = armv7_a7_pmu_init(pmu);
break;
}
/* Intel CPUs [xscale]. */
@@ -237,43 +240,54 @@ static struct arm_pmu *__devinit probe_current_pmu(void)
part_number = (cpuid >> 13) & 0x7;
switch (part_number) {
case 1:
- pmu = xscale1pmu_init();
+ ret = xscale1pmu_init(pmu);
break;
case 2:
- pmu = xscale2pmu_init();
+ ret = xscale2pmu_init(pmu);
break;
}
}
put_cpu();
- return pmu;
+ return ret;
}
static int __devinit cpu_pmu_device_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id;
- struct arm_pmu *(*init_fn)(void);
+ int (*init_fn)(struct arm_pmu *);
struct device_node *node = pdev->dev.of_node;
+ struct arm_pmu *pmu;
+ int ret = -ENODEV;
if (cpu_pmu) {
pr_info("attempt to register multiple PMU devices!");
return -ENOSPC;
}
+ pmu = kzalloc(sizeof(struct arm_pmu), GFP_KERNEL);
+ if (!pmu) {
+ pr_info("failed to allocate PMU device!");
+ return -ENOMEM;
+ }
+
if (node && (of_id = of_match_node(cpu_pmu_of_device_ids, pdev->dev.of_node))) {
init_fn = of_id->data;
- cpu_pmu = init_fn();
+ ret = init_fn(pmu);
} else {
- cpu_pmu = probe_current_pmu();
+ ret = probe_current_pmu(pmu);
}
- if (!cpu_pmu)
- return -ENODEV;
+ if (ret) {
+ pr_info("failed to register PMU devices!");
+ kfree(pmu);
+ return ret;
+ }
+ cpu_pmu = pmu;
cpu_pmu->plat_device = pdev;
cpu_pmu_init(cpu_pmu);
- register_cpu_notifier(&cpu_pmu_hotplug_notifier);
- armpmu_register(cpu_pmu, cpu_pmu->name, PERF_TYPE_RAW);
+ armpmu_register(cpu_pmu, PERF_TYPE_RAW);
return 0;
}
@@ -290,6 +304,16 @@ static struct platform_driver cpu_pmu_driver = {
static int __init register_pmu_driver(void)
{
- return platform_driver_register(&cpu_pmu_driver);
+ int err;
+
+ err = register_cpu_notifier(&cpu_pmu_hotplug_notifier);
+ if (err)
+ return err;
+
+ err = platform_driver_register(&cpu_pmu_driver);
+ if (err)
+ unregister_cpu_notifier(&cpu_pmu_hotplug_notifier);
+
+ return err;
}
device_initcall(register_pmu_driver);
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index 6ccc07971745..f3e22ff8b6a2 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -401,9 +401,10 @@ armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
return ret;
}
-static inline u32
-armv6pmu_read_counter(int counter)
+static inline u32 armv6pmu_read_counter(struct perf_event *event)
{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
unsigned long value = 0;
if (ARMV6_CYCLE_COUNTER == counter)
@@ -418,10 +419,11 @@ armv6pmu_read_counter(int counter)
return value;
}
-static inline void
-armv6pmu_write_counter(int counter,
- u32 value)
+static inline void armv6pmu_write_counter(struct perf_event *event, u32 value)
{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
if (ARMV6_CYCLE_COUNTER == counter)
asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
else if (ARMV6_COUNTER0 == counter)
@@ -432,12 +434,13 @@ armv6pmu_write_counter(int counter,
WARN_ONCE(1, "invalid counter number (%d)\n", counter);
}
-static void
-armv6pmu_enable_event(struct hw_perf_event *hwc,
- int idx)
+static void armv6pmu_enable_event(struct perf_event *event)
{
unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
if (ARMV6_CYCLE_COUNTER == idx) {
mask = 0;
@@ -473,7 +476,8 @@ armv6pmu_handle_irq(int irq_num,
{
unsigned long pmcr = armv6_pmcr_read();
struct perf_sample_data data;
- struct pmu_hw_events *cpuc;
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
struct pt_regs *regs;
int idx;
@@ -489,7 +493,6 @@ armv6pmu_handle_irq(int irq_num,
*/
armv6_pmcr_write(pmcr);
- cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
struct perf_event *event = cpuc->events[idx];
struct hw_perf_event *hwc;
@@ -506,13 +509,13 @@ armv6pmu_handle_irq(int irq_num,
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event);
perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event, hwc, idx))
+ if (!armpmu_event_set_period(event))
continue;
if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(hwc, idx);
+ cpu_pmu->disable(event);
}
/*
@@ -527,8 +530,7 @@ armv6pmu_handle_irq(int irq_num,
return IRQ_HANDLED;
}
-static void
-armv6pmu_start(void)
+static void armv6pmu_start(struct arm_pmu *cpu_pmu)
{
unsigned long flags, val;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -540,8 +542,7 @@ armv6pmu_start(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void
-armv6pmu_stop(void)
+static void armv6pmu_stop(struct arm_pmu *cpu_pmu)
{
unsigned long flags, val;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -555,10 +556,11 @@ armv6pmu_stop(void)
static int
armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct hw_perf_event *event)
+ struct perf_event *event)
{
+ struct hw_perf_event *hwc = &event->hw;
/* Always place a cycle counter into the cycle counter. */
- if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
+ if (ARMV6_PERFCTR_CPU_CYCLES == hwc->config_base) {
if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
return -EAGAIN;
@@ -579,12 +581,13 @@ armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,
}
}
-static void
-armv6pmu_disable_event(struct hw_perf_event *hwc,
- int idx)
+static void armv6pmu_disable_event(struct perf_event *event)
{
unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
if (ARMV6_CYCLE_COUNTER == idx) {
mask = ARMV6_PMCR_CCOUNT_IEN;
@@ -613,12 +616,13 @@ armv6pmu_disable_event(struct hw_perf_event *hwc,
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void
-armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
- int idx)
+static void armv6mpcore_pmu_disable_event(struct perf_event *event)
{
unsigned long val, mask, flags, evt = 0;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
if (ARMV6_CYCLE_COUNTER == idx) {
mask = ARMV6_PMCR_CCOUNT_IEN;
@@ -649,24 +653,22 @@ static int armv6_map_event(struct perf_event *event)
&armv6_perf_cache_map, 0xFF);
}
-static struct arm_pmu armv6pmu = {
- .name = "v6",
- .handle_irq = armv6pmu_handle_irq,
- .enable = armv6pmu_enable_event,
- .disable = armv6pmu_disable_event,
- .read_counter = armv6pmu_read_counter,
- .write_counter = armv6pmu_write_counter,
- .get_event_idx = armv6pmu_get_event_idx,
- .start = armv6pmu_start,
- .stop = armv6pmu_stop,
- .map_event = armv6_map_event,
- .num_events = 3,
- .max_period = (1LLU << 32) - 1,
-};
-
-static struct arm_pmu *__devinit armv6pmu_init(void)
+static int __devinit armv6pmu_init(struct arm_pmu *cpu_pmu)
{
- return &armv6pmu;
+ cpu_pmu->name = "v6";
+ cpu_pmu->handle_irq = armv6pmu_handle_irq;
+ cpu_pmu->enable = armv6pmu_enable_event;
+ cpu_pmu->disable = armv6pmu_disable_event;
+ cpu_pmu->read_counter = armv6pmu_read_counter;
+ cpu_pmu->write_counter = armv6pmu_write_counter;
+ cpu_pmu->get_event_idx = armv6pmu_get_event_idx;
+ cpu_pmu->start = armv6pmu_start;
+ cpu_pmu->stop = armv6pmu_stop;
+ cpu_pmu->map_event = armv6_map_event;
+ cpu_pmu->num_events = 3;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
}
/*
@@ -683,33 +685,31 @@ static int armv6mpcore_map_event(struct perf_event *event)
&armv6mpcore_perf_cache_map, 0xFF);
}
-static struct arm_pmu armv6mpcore_pmu = {
- .name = "v6mpcore",
- .handle_irq = armv6pmu_handle_irq,
- .enable = armv6pmu_enable_event,
- .disable = armv6mpcore_pmu_disable_event,
- .read_counter = armv6pmu_read_counter,
- .write_counter = armv6pmu_write_counter,
- .get_event_idx = armv6pmu_get_event_idx,
- .start = armv6pmu_start,
- .stop = armv6pmu_stop,
- .map_event = armv6mpcore_map_event,
- .num_events = 3,
- .max_period = (1LLU << 32) - 1,
-};
-
-static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
+static int __devinit armv6mpcore_pmu_init(struct arm_pmu *cpu_pmu)
{
- return &armv6mpcore_pmu;
+ cpu_pmu->name = "v6mpcore";
+ cpu_pmu->handle_irq = armv6pmu_handle_irq;
+ cpu_pmu->enable = armv6pmu_enable_event;
+ cpu_pmu->disable = armv6mpcore_pmu_disable_event;
+ cpu_pmu->read_counter = armv6pmu_read_counter;
+ cpu_pmu->write_counter = armv6pmu_write_counter;
+ cpu_pmu->get_event_idx = armv6pmu_get_event_idx;
+ cpu_pmu->start = armv6pmu_start;
+ cpu_pmu->stop = armv6pmu_stop;
+ cpu_pmu->map_event = armv6mpcore_map_event;
+ cpu_pmu->num_events = 3;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
}
#else
-static struct arm_pmu *__devinit armv6pmu_init(void)
+static int armv6pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
-static struct arm_pmu *__devinit armv6mpcore_pmu_init(void)
+static int armv6mpcore_pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
#endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index bd4b090ebcfd..7d0cce85d17e 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -18,8 +18,6 @@
#ifdef CONFIG_CPU_V7
-static struct arm_pmu armv7pmu;
-
/*
* Common ARMv7 event types
*
@@ -738,7 +736,8 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
*/
#define ARMV7_IDX_CYCLE_COUNTER 0
#define ARMV7_IDX_COUNTER0 1
-#define ARMV7_IDX_COUNTER_LAST (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
+#define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
+ (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
#define ARMV7_MAX_COUNTERS 32
#define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
@@ -804,49 +803,34 @@ static inline int armv7_pmnc_has_overflowed(u32 pmnc)
return pmnc & ARMV7_OVERFLOWED_MASK;
}
-static inline int armv7_pmnc_counter_valid(int idx)
+static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx)
{
- return idx >= ARMV7_IDX_CYCLE_COUNTER && idx <= ARMV7_IDX_COUNTER_LAST;
+ return idx >= ARMV7_IDX_CYCLE_COUNTER &&
+ idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu);
}
static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
{
- int ret = 0;
- u32 counter;
-
- if (!armv7_pmnc_counter_valid(idx)) {
- pr_err("CPU%u checking wrong counter %d overflow status\n",
- smp_processor_id(), idx);
- } else {
- counter = ARMV7_IDX_TO_COUNTER(idx);
- ret = pmnc & BIT(counter);
- }
-
- return ret;
+ return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx));
}
static inline int armv7_pmnc_select_counter(int idx)
{
- u32 counter;
-
- if (!armv7_pmnc_counter_valid(idx)) {
- pr_err("CPU%u selecting wrong PMNC counter %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV7_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
isb();
return idx;
}
-static inline u32 armv7pmu_read_counter(int idx)
+static inline u32 armv7pmu_read_counter(struct perf_event *event)
{
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
u32 value = 0;
- if (!armv7_pmnc_counter_valid(idx))
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx))
pr_err("CPU%u reading wrong counter %d\n",
smp_processor_id(), idx);
else if (idx == ARMV7_IDX_CYCLE_COUNTER)
@@ -857,9 +841,13 @@ static inline u32 armv7pmu_read_counter(int idx)
return value;
}
-static inline void armv7pmu_write_counter(int idx, u32 value)
+static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
{
- if (!armv7_pmnc_counter_valid(idx))
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx))
pr_err("CPU%u writing wrong counter %d\n",
smp_processor_id(), idx);
else if (idx == ARMV7_IDX_CYCLE_COUNTER)
@@ -878,60 +866,28 @@ static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
static inline int armv7_pmnc_enable_counter(int idx)
{
- u32 counter;
-
- if (!armv7_pmnc_counter_valid(idx)) {
- pr_err("CPU%u enabling wrong PMNC counter %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV7_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
return idx;
}
static inline int armv7_pmnc_disable_counter(int idx)
{
- u32 counter;
-
- if (!armv7_pmnc_counter_valid(idx)) {
- pr_err("CPU%u disabling wrong PMNC counter %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV7_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
return idx;
}
static inline int armv7_pmnc_enable_intens(int idx)
{
- u32 counter;
-
- if (!armv7_pmnc_counter_valid(idx)) {
- pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV7_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
return idx;
}
static inline int armv7_pmnc_disable_intens(int idx)
{
- u32 counter;
-
- if (!armv7_pmnc_counter_valid(idx)) {
- pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
- smp_processor_id(), idx);
- return -EINVAL;
- }
-
- counter = ARMV7_IDX_TO_COUNTER(idx);
+ u32 counter = ARMV7_IDX_TO_COUNTER(idx);
asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
isb();
/* Clear the overflow flag in case an interrupt is pending. */
@@ -956,7 +912,7 @@ static inline u32 armv7_pmnc_getreset_flags(void)
}
#ifdef DEBUG
-static void armv7_pmnc_dump_regs(void)
+static void armv7_pmnc_dump_regs(struct arm_pmu *cpu_pmu)
{
u32 val;
unsigned int cnt;
@@ -981,7 +937,8 @@ static void armv7_pmnc_dump_regs(void)
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
printk(KERN_INFO "CCNT =0x%08x\n", val);
- for (cnt = ARMV7_IDX_COUNTER0; cnt <= ARMV7_IDX_COUNTER_LAST; cnt++) {
+ for (cnt = ARMV7_IDX_COUNTER0;
+ cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
armv7_pmnc_select_counter(cnt);
asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
printk(KERN_INFO "CNT[%d] count =0x%08x\n",
@@ -993,10 +950,19 @@ static void armv7_pmnc_dump_regs(void)
}
#endif
-static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void armv7pmu_enable_event(struct perf_event *event)
{
unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
+ pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
+ smp_processor_id(), idx);
+ return;
+ }
/*
* Enable counter and interrupt, and set the counter to count
@@ -1014,7 +980,7 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
* We only need to set the event for the cycle counter if we
* have the ability to perform event filtering.
*/
- if (armv7pmu.set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
+ if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
armv7_pmnc_write_evtsel(idx, hwc->config_base);
/*
@@ -1030,10 +996,19 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static void armv7pmu_disable_event(struct perf_event *event)
{
unsigned long flags;
+ struct hw_perf_event *hwc = &event->hw;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
+
+ if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
+ pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
+ smp_processor_id(), idx);
+ return;
+ }
/*
* Disable counter and interrupt
@@ -1057,7 +1032,8 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
{
u32 pmnc;
struct perf_sample_data data;
- struct pmu_hw_events *cpuc;
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
struct pt_regs *regs;
int idx;
@@ -1077,7 +1053,6 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
*/
regs = get_irq_regs();
- cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
struct perf_event *event = cpuc->events[idx];
struct hw_perf_event *hwc;
@@ -1094,13 +1069,13 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event);
perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event, hwc, idx))
+ if (!armpmu_event_set_period(event))
continue;
if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(hwc, idx);
+ cpu_pmu->disable(event);
}
/*
@@ -1115,7 +1090,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
return IRQ_HANDLED;
}
-static void armv7pmu_start(void)
+static void armv7pmu_start(struct arm_pmu *cpu_pmu)
{
unsigned long flags;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -1126,7 +1101,7 @@ static void armv7pmu_start(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void armv7pmu_stop(void)
+static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
{
unsigned long flags;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -1138,10 +1113,12 @@ static void armv7pmu_stop(void)
}
static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct hw_perf_event *event)
+ struct perf_event *event)
{
int idx;
- unsigned long evtype = event->config_base & ARMV7_EVTYPE_EVENT;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
+ unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
/* Always place a cycle counter into the cycle counter. */
if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
@@ -1192,11 +1169,14 @@ static int armv7pmu_set_event_filter(struct hw_perf_event *event,
static void armv7pmu_reset(void *info)
{
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
u32 idx, nb_cnt = cpu_pmu->num_events;
/* The counter and interrupt enable registers are unknown at reset. */
- for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx)
- armv7pmu_disable_event(NULL, idx);
+ for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
+ armv7_pmnc_disable_counter(idx);
+ armv7_pmnc_disable_intens(idx);
+ }
/* Initialize & Reset PMNC: C and P bits */
armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
@@ -1232,17 +1212,18 @@ static int armv7_a7_map_event(struct perf_event *event)
&armv7_a7_perf_cache_map, 0xFF);
}
-static struct arm_pmu armv7pmu = {
- .handle_irq = armv7pmu_handle_irq,
- .enable = armv7pmu_enable_event,
- .disable = armv7pmu_disable_event,
- .read_counter = armv7pmu_read_counter,
- .write_counter = armv7pmu_write_counter,
- .get_event_idx = armv7pmu_get_event_idx,
- .start = armv7pmu_start,
- .stop = armv7pmu_stop,
- .reset = armv7pmu_reset,
- .max_period = (1LLU << 32) - 1,
+static void armv7pmu_init(struct arm_pmu *cpu_pmu)
+{
+ cpu_pmu->handle_irq = armv7pmu_handle_irq;
+ cpu_pmu->enable = armv7pmu_enable_event;
+ cpu_pmu->disable = armv7pmu_disable_event;
+ cpu_pmu->read_counter = armv7pmu_read_counter;
+ cpu_pmu->write_counter = armv7pmu_write_counter;
+ cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
+ cpu_pmu->start = armv7pmu_start;
+ cpu_pmu->stop = armv7pmu_stop;
+ cpu_pmu->reset = armv7pmu_reset;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
};
static u32 __devinit armv7_read_num_pmnc_events(void)
@@ -1256,70 +1237,75 @@ static u32 __devinit armv7_read_num_pmnc_events(void)
return nb_cnt + 1;
}
-static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
+static int __devinit armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
{
- armv7pmu.name = "ARMv7 Cortex-A8";
- armv7pmu.map_event = armv7_a8_map_event;
- armv7pmu.num_events = armv7_read_num_pmnc_events();
- return &armv7pmu;
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "ARMv7 Cortex-A8";
+ cpu_pmu->map_event = armv7_a8_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ return 0;
}
-static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
+static int __devinit armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
{
- armv7pmu.name = "ARMv7 Cortex-A9";
- armv7pmu.map_event = armv7_a9_map_event;
- armv7pmu.num_events = armv7_read_num_pmnc_events();
- return &armv7pmu;
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "ARMv7 Cortex-A9";
+ cpu_pmu->map_event = armv7_a9_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ return 0;
}
-static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
+static int __devinit armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
{
- armv7pmu.name = "ARMv7 Cortex-A5";
- armv7pmu.map_event = armv7_a5_map_event;
- armv7pmu.num_events = armv7_read_num_pmnc_events();
- return &armv7pmu;
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "ARMv7 Cortex-A5";
+ cpu_pmu->map_event = armv7_a5_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ return 0;
}
-static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
+static int __devinit armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
{
- armv7pmu.name = "ARMv7 Cortex-A15";
- armv7pmu.map_event = armv7_a15_map_event;
- armv7pmu.num_events = armv7_read_num_pmnc_events();
- armv7pmu.set_event_filter = armv7pmu_set_event_filter;
- return &armv7pmu;
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "ARMv7 Cortex-A15";
+ cpu_pmu->map_event = armv7_a15_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ return 0;
}
-static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
+static int __devinit armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
{
- armv7pmu.name = "ARMv7 Cortex-A7";
- armv7pmu.map_event = armv7_a7_map_event;
- armv7pmu.num_events = armv7_read_num_pmnc_events();
- armv7pmu.set_event_filter = armv7pmu_set_event_filter;
- return &armv7pmu;
+ armv7pmu_init(cpu_pmu);
+ cpu_pmu->name = "ARMv7 Cortex-A7";
+ cpu_pmu->map_event = armv7_a7_map_event;
+ cpu_pmu->num_events = armv7_read_num_pmnc_events();
+ cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+ return 0;
}
#else
-static struct arm_pmu *__devinit armv7_a8_pmu_init(void)
+static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
-static struct arm_pmu *__devinit armv7_a9_pmu_init(void)
+static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
-static struct arm_pmu *__devinit armv7_a5_pmu_init(void)
+static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
-static struct arm_pmu *__devinit armv7_a15_pmu_init(void)
+static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
-static struct arm_pmu *__devinit armv7_a7_pmu_init(void)
+static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index 426e19f380a2..0c8265e53d5f 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -224,7 +224,8 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
{
unsigned long pmnc;
struct perf_sample_data data;
- struct pmu_hw_events *cpuc;
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
struct pt_regs *regs;
int idx;
@@ -248,7 +249,6 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
regs = get_irq_regs();
- cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
struct perf_event *event = cpuc->events[idx];
struct hw_perf_event *hwc;
@@ -260,13 +260,13 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event);
perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event, hwc, idx))
+ if (!armpmu_event_set_period(event))
continue;
if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(hwc, idx);
+ cpu_pmu->disable(event);
}
irq_work_run();
@@ -280,11 +280,13 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
return IRQ_HANDLED;
}
-static void
-xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void xscale1pmu_enable_event(struct perf_event *event)
{
unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
switch (idx) {
case XSCALE_CYCLE_COUNTER:
@@ -314,11 +316,13 @@ xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void
-xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static void xscale1pmu_disable_event(struct perf_event *event)
{
unsigned long val, mask, evt, flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
switch (idx) {
case XSCALE_CYCLE_COUNTER:
@@ -348,9 +352,10 @@ xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
static int
xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct hw_perf_event *event)
+ struct perf_event *event)
{
- if (XSCALE_PERFCTR_CCNT == event->config_base) {
+ struct hw_perf_event *hwc = &event->hw;
+ if (XSCALE_PERFCTR_CCNT == hwc->config_base) {
if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
return -EAGAIN;
@@ -366,8 +371,7 @@ xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,
}
}
-static void
-xscale1pmu_start(void)
+static void xscale1pmu_start(struct arm_pmu *cpu_pmu)
{
unsigned long flags, val;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -379,8 +383,7 @@ xscale1pmu_start(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void
-xscale1pmu_stop(void)
+static void xscale1pmu_stop(struct arm_pmu *cpu_pmu)
{
unsigned long flags, val;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -392,9 +395,10 @@ xscale1pmu_stop(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static inline u32
-xscale1pmu_read_counter(int counter)
+static inline u32 xscale1pmu_read_counter(struct perf_event *event)
{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
u32 val = 0;
switch (counter) {
@@ -412,9 +416,11 @@ xscale1pmu_read_counter(int counter)
return val;
}
-static inline void
-xscale1pmu_write_counter(int counter, u32 val)
+static inline void xscale1pmu_write_counter(struct perf_event *event, u32 val)
{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
switch (counter) {
case XSCALE_CYCLE_COUNTER:
asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
@@ -434,24 +440,22 @@ static int xscale_map_event(struct perf_event *event)
&xscale_perf_cache_map, 0xFF);
}
-static struct arm_pmu xscale1pmu = {
- .name = "xscale1",
- .handle_irq = xscale1pmu_handle_irq,
- .enable = xscale1pmu_enable_event,
- .disable = xscale1pmu_disable_event,
- .read_counter = xscale1pmu_read_counter,
- .write_counter = xscale1pmu_write_counter,
- .get_event_idx = xscale1pmu_get_event_idx,
- .start = xscale1pmu_start,
- .stop = xscale1pmu_stop,
- .map_event = xscale_map_event,
- .num_events = 3,
- .max_period = (1LLU << 32) - 1,
-};
-
-static struct arm_pmu *__devinit xscale1pmu_init(void)
+static int __devinit xscale1pmu_init(struct arm_pmu *cpu_pmu)
{
- return &xscale1pmu;
+ cpu_pmu->name = "xscale1";
+ cpu_pmu->handle_irq = xscale1pmu_handle_irq;
+ cpu_pmu->enable = xscale1pmu_enable_event;
+ cpu_pmu->disable = xscale1pmu_disable_event;
+ cpu_pmu->read_counter = xscale1pmu_read_counter;
+ cpu_pmu->write_counter = xscale1pmu_write_counter;
+ cpu_pmu->get_event_idx = xscale1pmu_get_event_idx;
+ cpu_pmu->start = xscale1pmu_start;
+ cpu_pmu->stop = xscale1pmu_stop;
+ cpu_pmu->map_event = xscale_map_event;
+ cpu_pmu->num_events = 3;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
}
#define XSCALE2_OVERFLOWED_MASK 0x01f
@@ -567,7 +571,8 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
{
unsigned long pmnc, of_flags;
struct perf_sample_data data;
- struct pmu_hw_events *cpuc;
+ struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
+ struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
struct pt_regs *regs;
int idx;
@@ -585,7 +590,6 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
regs = get_irq_regs();
- cpuc = &__get_cpu_var(cpu_hw_events);
for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
struct perf_event *event = cpuc->events[idx];
struct hw_perf_event *hwc;
@@ -597,13 +601,13 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event);
perf_sample_data_init(&data, 0, hwc->last_period);
- if (!armpmu_event_set_period(event, hwc, idx))
+ if (!armpmu_event_set_period(event))
continue;
if (perf_event_overflow(event, &data, regs))
- cpu_pmu->disable(hwc, idx);
+ cpu_pmu->disable(event);
}
irq_work_run();
@@ -617,11 +621,13 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
return IRQ_HANDLED;
}
-static void
-xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
+static void xscale2pmu_enable_event(struct perf_event *event)
{
unsigned long flags, ien, evtsel;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
ien = xscale2pmu_read_int_enable();
evtsel = xscale2pmu_read_event_select();
@@ -661,11 +667,13 @@ xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void
-xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
+static void xscale2pmu_disable_event(struct perf_event *event)
{
unsigned long flags, ien, evtsel, of_flags;
+ struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
+ struct hw_perf_event *hwc = &event->hw;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
+ int idx = hwc->idx;
ien = xscale2pmu_read_int_enable();
evtsel = xscale2pmu_read_event_select();
@@ -713,7 +721,7 @@ xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
static int
xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc,
- struct hw_perf_event *event)
+ struct perf_event *event)
{
int idx = xscale1pmu_get_event_idx(cpuc, event);
if (idx >= 0)
@@ -727,8 +735,7 @@ out:
return idx;
}
-static void
-xscale2pmu_start(void)
+static void xscale2pmu_start(struct arm_pmu *cpu_pmu)
{
unsigned long flags, val;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -740,8 +747,7 @@ xscale2pmu_start(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static void
-xscale2pmu_stop(void)
+static void xscale2pmu_stop(struct arm_pmu *cpu_pmu)
{
unsigned long flags, val;
struct pmu_hw_events *events = cpu_pmu->get_hw_events();
@@ -753,9 +759,10 @@ xscale2pmu_stop(void)
raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
}
-static inline u32
-xscale2pmu_read_counter(int counter)
+static inline u32 xscale2pmu_read_counter(struct perf_event *event)
{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
u32 val = 0;
switch (counter) {
@@ -779,9 +786,11 @@ xscale2pmu_read_counter(int counter)
return val;
}
-static inline void
-xscale2pmu_write_counter(int counter, u32 val)
+static inline void xscale2pmu_write_counter(struct perf_event *event, u32 val)
{
+ struct hw_perf_event *hwc = &event->hw;
+ int counter = hwc->idx;
+
switch (counter) {
case XSCALE_CYCLE_COUNTER:
asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
@@ -801,33 +810,31 @@ xscale2pmu_write_counter(int counter, u32 val)
}
}
-static struct arm_pmu xscale2pmu = {
- .name = "xscale2",
- .handle_irq = xscale2pmu_handle_irq,
- .enable = xscale2pmu_enable_event,
- .disable = xscale2pmu_disable_event,
- .read_counter = xscale2pmu_read_counter,
- .write_counter = xscale2pmu_write_counter,
- .get_event_idx = xscale2pmu_get_event_idx,
- .start = xscale2pmu_start,
- .stop = xscale2pmu_stop,
- .map_event = xscale_map_event,
- .num_events = 5,
- .max_period = (1LLU << 32) - 1,
-};
-
-static struct arm_pmu *__devinit xscale2pmu_init(void)
+static int __devinit xscale2pmu_init(struct arm_pmu *cpu_pmu)
{
- return &xscale2pmu;
+ cpu_pmu->name = "xscale2";
+ cpu_pmu->handle_irq = xscale2pmu_handle_irq;
+ cpu_pmu->enable = xscale2pmu_enable_event;
+ cpu_pmu->disable = xscale2pmu_disable_event;
+ cpu_pmu->read_counter = xscale2pmu_read_counter;
+ cpu_pmu->write_counter = xscale2pmu_write_counter;
+ cpu_pmu->get_event_idx = xscale2pmu_get_event_idx;
+ cpu_pmu->start = xscale2pmu_start;
+ cpu_pmu->stop = xscale2pmu_stop;
+ cpu_pmu->map_event = xscale_map_event;
+ cpu_pmu->num_events = 5;
+ cpu_pmu->max_period = (1LLU << 32) - 1;
+
+ return 0;
}
#else
-static struct arm_pmu *__devinit xscale1pmu_init(void)
+static inline int xscale1pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
-static struct arm_pmu *__devinit xscale2pmu_init(void)
+static inline int xscale2pmu_init(struct arm_pmu *cpu_pmu)
{
- return NULL;
+ return -ENODEV;
}
#endif /* CONFIG_CPU_XSCALE */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 90084a6de35a..44bc0b327e2b 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -34,6 +34,7 @@
#include <linux/leds.h>
#include <asm/cacheflush.h>
+#include <asm/idmap.h>
#include <asm/processor.h>
#include <asm/thread_notify.h>
#include <asm/stacktrace.h>
@@ -56,8 +57,6 @@ static const char *isa_modes[] = {
"ARM" , "Thumb" , "Jazelle", "ThumbEE"
};
-extern void setup_mm_for_reboot(void);
-
static volatile int hlt_counter;
void disable_hlt(void)
@@ -70,6 +69,7 @@ EXPORT_SYMBOL(disable_hlt);
void enable_hlt(void)
{
hlt_counter--;
+ BUG_ON(hlt_counter < 0);
}
EXPORT_SYMBOL(enable_hlt);
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 739db3a1b2d2..03deeffd9f6d 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -916,16 +916,11 @@ enum ptrace_syscall_dir {
PTRACE_SYSCALL_EXIT,
};
-static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
- enum ptrace_syscall_dir dir)
+static int tracehook_report_syscall(struct pt_regs *regs,
+ enum ptrace_syscall_dir dir)
{
unsigned long ip;
- current_thread_info()->syscall = scno;
-
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return scno;
-
/*
* IP is used to denote syscall entry/exit:
* IP = 0 -> entry, =1 -> exit
@@ -944,19 +939,41 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
{
- scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER);
+ current_thread_info()->syscall = scno;
+
+ /* Do the secure computing check first; failures should be fast. */
+ if (secure_computing(scno) == -1)
+ return -1;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, scno);
+
audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,
regs->ARM_r2, regs->ARM_r3);
+
return scno;
}
-asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
+asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{
- scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT);
- if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
- trace_sys_exit(regs, scno);
+ /*
+ * Audit the syscall before anything else, as a debugger may
+ * come in and change the current registers.
+ */
audit_syscall_exit(regs);
- return scno;
+
+ /*
+ * Note that we haven't updated the ->syscall field for the
+ * current thread. This isn't a problem because it will have
+ * been set on syscall entry and there hasn't been an opportunity
+ * for a PTRACE_SET_SYSCALL since then.
+ */
+ if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+ trace_sys_exit(regs, regs_return_value(regs));
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index da1d1aa20ad9..9a89bf4aefe1 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -383,6 +383,12 @@ void cpu_init(void)
BUG();
}
+ /*
+ * This only works on resume and secondary cores. For booting on the
+ * boot cpu, smp_prepare_boot_cpu is called after percpu area setup.
+ */
+ set_my_cpu_offset(per_cpu_offset(cpu));
+
cpu_proc_init();
/*
@@ -426,13 +432,14 @@ int __cpu_logical_map[NR_CPUS];
void __init smp_setup_processor_id(void)
{
int i;
- u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
+ u32 mpidr = is_smp() ? read_cpuid_mpidr() & MPIDR_HWID_BITMASK : 0;
+ u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
cpu_logical_map(0) = cpu;
- for (i = 1; i < NR_CPUS; ++i)
+ for (i = 1; i < nr_cpu_ids; ++i)
cpu_logical_map(i) = i == cpu ? 0 : i;
- printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
+ printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr);
}
static void __init setup_processor(void)
@@ -758,6 +765,7 @@ void __init setup_arch(char **cmdline_p)
unflatten_device_tree();
+ arm_dt_init_cpu_maps();
#ifdef CONFIG_SMP
if (is_smp()) {
smp_set_ops(mdesc->smp);
@@ -841,12 +849,9 @@ static const char *hwcap_str[] = {
static int c_show(struct seq_file *m, void *v)
{
- int i;
+ int i, j;
+ u32 cpuid;
- seq_printf(m, "Processor\t: %s rev %d (%s)\n",
- cpu_name, read_cpuid_id() & 15, elf_platform);
-
-#if defined(CONFIG_SMP)
for_each_online_cpu(i) {
/*
* glibc reads /proc/cpuinfo to determine the number of
@@ -854,45 +859,48 @@ static int c_show(struct seq_file *m, void *v)
* "processor". Give glibc what it expects.
*/
seq_printf(m, "processor\t: %d\n", i);
- seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
+ cpuid = is_smp() ? per_cpu(cpu_data, i).cpuid : read_cpuid_id();
+ seq_printf(m, "model name\t: %s rev %d (%s)\n",
+ cpu_name, cpuid & 15, elf_platform);
+
+#if defined(CONFIG_SMP)
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
(per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
- }
-#else /* CONFIG_SMP */
- seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
- loops_per_jiffy / (500000/HZ),
- (loops_per_jiffy / (5000/HZ)) % 100);
+#else
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000/HZ),
+ (loops_per_jiffy / (5000/HZ)) % 100);
#endif
+ /* dump out the processor features */
+ seq_puts(m, "Features\t: ");
- /* dump out the processor features */
- seq_puts(m, "Features\t: ");
-
- for (i = 0; hwcap_str[i]; i++)
- if (elf_hwcap & (1 << i))
- seq_printf(m, "%s ", hwcap_str[i]);
+ for (j = 0; hwcap_str[j]; j++)
+ if (elf_hwcap & (1 << j))
+ seq_printf(m, "%s ", hwcap_str[j]);
- seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
- seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
+ seq_printf(m, "\nCPU implementer\t: 0x%02x\n", cpuid >> 24);
+ seq_printf(m, "CPU architecture: %s\n",
+ proc_arch[cpu_architecture()]);
- if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
- /* pre-ARM7 */
- seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
- } else {
- if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
- /* ARM7 */
- seq_printf(m, "CPU variant\t: 0x%02x\n",
- (read_cpuid_id() >> 16) & 127);
+ if ((cpuid & 0x0008f000) == 0x00000000) {
+ /* pre-ARM7 */
+ seq_printf(m, "CPU part\t: %07x\n", cpuid >> 4);
} else {
- /* post-ARM7 */
- seq_printf(m, "CPU variant\t: 0x%x\n",
- (read_cpuid_id() >> 20) & 15);
+ if ((cpuid & 0x0008f000) == 0x00007000) {
+ /* ARM7 */
+ seq_printf(m, "CPU variant\t: 0x%02x\n",
+ (cpuid >> 16) & 127);
+ } else {
+ /* post-ARM7 */
+ seq_printf(m, "CPU variant\t: 0x%x\n",
+ (cpuid >> 20) & 15);
+ }
+ seq_printf(m, "CPU part\t: 0x%03x\n",
+ (cpuid >> 4) & 0xfff);
}
- seq_printf(m, "CPU part\t: 0x%03x\n",
- (read_cpuid_id() >> 4) & 0xfff);
+ seq_printf(m, "CPU revision\t: %d\n\n", cpuid & 15);
}
- seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
-
- seq_puts(m, "\n");
seq_printf(m, "Hardware\t: %s\n", machine_name);
seq_printf(m, "Revision\t: %04x\n", system_rev);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index fbc8b2623d82..84f4cbf652e5 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -281,6 +281,7 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
cpu_info->loops_per_jiffy = loops_per_jiffy;
+ cpu_info->cpuid = read_cpuid_id();
store_cpu_topology(cpuid);
}
@@ -313,9 +314,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
current->active_mm = mm;
cpumask_set_cpu(cpu, mm_cpumask(mm));
+ cpu_init();
+
printk("CPU%u: Booted secondary processor\n", cpu);
- cpu_init();
preempt_disable();
trace_hardirqs_off();
@@ -371,6 +373,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
void __init smp_prepare_boot_cpu(void)
{
+ set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
}
void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -421,6 +424,11 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
smp_cross_call(mask, IPI_CALL_FUNC);
}
+void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_WAKEUP);
+}
+
void arch_send_call_function_single_ipi(int cpu)
{
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
@@ -443,7 +451,7 @@ void show_ipi_list(struct seq_file *p, int prec)
for (i = 0; i < NR_IPI; i++) {
seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
- for_each_present_cpu(cpu)
+ for_each_online_cpu(cpu)
seq_printf(p, "%10u ",
__get_irq_stat(cpu, ipi_irqs[i]));
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index b22d700fea27..ff07879ad95d 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -31,6 +31,8 @@ static void __iomem *twd_base;
static struct clk *twd_clk;
static unsigned long twd_timer_rate;
+static bool common_setup_called;
+static DEFINE_PER_CPU(bool, percpu_setup_called);
static struct clock_event_device __percpu **twd_evt;
static int twd_ppi;
@@ -248,17 +250,9 @@ static struct clk *twd_get_clock(void)
return clk;
}
- err = clk_prepare(clk);
+ err = clk_prepare_enable(clk);
if (err) {
- pr_err("smp_twd: clock failed to prepare: %d\n", err);
- clk_put(clk);
- return ERR_PTR(err);
- }
-
- err = clk_enable(clk);
- if (err) {
- pr_err("smp_twd: clock failed to enable: %d\n", err);
- clk_unprepare(clk);
+ pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
clk_put(clk);
return ERR_PTR(err);
}
@@ -272,15 +266,45 @@ static struct clk *twd_get_clock(void)
static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
{
struct clock_event_device **this_cpu_clk;
+ int cpu = smp_processor_id();
+
+ /*
+ * If the basic setup for this CPU has been done before don't
+ * bother with the below.
+ */
+ if (per_cpu(percpu_setup_called, cpu)) {
+ __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+ clockevents_register_device(*__this_cpu_ptr(twd_evt));
+ enable_percpu_irq(clk->irq, 0);
+ return 0;
+ }
+ per_cpu(percpu_setup_called, cpu) = true;
- if (!twd_clk)
+ /*
+ * This stuff only need to be done once for the entire TWD cluster
+ * during the runtime of the system.
+ */
+ if (!common_setup_called) {
twd_clk = twd_get_clock();
- if (!IS_ERR_OR_NULL(twd_clk))
- twd_timer_rate = clk_get_rate(twd_clk);
- else
- twd_calibrate_rate();
+ /*
+ * We use IS_ERR_OR_NULL() here, because if the clock stubs
+ * are active we will get a valid clk reference which is
+ * however NULL and will return the rate 0. In that case we
+ * need to calibrate the rate instead.
+ */
+ if (!IS_ERR_OR_NULL(twd_clk))
+ twd_timer_rate = clk_get_rate(twd_clk);
+ else
+ twd_calibrate_rate();
+
+ common_setup_called = true;
+ }
+ /*
+ * The following is done once per CPU the first time .setup() is
+ * called.
+ */
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
clk->name = "local_timer";
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 26c12c6440fc..79282ebcd939 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -196,32 +196,7 @@ static inline void parse_dt_topology(void) {}
static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
#endif
-
-/*
- * cpu topology management
- */
-
-#define MPIDR_SMP_BITMASK (0x3 << 30)
-#define MPIDR_SMP_VALUE (0x2 << 30)
-
-#define MPIDR_MT_BITMASK (0x1 << 24)
-
-/*
- * These masks reflect the current use of the affinity levels.
- * The affinity level can be up to 16 bits according to ARM ARM
- */
-#define MPIDR_HWID_BITMASK 0xFFFFFF
-
-#define MPIDR_LEVEL0_MASK 0x3
-#define MPIDR_LEVEL0_SHIFT 0
-
-#define MPIDR_LEVEL1_MASK 0xF
-#define MPIDR_LEVEL1_SHIFT 8
-
-#define MPIDR_LEVEL2_MASK 0xFF
-#define MPIDR_LEVEL2_SHIFT 16
-
-/*
+ /*
* cpu topology table
*/
struct cputopo_arm cpu_topology[NR_CPUS];
@@ -282,19 +257,14 @@ void store_cpu_topology(unsigned int cpuid)
if (mpidr & MPIDR_MT_BITMASK) {
/* core performance interdependency */
- cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
- & MPIDR_LEVEL0_MASK;
- cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
- & MPIDR_LEVEL1_MASK;
- cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT)
- & MPIDR_LEVEL2_MASK;
+ cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+ cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
} else {
/* largely independent cores */
cpuid_topo->thread_id = -1;
- cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
- & MPIDR_LEVEL0_MASK;
- cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
- & MPIDR_LEVEL1_MASK;
+ cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+ cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
}
} else {
/*
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 36ff15bbfdd4..b9f38e388b43 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -114,6 +114,15 @@ SECTIONS
RO_DATA(PAGE_SIZE)
+ . = ALIGN(4);
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
+ __start___ex_table = .;
+#ifdef CONFIG_MMU
+ *(__ex_table)
+#endif
+ __stop___ex_table = .;
+ }
+
#ifdef CONFIG_ARM_UNWIND
/*
* Stack unwinding tables
@@ -220,16 +229,6 @@ SECTIONS
READ_MOSTLY_DATA(L1_CACHE_BYTES)
/*
- * The exception fixup table (might need resorting at runtime)
- */
- . = ALIGN(4);
- __start___ex_table = .;
-#ifdef CONFIG_MMU
- *(__ex_table)
-#endif
- __stop___ex_table = .;
-
- /*
* and the usual data section
*/
DATA_DATA
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 043624219b55..e34c1bdb804d 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -494,8 +494,17 @@ endif
comment "Generic Board Type"
+config MACH_AT91RM9200_DT
+ bool "Atmel AT91RM9200 Evaluation Kits with device-tree support"
+ depends on SOC_AT91RM9200
+ select USE_OF
+ help
+ Select this if you want to experiment device-tree with
+ an Atmel RM9200 Evaluation Kit.
+
config MACH_AT91SAM_DT
bool "Atmel AT91SAM Evaluation Kits with device-tree support"
+ depends on SOC_AT91SAM9
select USE_OF
help
Select this if you want to experiment device-tree with
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 3bb7a51efc9d..b38a1dcb79b8 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
# AT91SAM board with device-tree
+obj-$(CONFIG_MACH_AT91RM9200_DT) += board-rm9200-dt.o
obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
# AT91X40 board-specific support
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 5269825194a8..6cceb42a4c33 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -194,6 +194,24 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
CLKDEV_CON_ID("pioD", &pioD_clk),
+ /* usart lookup table for DT entries */
+ CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+ CLKDEV_CON_DEV_ID("usart", "fffc0000.serial", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffc4000.serial", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffc8000.serial", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffcc000.serial", &usart3_clk),
+ /* tc lookup table for DT entries */
+ CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "fffa4000.timer", &tc3_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "fffa4000.timer", &tc4_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "fffa4000.timer", &tc5_clk),
+ CLKDEV_CON_DEV_ID("hclk", "300000.ohci", &ohci_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
@@ -361,10 +379,10 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
0 /* Advanced Interrupt Controller (IRQ6) */
};
-struct at91_init_soc __initdata at91rm9200_soc = {
+AT91_SOC_START(rm9200)
.map_io = at91rm9200_map_io,
.default_irq_priority = at91rm9200_default_irq_priority,
.ioremap_registers = at91rm9200_ioremap_registers,
.register_clocks = at91rm9200_register_clocks,
.init = at91rm9200_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index aaa443b48c91..cafe98836c8a 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -24,6 +24,9 @@
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/export.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <asm/mach/time.h>
@@ -91,7 +94,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
static struct irqaction at91rm9200_timer_irq = {
.name = "at91_tick",
.flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = at91rm9200_timer_interrupt
+ .handler = at91rm9200_timer_interrupt,
+ .irq = NR_IRQS_LEGACY + AT91_ID_SYS,
};
static cycle_t read_clk32k(struct clocksource *cs)
@@ -179,8 +183,60 @@ static struct clock_event_device clkevt = {
void __iomem *at91_st_base;
EXPORT_SYMBOL_GPL(at91_st_base);
+#ifdef CONFIG_OF
+static struct of_device_id at91rm9200_st_timer_ids[] = {
+ { .compatible = "atmel,at91rm9200-st" },
+ { /* sentinel */ }
+};
+
+static int __init of_at91rm9200_st_init(void)
+{
+ struct device_node *np;
+ int ret;
+
+ np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
+ if (!np)
+ goto err;
+
+ at91_st_base = of_iomap(np, 0);
+ if (!at91_st_base)
+ goto node_err;
+
+ /* Get the interrupts property */
+ ret = irq_of_parse_and_map(np, 0);
+ if (!ret)
+ goto ioremap_err;
+ at91rm9200_timer_irq.irq = ret;
+
+ of_node_put(np);
+
+ return 0;
+
+ioremap_err:
+ iounmap(at91_st_base);
+node_err:
+ of_node_put(np);
+err:
+ return -EINVAL;
+}
+#else
+static int __init of_at91rm9200_st_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
void __init at91rm9200_ioremap_st(u32 addr)
{
+#ifdef CONFIG_OF
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
+ if (np) {
+ of_node_put(np);
+ return;
+ }
+#endif
at91_st_base = ioremap(addr, 256);
if (!at91_st_base)
panic("Impossible to ioremap ST\n");
@@ -191,13 +247,16 @@ void __init at91rm9200_ioremap_st(u32 addr)
*/
void __init at91rm9200_timer_init(void)
{
+ /* For device tree enabled device: initialize here */
+ of_at91rm9200_st_init();
+
/* Disable all timer interrupts, and clear any pending ones */
at91_st_write(AT91_ST_IDR,
AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
at91_st_read(AT91_ST_SR);
/* Make IRQs happen for the system timer */
- setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq);
+ setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq);
/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
* directly for the clocksource and all clockevents, after adjusting
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index f8202615f4a8..c9e029e44d8a 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -230,11 +230,15 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk),
CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk),
CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
CLKDEV_CON_ID("pioA", &pioA_clk),
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
@@ -390,10 +394,10 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
-struct at91_init_soc __initdata at91sam9260_soc = {
+AT91_SOC_START(sam9260)
.map_io = at91sam9260_map_io,
.default_irq_priority = at91sam9260_default_irq_priority,
.ioremap_registers = at91sam9260_ioremap_registers,
.register_clocks = at91sam9260_register_clocks,
.init = at91sam9260_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 04295c04b3e0..4d262f346fd9 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -334,10 +334,10 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
-struct at91_init_soc __initdata at91sam9261_soc = {
+AT91_SOC_START(sam9261)
.map_io = at91sam9261_map_io,
.default_irq_priority = at91sam9261_default_irq_priority,
.ioremap_registers = at91sam9261_ioremap_registers,
.register_clocks = at91sam9261_register_clocks,
.init = at91sam9261_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index d6f9c23927c4..ed390f6fa232 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -211,7 +211,14 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk),
CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fff84000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioCDE_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
@@ -365,10 +372,10 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ1) */
};
-struct at91_init_soc __initdata at91sam9263_soc = {
+AT91_SOC_START(sam9263)
.map_io = at91sam9263_map_io,
.default_irq_priority = at91sam9263_default_irq_priority,
.ioremap_registers = at91sam9263_ioremap_registers,
.register_clocks = at91sam9263_register_clocks,
.init = at91sam9263_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 84af1b506d92..c5c2acc4bf22 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -256,10 +256,18 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk),
CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk),
CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
/* fake hclk clock */
CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioDE_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioDE_clk),
+
CLKDEV_CON_ID("pioA", &pioA_clk),
CLKDEV_CON_ID("pioB", &pioB_clk),
CLKDEV_CON_ID("pioC", &pioC_clk),
@@ -409,10 +417,10 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ0) */
};
-struct at91_init_soc __initdata at91sam9g45_soc = {
+AT91_SOC_START(sam9g45)
.map_io = at91sam9g45_map_io,
.default_irq_priority = at91sam9g45_default_irq_priority,
.ioremap_registers = at91sam9g45_ioremap_registers,
.register_clocks = at91sam9g45_register_clocks,
.init = at91sam9g45_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 732d3d3f4ec5..70b3a99244ab 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -168,13 +168,14 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk),
CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
- CLKDEV_CON_ID("pioA", &pioAB_clk),
- CLKDEV_CON_ID("pioB", &pioAB_clk),
- CLKDEV_CON_ID("pioC", &pioCD_clk),
- CLKDEV_CON_ID("pioD", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk),
/* additional fake clock for macb_hclk */
CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk),
CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk),
@@ -223,13 +224,10 @@ static void __init at91sam9n12_map_io(void)
void __init at91sam9n12_initialize(void)
{
at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0);
-
- /* Register GPIO subsystem (using DT) */
- at91_gpio_init(NULL, 0);
}
-struct at91_init_soc __initdata at91sam9n12_soc = {
+AT91_SOC_START(sam9n12)
.map_io = at91sam9n12_map_io,
.register_clocks = at91sam9n12_register_clocks,
.init = at91sam9n12_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 72e908412222..cbe72e44c13f 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -338,10 +338,10 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};
-struct at91_init_soc __initdata at91sam9rl_soc = {
+AT91_SOC_START(sam9rl)
.map_io = at91sam9rl_map_io,
.default_irq_priority = at91sam9rl_default_irq_priority,
.ioremap_registers = at91sam9rl_ioremap_registers,
.register_clocks = at91sam9rl_register_clocks,
.init = at91sam9rl_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index e5035380dcbc..3c729f0e2d3c 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -229,15 +229,17 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk),
- CLKDEV_CON_ID("pioA", &pioAB_clk),
- CLKDEV_CON_ID("pioB", &pioAB_clk),
- CLKDEV_CON_ID("pioC", &pioCD_clk),
- CLKDEV_CON_ID("pioD", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk),
+ CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk),
/* additional fake clock for macb_hclk */
CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
@@ -313,18 +315,11 @@ static void __init at91sam9x5_map_io(void)
at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
}
-void __init at91sam9x5_initialize(void)
-{
- /* Register GPIO subsystem (using DT) */
- at91_gpio_init(NULL, 0);
-}
-
/* --------------------------------------------------------------------
* Interrupt initialization
* -------------------------------------------------------------------- */
-struct at91_init_soc __initdata at91sam9x5_soc = {
+AT91_SOC_START(sam9x5)
.map_io = at91sam9x5_map_io,
.register_clocks = at91sam9x5_register_clocks,
- .init = at91sam9x5_initialize,
-};
+AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index e8f45c4e0ea8..3b6a94820fa0 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -30,8 +30,6 @@
static const struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
- { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup },
- { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup },
{ /*sentinel*/ }
};
diff --git a/arch/arm/mach-at91/board-rm9200-dt.c b/arch/arm/mach-at91/board-rm9200-dt.c
new file mode 100644
index 000000000000..5f9ce3da3fde
--- /dev/null
+++ b/arch/arm/mach-at91/board-rm9200-dt.c
@@ -0,0 +1,57 @@
+/*
+ * Setup code for AT91RM9200 Evaluation Kits with Device Tree support
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ * 2012 Joachim Eastwood <manabian@gmail.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "at91_aic.h"
+#include "generic.h"
+
+
+static const struct of_device_id irq_of_match[] __initconst = {
+ { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
+ { /*sentinel*/ }
+};
+
+static void __init at91rm9200_dt_init_irq(void)
+{
+ of_irq_init(irq_of_match);
+}
+
+static void __init at91rm9200_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char *at91rm9200_dt_board_compat[] __initdata = {
+ "atmel,at91rm9200",
+ NULL
+};
+
+DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
+ .timer = &at91rm9200_timer,
+ .map_io = at91_map_io,
+ .handle_irq = at91_aic_handle_irq,
+ .init_early = at91rm9200_dt_initialize,
+ .init_irq = at91rm9200_dt_init_irq,
+ .init_machine = at91rm9200_dt_device_init,
+ .dt_compat = at91rm9200_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index b62f560e6c75..fc593d615e7d 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -20,6 +20,7 @@ extern void __init at91_init_sram(int bank, unsigned long base,
extern void __init at91rm9200_set_type(int type);
extern void __init at91_initialize(unsigned long main_clock);
extern void __init at91x40_initialize(unsigned long main_clock);
+extern void __init at91rm9200_dt_initialize(void);
extern void __init at91_dt_initialize(void);
/* Interrupts */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index be42cf0e74bd..c5d7e1e9d757 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -23,8 +23,6 @@
#include <linux/io.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/of_gpio.h>
#include <asm/mach/irq.h>
@@ -33,6 +31,8 @@
#include "generic.h"
+#define MAX_NB_GPIO_PER_BANK 32
+
struct at91_gpio_chip {
struct gpio_chip chip;
struct at91_gpio_chip *next; /* Bank sharing same clock */
@@ -46,6 +46,7 @@ struct at91_gpio_chip {
#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip);
static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val);
static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset);
@@ -55,26 +56,27 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset);
static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset);
-#define AT91_GPIO_CHIP(name, nr_gpio) \
+#define AT91_GPIO_CHIP(name) \
{ \
.chip = { \
.label = name, \
+ .request = at91_gpiolib_request, \
.direction_input = at91_gpiolib_direction_input, \
.direction_output = at91_gpiolib_direction_output, \
.get = at91_gpiolib_get, \
.set = at91_gpiolib_set, \
.dbg_show = at91_gpiolib_dbg_show, \
.to_irq = at91_gpiolib_to_irq, \
- .ngpio = nr_gpio, \
+ .ngpio = MAX_NB_GPIO_PER_BANK, \
}, \
}
static struct at91_gpio_chip gpio_chip[] = {
- AT91_GPIO_CHIP("pioA", 32),
- AT91_GPIO_CHIP("pioB", 32),
- AT91_GPIO_CHIP("pioC", 32),
- AT91_GPIO_CHIP("pioD", 32),
- AT91_GPIO_CHIP("pioE", 32),
+ AT91_GPIO_CHIP("pioA"),
+ AT91_GPIO_CHIP("pioB"),
+ AT91_GPIO_CHIP("pioC"),
+ AT91_GPIO_CHIP("pioD"),
+ AT91_GPIO_CHIP("pioE"),
};
static int gpio_banks;
@@ -89,7 +91,7 @@ static unsigned long at91_gpio_caps;
static inline void __iomem *pin_to_controller(unsigned pin)
{
- pin /= 32;
+ pin /= MAX_NB_GPIO_PER_BANK;
if (likely(pin < gpio_banks))
return gpio_chip[pin].regbase;
@@ -98,7 +100,7 @@ static inline void __iomem *pin_to_controller(unsigned pin)
static inline unsigned pin_to_mask(unsigned pin)
{
- return 1 << (pin % 32);
+ return 1 << (pin % MAX_NB_GPIO_PER_BANK);
}
@@ -713,80 +715,6 @@ postcore_initcall(at91_gpio_debugfs_init);
*/
static struct lock_class_key gpio_lock_class;
-#if defined(CONFIG_OF)
-static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct at91_gpio_chip *at91_gpio = h->host_data;
-
- irq_set_lockdep_class(virq, &gpio_lock_class);
-
- /*
- * Can use the "simple" and not "edge" handler since it's
- * shorter, and the AIC handles interrupts sanely.
- */
- irq_set_chip_and_handler(virq, &gpio_irqchip,
- handle_simple_irq);
- set_irq_flags(virq, IRQF_VALID);
- irq_set_chip_data(virq, at91_gpio);
-
- return 0;
-}
-
-static struct irq_domain_ops at91_gpio_ops = {
- .map = at91_gpio_irq_map,
- .xlate = irq_domain_xlate_twocell,
-};
-
-int __init at91_gpio_of_irq_setup(struct device_node *node,
- struct device_node *parent)
-{
- struct at91_gpio_chip *prev = NULL;
- int alias_idx = of_alias_get_id(node, "gpio");
- struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx];
-
- /* Setup proper .irq_set_type function */
- if (has_pio3())
- gpio_irqchip.irq_set_type = alt_gpio_irq_type;
- else
- gpio_irqchip.irq_set_type = gpio_irq_type;
-
- /* Disable irqs of this PIO controller */
- __raw_writel(~0, at91_gpio->regbase + PIO_IDR);
-
- /* Setup irq domain */
- at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio,
- &at91_gpio_ops, at91_gpio);
- if (!at91_gpio->domain)
- panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n",
- at91_gpio->pioc_idx);
-
- /* Setup chained handler */
- if (at91_gpio->pioc_idx)
- prev = &gpio_chip[at91_gpio->pioc_idx - 1];
-
- /* The toplevel handler handles one bank of GPIOs, except
- * on some SoC it can handles up to three...
- * We only set up the handler for the first of the list.
- */
- if (prev && prev->next == at91_gpio)
- return 0;
-
- at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent),
- at91_gpio->pioc_hwirq);
- irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio);
- irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler);
-
- return 0;
-}
-#else
-int __init at91_gpio_of_irq_setup(struct device_node *node,
- struct device_node *parent)
-{
- return -EINVAL;
-}
-#endif
-
/*
* irqdomain initialization: pile up irqdomains on top of AIC range
*/
@@ -862,6 +790,16 @@ void __init at91_gpio_irq_setup(void)
}
/* gpiolib support */
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + PIO_PER);
+ return 0;
+}
+
static int at91_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset)
{
@@ -975,81 +913,11 @@ err:
return -EINVAL;
}
-#ifdef CONFIG_OF_GPIO
-static void __init of_at91_gpio_init_one(struct device_node *np)
-{
- int alias_idx;
- struct at91_gpio_chip *at91_gpio;
-
- if (!np)
- return;
-
- alias_idx = of_alias_get_id(np, "gpio");
- if (alias_idx >= MAX_GPIO_BANKS) {
- pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n",
- alias_idx, MAX_GPIO_BANKS);
- return;
- }
-
- at91_gpio = &gpio_chip[alias_idx];
- at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio;
-
- at91_gpio->regbase = of_iomap(np, 0);
- if (!at91_gpio->regbase) {
- pr_err("at91_gpio.%d, failed to map registers, ignoring.\n",
- alias_idx);
- return;
- }
-
- /* Get the interrupts property */
- if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) {
- pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n",
- alias_idx);
- goto ioremap_err;
- }
-
- /* Get capabilities from compatibility property */
- if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio"))
- at91_gpio_caps |= AT91_GPIO_CAP_PIO3;
-
- /* Setup clock */
- if (at91_gpio_setup_clk(alias_idx))
- goto ioremap_err;
-
- at91_gpio->chip.of_node = np;
- gpio_banks = max(gpio_banks, alias_idx + 1);
- at91_gpio->pioc_idx = alias_idx;
- return;
-
-ioremap_err:
- iounmap(at91_gpio->regbase);
-}
-
-static int __init of_at91_gpio_init(void)
-{
- struct device_node *np = NULL;
-
- /*
- * This isn't ideal, but it gets things hooked up until this
- * driver is converted into a platform_device
- */
- for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio")
- of_at91_gpio_init_one(np);
-
- return gpio_banks > 0 ? 0 : -EINVAL;
-}
-#else
-static int __init of_at91_gpio_init(void)
-{
- return -EINVAL;
-}
-#endif
-
static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq)
{
struct at91_gpio_chip *at91_gpio = &gpio_chip[idx];
- at91_gpio->chip.base = idx * at91_gpio->chip.ngpio;
+ at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK;
at91_gpio->pioc_hwirq = pioc_hwirq;
at91_gpio->pioc_idx = idx;
@@ -1079,11 +947,11 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
BUG_ON(nr_banks > MAX_GPIO_BANKS);
- if (of_at91_gpio_init() < 0) {
- /* No GPIO controller found in device tree */
- for (i = 0; i < nr_banks; i++)
- at91_gpio_init_one(i, data[i].regbase, data[i].id);
- }
+ if (of_have_populated_dt())
+ return;
+
+ for (i = 0; i < nr_banks; i++)
+ at91_gpio_init_one(i, data[i].regbase, data[i].id);
for (i = 0; i < gpio_banks; i++) {
at91_gpio = &gpio_chip[i];
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index c55a4364ffb4..a0d92a960f46 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -70,16 +70,6 @@ struct at91_cf_data {
extern void __init at91_add_device_cf(struct at91_cf_data *data);
/* MMC / SD */
- /* at91_mci platform config */
-struct at91_mmc_data {
- int det_pin; /* card detect IRQ */
- unsigned slot_b:1; /* uses Slot B */
- unsigned wire4:1; /* (SD) supports DAT0..DAT3 */
- int wp_pin; /* (SD) writeprotect detect */
- int vcc_pin; /* power switching (high == on) */
-};
-extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
-
/* atmel-mci platform config */
extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data);
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 0b32c81730a5..19cdd0b5b391 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <linux/pm.h>
#include <linux/of_address.h>
+#include <linux/pinctrl/machine.h>
#include <asm/system_misc.h>
#include <asm/mach/map.h>
@@ -338,6 +339,7 @@ static void at91_dt_rstc(void)
}
static struct of_device_id ramc_ids[] = {
+ { .compatible = "atmel,at91rm9200-sdramc" },
{ .compatible = "atmel,at91sam9260-sdramc" },
{ .compatible = "atmel,at91sam9g45-ddramc" },
{ /*sentinel*/ }
@@ -436,6 +438,19 @@ end:
of_node_put(np);
}
+void __init at91rm9200_dt_initialize(void)
+{
+ at91_dt_ramc();
+
+ /* Init clock subsystem */
+ at91_dt_clock_init();
+
+ /* Register the processor-specific clocks */
+ at91_boot_soc.register_clocks();
+
+ at91_boot_soc.init();
+}
+
void __init at91_dt_initialize(void)
{
at91_dt_rstc();
@@ -448,7 +463,8 @@ void __init at91_dt_initialize(void)
/* Register the processor-specific clocks */
at91_boot_soc.register_clocks();
- at91_boot_soc.init();
+ if (at91_boot_soc.init)
+ at91_boot_soc.init();
}
#endif
@@ -463,4 +479,6 @@ void __init at91_initialize(unsigned long main_clock)
at91_boot_soc.register_clocks();
at91_boot_soc.init();
+
+ pinctrl_provide_dummies();
}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index a9cfeb153719..9c6d3d4f9a23 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -5,6 +5,7 @@
*/
struct at91_init_soc {
+ int builtin;
unsigned int *default_irq_priority;
void (*map_io)(void);
void (*ioremap_registers)(void);
@@ -22,9 +23,18 @@ extern struct at91_init_soc at91sam9rl_soc;
extern struct at91_init_soc at91sam9x5_soc;
extern struct at91_init_soc at91sam9n12_soc;
+#define AT91_SOC_START(_name) \
+struct at91_init_soc __initdata at91##_name##_soc \
+ __used \
+ = { \
+ .builtin = 1, \
+
+#define AT91_SOC_END \
+};
+
static inline int at91_soc_is_enabled(void)
{
- return at91_boot_soc.init != NULL;
+ return at91_boot_soc.builtin;
}
#if !defined(CONFIG_SOC_AT91RM9200)
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
index 2c5fb4c7e509..ae305397003c 100644
--- a/arch/arm/mach-cns3xxx/cns3420vb.c
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -24,6 +24,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/partitions.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/hardware/gic.h>
@@ -32,6 +34,7 @@
#include <asm/mach/time.h>
#include <mach/cns3xxx.h>
#include <mach/irqs.h>
+#include <mach/pm.h>
#include "core.h"
#include "devices.h"
@@ -125,13 +128,52 @@ static struct resource cns3xxx_usb_ehci_resources[] = {
static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
+static int csn3xxx_usb_power_on(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ *
+ * Set USB AHB INCR length to 16
+ */
+ if (atomic_inc_return(&usb_pwr_ref) == 1) {
+ cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
+ cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+ cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
+ __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
+ MISC_CHIP_CONFIG_REG);
+ }
+
+ return 0;
+}
+
+static void csn3xxx_usb_power_off(struct platform_device *pdev)
+{
+ /*
+ * EHCI and OHCI share the same clock and power,
+ * resetting twice would cause the 1st controller been reset.
+ * Therefore only do power up at the first up device, and
+ * power down at the last down device.
+ */
+ if (atomic_dec_return(&usb_pwr_ref) == 0)
+ cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
+}
+
+static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
static struct platform_device cns3xxx_usb_ehci_device = {
- .name = "cns3xxx-ehci",
+ .name = "ehci-platform",
.num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
.resource = cns3xxx_usb_ehci_resources,
.dev = {
.dma_mask = &cns3xxx_usb_ehci_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &cns3xxx_usb_ehci_pdata,
},
};
@@ -149,13 +191,20 @@ static struct resource cns3xxx_usb_ohci_resources[] = {
static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
+static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
+ .num_ports = 1,
+ .power_on = csn3xxx_usb_power_on,
+ .power_off = csn3xxx_usb_power_off,
+};
+
static struct platform_device cns3xxx_usb_ohci_device = {
- .name = "cns3xxx-ohci",
+ .name = "ohci-platform",
.num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
.resource = cns3xxx_usb_ohci_resources,
.dev = {
.dma_mask = &cns3xxx_usb_ohci_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &cns3xxx_usb_ohci_pdata,
},
};
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index cd0c8b1e1ecf..14e9947bad6e 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
break;
case VPBE_ENC_CUSTOM_TIMINGS:
if (pclock <= 27000000) {
- v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
- DM644X_VPSS_DACCLKEN;
+ v |= DM644X_VPSS_DACCLKEN;
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
} else {
/*
diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h
index 7bcd0dfce4b1..b47f75038686 100644
--- a/arch/arm/mach-dove/include/mach/pm.h
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin)
static inline int irq_to_pmu(int irq)
{
- if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
+ if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
return irq - IRQ_DOVE_PMU_START;
return -EINVAL;
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 087711524e8a..bc4344aa1009 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d)
int pin = irq_to_pmu(d->irq);
u32 u;
+ /*
+ * The PMU mask register is not RW0C: it is RW. This means that
+ * the bits take whatever value is written to them; if you write
+ * a '1', you will set the interrupt.
+ *
+ * Unfortunately this means there is NO race free way to clear
+ * these interrupts.
+ *
+ * So, let's structure the code so that the window is as small as
+ * possible.
+ */
u = ~(1 << (pin & 31));
- writel(u, PMU_INTERRUPT_CAUSE);
+ u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
+ writel_relaxed(u, PMU_INTERRUPT_CAUSE);
}
static struct irq_chip pmu_irq_chip = {
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 21d568b3b149..87e07d6fc615 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -275,6 +275,9 @@ static int __init exynos_dma_init(void)
exynos_pdma1_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4210_pdma1_peri);
exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
+
+ if (samsung_rev() == EXYNOS4210_REV_0)
+ exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
exynos_pdma0_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4212_pdma0_peri);
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 8480849affb9..ed4da4544cd2 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -90,6 +90,7 @@
#define EXYNOS4_PA_MDMA0 0x10810000
#define EXYNOS4_PA_MDMA1 0x12850000
+#define EXYNOS4_PA_S_MDMA1 0x12840000
#define EXYNOS4_PA_PDMA0 0x12680000
#define EXYNOS4_PA_PDMA1 0x12690000
#define EXYNOS5_PA_MDMA0 0x10800000
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index e428f3ab15c7..9f82f9dcbb98 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -21,10 +21,9 @@
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/io.h>
+#include <linux/platform_data/clk-integrator.h>
#include <linux/slab.h>
-#include <linux/clkdev.h>
-#include <asm/hardware/icst.h>
#include <mach/lm.h>
#include <mach/impd1.h>
#include <asm/sizes.h>
@@ -36,45 +35,6 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
struct impd1_module {
void __iomem *base;
- struct clk vcos[2];
- struct clk_lookup *clks[3];
-};
-
-static const struct icst_params impd1_vco_params = {
- .ref = 24000000, /* 24 MHz */
- .vco_max = ICST525_VCO_MAX_3V,
- .vco_min = ICST525_VCO_MIN,
- .vd_min = 12,
- .vd_max = 519,
- .rd_min = 3,
- .rd_max = 120,
- .s2div = icst525_s2div,
- .idx2s = icst525_idx2s,
-};
-
-static void impd1_setvco(struct clk *clk, struct icst_vco vco)
-{
- struct impd1_module *impd1 = clk->data;
- u32 val = vco.v | (vco.r << 9) | (vco.s << 16);
-
- writel(0xa05f, impd1->base + IMPD1_LOCK);
- writel(val, clk->vcoreg);
- writel(0, impd1->base + IMPD1_LOCK);
-
-#ifdef DEBUG
- vco.v = val & 0x1ff;
- vco.r = (val >> 9) & 0x7f;
- vco.s = (val >> 16) & 7;
-
- pr_debug("IM-PD1: VCO%d clock is %ld Hz\n",
- vconr, icst525_hz(&impd1_vco_params, vco));
-#endif
-}
-
-static const struct clk_ops impd1_clk_ops = {
- .round = icst_clk_round,
- .set = icst_clk_set,
- .setvco = impd1_setvco,
};
void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
@@ -344,10 +304,6 @@ static struct impd1_device impd1_devs[] = {
}
};
-static struct clk fixed_14745600 = {
- .rate = 14745600,
-};
-
static int impd1_probe(struct lm_device *dev)
{
struct impd1_module *impd1;
@@ -376,23 +332,7 @@ static int impd1_probe(struct lm_device *dev)
printk("IM-PD1 found at 0x%08lx\n",
(unsigned long)dev->resource.start);
- for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
- impd1->vcos[i].ops = &impd1_clk_ops,
- impd1->vcos[i].owner = THIS_MODULE,
- impd1->vcos[i].params = &impd1_vco_params,
- impd1->vcos[i].data = impd1;
- }
- impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1;
- impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2;
-
- impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
- dev->id);
- impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100",
- dev->id);
- impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200",
- dev->id);
- for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
- clkdev_add(impd1->clks[i]);
+ integrator_impd1_clk_init(impd1->base, dev->id);
for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
struct impd1_device *idev = impd1_devs + i;
@@ -402,9 +342,10 @@ static int impd1_probe(struct lm_device *dev)
pc_base = dev->resource.start + idev->offset;
snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
- d = amba_ahb_device_add(&dev->dev, devname, pc_base, SZ_4K,
- dev->irq, dev->irq,
- idev->platform_data, idev->id);
+ d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K,
+ dev->irq, dev->irq,
+ idev->platform_data, idev->id,
+ &dev->resource);
if (IS_ERR(d)) {
dev_err(&dev->dev, "unable to register device: %ld\n", PTR_ERR(d));
continue;
@@ -431,12 +372,9 @@ static int impd1_remove_one(struct device *dev, void *data)
static void impd1_remove(struct lm_device *dev)
{
struct impd1_module *impd1 = lm_get_drvdata(dev);
- int i;
device_for_each_child(&dev->dev, NULL, impd1_remove_one);
-
- for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
- clkdev_drop(impd1->clks[i]);
+ integrator_impd1_clk_exit(dev->id);
lm_set_drvdata(dev, NULL);
diff --git a/arch/arm/mach-ixp4xx/include/mach/udc.h b/arch/arm/mach-ixp4xx/include/mach/udc.h
index 80d6da2eafac..7bd8b96c8843 100644
--- a/arch/arm/mach-ixp4xx/include/mach/udc.h
+++ b/arch/arm/mach-ixp4xx/include/mach/udc.h
@@ -2,7 +2,7 @@
* arch/arm/mach-ixp4xx/include/mach/udc.h
*
*/
-#include <asm/mach/udc_pxa2xx.h>
+#include <linux/platform_data/pxa2xx_udc.h>
extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index ec544918b12c..74fc5a074fc4 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
return 1;
}
+/*
+ * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
+ * is operating as a root complex this needs to be switched to
+ * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
+ * the device. Decoding setup is handled by the orion code.
+ */
static void __devinit rc_pci_fixup(struct pci_dev *dev)
{
- /*
- * Prevent enumeration of root complex.
- */
if (dev->bus->parent == NULL && dev->devfn == 0) {
int i;
+ dev->class &= 0xff;
+ dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
dev->resource[i].start = 0;
dev->resource[i].end = 0;
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index bfa1eab91f41..22ef8a1abe08 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -24,6 +24,7 @@
#include <linux/i2c.h>
#include <linux/io.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/hardware/vic.h>
#include <asm/sizes.h>
#include <asm/mach-types.h>
@@ -32,9 +33,7 @@
#include <asm/mach/flash.h>
#include <asm/mach/time.h>
-#include <plat/gpio-nomadik.h>
#include <plat/mtu.h>
-#include <plat/pincfg.h>
#include <linux/platform_data/mtd-nomadik-nand.h>
#include <mach/fsmc.h>
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index b617eaed0ce5..1273931303fb 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -26,8 +26,8 @@
#include <linux/irq.h>
#include <linux/dma-mapping.h>
#include <linux/platform_data/clk-nomadik.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c
index 6d14454d4609..0c2f6628299a 100644
--- a/arch/arm/mach-nomadik/i2c-8815nhk.c
+++ b/arch/arm/mach-nomadik/i2c-8815nhk.c
@@ -4,8 +4,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/platform_device.h>
-#include <plat/gpio-nomadik.h>
-#include <plat/pincfg.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
/*
* There are two busses in the 8815NHK.
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 48d5e41dfbfa..378590694447 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void)
} else
return;
+ /* Make sure that the GPIO pins are muxed correctly */
+ omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT);
+
err = gpio_request_array(igep_wlan_bt_gpios,
ARRAY_SIZE(igep_wlan_bt_gpios));
if (err) {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b700685762b5..56277a047136 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -45,7 +45,6 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include "common.h"
#include <video/omapdss.h>
#include <video/omap-panel-generic-dpi.h>
#include <video/omap-panel-tfp410.h>
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
index 48daac2581b4..84551f205e46 100644
--- a/arch/arm/mach-omap2/common-board-devices.c
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
struct spi_board_info *spi_bi = &ads7846_spi_board_info;
int err;
- err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
- if (err) {
- pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
- return;
- }
+ /*
+ * If a board defines get_pendown_state() function, request the pendown
+ * GPIO and set the GPIO debounce time.
+ * If a board does not define the get_pendown_state() function, then
+ * the ads7846 driver will setup the pendown GPIO itself.
+ */
+ if (board_pdata && board_pdata->get_pendown_state) {
+ err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+ if (err) {
+ pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+ return;
+ }
- if (gpio_debounce)
- gpio_set_debounce(gpio_pendown, gpio_debounce);
+ if (gpio_debounce)
+ gpio_set_debounce(gpio_pendown, gpio_debounce);
+
+ gpio_export(gpio_pendown, 0);
+ }
spi_bi->bus_num = bus_num;
spi_bi->irq = gpio_to_irq(gpio_pendown);
+ ads7846_config.gpio_pendown = gpio_pendown;
+
if (board_pdata) {
board_pdata->gpio_pendown = gpio_pendown;
+ board_pdata->gpio_pendown_debounce = gpio_debounce;
spi_bi->platform_data = board_pdata;
- if (board_pdata->get_pendown_state)
- gpio_export(gpio_pendown, 0);
- } else {
- ads7846_config.gpio_pendown = gpio_pendown;
}
- if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state))
- gpio_free(gpio_pendown);
-
spi_register_board_info(&ads7846_spi_board_info, 1);
}
#else
diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c
index 72e0f01b715c..49a7ffb716a5 100644
--- a/arch/arm/mach-omap2/drm.c
+++ b/arch/arm/mach-omap2/drm.c
@@ -23,15 +23,20 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/platform_data/omap_drm.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
+#include <plat/cpu.h>
#if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE)
+static struct omap_drm_platform_data platform_data;
+
static struct platform_device omap_drm_device = {
.dev = {
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &platform_data,
},
.name = "omapdrm",
.id = 0,
@@ -52,6 +57,8 @@ static int __init omap_init_drm(void)
oh->name);
}
+ platform_data.omaprev = GET_OMAP_REVISION();
+
return platform_device_register(&omap_drm_device);
}
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 2a791766283d..031e2fbd0e19 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -57,8 +57,6 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
if (IS_ERR(omap_pmu_dev))
return PTR_ERR(omap_pmu_dev);
- pm_runtime_enable(&omap_pmu_dev->dev);
-
return 0;
}
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 44c42057b61c..a256135d8e48 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type,
{
/* PMIC part*/
omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
+ omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);
/* Register additional devices on i2c1 bus if needed */
diff --git a/arch/arm/mach-pxa/include/mach/udc.h b/arch/arm/mach-pxa/include/mach/udc.h
index 2f82332e81a0..9a827e32db98 100644
--- a/arch/arm/mach-pxa/include/mach/udc.h
+++ b/arch/arm/mach-pxa/include/mach/udc.h
@@ -2,7 +2,7 @@
* arch/arm/mach-pxa/include/mach/udc.h
*
*/
-#include <asm/mach/udc_pxa2xx.h>
+#include <linux/platform_data/pxa2xx_udc.h>
extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index d3b3cd216d64..28511d43637a 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -467,6 +467,7 @@ static void __init realview_eb_init(void)
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.atag_offset = 0x100,
+ .smp = smp_ops(realview_smp_ops),
.fixup = realview_fixup,
.map_io = realview_eb_map_io,
.init_early = realview_init_early,
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 6a7ad3c2a3fc..9a23739f7026 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/ioport.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/serial_core.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h>
@@ -37,7 +38,6 @@
#include <asm/mach/flash.h>
#include <asm/mach/irda.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/assabet.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 038df4894b0f..b2dadf3ea3df 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/tty.h>
@@ -34,7 +35,6 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/hardware/sa1111.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/badge4.h>
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index ad0eb08ea077..304bca4a07c0 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/tty.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/mtd/mtd.h>
@@ -27,7 +28,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/cerf.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 170cb6107f68..45f424f5fca6 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h>
@@ -40,7 +41,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index 63150e1ffe9e..f17e7382242a 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -17,12 +17,12 @@
#include <linux/mfd/htc-egpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/h3xxx.h>
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index fc106aab7c7e..d005939c41fc 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/cpufreq.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/serial_core.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -35,7 +36,6 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index e3084f47027d..35cfc428b4d4 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/delay.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
@@ -30,7 +31,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 3048b17e84c5..f69f78fc3ddd 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -4,6 +4,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/tty.h>
#include <linux/gpio.h>
#include <linux/leds.h>
@@ -18,7 +19,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index 41f69d97066f..102e08f7b109 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/root_dev.h>
@@ -24,7 +25,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/hardware.h>
#include <mach/nanoengine.h>
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 266db873a4e4..88be0474f3d7 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -7,6 +7,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/serial_core.h>
@@ -14,7 +15,6 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <asm/hardware/sa1111.h>
#include <asm/sizes.h>
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 37fe0a0a5369..c51bb63f90fb 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -6,6 +6,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/ioport.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <linux/io.h>
@@ -18,7 +19,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
-#include <asm/mach/serial_sa1100.h>
#include <mach/irqs.h>
#include "generic.h"
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index ff6b7b35bca9..6460d25fbb88 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -5,6 +5,7 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/kernel.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/tty.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -18,7 +19,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/shannon.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 71790e581d93..6d65f65fcb23 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -9,6 +9,7 @@
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <linux/platform_data/sa11x0-serial.h>
#include <linux/platform_device.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/mtd/mtd.h>
@@ -23,7 +24,6 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/serial_sa1100.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
#include <mach/simpad.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index 0a43f3189c21..7a05de794a8c 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -548,7 +548,6 @@ static struct platform_device fsi_ak4648_device = {
/* I2C */
static struct pcf857x_platform_data pcf8575_pdata = {
.gpio_base = GPIO_PCF8575_BASE,
- .irq = intcs_evt2irq(0x3260), /* IRQ19 */
};
static struct i2c_board_info i2c0_devices[] = {
@@ -570,6 +569,7 @@ static struct i2c_board_info i2c1_devices[] = {
static struct i2c_board_info i2c3_devices[] = {
{
I2C_BOARD_INFO("pcf8575", 0x20),
+ .irq = intcs_evt2irq(0x3260), /* IRQ19 */
.platform_data = &pcf8575_pdata,
},
};
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index b8efac4daed8..ece8a2dfb814 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -1445,8 +1445,6 @@ static struct platform_device pinctrl_device = {
static struct u300_gpio_platform u300_gpio_plat = {
.ports = 7,
.gpio_base = 0,
- .gpio_irq_base = IRQ_U300_GPIO_BASE,
- .pinctrl_device = &pinctrl_device,
};
static struct platform_device gpio_device = {
@@ -1590,6 +1588,7 @@ static struct platform_device *platform_devs[] __initdata = {
&i2c1_device,
&keypad_device,
&rtc_device,
+ &pinctrl_device,
&gpio_device,
&nand_device,
&wdog_device,
@@ -1804,7 +1803,7 @@ MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board")
/* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
.atag_offset = 0x100,
.map_io = u300_map_io,
- .nr_irqs = NR_IRQS_U300,
+ .nr_irqs = 0,
.init_irq = u300_init_irq,
.handle_irq = vic_handle_irq,
.timer = &u300_timer,
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h
index e27425a63fa1..21d5e76a6cd3 100644
--- a/arch/arm/mach-u300/include/mach/irqs.h
+++ b/arch/arm/mach-u300/include/mach/irqs.h
@@ -12,79 +12,69 @@
#ifndef __MACH_IRQS_H
#define __MACH_IRQS_H
-#define IRQ_U300_INTCON0_START 1
-#define IRQ_U300_INTCON1_START 33
+#define IRQ_U300_INTCON0_START 32
+#define IRQ_U300_INTCON1_START 64
/* These are on INTCON0 - 30 lines */
-#define IRQ_U300_IRQ0_EXT 1
-#define IRQ_U300_IRQ1_EXT 2
-#define IRQ_U300_DMA 3
-#define IRQ_U300_VIDEO_ENC_0 4
-#define IRQ_U300_VIDEO_ENC_1 5
-#define IRQ_U300_AAIF_RX 6
-#define IRQ_U300_AAIF_TX 7
-#define IRQ_U300_AAIF_VGPIO 8
-#define IRQ_U300_AAIF_WAKEUP 9
-#define IRQ_U300_PCM_I2S0_FRAME 10
-#define IRQ_U300_PCM_I2S0_FIFO 11
-#define IRQ_U300_PCM_I2S1_FRAME 12
-#define IRQ_U300_PCM_I2S1_FIFO 13
-#define IRQ_U300_XGAM_GAMCON 14
-#define IRQ_U300_XGAM_CDI 15
-#define IRQ_U300_XGAM_CDICON 16
-#define IRQ_U300_XGAM_PDI 18
-#define IRQ_U300_XGAM_PDICON 19
-#define IRQ_U300_XGAM_GAMEACC 20
-#define IRQ_U300_XGAM_MCIDCT 21
-#define IRQ_U300_APEX 22
-#define IRQ_U300_UART0 23
-#define IRQ_U300_SPI 24
-#define IRQ_U300_TIMER_APP_OS 25
-#define IRQ_U300_TIMER_APP_DD 26
-#define IRQ_U300_TIMER_APP_GP1 27
-#define IRQ_U300_TIMER_APP_GP2 28
-#define IRQ_U300_TIMER_OS 29
-#define IRQ_U300_TIMER_MS 30
-#define IRQ_U300_KEYPAD_KEYBF 31
-#define IRQ_U300_KEYPAD_KEYBR 32
+#define IRQ_U300_IRQ0_EXT 32
+#define IRQ_U300_IRQ1_EXT 33
+#define IRQ_U300_DMA 34
+#define IRQ_U300_VIDEO_ENC_0 35
+#define IRQ_U300_VIDEO_ENC_1 36
+#define IRQ_U300_AAIF_RX 37
+#define IRQ_U300_AAIF_TX 38
+#define IRQ_U300_AAIF_VGPIO 39
+#define IRQ_U300_AAIF_WAKEUP 40
+#define IRQ_U300_PCM_I2S0_FRAME 41
+#define IRQ_U300_PCM_I2S0_FIFO 42
+#define IRQ_U300_PCM_I2S1_FRAME 43
+#define IRQ_U300_PCM_I2S1_FIFO 44
+#define IRQ_U300_XGAM_GAMCON 45
+#define IRQ_U300_XGAM_CDI 46
+#define IRQ_U300_XGAM_CDICON 47
+#define IRQ_U300_XGAM_PDI 49
+#define IRQ_U300_XGAM_PDICON 50
+#define IRQ_U300_XGAM_GAMEACC 51
+#define IRQ_U300_XGAM_MCIDCT 52
+#define IRQ_U300_APEX 53
+#define IRQ_U300_UART0 54
+#define IRQ_U300_SPI 55
+#define IRQ_U300_TIMER_APP_OS 56
+#define IRQ_U300_TIMER_APP_DD 57
+#define IRQ_U300_TIMER_APP_GP1 58
+#define IRQ_U300_TIMER_APP_GP2 59
+#define IRQ_U300_TIMER_OS 60
+#define IRQ_U300_TIMER_MS 61
+#define IRQ_U300_KEYPAD_KEYBF 62
+#define IRQ_U300_KEYPAD_KEYBR 63
/* These are on INTCON1 - 32 lines */
-#define IRQ_U300_GPIO_PORT0 33
-#define IRQ_U300_GPIO_PORT1 34
-#define IRQ_U300_GPIO_PORT2 35
+#define IRQ_U300_GPIO_PORT0 64
+#define IRQ_U300_GPIO_PORT1 65
+#define IRQ_U300_GPIO_PORT2 66
/* These are for DB3150, DB3200 and DB3350 */
-#define IRQ_U300_WDOG 36
-#define IRQ_U300_EVHIST 37
-#define IRQ_U300_MSPRO 38
-#define IRQ_U300_MMCSD_MCIINTR0 39
-#define IRQ_U300_MMCSD_MCIINTR1 40
-#define IRQ_U300_I2C0 41
-#define IRQ_U300_I2C1 42
-#define IRQ_U300_RTC 43
-#define IRQ_U300_NFIF 44
-#define IRQ_U300_NFIF2 45
+#define IRQ_U300_WDOG 67
+#define IRQ_U300_EVHIST 68
+#define IRQ_U300_MSPRO 69
+#define IRQ_U300_MMCSD_MCIINTR0 70
+#define IRQ_U300_MMCSD_MCIINTR1 71
+#define IRQ_U300_I2C0 72
+#define IRQ_U300_I2C1 73
+#define IRQ_U300_RTC 74
+#define IRQ_U300_NFIF 75
+#define IRQ_U300_NFIF2 76
/* The DB3350-specific interrupt lines */
-#define IRQ_U300_ISP_F0 46
-#define IRQ_U300_ISP_F1 47
-#define IRQ_U300_ISP_F2 48
-#define IRQ_U300_ISP_F3 49
-#define IRQ_U300_ISP_F4 50
-#define IRQ_U300_GPIO_PORT3 51
-#define IRQ_U300_SYSCON_PLL_LOCK 52
-#define IRQ_U300_UART1 53
-#define IRQ_U300_GPIO_PORT4 54
-#define IRQ_U300_GPIO_PORT5 55
-#define IRQ_U300_GPIO_PORT6 56
-#define U300_VIC_IRQS_END 57
-
-/* Maximum 8*7 GPIO lines */
-#ifdef CONFIG_PINCTRL_COH901
-#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END)
-#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56)
-#else
-#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END)
-#endif
-
-#define NR_IRQS_U300 (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START)
+#define IRQ_U300_ISP_F0 77
+#define IRQ_U300_ISP_F1 78
+#define IRQ_U300_ISP_F2 79
+#define IRQ_U300_ISP_F3 80
+#define IRQ_U300_ISP_F4 81
+#define IRQ_U300_GPIO_PORT3 82
+#define IRQ_U300_SYSCON_PLL_LOCK 83
+#define IRQ_U300_UART1 84
+#define IRQ_U300_GPIO_PORT4 85
+#define IRQ_U300_GPIO_PORT5 86
+#define IRQ_U300_GPIO_PORT6 87
+#define U300_VIC_IRQS_END 88
#endif
diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c
index 070629a95625..33631c9f1218 100644
--- a/arch/arm/mach-ux500/board-mop500-audio.c
+++ b/arch/arm/mach-ux500/board-mop500-audio.c
@@ -7,9 +7,8 @@
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/gpio.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
-#include <plat/gpio-nomadik.h>
-#include <plat/pincfg.h>
#include <plat/ste_dma40.h>
#include <mach/devices.h>
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index a267c6d30e37..c34d4efd0d5c 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -9,10 +9,9 @@
#include <linux/bug.h>
#include <linux/string.h>
#include <linux/pinctrl/machine.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/mach-types.h>
-#include <plat/pincfg.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 416d436111f2..2d16b1dd5fec 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -16,6 +16,7 @@
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/platform_data/i2c-nomadik.h>
+#include <linux/platform_data/db8500_thermal.h>
#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl022.h>
@@ -37,13 +38,13 @@
#include <linux/of_platform.h>
#include <linux/leds.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
#include <plat/ste_dma40.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/setup.h>
@@ -229,6 +230,67 @@ static struct ab8500_platform_data ab8500_platdata = {
};
/*
+ * Thermal Sensor
+ */
+
+static struct resource db8500_thsens_resources[] = {
+ {
+ .name = "IRQ_HOTMON_LOW",
+ .start = IRQ_PRCMU_HOTMON_LOW,
+ .end = IRQ_PRCMU_HOTMON_LOW,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "IRQ_HOTMON_HIGH",
+ .start = IRQ_PRCMU_HOTMON_HIGH,
+ .end = IRQ_PRCMU_HOTMON_HIGH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct db8500_thsens_platform_data db8500_thsens_data = {
+ .trip_points[0] = {
+ .temp = 70000,
+ .type = THERMAL_TRIP_ACTIVE,
+ .cdev_name = {
+ [0] = "thermal-cpufreq-0",
+ },
+ },
+ .trip_points[1] = {
+ .temp = 75000,
+ .type = THERMAL_TRIP_ACTIVE,
+ .cdev_name = {
+ [0] = "thermal-cpufreq-0",
+ },
+ },
+ .trip_points[2] = {
+ .temp = 80000,
+ .type = THERMAL_TRIP_ACTIVE,
+ .cdev_name = {
+ [0] = "thermal-cpufreq-0",
+ },
+ },
+ .trip_points[3] = {
+ .temp = 85000,
+ .type = THERMAL_TRIP_CRITICAL,
+ },
+ .num_trips = 4,
+};
+
+static struct platform_device u8500_thsens_device = {
+ .name = "db8500-thermal",
+ .resource = db8500_thsens_resources,
+ .num_resources = ARRAY_SIZE(db8500_thsens_resources),
+ .dev = {
+ .platform_data = &db8500_thsens_data,
+ },
+};
+
+static struct platform_device u8500_cpufreq_cooling_device = {
+ .name = "db8500-cpufreq-cooling",
+};
+
+/*
* TPS61052
*/
@@ -583,6 +645,8 @@ static struct platform_device *snowball_platform_devs[] __initdata = {
&snowball_key_dev,
&snowball_sbnet_dev,
&snowball_gpio_en_3v3_regulator_dev,
+ &u8500_thsens_device,
+ &u8500_cpufreq_cooling_device,
};
static void __init mop500_init_machine(void)
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index bcdfe6b1d453..91f028c1264a 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -17,14 +17,14 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/mfd/abx500/ab8500.h>
+#include <linux/platform_data/usb-musb-ux500.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <asm/pmu.h>
#include <asm/mach/map.h>
-#include <plat/gpio-nomadik.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
-#include <linux/platform_data/usb-musb-ux500.h>
#include <mach/db8500-regs.h>
#include "devices-db8500.h"
@@ -158,7 +158,7 @@ static void __init db8500_add_gpios(struct device *parent)
dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base),
IRQ_DB8500_GPIO0, &pdata);
- dbx500_add_pinctrl(parent, "pinctrl-db8500");
+ dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE);
}
static int usb_db8500_rx_dma_cfg[] = {
@@ -214,9 +214,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500)
db8500_add_gpios(parent);
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
- platform_device_register_data(parent,
- "cpufreq-u8500", -1, NULL, 0);
-
for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
platform_devs[i]->dev.parent = parent;
@@ -236,9 +233,6 @@ struct device * __init u8500_of_init_devices(void)
db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
- platform_device_register_data(parent,
- "cpufreq-u8500", -1, NULL, 0);
-
u8500_dma40_device.dev.parent = parent;
/*
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
index dfdd4a54668d..692a77a1c153 100644
--- a/arch/arm/mach-ux500/devices-common.c
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -11,8 +11,7 @@
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
-
-#include <plat/gpio-nomadik.h>
+#include <linux/platform_data/pinctrl-nomadik.h>
#include <mach/hardware.h>
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
index 7fbf0ba336e1..96fa4ac89e2e 100644
--- a/arch/arm/mach-ux500/devices-common.h
+++ b/arch/arm/mach-ux500/devices-common.h
@@ -129,12 +129,18 @@ void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
int irq, struct nmk_gpio_platform_data *pdata);
static inline void
-dbx500_add_pinctrl(struct device *parent, const char *name)
+dbx500_add_pinctrl(struct device *parent, const char *name,
+ resource_size_t base)
{
+ struct resource res[] = {
+ DEFINE_RES_MEM(base, SZ_8K),
+ };
struct platform_device_info pdevinfo = {
.parent = parent,
.name = name,
.id = -1,
+ .res = res,
+ .num_res = ARRAY_SIZE(res),
};
platform_device_register_full(&pdevinfo);
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 560e0df728f8..359f782c747d 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -589,7 +589,7 @@ void __init v2m_dt_init_early(void)
return;
/* Confirm board type against DT property, if available */
- if (of_property_read_u32(allnodes, "arm,hbi", &dt_hbi) == 0) {
+ if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) {
int site = v2m_get_master_site();
u32 id = readl(v2m_sysreg_base + (site == SYS_CFG_SITE_DB2 ?
V2M_SYS_PROCID1 : V2M_SYS_PROCID0));
diff --git a/arch/arm/mm/cache-aurora-l2.h b/arch/arm/mm/cache-aurora-l2.h
new file mode 100644
index 000000000000..c86124769831
--- /dev/null
+++ b/arch/arm/mm/cache-aurora-l2.h
@@ -0,0 +1,55 @@
+/*
+ * AURORA shared L2 cache controller support
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARM_HARDWARE_AURORA_L2_H
+#define __ASM_ARM_HARDWARE_AURORA_L2_H
+
+#define AURORA_SYNC_REG 0x700
+#define AURORA_RANGE_BASE_ADDR_REG 0x720
+#define AURORA_FLUSH_PHY_ADDR_REG 0x7f0
+#define AURORA_INVAL_RANGE_REG 0x774
+#define AURORA_CLEAN_RANGE_REG 0x7b4
+#define AURORA_FLUSH_RANGE_REG 0x7f4
+
+#define AURORA_ACR_REPLACEMENT_OFFSET 27
+#define AURORA_ACR_REPLACEMENT_MASK \
+ (0x3 << AURORA_ACR_REPLACEMENT_OFFSET)
+#define AURORA_ACR_REPLACEMENT_TYPE_WAYRR \
+ (0 << AURORA_ACR_REPLACEMENT_OFFSET)
+#define AURORA_ACR_REPLACEMENT_TYPE_LFSR \
+ (1 << AURORA_ACR_REPLACEMENT_OFFSET)
+#define AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU \
+ (3 << AURORA_ACR_REPLACEMENT_OFFSET)
+
+#define AURORA_ACR_FORCE_WRITE_POLICY_OFFSET 0
+#define AURORA_ACR_FORCE_WRITE_POLICY_MASK \
+ (0x3 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+#define AURORA_ACR_FORCE_WRITE_POLICY_DIS \
+ (0 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+#define AURORA_ACR_FORCE_WRITE_BACK_POLICY \
+ (1 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+#define AURORA_ACR_FORCE_WRITE_THRO_POLICY \
+ (2 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
+
+#define MAX_RANGE_SIZE 1024
+
+#define AURORA_WAY_SIZE_SHIFT 2
+
+#define AURORA_CTRL_FW 0x100
+
+/* chose a number outside L2X0_CACHE_ID_PART_MASK to be sure to make
+ * the distinction between a number coming from hardware and a number
+ * coming from the device tree */
+#define AURORA_CACHE_ID 0x100
+
+#endif /* __ASM_ARM_HARDWARE_AURORA_L2_H */
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 8a97e6443c62..6911b8b2745c 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -25,6 +25,7 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
+#include "cache-aurora-l2.h"
#define CACHE_LINE_SIZE 32
@@ -34,14 +35,20 @@ static u32 l2x0_way_mask; /* Bitmask of active ways */
static u32 l2x0_size;
static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
+/* Aurora don't have the cache ID register available, so we have to
+ * pass it though the device tree */
+static u32 cache_id_part_number_from_dt;
+
struct l2x0_regs l2x0_saved_regs;
struct l2x0_of_data {
void (*setup)(const struct device_node *, u32 *, u32 *);
void (*save)(void);
- void (*resume)(void);
+ struct outer_cache_fns outer_cache;
};
+static bool of_init = false;
+
static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
{
/* wait for cache operation by line or way to complete */
@@ -168,7 +175,7 @@ static void l2x0_inv_all(void)
/* invalidate all ways */
raw_spin_lock_irqsave(&l2x0_lock, flags);
/* Invalidating when L2 is enabled is a nono */
- BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1);
+ BUG_ON(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN);
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
cache_sync();
@@ -292,11 +299,18 @@ static void l2x0_unlock(u32 cache_id)
int lockregs;
int i;
- if (cache_id == L2X0_CACHE_ID_PART_L310)
+ switch (cache_id) {
+ case L2X0_CACHE_ID_PART_L310:
lockregs = 8;
- else
+ break;
+ case AURORA_CACHE_ID:
+ lockregs = 4;
+ break;
+ default:
/* L210 and unknown types */
lockregs = 1;
+ break;
+ }
for (i = 0; i < lockregs; i++) {
writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
@@ -312,18 +326,22 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
u32 cache_id;
u32 way_size = 0;
int ways;
+ int way_size_shift = L2X0_WAY_SIZE_SHIFT;
const char *type;
l2x0_base = base;
-
- cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
+ if (cache_id_part_number_from_dt)
+ cache_id = cache_id_part_number_from_dt;
+ else
+ cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID)
+ & L2X0_CACHE_ID_PART_MASK;
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
aux &= aux_mask;
aux |= aux_val;
/* Determine the number of ways */
- switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+ switch (cache_id) {
case L2X0_CACHE_ID_PART_L310:
if (aux & (1 << 16))
ways = 16;
@@ -340,6 +358,14 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
ways = (aux >> 13) & 0xf;
type = "L210";
break;
+
+ case AURORA_CACHE_ID:
+ sync_reg_offset = AURORA_SYNC_REG;
+ ways = (aux >> 13) & 0xf;
+ ways = 2 << ((ways + 1) >> 2);
+ way_size_shift = AURORA_WAY_SIZE_SHIFT;
+ type = "Aurora";
+ break;
default:
/* Assume unknown chips have 8 ways */
ways = 8;
@@ -353,7 +379,8 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
* L2 cache Size = Way size * Number of ways
*/
way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
- way_size = 1 << (way_size + 3);
+ way_size = 1 << (way_size + way_size_shift);
+
l2x0_size = ways * way_size * SZ_1K;
/*
@@ -361,7 +388,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
* If you are booting from non-secure mode
* accessing the below registers will fault.
*/
- if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
/* Make sure that I&D is not locked down when starting */
l2x0_unlock(cache_id);
@@ -371,7 +398,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
l2x0_inv_all();
/* enable L2X0 */
- writel_relaxed(1, l2x0_base + L2X0_CTRL);
+ writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
}
/* Re-read it in case some bits are reserved. */
@@ -380,13 +407,15 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
/* Save the value for resuming. */
l2x0_saved_regs.aux_ctrl = aux;
- outer_cache.inv_range = l2x0_inv_range;
- outer_cache.clean_range = l2x0_clean_range;
- outer_cache.flush_range = l2x0_flush_range;
- outer_cache.sync = l2x0_cache_sync;
- outer_cache.flush_all = l2x0_flush_all;
- outer_cache.inv_all = l2x0_inv_all;
- outer_cache.disable = l2x0_disable;
+ if (!of_init) {
+ outer_cache.inv_range = l2x0_inv_range;
+ outer_cache.clean_range = l2x0_clean_range;
+ outer_cache.flush_range = l2x0_flush_range;
+ outer_cache.sync = l2x0_cache_sync;
+ outer_cache.flush_all = l2x0_flush_all;
+ outer_cache.inv_all = l2x0_inv_all;
+ outer_cache.disable = l2x0_disable;
+ }
printk(KERN_INFO "%s cache controller enabled\n", type);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
@@ -394,6 +423,100 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
}
#ifdef CONFIG_OF
+static int l2_wt_override;
+
+/*
+ * Note that the end addresses passed to Linux primitives are
+ * noninclusive, while the hardware cache range operations use
+ * inclusive start and end addresses.
+ */
+static unsigned long calc_range_end(unsigned long start, unsigned long end)
+{
+ /*
+ * Limit the number of cache lines processed at once,
+ * since cache range operations stall the CPU pipeline
+ * until completion.
+ */
+ if (end > start + MAX_RANGE_SIZE)
+ end = start + MAX_RANGE_SIZE;
+
+ /*
+ * Cache range operations can't straddle a page boundary.
+ */
+ if (end > PAGE_ALIGN(start+1))
+ end = PAGE_ALIGN(start+1);
+
+ return end;
+}
+
+/*
+ * Make sure 'start' and 'end' reference the same page, as L2 is PIPT
+ * and range operations only do a TLB lookup on the start address.
+ */
+static void aurora_pa_range(unsigned long start, unsigned long end,
+ unsigned long offset)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ writel(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG);
+ writel(end, l2x0_base + offset);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ cache_sync();
+}
+
+static void aurora_inv_range(unsigned long start, unsigned long end)
+{
+ /*
+ * round start and end adresses up to cache line size
+ */
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = ALIGN(end, CACHE_LINE_SIZE);
+
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+ while (start < end) {
+ unsigned long range_end = calc_range_end(start, end);
+ aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
+ AURORA_INVAL_RANGE_REG);
+ start = range_end;
+ }
+}
+
+static void aurora_clean_range(unsigned long start, unsigned long end)
+{
+ /*
+ * If L2 is forced to WT, the L2 will always be clean and we
+ * don't need to do anything here.
+ */
+ if (!l2_wt_override) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = ALIGN(end, CACHE_LINE_SIZE);
+ while (start != end) {
+ unsigned long range_end = calc_range_end(start, end);
+ aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
+ AURORA_CLEAN_RANGE_REG);
+ start = range_end;
+ }
+ }
+}
+
+static void aurora_flush_range(unsigned long start, unsigned long end)
+{
+ if (!l2_wt_override) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = ALIGN(end, CACHE_LINE_SIZE);
+ while (start != end) {
+ unsigned long range_end = calc_range_end(start, end);
+ aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
+ AURORA_FLUSH_RANGE_REG);
+ start = range_end;
+ }
+ }
+}
+
static void __init l2x0_of_setup(const struct device_node *np,
u32 *aux_val, u32 *aux_mask)
{
@@ -491,9 +614,15 @@ static void __init pl310_save(void)
}
}
+static void aurora_save(void)
+{
+ l2x0_saved_regs.ctrl = readl_relaxed(l2x0_base + L2X0_CTRL);
+ l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+}
+
static void l2x0_resume(void)
{
- if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
/* restore aux ctrl and enable l2 */
l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID));
@@ -502,7 +631,7 @@ static void l2x0_resume(void)
l2x0_inv_all();
- writel_relaxed(1, l2x0_base + L2X0_CTRL);
+ writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
}
}
@@ -510,7 +639,7 @@ static void pl310_resume(void)
{
u32 l2x0_revision;
- if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
/* restore pl310 setup */
writel_relaxed(l2x0_saved_regs.tag_latency,
l2x0_base + L2X0_TAG_LATENCY_CTRL);
@@ -536,22 +665,108 @@ static void pl310_resume(void)
l2x0_resume();
}
+static void aurora_resume(void)
+{
+ if (!(readl(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
+ writel(l2x0_saved_regs.aux_ctrl, l2x0_base + L2X0_AUX_CTRL);
+ writel(l2x0_saved_regs.ctrl, l2x0_base + L2X0_CTRL);
+ }
+}
+
+static void __init aurora_broadcast_l2_commands(void)
+{
+ __u32 u;
+ /* Enable Broadcasting of cache commands to L2*/
+ __asm__ __volatile__("mrc p15, 1, %0, c15, c2, 0" : "=r"(u));
+ u |= AURORA_CTRL_FW; /* Set the FW bit */
+ __asm__ __volatile__("mcr p15, 1, %0, c15, c2, 0\n" : : "r"(u));
+ isb();
+}
+
+static void __init aurora_of_setup(const struct device_node *np,
+ u32 *aux_val, u32 *aux_mask)
+{
+ u32 val = AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU;
+ u32 mask = AURORA_ACR_REPLACEMENT_MASK;
+
+ of_property_read_u32(np, "cache-id-part",
+ &cache_id_part_number_from_dt);
+
+ /* Determine and save the write policy */
+ l2_wt_override = of_property_read_bool(np, "wt-override");
+
+ if (l2_wt_override) {
+ val |= AURORA_ACR_FORCE_WRITE_THRO_POLICY;
+ mask |= AURORA_ACR_FORCE_WRITE_POLICY_MASK;
+ }
+
+ *aux_val &= ~mask;
+ *aux_val |= val;
+ *aux_mask &= ~mask;
+}
+
static const struct l2x0_of_data pl310_data = {
- pl310_of_setup,
- pl310_save,
- pl310_resume,
+ .setup = pl310_of_setup,
+ .save = pl310_save,
+ .outer_cache = {
+ .resume = pl310_resume,
+ .inv_range = l2x0_inv_range,
+ .clean_range = l2x0_clean_range,
+ .flush_range = l2x0_flush_range,
+ .sync = l2x0_cache_sync,
+ .flush_all = l2x0_flush_all,
+ .inv_all = l2x0_inv_all,
+ .disable = l2x0_disable,
+ .set_debug = pl310_set_debug,
+ },
};
static const struct l2x0_of_data l2x0_data = {
- l2x0_of_setup,
- NULL,
- l2x0_resume,
+ .setup = l2x0_of_setup,
+ .save = NULL,
+ .outer_cache = {
+ .resume = l2x0_resume,
+ .inv_range = l2x0_inv_range,
+ .clean_range = l2x0_clean_range,
+ .flush_range = l2x0_flush_range,
+ .sync = l2x0_cache_sync,
+ .flush_all = l2x0_flush_all,
+ .inv_all = l2x0_inv_all,
+ .disable = l2x0_disable,
+ },
+};
+
+static const struct l2x0_of_data aurora_with_outer_data = {
+ .setup = aurora_of_setup,
+ .save = aurora_save,
+ .outer_cache = {
+ .resume = aurora_resume,
+ .inv_range = aurora_inv_range,
+ .clean_range = aurora_clean_range,
+ .flush_range = aurora_flush_range,
+ .sync = l2x0_cache_sync,
+ .flush_all = l2x0_flush_all,
+ .inv_all = l2x0_inv_all,
+ .disable = l2x0_disable,
+ },
+};
+
+static const struct l2x0_of_data aurora_no_outer_data = {
+ .setup = aurora_of_setup,
+ .save = aurora_save,
+ .outer_cache = {
+ .resume = aurora_resume,
+ },
};
static const struct of_device_id l2x0_ids[] __initconst = {
{ .compatible = "arm,pl310-cache", .data = (void *)&pl310_data },
{ .compatible = "arm,l220-cache", .data = (void *)&l2x0_data },
{ .compatible = "arm,l210-cache", .data = (void *)&l2x0_data },
+ { .compatible = "marvell,aurora-system-cache",
+ .data = (void *)&aurora_no_outer_data},
+ { .compatible = "marvell,aurora-outer-cache",
+ .data = (void *)&aurora_with_outer_data},
{}
};
@@ -577,17 +792,24 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
data = of_match_node(l2x0_ids, np)->data;
/* L2 configuration can only be changed if the cache is disabled */
- if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
if (data->setup)
data->setup(np, &aux_val, &aux_mask);
+
+ /* For aurora cache in no outer mode select the
+ * correct mode using the coprocessor*/
+ if (data == &aurora_no_outer_data)
+ aurora_broadcast_l2_commands();
}
if (data->save)
data->save();
+ of_init = true;
l2x0_init(l2x0_base, aux_val, aux_mask);
- outer_cache.resume = data->resume;
+ memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache));
+
return 0;
}
#endif
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 4e07eec1270d..bc4a5e9ebb78 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -2,6 +2,9 @@
* linux/arch/arm/mm/context.c
*
* Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
+ * Copyright (C) 2012 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
*
* 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
@@ -14,14 +17,40 @@
#include <linux/percpu.h>
#include <asm/mmu_context.h>
+#include <asm/smp_plat.h>
#include <asm/thread_notify.h>
#include <asm/tlbflush.h>
+/*
+ * On ARMv6, we have the following structure in the Context ID:
+ *
+ * 31 7 0
+ * +-------------------------+-----------+
+ * | process ID | ASID |
+ * +-------------------------+-----------+
+ * | context ID |
+ * +-------------------------------------+
+ *
+ * The ASID is used to tag entries in the CPU caches and TLBs.
+ * The context ID is used by debuggers and trace logic, and
+ * should be unique within all running processes.
+ */
+#define ASID_FIRST_VERSION (1ULL << ASID_BITS)
+#define NUM_USER_ASIDS (ASID_FIRST_VERSION - 1)
+
+#define ASID_TO_IDX(asid) ((asid & ~ASID_MASK) - 1)
+#define IDX_TO_ASID(idx) ((idx + 1) & ~ASID_MASK)
+
static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
-unsigned int cpu_last_asid = ASID_FIRST_VERSION;
+static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
+static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS);
+
+static DEFINE_PER_CPU(atomic64_t, active_asids);
+static DEFINE_PER_CPU(u64, reserved_asids);
+static cpumask_t tlb_flush_pending;
#ifdef CONFIG_ARM_LPAE
-void cpu_set_reserved_ttbr0(void)
+static void cpu_set_reserved_ttbr0(void)
{
unsigned long ttbl = __pa(swapper_pg_dir);
unsigned long ttbh = 0;
@@ -37,7 +66,7 @@ void cpu_set_reserved_ttbr0(void)
isb();
}
#else
-void cpu_set_reserved_ttbr0(void)
+static void cpu_set_reserved_ttbr0(void)
{
u32 ttb;
/* Copy TTBR1 into TTBR0 */
@@ -84,124 +113,104 @@ static int __init contextidr_notifier_init(void)
arch_initcall(contextidr_notifier_init);
#endif
-/*
- * We fork()ed a process, and we need a new context for the child
- * to run in.
- */
-void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+static void flush_context(unsigned int cpu)
{
- mm->context.id = 0;
- raw_spin_lock_init(&mm->context.id_lock);
-}
+ int i;
+ u64 asid;
+
+ /* Update the list of reserved ASIDs and the ASID bitmap. */
+ bitmap_clear(asid_map, 0, NUM_USER_ASIDS);
+ for_each_possible_cpu(i) {
+ if (i == cpu) {
+ asid = 0;
+ } else {
+ asid = atomic64_xchg(&per_cpu(active_asids, i), 0);
+ __set_bit(ASID_TO_IDX(asid), asid_map);
+ }
+ per_cpu(reserved_asids, i) = asid;
+ }
-static void flush_context(void)
-{
- cpu_set_reserved_ttbr0();
- local_flush_tlb_all();
- if (icache_is_vivt_asid_tagged()) {
+ /* Queue a TLB invalidate and flush the I-cache if necessary. */
+ if (!tlb_ops_need_broadcast())
+ cpumask_set_cpu(cpu, &tlb_flush_pending);
+ else
+ cpumask_setall(&tlb_flush_pending);
+
+ if (icache_is_vivt_asid_tagged())
__flush_icache_all();
- dsb();
- }
}
-#ifdef CONFIG_SMP
+static int is_reserved_asid(u64 asid)
+{
+ int cpu;
+ for_each_possible_cpu(cpu)
+ if (per_cpu(reserved_asids, cpu) == asid)
+ return 1;
+ return 0;
+}
-static void set_mm_context(struct mm_struct *mm, unsigned int asid)
+static void new_context(struct mm_struct *mm, unsigned int cpu)
{
- unsigned long flags;
+ u64 asid = mm->context.id;
+ u64 generation = atomic64_read(&asid_generation);
- /*
- * Locking needed for multi-threaded applications where the
- * same mm->context.id could be set from different CPUs during
- * the broadcast. This function is also called via IPI so the
- * mm->context.id_lock has to be IRQ-safe.
- */
- raw_spin_lock_irqsave(&mm->context.id_lock, flags);
- if (likely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) {
+ if (asid != 0 && is_reserved_asid(asid)) {
/*
- * Old version of ASID found. Set the new one and
- * reset mm_cpumask(mm).
+ * Our current ASID was active during a rollover, we can
+ * continue to use it and this was just a false alarm.
*/
- mm->context.id = asid;
+ asid = generation | (asid & ~ASID_MASK);
+ } else {
+ /*
+ * Allocate a free ASID. If we can't find one, take a
+ * note of the currently active ASIDs and mark the TLBs
+ * as requiring flushes.
+ */
+ asid = find_first_zero_bit(asid_map, NUM_USER_ASIDS);
+ if (asid == NUM_USER_ASIDS) {
+ generation = atomic64_add_return(ASID_FIRST_VERSION,
+ &asid_generation);
+ flush_context(cpu);
+ asid = find_first_zero_bit(asid_map, NUM_USER_ASIDS);
+ }
+ __set_bit(asid, asid_map);
+ asid = generation | IDX_TO_ASID(asid);
cpumask_clear(mm_cpumask(mm));
}
- raw_spin_unlock_irqrestore(&mm->context.id_lock, flags);
- /*
- * Set the mm_cpumask(mm) bit for the current CPU.
- */
- cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+ mm->context.id = asid;
}
-/*
- * Reset the ASID on the current CPU. This function call is broadcast
- * from the CPU handling the ASID rollover and holding cpu_asid_lock.
- */
-static void reset_context(void *info)
+void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
{
- unsigned int asid;
+ unsigned long flags;
unsigned int cpu = smp_processor_id();
- struct mm_struct *mm = current->active_mm;
- smp_rmb();
- asid = cpu_last_asid + cpu + 1;
+ if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
+ __check_vmalloc_seq(mm);
- flush_context();
- set_mm_context(mm, asid);
-
- /* set the new ASID */
- cpu_switch_mm(mm->pgd, mm);
-}
+ /*
+ * Required during context switch to avoid speculative page table
+ * walking with the wrong TTBR.
+ */
+ cpu_set_reserved_ttbr0();
-#else
+ if (!((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+ && atomic64_xchg(&per_cpu(active_asids, cpu), mm->context.id))
+ goto switch_mm_fastpath;
-static inline void set_mm_context(struct mm_struct *mm, unsigned int asid)
-{
- mm->context.id = asid;
- cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
-}
+ raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+ /* Check that our ASID belongs to the current generation. */
+ if ((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+ new_context(mm, cpu);
-#endif
+ atomic64_set(&per_cpu(active_asids, cpu), mm->context.id);
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
-void __new_context(struct mm_struct *mm)
-{
- unsigned int asid;
+ if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending))
+ local_flush_tlb_all();
+ raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
- raw_spin_lock(&cpu_asid_lock);
-#ifdef CONFIG_SMP
- /*
- * Check the ASID again, in case the change was broadcast from
- * another CPU before we acquired the lock.
- */
- if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) {
- cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
- raw_spin_unlock(&cpu_asid_lock);
- return;
- }
-#endif
- /*
- * At this point, it is guaranteed that the current mm (with
- * an old ASID) isn't active on any other CPU since the ASIDs
- * are changed simultaneously via IPI.
- */
- asid = ++cpu_last_asid;
- if (asid == 0)
- asid = cpu_last_asid = ASID_FIRST_VERSION;
-
- /*
- * If we've used up all our ASIDs, we need
- * to start a new version and flush the TLB.
- */
- if (unlikely((asid & ~ASID_MASK) == 0)) {
- asid = cpu_last_asid + smp_processor_id() + 1;
- flush_context();
-#ifdef CONFIG_SMP
- smp_wmb();
- smp_call_function(reset_context, NULL, 1);
-#endif
- cpu_last_asid += NR_CPUS;
- }
-
- set_mm_context(mm, asid);
- raw_spin_unlock(&cpu_asid_lock);
+switch_mm_fastpath:
+ cpu_switch_mm(mm->pgd, mm);
}
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index ab88ed4f8e08..99db769307ec 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -92,6 +92,9 @@ static int __init init_static_idmap(void)
(long long)idmap_start, (long long)idmap_end);
identity_mapping_add(idmap_pgd, idmap_start, idmap_end);
+ /* Flush L1 for the hardware to see this page table content */
+ flush_cache_louis();
+
return 0;
}
early_initcall(init_static_idmap);
@@ -103,12 +106,15 @@ early_initcall(init_static_idmap);
*/
void setup_mm_for_reboot(void)
{
- /* Clean and invalidate L1. */
- flush_cache_all();
-
/* Switch to the identity mapping. */
cpu_switch_mm(idmap_pgd, &init_mm);
- /* Flush the TLB. */
+#ifdef CONFIG_CPU_HAS_ASID
+ /*
+ * We don't have a clean ASID for the identity mapping, which
+ * may clash with virtual addresses of the previous page tables
+ * and therefore potentially in the TLB.
+ */
local_flush_tlb_all();
+#endif
}
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 5dcc2fd46c46..88fd86cf3d9a 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -47,18 +47,18 @@ int ioremap_page(unsigned long virt, unsigned long phys,
}
EXPORT_SYMBOL(ioremap_page);
-void __check_kvm_seq(struct mm_struct *mm)
+void __check_vmalloc_seq(struct mm_struct *mm)
{
unsigned int seq;
do {
- seq = init_mm.context.kvm_seq;
+ seq = init_mm.context.vmalloc_seq;
memcpy(pgd_offset(mm, VMALLOC_START),
pgd_offset_k(VMALLOC_START),
sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
pgd_index(VMALLOC_START)));
- mm->context.kvm_seq = seq;
- } while (seq != init_mm.context.kvm_seq);
+ mm->context.vmalloc_seq = seq;
+ } while (seq != init_mm.context.vmalloc_seq);
}
#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
@@ -89,13 +89,13 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
if (!pmd_none(pmd)) {
/*
* Clear the PMD from the page table, and
- * increment the kvm sequence so others
+ * increment the vmalloc sequence so others
* notice this change.
*
* Note: this is still racy on SMP machines.
*/
pmd_clear(pmdp);
- init_mm.context.kvm_seq++;
+ init_mm.context.vmalloc_seq++;
/*
* Free the page table, if there was one.
@@ -112,8 +112,8 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
* Ensure that the active_mm is up to date - we want to
* catch any use-after-iounmap cases.
*/
- if (current->active_mm->context.kvm_seq != init_mm.context.kvm_seq)
- __check_kvm_seq(current->active_mm);
+ if (current->active_mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)
+ __check_vmalloc_seq(current->active_mm);
flush_tlb_kernel_range(virt, end);
}
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index ce8cb1970d7a..10062ceadd1c 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -11,18 +11,6 @@
#include <linux/random.h>
#include <asm/cachetype.h>
-static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
- unsigned long pgoff)
-{
- unsigned long base = addr & ~(SHMLBA-1);
- unsigned long off = (pgoff << PAGE_SHIFT) & (SHMLBA-1);
-
- if (base + off <= addr)
- return base + off;
-
- return base - off;
-}
-
#define COLOUR_ALIGN(addr,pgoff) \
((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
(((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
@@ -69,9 +57,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
- unsigned long start_addr;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
+ struct vm_unmapped_area_info info;
/*
* We only need to do colour alignment if either the I or D
@@ -104,46 +92,14 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
(!vma || addr + len <= vma->vm_start))
return addr;
}
- if (len > mm->cached_hole_size) {
- start_addr = addr = mm->free_area_cache;
- } else {
- start_addr = addr = mm->mmap_base;
- mm->cached_hole_size = 0;
- }
-full_search:
- if (do_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(addr);
-
- for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
- /* At this point: (!vma || addr < vma->vm_end). */
- if (TASK_SIZE - len < addr) {
- /*
- * Start a new search - just in case we missed
- * some holes.
- */
- if (start_addr != TASK_UNMAPPED_BASE) {
- start_addr = addr = TASK_UNMAPPED_BASE;
- mm->cached_hole_size = 0;
- goto full_search;
- }
- return -ENOMEM;
- }
- if (!vma || addr + len <= vma->vm_start) {
- /*
- * Remember the place where we stopped the search:
- */
- mm->free_area_cache = addr + len;
- return addr;
- }
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
- addr = vma->vm_end;
- if (do_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ return vm_unmapped_area(&info);
}
unsigned long
@@ -156,6 +112,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
unsigned long addr = addr0;
int do_align = 0;
int aliasing = cache_is_vipt_aliasing();
+ struct vm_unmapped_area_info info;
/*
* We only need to do colour alignment if either the I or D
@@ -187,70 +144,27 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
return addr;
}
- /* check if free_area_cache is useful for us */
- if (len <= mm->cached_hole_size) {
- mm->cached_hole_size = 0;
- mm->free_area_cache = mm->mmap_base;
- }
-
- /* either no address requested or can't fit in requested address hole */
- addr = mm->free_area_cache;
- if (do_align) {
- unsigned long base = COLOUR_ALIGN_DOWN(addr - len, pgoff);
- addr = base + len;
- }
-
- /* make sure it can fit in the remaining address space */
- if (addr > len) {
- vma = find_vma(mm, addr-len);
- if (!vma || addr <= vma->vm_start)
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr-len);
- }
-
- if (mm->mmap_base < len)
- goto bottomup;
-
- addr = mm->mmap_base - len;
- if (do_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
-
- do {
- /*
- * Lookup failure means no vma is above this address,
- * else if new region fits below vma->vm_start,
- * return with success:
- */
- vma = find_vma(mm, addr);
- if (!vma || addr+len <= vma->vm_start)
- /* remember the address as a hint for next time */
- return (mm->free_area_cache = addr);
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+ addr = vm_unmapped_area(&info);
- /* remember the largest hole we saw so far */
- if (addr + mm->cached_hole_size < vma->vm_start)
- mm->cached_hole_size = vma->vm_start - addr;
-
- /* try just below the current vma->vm_start */
- addr = vma->vm_start - len;
- if (do_align)
- addr = COLOUR_ALIGN_DOWN(addr, pgoff);
- } while (len < vma->vm_start);
-
-bottomup:
/*
* A failed mmap() very likely causes application failure,
* so fall back to the bottom-up function here. This scenario
* can happen with large stack limits and large mmap()
* allocations.
*/
- mm->cached_hole_size = ~0UL;
- mm->free_area_cache = TASK_UNMAPPED_BASE;
- addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
- /*
- * Restore the topdown base:
- */
- mm->free_area_cache = mm->mmap_base;
- mm->cached_hole_size = ~0UL;
+ if (addr & ~PAGE_MASK) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
return addr;
}
@@ -279,7 +193,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
* You really shouldn't be using read() or write() on /dev/mem. This
* might go away in the future.
*/
-int valid_phys_addr_range(unsigned long addr, size_t size)
+int valid_phys_addr_range(phys_addr_t addr, size_t size)
{
if (addr < PHYS_OFFSET)
return 0;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 941dfb9e9a78..99b47b950efc 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -488,7 +488,7 @@ static void __init build_mem_type_table(void)
#endif
for (i = 0; i < 16; i++) {
- unsigned long v = pgprot_val(protection_map[i]);
+ pteval_t v = pgprot_val(protection_map[i]);
protection_map[i] = __pgprot(v | user_pgprot);
}
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index b29a2265af01..eb6aa73bc8b7 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -167,6 +167,10 @@
tst r1, #L_PTE_YOUNG
tstne r1, #L_PTE_PRESENT
moveq r3, #0
+#ifndef CONFIG_CPU_USE_DOMAINS
+ tstne r1, #L_PTE_NONE
+ movne r3, #0
+#endif
str r3, [r0]
mcr p15, 0, r0, c7, c10, 1 @ flush_pte
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 86b8b480634f..09c5233f4dfc 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area)
mov pc, lr
/*
- * cpu_arm926_switch_mm(pgd_phys, tsk)
+ * cpu_v6_switch_mm(pgd_phys, tsk)
*
* Set the translation table base pointer to be pgd_phys
*
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index fd045e706390..6d98c13ab827 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -100,7 +100,11 @@ ENTRY(cpu_v7_set_pte_ext)
orrne r3, r3, #PTE_EXT_XN
tst r1, #L_PTE_YOUNG
- tstne r1, #L_PTE_PRESENT
+ tstne r1, #L_PTE_VALID
+#ifndef CONFIG_CPU_USE_DOMAINS
+ eorne r1, r1, #L_PTE_NONE
+ tstne r1, #L_PTE_NONE
+#endif
moveq r3, #0
ARM( str r3, [r0, #2048]! )
@@ -161,11 +165,11 @@ ENDPROC(cpu_v7_set_pte_ext)
* TFR EV X F I D LR S
* .EEE ..EE PUI. .T.T 4RVI ZWRS BLDP WCAM
* rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
- * 1 0 110 0011 1100 .111 1101 < we want
+ * 01 0 110 0011 1100 .111 1101 < we want
*/
.align 2
.type v7_crval, #object
v7_crval:
- crval clear=0x0120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c
+ crval clear=0x2120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c
.previous
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
index 8de0f1dd1549..7b56386f9496 100644
--- a/arch/arm/mm/proc-v7-3level.S
+++ b/arch/arm/mm/proc-v7-3level.S
@@ -65,8 +65,11 @@ ENDPROC(cpu_v7_switch_mm)
*/
ENTRY(cpu_v7_set_pte_ext)
#ifdef CONFIG_MMU
- tst r2, #L_PTE_PRESENT
+ tst r2, #L_PTE_VALID
beq 1f
+ tst r3, #1 << (57 - 32) @ L_PTE_NONE
+ bicne r2, #L_PTE_VALID
+ bne 1f
tst r3, #1 << (55 - 32) @ L_PTE_DIRTY
orreq r2, #L_PTE_RDONLY
1: strd r2, r3, [r0]
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 846d279f3176..42cc833aa02f 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -57,7 +57,7 @@ ENTRY(cpu_v7_reset)
THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
mcr p15, 0, r1, c1, c0, 0 @ disable MMU
isb
- mov pc, r0
+ bx r0
ENDPROC(cpu_v7_reset)
.popsection
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index c641fb685017..b6f305e3b908 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -42,7 +42,7 @@
#define r_skb_hl ARM_R8
#define SCRATCH_SP_OFFSET 0
-#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k))
+#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + 4 * (k))
#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1)
#define SEEN_MEM_WORD(k) (1 << (k))
@@ -845,7 +845,7 @@ void bpf_jit_compile(struct sk_filter *fp)
ctx.skf = fp;
ctx.ret0_fp_idx = -1;
- ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1));
+ ctx.offsets = kzalloc(4 * (ctx.skf->len + 1), GFP_KERNEL);
if (ctx.offsets == NULL)
return;
@@ -864,7 +864,7 @@ void bpf_jit_compile(struct sk_filter *fp)
ctx.idx += ctx.imm_count;
if (ctx.imm_count) {
- ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count);
+ ctx.imms = kzalloc(4 * ctx.imm_count, GFP_KERNEL);
if (ctx.imms == NULL)
goto out;
}
diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
deleted file mode 100644
index c08a54d9d889..000000000000
--- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Structures and registers for GPIO access in the Nomadik SoC
- *
- * Copyright (C) 2008 STMicroelectronics
- * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *
- * 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.
- */
-
-#ifndef __PLAT_NOMADIK_GPIO
-#define __PLAT_NOMADIK_GPIO
-
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT 0x00
-#define NMK_GPIO_DATS 0x04
-#define NMK_GPIO_DATC 0x08
-#define NMK_GPIO_PDIS 0x0c
-#define NMK_GPIO_DIR 0x10
-#define NMK_GPIO_DIRS 0x14
-#define NMK_GPIO_DIRC 0x18
-#define NMK_GPIO_SLPC 0x1c
-#define NMK_GPIO_AFSLA 0x20
-#define NMK_GPIO_AFSLB 0x24
-#define NMK_GPIO_LOWEMI 0x28
-
-#define NMK_GPIO_RIMSC 0x40
-#define NMK_GPIO_FIMSC 0x44
-#define NMK_GPIO_IS 0x48
-#define NMK_GPIO_IC 0x4c
-#define NMK_GPIO_RWIMSC 0x50
-#define NMK_GPIO_FWIMSC 0x54
-#define NMK_GPIO_WKS 0x58
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO 0
-#define NMK_GPIO_ALT_A 1
-#define NMK_GPIO_ALT_B 2
-#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-#define NMK_GPIO_ALT_CX_SHIFT 2
-#define NMK_GPIO_ALT_C1 ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C2 ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C3 ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-#define NMK_GPIO_ALT_C4 ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
-
-/* Pull up/down values */
-enum nmk_gpio_pull {
- NMK_GPIO_PULL_NONE,
- NMK_GPIO_PULL_UP,
- NMK_GPIO_PULL_DOWN,
-};
-
-/* Sleep mode */
-enum nmk_gpio_slpm {
- NMK_GPIO_SLPM_INPUT,
- NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
- NMK_GPIO_SLPM_NOCHANGE,
- NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
-};
-
-extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
-extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
-#ifdef CONFIG_PINCTRL_NOMADIK
-extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
-#else
-static inline int nmk_gpio_set_mode(int gpio, int gpio_mode)
-{
- return -ENODEV;
-}
-#endif
-extern int nmk_gpio_get_mode(int gpio);
-
-extern void nmk_gpio_wakeups_suspend(void);
-extern void nmk_gpio_wakeups_resume(void);
-
-extern void nmk_gpio_clocks_enable(void);
-extern void nmk_gpio_clocks_disable(void);
-
-extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
-
-/*
- * Platform data to register a block: only the initial gpio/irq number.
- */
-struct nmk_gpio_platform_data {
- char *name;
- int first_gpio;
- int first_irq;
- int num_gpio;
- u32 (*get_secondary_status)(unsigned int bank);
- void (*set_ioforce)(bool enable);
- bool supports_sleepmode;
-};
-
-#endif /* __PLAT_NOMADIK_GPIO */
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
deleted file mode 100644
index 3b8ec60af351..000000000000
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License terms: GNU General Public License, version 2
- * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
- *
- * Based on arch/arm/mach-pxa/include/mach/mfp.h:
- * Copyright (C) 2007 Marvell International Ltd.
- * eric miao <eric.miao@marvell.com>
- */
-
-#ifndef __PLAT_PINCFG_H
-#define __PLAT_PINCFG_H
-
-/*
- * pin configurations are represented by 32-bit integers:
- *
- * bit 0.. 8 - Pin Number (512 Pins Maximum)
- * bit 9..10 - Alternate Function Selection
- * bit 11..12 - Pull up/down state
- * bit 13 - Sleep mode behaviour
- * bit 14 - Direction
- * bit 15 - Value (if output)
- * bit 16..18 - SLPM pull up/down state
- * bit 19..20 - SLPM direction
- * bit 21..22 - SLPM Value (if output)
- * bit 23..25 - PDIS value (if input)
- * bit 26 - Gpio mode
- * bit 27 - Sleep mode
- *
- * to facilitate the definition, the following macros are provided
- *
- * PIN_CFG_DEFAULT - default config (0):
- * pull up/down = disabled
- * sleep mode = input/wakeup
- * direction = input
- * value = low
- * SLPM direction = same as normal
- * SLPM pull = same as normal
- * SLPM value = same as normal
- *
- * PIN_CFG - default config with alternate function
- */
-
-typedef unsigned long pin_cfg_t;
-
-#define PIN_NUM_MASK 0x1ff
-#define PIN_NUM(x) ((x) & PIN_NUM_MASK)
-
-#define PIN_ALT_SHIFT 9
-#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT)
-#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
-#define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
-#define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
-#define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
-#define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
-
-#define PIN_PULL_SHIFT 11
-#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT)
-#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
-#define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
-#define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
-#define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
-
-#define PIN_SLPM_SHIFT 13
-#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
-#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
-#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
-#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
-/* These two replace the above in DB8500v2+ */
-#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
-#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
-#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE
-
-#define PIN_SLPM_GPIO PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */
-#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */
-
-#define PIN_DIR_SHIFT 14
-#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
-#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
-#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
-#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
-
-#define PIN_VAL_SHIFT 15
-#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
-#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
-#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
-#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
-
-#define PIN_SLPM_PULL_SHIFT 16
-#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL(x) \
- (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL_NONE \
- ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL_UP \
- ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
-#define PIN_SLPM_PULL_DOWN \
- ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
-
-#define PIN_SLPM_DIR_SHIFT 19
-#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
-#define PIN_SLPM_DIR(x) \
- (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
-#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
-#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
-
-#define PIN_SLPM_VAL_SHIFT 21
-#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
-#define PIN_SLPM_VAL(x) \
- (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
-#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
-#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
-
-#define PIN_SLPM_PDIS_SHIFT 23
-#define PIN_SLPM_PDIS_MASK (0x3 << PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS(x) \
- (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS_NO_CHANGE (0 << PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS_DISABLED (1 << PIN_SLPM_PDIS_SHIFT)
-#define PIN_SLPM_PDIS_ENABLED (2 << PIN_SLPM_PDIS_SHIFT)
-
-#define PIN_LOWEMI_SHIFT 25
-#define PIN_LOWEMI_MASK (0x1 << PIN_LOWEMI_SHIFT)
-#define PIN_LOWEMI(x) (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT)
-#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT)
-#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT)
-
-#define PIN_GPIOMODE_SHIFT 26
-#define PIN_GPIOMODE_MASK (0x1 << PIN_GPIOMODE_SHIFT)
-#define PIN_GPIOMODE(x) (((x) & PIN_GPIOMODE_MASK) >> PIN_GPIOMODE_SHIFT)
-#define PIN_GPIOMODE_DISABLED (0 << PIN_GPIOMODE_SHIFT)
-#define PIN_GPIOMODE_ENABLED (1 << PIN_GPIOMODE_SHIFT)
-
-#define PIN_SLEEPMODE_SHIFT 27
-#define PIN_SLEEPMODE_MASK (0x1 << PIN_SLEEPMODE_SHIFT)
-#define PIN_SLEEPMODE(x) (((x) & PIN_SLEEPMODE_MASK) >> PIN_SLEEPMODE_SHIFT)
-#define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT)
-#define PIN_SLEEPMODE_ENABLED (1 << PIN_SLEEPMODE_SHIFT)
-
-
-/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
-#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
-#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
-#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
-#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
-#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
-
-#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
-#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
-#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
-#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
-#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
-
-#define PIN_CFG_DEFAULT (0)
-
-#define PIN_CFG(num, alt) \
- (PIN_CFG_DEFAULT |\
- (PIN_NUM(num) | PIN_##alt))
-
-#define PIN_CFG_INPUT(num, alt, pull) \
- (PIN_CFG_DEFAULT |\
- (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
-
-#define PIN_CFG_OUTPUT(num, alt, val) \
- (PIN_CFG_DEFAULT |\
- (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
-
-extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
-extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
-extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num);
-
-#endif
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index a5683a84c6ee..6013831a043e 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -26,12 +26,14 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
+#include <linux/i2c-omap.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/irqs.h>
#include <plat/i2c.h>
+#include <plat/omap-pm.h>
#include <plat/omap_device.h>
#define OMAP_I2C_SIZE 0x3f
@@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id)
#ifdef CONFIG_ARCH_OMAP2PLUS
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+ omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
static inline int omap2_i2c_add_bus(int bus_id)
{
int l;
@@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id)
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
pdata->flags = dev_attr->flags;
+ /*
+ * When waiting for completion of a i2c transfer, we need to
+ * set a wake up latency constraint for the MPU. This is to
+ * ensure quick enough wakeup from idle, when transfer
+ * completes.
+ * Only omap3 has support for constraints
+ */
+ if (cpu_is_omap34xx())
+ pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 8b4e4f2da2f5..346af5b490be 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -126,6 +126,7 @@ struct omap_mmc_platform_data {
/* we can put the features above into this variable */
#define HSMMC_HAS_PBIAS (1 << 0)
#define HSMMC_HAS_UPDATED_RESET (1 << 1)
+#define HSMMC_HAS_HSPE_SUPPORT (1 << 2)
unsigned features;
int switch_pin; /* gpio (card detect) */
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 1957a8516e93..ff9b0aab5281 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -30,35 +30,6 @@
*/
#define OMAP_SERIAL_NAME "ttyO"
-#define OMAP_MODE13X_SPEED 230400
-
-#define OMAP_UART_SCR_TX_EMPTY 0x08
-
-/* WER = 0x7F
- * Enable module level wakeup in WER reg
- */
-#define OMAP_UART_WER_MOD_WKUP 0X7F
-
-/* Enable XON/XOFF flow control on output */
-#define OMAP_UART_SW_TX 0x04
-
-/* Enable XON/XOFF flow control on input */
-#define OMAP_UART_SW_RX 0x04
-
-#define OMAP_UART_SYSC_RESET 0X07
-#define OMAP_UART_TCR_TRIG 0X0F
-#define OMAP_UART_SW_CLR 0XF0
-#define OMAP_UART_FIFO_CLR 0X06
-
-#define OMAP_UART_DMA_CH_FREE -1
-
-#define OMAP_MAX_HSUART_PORTS 6
-
-#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
-
-#define UART_ERRATA_i202_MDR1_ACCESS BIT(0)
-#define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1)
-
struct omap_uart_port_info {
bool dma_enabled; /* To specify DMA Mode */
unsigned int uartclk; /* UART clock rate */
@@ -77,30 +48,4 @@ struct omap_uart_port_info {
void (*enable_wakeup)(struct device *, bool);
};
-struct uart_omap_dma {
- u8 uart_dma_tx;
- u8 uart_dma_rx;
- int rx_dma_channel;
- int tx_dma_channel;
- dma_addr_t rx_buf_dma_phys;
- dma_addr_t tx_buf_dma_phys;
- unsigned int uart_base;
- /*
- * Buffer for rx dma.It is not required for tx because the buffer
- * comes from port structure.
- */
- unsigned char *rx_buf;
- unsigned int prev_rx_dma_pos;
- int tx_buf_size;
- int tx_dma_used;
- int rx_dma_used;
- spinlock_t tx_lock;
- spinlock_t rx_lock;
- /* timer to poll activity on rx dma */
- struct timer_list rx_timer;
- unsigned int rx_buf_size;
- unsigned int rx_poll_rate;
- unsigned int rx_timeout;
-};
-
#endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 65fce44dce34..b780470d03ea 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -109,15 +109,6 @@
#define OMAP5UART4 OMAP4UART4
#define ZOOM_UART 95 /* Only on zoom2/3 */
-/* This is only used by 8250.c for omap1510 */
-#define is_omap_port(pt) ({int __ret = 0; \
- if ((pt)->port.mapbase == OMAP1_UART1_BASE || \
- (pt)->port.mapbase == OMAP1_UART2_BASE || \
- (pt)->port.mapbase == OMAP1_UART3_BASE) \
- __ret = 1; \
- __ret; \
- })
-
#ifndef __ASSEMBLER__
struct omap_board_data;
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index db98e7021f0d..0abd1c469887 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
chan->number, __func__, buf);
- if (chan->end == NULL)
+ if (chan->end == NULL) {
pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
chan->number, __func__, chan);
-
- chan->end->next = buf;
- chan->end = buf;
+ } else {
+ chan->end->next = buf;
+ chan->end = buf;
+ }
}
/* if necessary, update the next buffer field */
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index f8db7b2deb36..87dbd81bdf51 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -12,6 +12,7 @@ config ARCH_SPEAR13XX
bool "ST SPEAr13xx with Device Tree"
select ARM_GIC
select CPU_V7
+ select GPIO_SPEAR_SPICS
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
select PINCTRL